Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c6c34bc23ba0
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: fe84356a6e52
Choose a head ref
  • 3 commits
  • 10 files changed
  • 1 contributor

Commits on Apr 13, 2016

  1. Copy the full SHA
    58e8e64 View commit details
  2. Copy the full SHA
    b5c6f62 View commit details
  3. Copy the full SHA
    fe84356 View commit details
Original file line number Diff line number Diff line change
@@ -9,26 +9,27 @@
*/
package org.jruby.truffle.core.array;

import static org.jruby.truffle.core.array.ArrayHelpers.createArray;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.language.RubyGuards;
import org.jruby.truffle.language.RubyNode;

/**
* Concatenate arrays.
* Concatenate argument arrays (translating a org.jruby.ast.ArgsCatNode).
*/
public final class ArrayConcatNode extends RubyNode {

@Children private final RubyNode[] children;
// Use an arrayBuilderNode to stabilize the array type for a given location.
@Child private ArrayBuilderNode arrayBuilderNode;

private final BranchProfile appendArrayProfile = BranchProfile.create();
private final BranchProfile appendObjectProfile = BranchProfile.create();
private final ConditionProfile isArrayProfile = ConditionProfile.createBinaryProfile();

public ArrayConcatNode(RubyContext context, SourceSection sourceSection, RubyNode[] children) {
super(context, sourceSection);
@@ -39,53 +40,53 @@ public ArrayConcatNode(RubyContext context, SourceSection sourceSection, RubyNod

@Override
public DynamicObject execute(VirtualFrame frame) {
Object store = arrayBuilderNode.start();
int length = 0;
if (children.length == 1) {
return executeSingle(frame, store, length);
return executeSingle(frame);
} else {
return executeRubyArray(frame, store, length);
return executeMultiple(frame);
}
}

@ExplodeLoop
private DynamicObject executeSingle(VirtualFrame frame, Object store, int length) {
private DynamicObject executeSingle(VirtualFrame frame) {
Object store = arrayBuilderNode.start();
final Object childObject = children[0].execute(frame);
if (RubyGuards.isRubyArray(childObject)) {
appendArrayProfile.enter();

final int size;
if (isArrayProfile.profile(RubyGuards.isRubyArray(childObject))) {
final DynamicObject childArray = (DynamicObject) childObject;
store = arrayBuilderNode.ensure(store, length + Layouts.ARRAY.getSize(childArray));
store = arrayBuilderNode.appendArray(store, length, childArray);
length += Layouts.ARRAY.getSize(childArray);
size = Layouts.ARRAY.getSize(childArray);
store = arrayBuilderNode.ensure(store, size);
store = arrayBuilderNode.appendArray(store, 0, childArray);
} else {
appendObjectProfile.enter();
store = arrayBuilderNode.ensure(store, length + 1);
store = arrayBuilderNode.appendValue(store, length, childObject);
length++;
size = 1;
store = arrayBuilderNode.ensure(store, 1);
store = arrayBuilderNode.appendValue(store, 0, childObject);
}
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), arrayBuilderNode.finish(store, length), length);
return createArray(getContext(), arrayBuilderNode.finish(store, size), size);
}

@ExplodeLoop
private DynamicObject executeRubyArray(VirtualFrame frame, Object store, int length) {
private DynamicObject executeMultiple(VirtualFrame frame) {
Object store = arrayBuilderNode.start();
int length = 0;

for (int n = 0; n < children.length; n++) {
final Object childObject = children[n].execute(frame);

if (RubyGuards.isRubyArray(childObject)) {
appendArrayProfile.enter();
if (isArrayProfile.profile(RubyGuards.isRubyArray(childObject))) {
final DynamicObject childArray = (DynamicObject) childObject;
store = arrayBuilderNode.ensure(store, length + Layouts.ARRAY.getSize(childArray));
final int size = Layouts.ARRAY.getSize(childArray);
store = arrayBuilderNode.ensure(store, length + size);
store = arrayBuilderNode.appendArray(store, length, childArray);
length += Layouts.ARRAY.getSize(childArray);
length += size;
} else {
appendObjectProfile.enter();
store = arrayBuilderNode.ensure(store, length + 1);
store = arrayBuilderNode.appendValue(store, length, childObject);
length++;
}
}

return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), arrayBuilderNode.finish(store, length), length);
return createArray(getContext(), arrayBuilderNode.finish(store, length), length);
}

@ExplodeLoop
Original file line number Diff line number Diff line change
@@ -9,18 +9,20 @@
*/
package org.jruby.truffle.core.array;

import com.oracle.truffle.api.CompilerDirectives;
import static org.jruby.truffle.core.array.ArrayHelpers.createArray;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.language.RubyNode;

@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)})
@NodeChildren({ @NodeChild(value = "array", type = RubyNode.class) })
@ImportStatic(ArrayGuards.class)
public abstract class ArrayDropTailNode extends RubyNode {

@@ -33,55 +35,20 @@ public ArrayDropTailNode(RubyContext context, SourceSection sourceSection, int i

@Specialization(guards = "isNullArray(array)")
public DynamicObject getHeadNull(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), null, 0);
return createArray(getContext(), null, 0);
}

@Specialization(guards = "isIntArray(array)")
public DynamicObject getHeadIntegerFixnum(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), null, 0);
} else {
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), ArrayUtils.extractRange((int[]) Layouts.ARRAY.getStore(array), 0, Layouts.ARRAY.getSize(array) - index), Layouts.ARRAY.getSize(array) - index);
}
}

@Specialization(guards = "isLongArray(array)")
public DynamicObject geHeadLongFixnum(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), null, 0);
} else {
final int size = Layouts.ARRAY.getSize(array) - index;
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), ArrayUtils.extractRange((long[]) Layouts.ARRAY.getStore(array), 0, size), size);
}
}

@Specialization(guards = "isDoubleArray(array)")
public DynamicObject getHeadFloat(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), null, 0);
} else {
final int size = Layouts.ARRAY.getSize(array) - index;
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), ArrayUtils.extractRange((double[]) Layouts.ARRAY.getStore(array), 0, size), size);
}
}

@Specialization(guards = "isObjectArray(array)")
public DynamicObject getHeadObject(DynamicObject array) {
CompilerDirectives.transferToInterpreter();

if (index >= Layouts.ARRAY.getSize(array)) {
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), null, 0);
@Specialization(guards = "strategy.matches(array)")
public DynamicObject dropTail(DynamicObject array,
@Cached("of(array)") ArrayStrategy strategy,
@Cached("createBinaryProfile()") ConditionProfile indexLargerThanSize) {
final int size = Layouts.ARRAY.getSize(array);
if (indexLargerThanSize.profile(index >= size)) {
return createArray(getContext(), null, 0);
} else {
final int size = Layouts.ARRAY.getSize(array) - index;
return Layouts.ARRAY.createArray(coreLibrary().getArrayFactory(), ArrayUtils.extractRange((Object[]) Layouts.ARRAY.getStore(array), 0, size), size);
final int newSize = size - index;
final Object newStore = strategy.newMirror(array).extractRange(0, newSize).getArray();
return createArray(getContext(), newStore, newSize);
}
}

Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@ public interface ArrayMirror {

void copyTo(Object[] destination, int sourceStart, int destinationStart, int count);

ArrayMirror extractRange(int start, int end);

Object getArray();

ArrayMirror copyArrayAndMirror();
Original file line number Diff line number Diff line change
@@ -137,17 +137,15 @@ public DynamicObject addNullNull(DynamicObject a, DynamicObject b) {
public DynamicObject addNullOther(DynamicObject a, DynamicObject b,
@Cached("of(b)") ArrayStrategy strategy) {
final int size = getSize(b);
final ArrayMirror mirror = strategy.newArray(size);
strategy.newMirror(b).copyTo(mirror, 0, 0, size);
final ArrayMirror mirror = strategy.newMirror(b).extractRange(0, size);
return createArray(getContext(), mirror.getArray(), size);
}

@Specialization(guards = { "!isNullArray(a)", "isNullArray(b)", "strategy.matches(a)" }, limit = "ARRAY_STRATEGIES")
public DynamicObject addOtherNull(DynamicObject a, DynamicObject b,
@Cached("of(a)") ArrayStrategy strategy) {
final int size = getSize(a);
final ArrayMirror mirror = strategy.newArray(size);
strategy.newMirror(a).copyTo(mirror, 0, 0, size);
final ArrayMirror mirror = strategy.newMirror(a).extractRange(0, size);
return createArray(getContext(), mirror.getArray(), size);
}

Original file line number Diff line number Diff line change
@@ -53,6 +53,11 @@ public void copyTo(Object[] destination, int sourceStart, int destinationStart,
}
}

@Override
public ArrayMirror extractRange(int start, int end) {
return new DoubleArrayMirror(ArrayUtils.extractRange(array, start, end));
}

@Override
public Object getArray() {
return array;
Original file line number Diff line number Diff line change
@@ -45,6 +45,12 @@ public void copyTo(Object[] destination, int sourceStart, int destinationStart,
}
}

@Override
public ArrayMirror extractRange(int start, int end) {
assert start == 0 && end == 0;
return new EmptyArrayMirror();
}

@Override
public Object getArray() {
return null;
Original file line number Diff line number Diff line change
@@ -64,6 +64,11 @@ public void copyTo(Object[] destination, int sourceStart, int destinationStart,
}
}

@Override
public ArrayMirror extractRange(int start, int end) {
return new IntegerArrayMirror(ArrayUtils.extractRange(array, start, end));
}

@Override
public Object getArray() {
return array;
Original file line number Diff line number Diff line change
@@ -53,6 +53,11 @@ public void copyTo(Object[] destination, int sourceStart, int destinationStart,
}
}

@Override
public ArrayMirror extractRange(int start, int end) {
return new LongArrayMirror(ArrayUtils.extractRange(array, start, end));
}

@Override
public Object getArray() {
return array;
Original file line number Diff line number Diff line change
@@ -55,6 +55,11 @@ public void copyTo(Object[] destination, int sourceStart, int destinationStart,
}
}

@Override
public ArrayMirror extractRange(int start, int end) {
return new LongIntArrayMirror(ArrayUtils.extractRange(array, start, end));
}

@Override
public Object getArray() {
return array;
Original file line number Diff line number Diff line change
@@ -49,6 +49,11 @@ public void copyTo(Object[] destination, int sourceStart, int destinationStart,
System.arraycopy(array, sourceStart, destination, destinationStart, count);
}

@Override
public ArrayMirror extractRange(int start, int end) {
return new ObjectArrayMirror(ArrayUtils.extractRange(array, start, end));
}

@Override
public Object getArray() {
return array;