Skip to content

Commit 09c2a3f

Browse files
committed
[Truffle] Pull out a node for calling hash and getting the result into an int.
1 parent 630660c commit 09c2a3f

File tree

3 files changed

+62
-22
lines changed

3 files changed

+62
-22
lines changed

truffle/src/main/java/org/jruby/truffle/nodes/core/HashNodes.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
2424
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
2525
import org.jruby.truffle.nodes.hash.FindEntryNode;
26+
import org.jruby.truffle.nodes.hash.HashNode;
2627
import org.jruby.truffle.nodes.yield.YieldDispatchHeadNode;
2728
import org.jruby.truffle.runtime.RubyArguments;
2829
import org.jruby.truffle.runtime.RubyContext;
@@ -118,7 +119,7 @@ public static boolean isSmallArrayOfPairs(RubyClass hashClass, Object[] args) {
118119
@ImportStatic(HashGuards.class)
119120
public abstract static class GetIndexNode extends CoreMethodArrayArgumentsNode {
120121

121-
@Child private CallDispatchHeadNode hashNode;
122+
@Child private HashNode hashNode;
122123
@Child private CallDispatchHeadNode eqlNode;
123124
@Child private BasicObjectNodes.ReferenceEqualNode equalNode;
124125
@Child private CallDispatchHeadNode callDefaultNode;
@@ -132,7 +133,7 @@ public abstract static class GetIndexNode extends CoreMethodArrayArgumentsNode {
132133

133134
public GetIndexNode(RubyContext context, SourceSection sourceSection) {
134135
super(context, sourceSection);
135-
hashNode = DispatchHeadNodeFactory.createMethodCall(context, true);
136+
hashNode = new HashNode(context, sourceSection);
136137
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
137138
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(context, sourceSection, null, null);
138139
callDefaultNode = DispatchHeadNodeFactory.createMethodCall(context);
@@ -143,7 +144,7 @@ public GetIndexNode(RubyContext context, SourceSection sourceSection) {
143144

144145
@Specialization(guards = "isNullStorage(hash)")
145146
public Object getNull(VirtualFrame frame, RubyHash hash, Object key) {
146-
hashNode.call(frame, key, "hash", null);
147+
hashNode.hash(frame, key);
147148

148149
if (undefinedValue != null) {
149150
return undefinedValue;
@@ -155,7 +156,7 @@ public Object getNull(VirtualFrame frame, RubyHash hash, Object key) {
155156
@ExplodeLoop
156157
@Specialization(guards = "isPackedArrayStorage(hash)")
157158
public Object getPackedArray(VirtualFrame frame, RubyHash hash, Object key) {
158-
hashNode.call(frame, key, "hash", null);
159+
hashNode.hash(frame, key);
159160

160161
final Object[] store = (Object[]) hash.getStore();
161162
final int size = hash.getSize();
@@ -233,7 +234,7 @@ public Object getOrUndefined(VirtualFrame frame, RubyHash hash, Object key) {
233234
@ImportStatic(HashGuards.class)
234235
public abstract static class SetIndexNode extends CoreMethodArrayArgumentsNode {
235236

236-
@Child private CallDispatchHeadNode hashNode;
237+
@Child private HashNode hashNode;
237238
@Child private CallDispatchHeadNode eqlNode;
238239
@Child private BasicObjectNodes.ReferenceEqualNode equalNode;
239240

@@ -243,15 +244,15 @@ public abstract static class SetIndexNode extends CoreMethodArrayArgumentsNode {
243244

244245
public SetIndexNode(RubyContext context, SourceSection sourceSection) {
245246
super(context, sourceSection);
246-
hashNode = DispatchHeadNodeFactory.createMethodCall(context, true);
247+
hashNode = new HashNode(context, sourceSection);
247248
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
248249
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(context, sourceSection, null, null);
249250
}
250251

251252
@Specialization(guards = { "isNullStorage(hash)", "!isRubyString(key)" })
252253
public Object setNull(VirtualFrame frame, RubyHash hash, Object key, Object value) {
253254
final Object[] store = new Object[PackedArrayStrategy.TRUFFLE_HASH_PACKED_ARRAY_MAX * 2];
254-
hashNode.call(frame, key, "hash", null);
255+
hashNode.hash(frame, key);
255256
store[0] = key;
256257
store[1] = value;
257258
hash.setStore(store, 1, null, null);
@@ -271,7 +272,7 @@ public Object setNull(VirtualFrame frame, RubyHash hash, RubyString key, Object
271272
@ExplodeLoop
272273
@Specialization(guards = {"isPackedArrayStorage(hash)", "!isRubyString(key)"})
273274
public Object setPackedArray(VirtualFrame frame, RubyHash hash, Object key, Object value) {
274-
hashNode.call(frame, key, "hash", null);
275+
hashNode.hash(frame, key);
275276

276277
final Object[] store = (Object[]) hash.getStore();
277278
final int size = hash.getSize();
@@ -1211,7 +1212,7 @@ public static boolean isNullStorage(RubyHash hash) {
12111212
}
12121213

12131214
public static boolean isPackedArrayStorage(RubyHash hash) {
1214-
// Can't do instanceof Object[] due to cavariance
1215+
// Can't do instanceof Object[] due to covariance
12151216
return !(isNullStorage(hash) || isBucketsStorage(hash));
12161217
}
12171218

truffle/src/main/java/org/jruby/truffle/nodes/hash/FindEntryNode.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,21 @@
2525

2626
public class FindEntryNode extends RubyNode {
2727

28-
@Child CallDispatchHeadNode hashNode;
28+
@Child HashNode hashNode;
2929
@Child CallDispatchHeadNode eqlNode;
3030
@Child BasicObjectNodes.ReferenceEqualNode equalNode;
3131

3232
private final ConditionProfile byIdentityProfile = ConditionProfile.createBinaryProfile();
3333

3434
public FindEntryNode(RubyContext context, SourceSection sourceSection) {
3535
super(context, sourceSection);
36-
hashNode = DispatchHeadNodeFactory.createMethodCall(context, true);
36+
hashNode = new HashNode(context, sourceSection);
3737
eqlNode = DispatchHeadNodeFactory.createMethodCall(context, false, false, null);
3838
equalNode = BasicObjectNodesFactory.ReferenceEqualNodeFactory.create(context, sourceSection, null, null);
3939
}
4040

4141
public HashSearchResult search(VirtualFrame frame, RubyHash hash, Object key) {
42-
final Object hashValue = hashNode.call(frame, key, "hash", null);
43-
44-
final int hashed;
45-
46-
if (hashValue instanceof Integer) {
47-
hashed = (int) hashValue;
48-
} else if (hashValue instanceof Long) {
49-
hashed = (int) (long) hashValue;
50-
} else {
51-
throw new UnsupportedOperationException();
52-
}
42+
final int hashed = hashNode.hash(frame, key);
5343

5444
final Entry[] entries = (Entry[]) hash.getStore();
5545
final int index = HashOperations.getIndex(hashed, entries.length);
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 1.0
7+
* GNU General Public License version 2
8+
* GNU Lesser General Public License version 2.1
9+
*/
10+
package org.jruby.truffle.nodes.hash;
11+
12+
import com.oracle.truffle.api.frame.VirtualFrame;
13+
import com.oracle.truffle.api.source.SourceSection;
14+
import com.oracle.truffle.api.utilities.ConditionProfile;
15+
import org.jruby.truffle.nodes.RubyNode;
16+
import org.jruby.truffle.nodes.dispatch.CallDispatchHeadNode;
17+
import org.jruby.truffle.nodes.dispatch.DispatchHeadNodeFactory;
18+
import org.jruby.truffle.runtime.RubyContext;
19+
20+
public class HashNode extends RubyNode {
21+
22+
@Child private CallDispatchHeadNode hashNode;
23+
24+
private final ConditionProfile isIntegerProfile = ConditionProfile.createBinaryProfile();
25+
private final ConditionProfile isLongProfile = ConditionProfile.createBinaryProfile();
26+
27+
public HashNode(RubyContext context, SourceSection sourceSection) {
28+
super(context, sourceSection);
29+
hashNode = DispatchHeadNodeFactory.createMethodCall(context, true);
30+
}
31+
32+
public int hash(VirtualFrame frame, Object key) {
33+
final Object hashedObject = hashNode.call(frame, key, "hash", null);
34+
35+
if (isIntegerProfile.profile(hashedObject instanceof Integer)) {
36+
return (int) hashedObject;
37+
} else if (isLongProfile.profile(hashedObject instanceof Long)) {
38+
return (int) (long) hashedObject;
39+
} else {
40+
throw new UnsupportedOperationException();
41+
}
42+
}
43+
44+
@Override
45+
public Object execute(VirtualFrame frame) {
46+
throw new UnsupportedOperationException();
47+
}
48+
49+
}

0 commit comments

Comments
 (0)