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

Commits on Jun 28, 2016

  1. [Truffle] ReferenceEqualNode does not need the frame.

    * Also add a create() helper for Cached.
    eregon committed Jun 28, 2016
    Copy the full SHA
    cbccc0a View commit details
  2. 2
    Copy the full SHA
    c9d6df5 View commit details
30 changes: 6 additions & 24 deletions truffle/src/main/java/org/jruby/truffle/core/VMPrimitiveNodes.java
Original file line number Diff line number Diff line change
@@ -37,7 +37,6 @@
*/
package org.jruby.truffle.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback;
@@ -55,10 +54,7 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.Primitive;
import org.jruby.truffle.builtins.PrimitiveArrayArgumentsNode;
import org.jruby.truffle.core.basicobject.BasicObjectNodes;
import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory.ReferenceEqualNodeFactory;
import org.jruby.truffle.core.kernel.KernelNodes;
import org.jruby.truffle.core.kernel.KernelNodesFactory;
import org.jruby.truffle.core.proc.ProcSignalHandler;
@@ -96,30 +92,22 @@ public abstract class VMPrimitiveNodes {
public abstract static class CatchNode extends PrimitiveArrayArgumentsNode {

@Child private YieldNode dispatchNode;
@Child private BasicObjectNodes.ReferenceEqualNode referenceEqualNode;

public CatchNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
dispatchNode = new YieldNode(context);
}

private boolean areSame(VirtualFrame frame, Object left, Object right) {
if (referenceEqualNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null));
}
return referenceEqualNode.executeReferenceEqual(frame, left, right);
}

@Specialization
public Object doCatch(VirtualFrame frame, Object tag, DynamicObject block,
@Cached("create()") BranchProfile catchProfile,
@Cached("createBinaryProfile()") ConditionProfile matchProfile) {
@Cached("createBinaryProfile()") ConditionProfile matchProfile,
@Cached("create()") ReferenceEqualNode referenceEqualNode) {
try {
return dispatchNode.dispatch(frame, block, tag);
} catch (ThrowException e) {
catchProfile.enter();
if (matchProfile.profile(areSame(frame, e.getTag(), tag))) {
if (matchProfile.profile(referenceEqualNode.executeReferenceEqual(e.getTag(), tag))) {
return e.getValue();
} else {
throw e;
@@ -232,16 +220,10 @@ public DynamicObject vmObjectClass(VirtualFrame frame, Object object) {
@Primitive(name = "vm_object_equal", needsSelf = false)
public static abstract class VMObjectEqualPrimitiveNode extends PrimitiveArrayArgumentsNode {

@Child ReferenceEqualNode referenceEqualNode;

public VMObjectEqualPrimitiveNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
referenceEqualNode = ReferenceEqualNodeFactory.create(null);
}

@Specialization
public boolean vmObjectEqual(VirtualFrame frame, Object a, Object b) {
return referenceEqualNode.executeReferenceEqual(frame, a, b);
public boolean vmObjectEqual(VirtualFrame frame, Object a, Object b,
@Cached("create()") ReferenceEqualNode referenceEqualNode) {
return referenceEqualNode.executeReferenceEqual(a, b);
}

}
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
import org.jruby.truffle.builtins.NonStandard;
import org.jruby.truffle.builtins.UnaryCoreMethodNode;
import org.jruby.truffle.core.array.ArrayHelpers;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory.ReferenceEqualNodeFactory;
import org.jruby.truffle.core.cast.BooleanCastNodeGen;
import org.jruby.truffle.core.module.ModuleOperations;
import org.jruby.truffle.core.rope.Rope;
@@ -50,7 +51,6 @@
import org.jruby.truffle.language.parser.ParserContext;
import org.jruby.truffle.language.supercall.SuperCallNode;
import org.jruby.truffle.language.yield.YieldNode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -93,7 +93,11 @@ public boolean equal(VirtualFrame frame, Object a, Object b) {
@CoreMethod(names = { "equal?", "==" }, required = 1)
public abstract static class ReferenceEqualNode extends CoreMethodArrayArgumentsNode {

public abstract boolean executeReferenceEqual(VirtualFrame frame, Object a, Object b);
public static ReferenceEqualNode create() {
return ReferenceEqualNodeFactory.create(null);
}

public abstract boolean executeReferenceEqual(Object a, Object b);

@Specialization
public boolean equal(boolean a, boolean b) {
10 changes: 5 additions & 5 deletions truffle/src/main/java/org/jruby/truffle/core/hash/HashNodes.java
Original file line number Diff line number Diff line change
@@ -222,7 +222,7 @@ public Object getConstantIndexPackedArray(VirtualFrame frame, DynamicObject hash
"isCompareByIdentity(hash)",
"cachedIndex >= 0",
"cachedIndex < getSize(hash)",
"equal(frame, key, getKeyAt(hash, cachedIndex))"
"equal(key, getKeyAt(hash, cachedIndex))"
}, limit = "1")
public Object getConstantIndexPackedArrayByIdentity(VirtualFrame frame, DynamicObject hash, Object key,
@Cached("index(frame, hash, key)") int cachedIndex) {
@@ -259,7 +259,7 @@ protected int index(VirtualFrame frame, DynamicObject hash, Object key) {

for (int n = 0; n < size; n++) {
if (HashGuards.isCompareByIdentity(hash)) {
if (equal(frame, key, PackedArrayStrategy.getKey(store, n))) {
if (equal(key, PackedArrayStrategy.getKey(store, n))) {
return n;
}
} else {
@@ -280,8 +280,8 @@ protected boolean eql(VirtualFrame frame, Object key1, Object key2) {
return eqlNode.callBoolean(frame, key1, "eql?", null, key2);
}

protected boolean equal(VirtualFrame frame, Object key1, Object key2) {
return equalNode.executeReferenceEqual(frame, key1, key2);
protected boolean equal(Object key1, Object key2) {
return equalNode.executeReferenceEqual(key1, key2);
}

@ExplodeLoop
@@ -325,7 +325,7 @@ public Object getPackedArrayByIdentity(VirtualFrame frame, DynamicObject hash, O

for (int n = 0; n < getContext().getOptions().HASH_PACKED_ARRAY_MAX; n++) {
if (n < size) {
if (equal(frame, key, PackedArrayStrategy.getKey(store, n))) {
if (equal(key, PackedArrayStrategy.getKey(store, n))) {
return PackedArrayStrategy.getValue(store, n);
}
}
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ public HashLookupResult lookup(VirtualFrame frame, DynamicObject hash, Object ke

while (entry != null) {
if (byIdentityProfile.profile(Layouts.HASH.getCompareByIdentity(hash))) {
if (equalNode.executeReferenceEqual(frame, key, entry.getKey())) {
if (equalNode.executeReferenceEqual(key, entry.getKey())) {
return new HashLookupResult(hashed, index, previousEntry, entry);
}
} else {
Original file line number Diff line number Diff line change
@@ -111,7 +111,7 @@ public Object setPackedArray(VirtualFrame frame, DynamicObject hash, Object key,
if (n < size) {
final boolean equal;
if (profiledByIdentity) {
equal = equalNode.executeReferenceEqual(frame, key, PackedArrayStrategy.getKey(store, n));
equal = equalNode.executeReferenceEqual(key, PackedArrayStrategy.getKey(store, n));
} else {
equal = hashed == PackedArrayStrategy.getHashed(store, n) &&
eqlNode.callBoolean(frame, key, "eql?", null, PackedArrayStrategy.getKey(store, n));
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@
import org.jruby.truffle.core.array.ArrayUtils;
import org.jruby.truffle.core.basicobject.BasicObjectNodes;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory;
import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.core.binding.BindingNodes;
import org.jruby.truffle.core.cast.BooleanCastWithDefaultNodeGen;
import org.jruby.truffle.core.cast.DurationToMillisecondsNodeGen;
@@ -213,31 +214,22 @@ private DynamicObject spawnAndCaptureOutput(DynamicObject command, final Dynamic
@CoreMethod(names = "===", required = 1)
public abstract static class SameOrEqualNode extends CoreMethodArrayArgumentsNode {

@Child private BasicObjectNodes.ReferenceEqualNode referenceEqualNode;
@Child private CallDispatchHeadNode equalNode;

private final ConditionProfile sameProfile = ConditionProfile.createBinaryProfile();

public abstract boolean executeSameOrEqual(VirtualFrame frame, Object a, Object b);

@Specialization
public boolean sameOrEqual(VirtualFrame frame, Object a, Object b) {
if (sameProfile.profile(areSame(frame, a, b))) {
public boolean sameOrEqual(VirtualFrame frame, Object a, Object b,
@Cached("create()") ReferenceEqualNode referenceEqualNode) {
if (sameProfile.profile(referenceEqualNode.executeReferenceEqual(a, b))) {
return true;
} else {
return areEqual(frame, a, b);
}
}

private boolean areSame(VirtualFrame frame, Object left, Object right) {
if (referenceEqualNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null));
}

return referenceEqualNode.executeReferenceEqual(frame, left, right);
}

private boolean areEqual(VirtualFrame frame, Object left, Object right) {
if (equalNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@
package org.jruby.truffle.core.method;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.RootCallTarget;
import com.oracle.truffle.api.Truffle;
@@ -30,7 +29,6 @@
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.builtins.UnaryCoreMethodNode;
import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.core.basicobject.BasicObjectNodesFactory;
import org.jruby.truffle.core.cast.ProcOrNullNode;
import org.jruby.truffle.core.cast.ProcOrNullNodeGen;
import org.jruby.truffle.core.proc.ProcOperations;
@@ -53,19 +51,11 @@ public abstract class MethodNodes {
@CoreMethod(names = { "==", "eql?" }, required = 1)
public abstract static class EqualNode extends CoreMethodArrayArgumentsNode {

@Child protected ReferenceEqualNode referenceEqualNode;

protected boolean areSame(VirtualFrame frame, Object left, Object right) {
if (referenceEqualNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
referenceEqualNode = insert(BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(null));
}
return referenceEqualNode.executeReferenceEqual(frame, left, right);
}

@Specialization(guards = "isRubyMethod(b)")
public boolean equal(VirtualFrame frame, DynamicObject a, DynamicObject b) {
return areSame(frame, Layouts.METHOD.getReceiver(a), Layouts.METHOD.getReceiver(b)) && Layouts.METHOD.getMethod(a) == Layouts.METHOD.getMethod(b);
public boolean equal(VirtualFrame frame, DynamicObject a, DynamicObject b,
@Cached("create()") ReferenceEqualNode referenceEqualNode) {
return referenceEqualNode.executeReferenceEqual(Layouts.METHOD.getReceiver(a), Layouts.METHOD.getReceiver(b)) &&
Layouts.METHOD.getMethod(a) == Layouts.METHOD.getMethod(b);
}

@Specialization(guards = "!isRubyMethod(b)")
Original file line number Diff line number Diff line change
@@ -42,23 +42,21 @@ public Assumption getUnchangedAssumption() {

public void setValue(Object value) {
if (assumeConstant) {
if (value != this.value) {
CompilerDirectives.transferToInterpreterAndInvalidate();
this.value = value;
CompilerDirectives.transferToInterpreterAndInvalidate();
this.value = value;

synchronized (this) {
if (!assumeConstant) {
// Compiled code didn't see that we do not assumeConstant anymore
return;
}
synchronized (this) {
if (!assumeConstant) {
// Compiled code didn't see that we do not assumeConstant anymore
return;
}

if (changes <= GLOBAL_VARIABLE_MAX_INVALIDATIONS) {
changes++;
unchangedAssumption.invalidate();
} else {
unchangedAssumption.getAssumption().invalidate();
assumeConstant = false;
}
if (changes <= GLOBAL_VARIABLE_MAX_INVALIDATIONS) {
changes++;
unchangedAssumption.invalidate();
} else {
unchangedAssumption.getAssumption().invalidate();
assumeConstant = false;
}
}
} else {
Original file line number Diff line number Diff line change
@@ -15,15 +15,35 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.basicobject.BasicObjectNodes.ReferenceEqualNode;
import org.jruby.truffle.language.RubyNode;

@NodeChild(value = "value")
public abstract class WriteGlobalVariableNode extends RubyNode {

private final String name;

public WriteGlobalVariableNode(RubyContext context, SourceSection sourceSection, String name) {
super(context, sourceSection);
this.name = name;
}

@Specialization(assumptions = "storage.getUnchangedAssumption()")
public Object writeTryToKeepConstant(Object value,
@Cached("getStorage()") GlobalVariableStorage storage,
@Cached("storage.getValue()") Object previousValue,
@Cached("create()") ReferenceEqualNode referenceEqualNode) {
if (referenceEqualNode.executeReferenceEqual(value, previousValue)) {
return previousValue;
} else {
storage.setValue(value);
return value;
}
}

@Specialization
public Object write(Object value, @Cached("getStorage()") GlobalVariableStorage storage) {
public Object write(Object value,
@Cached("getStorage()") GlobalVariableStorage storage) {
storage.setValue(value);
return value;
}
@@ -32,11 +52,6 @@ protected GlobalVariableStorage getStorage() {
return getContext().getCoreLibrary().getGlobalVariables().getStorage(name);
}

public WriteGlobalVariableNode(RubyContext context, SourceSection sourceSection, String name) {
super(context, sourceSection);
this.name = name;
}

@Override
public Object isDefined(VirtualFrame frame) {
return coreStrings().ASSIGNMENT.createInstance();