Skip to content

Commit

Permalink
Showing 19 changed files with 96 additions and 152 deletions.
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/array/dig_tags.txt

This file was deleted.

11 changes: 0 additions & 11 deletions spec/truffle/tags/core/hash/dig_tags.txt

This file was deleted.

4 changes: 0 additions & 4 deletions spec/truffle/tags/core/hash/fetch_values_tags.txt

This file was deleted.

6 changes: 0 additions & 6 deletions spec/truffle/tags/core/struct/dig_tags.txt

This file was deleted.

10 changes: 4 additions & 6 deletions test/truffle/compiler/pe/pe.rb
Original file line number Diff line number Diff line change
@@ -110,8 +110,6 @@ def report(status, code, message = nil)
puts message ? format(format_str + "\n %s", status, code, message) : format('%14s: %s', status, code)
end

Truffle::Globals.permanently_invalidate :$value

EXAMPLES.each do |example|
next if example.tagged

@@ -120,14 +118,14 @@ def report(status, code, message = nil)
runner = proc do
begin
tested += 1
$value = nil
eval "
def test_pe_code
$value = Truffle::Graal.assert_constant(begin; #{example.code}; end)
value = Truffle::Graal.assert_constant(begin; #{example.code}; end)
Truffle::Graal.assert_not_compiled
value
end"
while true
test_pe_code
value = test_pe_code
end
rescue RubyTruffleError => e
if e.message.include? 'Truffle::Graal.assert_not_compiled'
@@ -147,7 +145,7 @@ def test_pe_code
report 'FAILED', example.code, "wasn't constant"
failed += 1
else
if $value == example.expected_value
if value == example.expected_value
report 'OK', example.code
else
report 'INCORRECT', example.code, "was: #{$value.inspect} and not: #{example.expected_value.inspect}"
4 changes: 0 additions & 4 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -108,8 +108,6 @@
import org.jruby.truffle.language.control.TruffleFatalException;
import org.jruby.truffle.language.globals.GlobalVariableStorage;
import org.jruby.truffle.language.globals.GlobalVariables;
import org.jruby.truffle.language.globals.TruffleGlobalsNodes;
import org.jruby.truffle.language.globals.TruffleGlobalsNodesFactory;
import org.jruby.truffle.language.loader.CodeLoader;
import org.jruby.truffle.language.loader.SourceLoader;
import org.jruby.truffle.language.methods.DeclarationContext;
@@ -623,7 +621,6 @@ public CoreLibrary(RubyContext context) {
defineModule(truffleModule, "Process");
defineModule(truffleModule, "Binding");
defineModule(truffleModule, "POSIX");
defineModule(truffleModule, "Globals");
psychModule = defineModule("Psych");
psychParserClass = defineClass(psychModule, objectClass, "Parser");
final DynamicObject psychHandlerClass = defineClass(psychModule, objectClass, "Handler");
@@ -846,7 +843,6 @@ public void addCoreMethods() {
coreMethodNodeManager.addCoreMethodNodes(TruffleBindingNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleArrayNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleStringNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(TruffleGlobalsNodesFactory.getFactories());
coreMethodNodeManager.addCoreMethodNodes(BCryptNodesFactory.getFactories());
return null;
}));
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,33 +42,26 @@ 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 {
this.value = value;
}
}

public void permanentlyInvalidate() {
changes = Integer.MAX_VALUE;
unchangedAssumption.invalidate();
}

}

This file was deleted.

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();
1 change: 1 addition & 0 deletions truffle/src/main/ruby/core/array.rb
Original file line number Diff line number Diff line change
@@ -320,6 +320,7 @@ def dig(idx, *more)
if result.nil? || more.empty?
result
else
raise TypeError, "#{result.class} does not have #dig method" unless result.respond_to?(:dig)
result.dig(*more)
end
end
16 changes: 16 additions & 0 deletions truffle/src/main/ruby/core/hash.rb
Original file line number Diff line number Diff line change
@@ -149,6 +149,16 @@ def default_proc=(prc)
@default_proc = prc
end

def dig(key, *more)
result = self[key]
if result.nil? || more.empty?
result
else
raise TypeError, "#{result.class} does not have #dig method" unless result.respond_to?(:dig)
result.dig(*more)
end
end

def fetch(key, default=undefined)
if item = find_item(key)
return item.value
@@ -159,6 +169,12 @@ def fetch(key, default=undefined)
raise KeyError, "key #{key} not found"
end

def fetch_values(*keys, &block)
keys.map do |key|
self.fetch(key, &block)
end
end

def flatten(level=1)
to_a.flatten(level)
end
14 changes: 14 additions & 0 deletions truffle/src/main/ruby/core/struct.rb
Original file line number Diff line number Diff line change
@@ -207,6 +207,20 @@ def []=(var, obj)
return instance_variable_set(:"@#{var}", obj)
end

def dig(key, *more)
result = nil
begin
result = self[key]
rescue IndexError, NameError
end
if result.nil? || more.empty?
result
else
raise TypeError, "#{result.class} does not have #dig method" unless result.respond_to?(:dig)
result.dig(*more)
end
end

def eql?(other)
return true if equal? other
return false if self.class != other.class

0 comments on commit a3ac114

Please sign in to comment.