Skip to content

Commit df35b7c

Browse files
author
Nicolas Laurent
committed
refactor hashing & reference comparison nodes to accomodate @GenerateUnached
1 parent 34651a1 commit df35b7c

File tree

4 files changed

+41
-44
lines changed

4 files changed

+41
-44
lines changed

src/main/java/org/truffleruby/core/basicobject/BasicObjectNodes.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,20 @@ protected boolean equal(VirtualFrame frame, Object a, Object b) {
117117
/** This node is not trivial because primitives must be compared by value and never by identity. Also, this node
118118
* must consider (byte) n and (short) n and (int) n and (long) n equal, as well as (float) n and (double) n. So even
119119
* if a and b have different classes they might still be equal if they are primitives. */
120+
@GenerateUncached
121+
@GenerateNodeFactory
120122
@CoreMethod(names = { "equal?", "==" }, required = 1)
121-
public abstract static class ReferenceEqualNode extends CoreMethodArrayArgumentsNode {
123+
@NodeChild(value = "arguments", type = RubyNode[].class)
124+
public abstract static class ReferenceEqualNode extends RubySourceNode {
122125

123126
public static ReferenceEqualNode create() {
124127
return ReferenceEqualNodeFactory.create(null);
125128
}
126129

130+
public static ReferenceEqualNode getUncached() {
131+
return ReferenceEqualNodeFactory.getUncached();
132+
}
133+
127134
public abstract boolean executeReferenceEqual(Object a, Object b);
128135

129136
@Specialization

src/main/java/org/truffleruby/core/cast/ToRubyIntegerNode.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,23 @@
99
*/
1010
package org.truffleruby.core.cast;
1111

12+
import com.oracle.truffle.api.dsl.CachedContext;
13+
import com.oracle.truffle.api.dsl.GenerateUncached;
14+
import org.truffleruby.RubyContext;
15+
import org.truffleruby.RubyLanguage;
1216
import org.truffleruby.core.numeric.RubyBignum;
13-
import org.truffleruby.language.RubyContextSourceNode;
14-
import org.truffleruby.language.RubyNode;
17+
import org.truffleruby.language.RubyBaseNode;
1518
import org.truffleruby.language.dispatch.DispatchNode;
1619

1720
import com.oracle.truffle.api.dsl.Cached;
18-
import com.oracle.truffle.api.dsl.NodeChild;
1921
import com.oracle.truffle.api.dsl.Specialization;
2022

2123
/** See {@link ToIntNode} for a comparison of different integer conversion nodes. */
22-
@NodeChild(value = "child", type = RubyNode.class)
23-
public abstract class ToRubyIntegerNode extends RubyContextSourceNode {
24+
@GenerateUncached
25+
public abstract class ToRubyIntegerNode extends RubyBaseNode {
2426

2527
public static ToRubyIntegerNode create() {
26-
return ToRubyIntegerNodeGen.create(null);
27-
}
28-
29-
public static ToRubyIntegerNode create(RubyNode child) {
30-
return ToRubyIntegerNodeGen.create(child);
28+
return ToRubyIntegerNodeGen.create();
3129
}
3230

3331
public abstract Object execute(Object object);
@@ -49,7 +47,8 @@ protected RubyBignum coerceRubyBignum(RubyBignum value) {
4947

5048
@Specialization(guards = "!isRubyInteger(object)")
5149
protected Object coerceObject(Object object,
50+
@CachedContext(RubyLanguage.class) RubyContext context,
5251
@Cached DispatchNode toIntNode) {
53-
return toIntNode.call(getContext().getCoreLibrary().truffleTypeModule, "rb_to_int_fallback", object);
52+
return toIntNode.call(context.getCoreLibrary().truffleTypeModule, "rb_to_int_fallback", object);
5453
}
5554
}

src/main/java/org/truffleruby/core/hash/HashingNodes.java

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,22 @@
1313
import com.oracle.truffle.api.dsl.Cached;
1414
import com.oracle.truffle.api.dsl.CachedContext;
1515
import com.oracle.truffle.api.dsl.Fallback;
16+
import com.oracle.truffle.api.dsl.GenerateUncached;
1617
import com.oracle.truffle.api.dsl.Specialization;
1718
import org.truffleruby.RubyContext;
1819
import org.truffleruby.RubyLanguage;
1920
import org.truffleruby.core.basicobject.BasicObjectNodes.ObjectIDNode;
2021
import org.truffleruby.core.cast.ToRubyIntegerNode;
22+
import org.truffleruby.core.hash.HashingNodesFactory.HashCastResultNodeGen;
23+
import org.truffleruby.core.hash.HashingNodesFactory.ToHashByIdentityNodeGen;
2124
import org.truffleruby.core.numeric.BigIntegerOps;
2225
import org.truffleruby.core.numeric.RubyBignum;
2326
import org.truffleruby.core.string.RubyString;
2427
import org.truffleruby.core.string.StringNodes;
2528
import org.truffleruby.core.symbol.RubySymbol;
2629
import org.truffleruby.core.symbol.SymbolNodes;
2730
import org.truffleruby.core.string.ImmutableRubyString;
31+
import org.truffleruby.language.RubyBaseNode;
2832
import org.truffleruby.language.RubyContextNode;
2933
import org.truffleruby.language.dispatch.DispatchNode;
3034

@@ -137,7 +141,16 @@ private int castResult(Object value) {
137141

138142
}
139143

140-
public abstract static class ToHashByIdentity extends RubyContextNode {
144+
@GenerateUncached
145+
public abstract static class ToHashByIdentity extends RubyBaseNode {
146+
147+
public static ToHashByIdentity create() {
148+
return ToHashByIdentityNodeGen.create();
149+
}
150+
151+
public static ToHashByIdentity getUncached() {
152+
return ToHashByIdentityNodeGen.getUncached();
153+
}
141154

142155
public abstract int execute(Object key);
143156

@@ -147,19 +160,15 @@ protected int toHashByIdentity(Object hashed,
147160
@Cached HashCastResultNode hashCastResultNode) {
148161
return hashCastResultNode.execute(objectIDNode.execute(hashed));
149162
}
150-
151163
}
152164

153-
154-
public abstract static class HashCastResultNode extends RubyContextNode {
155-
156-
@Child private ToRubyIntegerNode toRubyInteger;
157-
@Child private HashCastResultNode hashCastResultNode;
165+
@GenerateUncached
166+
public abstract static class HashCastResultNode extends RubyBaseNode {
158167

159168
public abstract int execute(Object key);
160169

161170
public static HashCastResultNode create() {
162-
return HashingNodesFactory.HashCastResultNodeGen.create();
171+
return HashCastResultNodeGen.create();
163172
}
164173

165174
@Specialization
@@ -177,24 +186,11 @@ protected int castBignum(RubyBignum hashed) {
177186
return BigIntegerOps.hashCode(hashed);
178187
}
179188

180-
@Fallback
181-
protected int castOther(Object hashed) {
182-
if (toRubyInteger == null) {
183-
CompilerDirectives.transferToInterpreterAndInvalidate();
184-
toRubyInteger = insert(ToRubyIntegerNode.create());
185-
}
186-
final Object coercedHashedObject = toRubyInteger.execute(hashed);
187-
return castCoerced(coercedHashedObject);
189+
@Specialization(guards = "!isRubyInteger(hashed)")
190+
protected int castOther(Object hashed,
191+
@Cached ToRubyIntegerNode toRubyInteger,
192+
@Cached HashCastResultNode hashCastResult) {
193+
return hashCastResult.execute(toRubyInteger.execute(hashed));
188194
}
189-
190-
private int castCoerced(Object coerced) {
191-
if (hashCastResultNode == null) {
192-
CompilerDirectives.transferToInterpreterAndInvalidate();
193-
hashCastResultNode = insert(HashCastResultNode.create());
194-
}
195-
return hashCastResultNode.execute(coerced);
196-
}
197-
198195
}
199-
200196
}

src/main/ruby/truffleruby/core/weakmap.rb

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,7 @@
99
# GNU Lesser General Public License version 2.1.
1010

1111
module ObjectSpace
12-
# WeakMap uses identity comparison semantics. The implementation assumes that the Java representation of objects
13-
# do compare (equals() and hashCode()) using object identity. This is the case for instances of RubyDynamicObject,
14-
# boxed primitives, and RubySymbol.
15-
#
16-
# However, results are unspecified if used with instances of TruffleObject that override equals() and
17-
# hashCode().
12+
# WeakMap uses Ruby identity semantics to compare and hash keys.
1813
class WeakMap
1914
include Enumerable
2015

0 commit comments

Comments
 (0)