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

Commits on Mar 9, 2015

  1. Copy the full SHA
    4f828fb View commit details
  2. [Truffle] Hash#[]=

    chrisseaton committed Mar 9, 2015
    Copy the full SHA
    2ffaeb6 View commit details
1 change: 0 additions & 1 deletion spec/truffle/tags/core/hash/element_reference_tags.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
fails:Hash#[] calls subclass implementations of default
fails:Hash#[] finds a value via an identical key even when its #eql? isn't reflexive
fails:Hash#[] does not compare keys with different #hash values via #eql?
1 change: 0 additions & 1 deletion spec/truffle/tags/core/hash/element_set_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/truffle/tags/core/hash/store_tags.txt

This file was deleted.

46 changes: 15 additions & 31 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/HashNodes.java
Original file line number Diff line number Diff line change
@@ -123,7 +123,7 @@ public abstract static class GetIndexNode extends HashCoreMethodNode {
@Child private CallDispatchHeadNode hashNode;
@Child private CallDispatchHeadNode eqlNode;
@Child private BasicObjectNodes.ReferenceEqualNode equalNode;
@Child private YieldDispatchHeadNode yield;
@Child private CallDispatchHeadNode callDefaultNode;
@Child private FindEntryNode findEntryNode;

private final ConditionProfile byIdentityProfile = ConditionProfile.createBinaryProfile();
@@ -137,7 +137,7 @@ public GetIndexNode(RubyContext context, SourceSection sourceSection) {
hashNode = DispatchHeadNodeFactory.createMethodCall(context, true);
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(context, sourceSection, null, null);
yield = new YieldDispatchHeadNode(context);
callDefaultNode = DispatchHeadNodeFactory.createMethodCall(context);
findEntryNode = new FindEntryNode(context, sourceSection);
}

@@ -146,7 +146,7 @@ public GetIndexNode(GetIndexNode prev) {
hashNode = prev.hashNode;
eqlNode = prev.eqlNode;
equalNode = prev.equalNode;
yield = prev.yield;
callDefaultNode = prev.callDefaultNode;
findEntryNode = prev.findEntryNode;
undefinedValue = prev.undefinedValue;
}
@@ -161,12 +161,8 @@ public Object getNull(VirtualFrame frame, RubyHash hash, Object key) {

if (undefinedValue != null) {
return undefinedValue;
} else if (hash.getDefaultBlock() != null) {
return yield.dispatch(frame, hash.getDefaultBlock(), hash, key);
} else if (hash.getDefaultValue() != null) {
return hash.getDefaultValue();
} else {
return getContext().getCoreLibrary().getNilObject();
return callDefaultNode.call(frame, hash, "default", null, key);
}
}

@@ -200,16 +196,8 @@ public Object getPackedArray(VirtualFrame frame, RubyHash hash, Object key) {
return undefinedValue;
}

if (hash.getDefaultBlock() != null) {
useDefaultProfile.enter();
return yield.dispatch(frame, hash.getDefaultBlock(), hash, key);
}

if (hash.getDefaultValue() != null) {
return hash.getDefaultValue();
}

return getContext().getCoreLibrary().getNilObject();
useDefaultProfile.enter();
return callDefaultNode.call(frame, hash, "default", null, key);

}

@@ -227,16 +215,8 @@ public Object getBuckets(VirtualFrame frame, RubyHash hash, Object key) {
return undefinedValue;
}

if (hash.getDefaultBlock() != null) {
useDefaultProfile.enter();
return yield.dispatch(frame, hash.getDefaultBlock(), hash, key);
}

if (hash.getDefaultValue() != null) {
return hash.getDefaultValue();
}

return getContext().getCoreLibrary().getNilObject();
useDefaultProfile.enter();
return callDefaultNode.call(frame, hash, "default", null, key);
}

public void setUndefinedValue(Object undefinedValue) {
@@ -309,7 +289,7 @@ public Object setNull(VirtualFrame frame, RubyHash hash, RubyString key, Object
if (hash.isCompareByIdentity()) {
return setNull(frame, hash, (Object) key, value);
} else {
return setNull(frame, hash, ruby(frame, "key.dup.freeze", "key", key), value);
return setNull(frame, hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value);
}
}

@@ -373,7 +353,7 @@ public Object setPackedArray(VirtualFrame frame, RubyHash hash, RubyString key,
if (hash.isCompareByIdentity()) {
return setPackedArray(frame, hash, (Object) key, value);
} else {
return setPackedArray(frame, hash, ruby(frame, "key.dup.freeze", "key", key), value);
return setPackedArray(frame, hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value);
}
}

@@ -391,7 +371,11 @@ public Object setBuckets(RubyHash hash, Object key, Object value) {
@Specialization(guards = "isBuckets")
public Object setBuckets(VirtualFrame frame, RubyHash hash, RubyString key, Object value) {
notDesignedForCompilation();
return setBuckets(hash, ruby(frame, "key.dup.freeze", "key", key), value);
if (hash.isCompareByIdentity()) {
return setBuckets(hash, key, value);
} else {
return setBuckets(hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value);
}
}

}