Navigation Menu

Skip to content

Commit

Permalink
[Truffle] Randomise empty arrays to any storage type.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Feb 6, 2015
1 parent 1993f47 commit 7b206aa
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 1 deletion.
Expand Up @@ -46,6 +46,7 @@ public class RubyCallNode extends RubyNode {
@CompilerDirectives.CompilationFinal private boolean seenNullInUnsplat = false;
@CompilerDirectives.CompilationFinal private boolean seenIntegerFixnumInUnsplat = false;
@CompilerDirectives.CompilationFinal private boolean seenLongFixnumInUnsplat = false;
@CompilerDirectives.CompilationFinal private boolean seenFloatInUnsplat = false;
@CompilerDirectives.CompilationFinal private boolean seenObjectInUnsplat = false;

@Child private CallDispatchHeadNode respondToMissing;
Expand Down Expand Up @@ -136,6 +137,8 @@ private Object[] splat(Object argument) {
return ArrayUtils.boxUntil((int[]) store, size);
} else if (seenLongFixnumInUnsplat && store instanceof long[]) {
return ArrayUtils.boxUntil((long[]) store, size);
} else if (seenFloatInUnsplat && store instanceof double[]) {
return ArrayUtils.boxUntil((double[]) store, size);
} else if (seenObjectInUnsplat && store instanceof Object[]) {
return ArrayUtils.extractRange((Object[]) store, 0, size);
}
Expand All @@ -151,6 +154,9 @@ private Object[] splat(Object argument) {
} else if (store instanceof long[]) {
seenLongFixnumInUnsplat = true;
return ArrayUtils.boxUntil((long[]) store, size);
} else if (store instanceof double[]) {
seenFloatInUnsplat = true;
return ArrayUtils.boxUntil((double[]) store, size);
} else if (store instanceof Object[]) {
seenObjectInUnsplat = true;
return ArrayUtils.extractRange((Object[]) store, 0, size);
Expand Down
Expand Up @@ -440,6 +440,36 @@ public Object append(Object store, int index, RubyArray array) {

CompilerDirectives.transferToInterpreterAndInvalidate();

if (otherStore instanceof int[]) {
// TODO CS 5-Feb-15 hack to get things working with empty int[] store

if (((int[]) otherStore).length > 0) {
throw new UnsupportedOperationException();
}

return store;
}

if (otherStore instanceof long[]) {
// TODO CS 5-Feb-15 hack to get things working with empty long[] store

if (((long[]) otherStore).length > 0) {
throw new UnsupportedOperationException();
}

return store;
}

if (otherStore instanceof double[]) {
// TODO CS 5-Feb-15 hack to get things working with empty double[] store

if (((double[]) otherStore).length > 0) {
throw new UnsupportedOperationException();
}

return store;
}

if (otherStore instanceof Object[]) {
hasAppendedObjectArray = true;
System.arraycopy(otherStore, 0, store, index, array.getSize());
Expand Down
89 changes: 89 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
Expand Up @@ -136,6 +136,54 @@ public RubyArray addNullObject(RubyArray a, RubyArray b) {
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), Arrays.copyOf((Object[]) b.getStore(), size), size);
}

@Specialization(guards = "isIntegerFixnum")
public RubyArray addEmptyIntegerFixnum(RubyArray a, RubyArray b) {
// TODO CS 5-Feb-15 hack to get things working with empty int[] store

if (a.getSize() != 0) {
throw new UnsupportedOperationException();
}

final int size = b.getSize();
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
}

@Specialization(guards = "isLongFixnum")
public RubyArray addEmptyLongFixnum(RubyArray a, RubyArray b) {
// TODO CS 5-Feb-15 hack to get things working with empty long[] store

if (a.getSize() != 0) {
throw new UnsupportedOperationException();
}

final int size = b.getSize();
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
}

@Specialization(guards = "isFloat")
public RubyArray addEmptyDouble(RubyArray a, RubyArray b) {
// TODO CS 5-Feb-15 hack to get things working with empty double[] store

if (a.getSize() != 0) {
throw new UnsupportedOperationException();
}

final int size = b.getSize();
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
}

@Specialization(guards = "isObject")
public RubyArray addEmptyObject(RubyArray a, RubyArray b) {
// TODO CS 5-Feb-15 hack to get things working with empty Object[] store

if (a.getSize() != 0) {
throw new UnsupportedOperationException();
}

final int size = b.getSize();
return new RubyArray(getContext().getCoreLibrary().getArrayClass(), ArrayUtils.box(b.getStore()), size);
}

}

@CoreMethod(names = "-", required = 1)
Expand Down Expand Up @@ -2084,6 +2132,23 @@ public boolean includeLongFixnum(VirtualFrame frame, RubyArray array, Object val
return false;
}

@Specialization(guards = "isFloat")
public boolean includeFloat(VirtualFrame frame, RubyArray array, Object value) {
final double[] store = (double[]) array.getStore();

for (int n = 0; n < array.getSize(); n++) {
final Object stored = store[n];

notDesignedForCompilation();

if (equalNode.executeSameOrEqual(frame, stored, value)) {
return true;
}
}

return false;
}

@Specialization(guards = "isObject")
public boolean includeObject(VirtualFrame frame, RubyArray array, Object value) {
final Object[] store = (Object[]) array.getStore();
Expand Down Expand Up @@ -3289,6 +3354,30 @@ public RubyArray pushLongFixnumSingleLongFixnum(RubyArray array, Object... value
return array;
}

@Specialization(guards = "isLongFixnum")
public RubyArray pushLongFixnum(RubyArray array, Object... values) {
// TODO CS 5-Feb-15 hack to get things working with empty long[] store

if (array.getSize() != 0) {
throw new UnsupportedOperationException();
}

array.setStore(values, values.length);
return array;
}

@Specialization(guards = "isFloat")
public RubyArray pushFloat(RubyArray array, Object... values) {
// TODO CS 5-Feb-15 hack to get things working with empty double[] store

if (array.getSize() != 0) {
throw new UnsupportedOperationException();
}

array.setStore(values, values.length);
return array;
}

@Specialization(guards = "isObject")
public RubyArray pushObject(RubyArray array, Object... values) {
final int oldSize = array.getSize();
Expand Down
Expand Up @@ -223,6 +223,25 @@ public void setStore(Object store, int size) {

@CompilerDirectives.TruffleBoundary
private static Object randomizeStorageStrategy(Object store, int size) {
// Use any type for empty arrays

if (size == 0) {
switch (random.nextInt(5)) {
case 0:
return null;
case 1:
return new int[]{};
case 2:
return new long[]{};
case 3:
return new double[]{};
case 4:
return new Object[]{};
default:
throw new IllegalStateException();
}
}

// Convert to the canonical store type first

final Object[] boxedStore = ArrayUtils.box(store);
Expand Down Expand Up @@ -272,7 +291,7 @@ private static Object randomizeStorageStrategy(Object store, int size) {

return canonicalStore;
} else {
return canonicalStore;
throw new UnsupportedOperationException();
}
}

Expand Down

0 comments on commit 7b206aa

Please sign in to comment.