-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
…hes.
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
- 9.1.2.0
- 9.1.1.0
- 9.1.0.0
- 9.0.5.0
- 9.0.4.0
- 9.0.3.0
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,8 @@ | |
import org.jruby.truffle.nodes.core.BasicObjectNodesFactory; | ||
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode; | ||
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory; | ||
import org.jruby.truffle.nodes.objects.IsFrozenNode; | ||
import org.jruby.truffle.nodes.objects.IsFrozenNodeGen; | ||
import org.jruby.truffle.runtime.RubyContext; | ||
import org.jruby.truffle.runtime.hash.*; | ||
import org.jruby.truffle.runtime.layouts.Layouts; | ||
|
@@ -48,6 +50,12 @@ public abstract class SetNode extends RubyNode { | |
private final BranchProfile extendProfile = BranchProfile.create(); | ||
private final ConditionProfile strategyProfile = ConditionProfile.createBinaryProfile(); | ||
|
||
@Child private IsFrozenNode isFrozenNode; | ||
@Child private CallDispatchHeadNode dupNode; | ||
@Child private CallDispatchHeadNode freezeNode; | ||
|
||
private final ConditionProfile frozenProfile = ConditionProfile.createBinaryProfile(); | ||
|
||
public SetNode(RubyContext context, SourceSection sourceSection) { | ||
super(context, sourceSection); | ||
hashNode = new HashNode(context, sourceSection); | ||
|
@@ -72,12 +80,12 @@ public Object setNull(VirtualFrame frame, DynamicObject hash, Object key, Object | |
|
||
@Specialization(guards = {"isNullHash(hash)", "byIdentity", "isRubyString(key)"}) | ||
public Object setNullByIdentity(VirtualFrame frame, DynamicObject hash, DynamicObject key, Object value, boolean byIdentity) { | ||
return setNull(frame, hash, (Object) key, value, byIdentity); | ||
return setNull(frame, hash, key, value, byIdentity); | ||
} | ||
|
||
@Specialization(guards = {"isNullHash(hash)", "!byIdentity", "isRubyString(key)"}) | ||
public Object setNullNotByIdentity(VirtualFrame frame, DynamicObject hash, DynamicObject key, Object value, boolean byIdentity) { | ||
return setNull(frame, hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value, byIdentity); | ||
return setNull(frame, hash, freezeAndDupIfNeeded(frame, key), value, byIdentity); | ||
} | ||
|
||
@ExplodeLoop | ||
|
@@ -133,7 +141,7 @@ public Object setPackedArrayByIdentity(VirtualFrame frame, DynamicObject hash, D | |
|
||
@Specialization(guards = {"isPackedHash(hash)", "!byIdentity", "isRubyString(key)"}) | ||
public Object setPackedArrayNotByIdentity(VirtualFrame frame, DynamicObject hash, DynamicObject key, Object value, boolean byIdentity) { | ||
return setPackedArray(frame, hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value, byIdentity); | ||
return setPackedArray(frame, hash, freezeAndDupIfNeeded(frame, key), value, byIdentity); | ||
} | ||
|
||
// Can't be @Cached yet as we call from the RubyString specialisation | ||
|
@@ -197,12 +205,36 @@ public Object setBuckets(VirtualFrame frame, DynamicObject hash, Object key, Obj | |
|
||
@Specialization(guards = {"isBucketHash(hash)", "byIdentity", "isRubyString(key)"}) | ||
public Object setBucketsByIdentity(VirtualFrame frame, DynamicObject hash, DynamicObject key, Object value, boolean byIdentity) { | ||
return setBuckets(frame, hash, (Object) key, value, byIdentity); | ||
return setBuckets(frame, hash, key, value, byIdentity); | ||
} | ||
|
||
@Specialization(guards = {"isBucketHash(hash)", "!byIdentity", "isRubyString(key)"}) | ||
public Object setBucketsNotByIdentity(VirtualFrame frame, DynamicObject hash, DynamicObject key, Object value, boolean byIdentity) { | ||
return setBuckets(frame, hash, ruby(frame, "key.frozen? ? key : key.dup.freeze", "key", key), value, byIdentity); | ||
return setBuckets(frame, hash, freezeAndDupIfNeeded(frame, key), value, byIdentity); | ||
} | ||
|
||
private DynamicObject freezeAndDupIfNeeded(VirtualFrame frame, DynamicObject key) { | ||
if (isFrozenNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
isFrozenNode = insert(IsFrozenNodeGen.create(getContext(), getSourceSection(), null)); | ||
} | ||
|
||
if (frozenProfile.profile(isFrozenNode.executeIsFrozen(key))) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong. |
||
if (dupNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
dupNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext())); | ||
} | ||
|
||
if (freezeNode == null) { | ||
CompilerDirectives.transferToInterpreter(); | ||
freezeNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext())); | ||
} | ||
|
||
final Object dupped = dupNode.call(frame, key, "dup", null); | ||
This comment has been minimized.
Sorry, something went wrong.
nirvdrum
Contributor
|
||
return (DynamicObject) freezeNode.call(frame, dupped, "freeze", null); | ||
This comment has been minimized.
Sorry, something went wrong.
nirvdrum
Contributor
|
||
} else { | ||
return key; | ||
} | ||
} | ||
|
||
} |
The
if
/else
branches seem to be inverted to me. If theString
is frozen, use it as a key, if it is not frozen dup & freeze and use the obj as a key.