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: ddf220c99cac
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2b49f189007a
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Jun 13, 2015

  1. Copy the full SHA
    43f95ec View commit details
  2. Copy the full SHA
    2b49f18 View commit details
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.array.ArrayUtils;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.util.cli.Options;

import java.util.Arrays;
@@ -41,6 +42,10 @@ public ArrayBuilderNode(RubyContext context) {
public abstract Object append(Object store, int index, Object value);
public abstract Object finish(Object store, int length);

public RubyArray finishAndCreate(RubyClass arrayClass, Object store, int length) {
return ArrayNodes.createGeneralArray(arrayClass, finish(store, length), length);
}

protected RubyContext getContext() {
return context;
}
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
import org.jruby.truffle.nodes.RubyGuards;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.nodes.core.*;
import org.jruby.truffle.nodes.core.array.ArrayBuilderNode;
import org.jruby.truffle.nodes.core.array.ArrayNodes;
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
@@ -320,14 +321,12 @@ public Object construct(VirtualFrame frame, RubyClass hashClass, Object[] args)
final Object pair = store[n];

if (!(pair instanceof RubyArray)) {
CompilerDirectives.transferToInterpreter();
return constructFallback(frame, hashClass, args);
}

final RubyArray pairArray = (RubyArray) pair;

if (!(ArrayNodes.getStore(pairArray) instanceof Object[])) {
CompilerDirectives.transferToInterpreter();
return constructFallback(frame, hashClass, args);
}

@@ -924,6 +923,8 @@ private void copyOtherFields(RubyBasicObject self, RubyBasicObject from) {
@ImportStatic(HashGuards.class)
public abstract static class MapNode extends YieldingCoreMethodNode {

@Child ArrayBuilderNode arrayBuilderNode;

public MapNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}
@@ -940,47 +941,59 @@ public RubyBasicObject mapNull(VirtualFrame frame, RubyBasicObject hash, RubyPro
public RubyBasicObject mapPackedArray(VirtualFrame frame, RubyBasicObject hash, RubyProc block) {
assert verifyStore(hash);

final Object[] store = (Object[]) getStore(hash);
final int size = getSize(hash);
if (arrayBuilderNode == null) {
CompilerDirectives.transferToInterpreter();
arrayBuilderNode = insert(new ArrayBuilderNode.UninitializedArrayBuilderNode(getContext()));
}

final Object[] result = new Object[size];
final Object[] store = (Object[]) getStore(hash);

int count = 0;
final int length = getSize(hash);
Object resultStore = arrayBuilderNode.start(length);

try {
for (int n = 0; n < PackedArrayStrategy.MAX_ENTRIES; n++) {
if (n < size) {
if (n < length) {
final Object key = PackedArrayStrategy.getKey(store, n);
final Object value = PackedArrayStrategy.getValue(store, n);
result[n] = yield(frame, block, key, value);

if (CompilerDirectives.inInterpreter()) {
count++;
}
resultStore = arrayBuilderNode.append(resultStore, n, yield(frame, block, key, value));
}
}
} finally {
if (CompilerDirectives.inInterpreter()) {
getRootNode().reportLoopCount(count);
getRootNode().reportLoopCount(length);
}
}

return createArray(result, size);
return arrayBuilderNode.finishAndCreate(getContext().getCoreLibrary().getArrayClass(), resultStore, length);
}

@Specialization(guards = "isBucketHash(hash)")
public RubyBasicObject mapBuckets(VirtualFrame frame, RubyBasicObject hash, RubyProc block) {
CompilerDirectives.transferToInterpreter();

assert verifyStore(hash);

final RubyBasicObject array = createEmptyArray();
if (arrayBuilderNode == null) {
CompilerDirectives.transferToInterpreter();
arrayBuilderNode = insert(new ArrayBuilderNode.UninitializedArrayBuilderNode(getContext()));
}

for (Map.Entry<Object, Object> keyValue : HashNodes.iterableKeyValues(hash)) {
ArrayNodes.slowPush(array, yield(frame, block, keyValue.getKey(), keyValue.getValue()));
final int length = getSize(hash);
Object store = arrayBuilderNode.start(length);

int index = 0;

try {
for (Map.Entry<Object, Object> keyValue : BucketsStrategy.iterableKeyValues(getFirstInSequence(hash))) {
arrayBuilderNode.append(store, index, yield(frame, block, keyValue.getKey(), keyValue.getValue()));
index++;
}
} finally {
if (CompilerDirectives.inInterpreter()) {
getRootNode().reportLoopCount(length);
}
}

return array;
return arrayBuilderNode.finishAndCreate(getContext().getCoreLibrary().getArrayClass(), store, length);
}

}
@@ -1097,8 +1110,6 @@ public RubyBasicObject mergePackedArrayPackedArray(VirtualFrame frame, RubyBasic
return createHash(hash.getLogicalClass(), getDefaultBlock(hash), getDefaultValue(hash), merged, mergedSize, null, null);
}

CompilerDirectives.transferToInterpreter();

return mergeBucketsBuckets(frame, hash, other, block);
}