Skip to content

Commit e5b2b65

Browse files
committed
Deduplicate helper nodes
1 parent 455d7fc commit e5b2b65

File tree

1 file changed

+12
-40
lines changed

1 file changed

+12
-40
lines changed

src/main/java/org/truffleruby/core/hash/library/CompactHashStore.java

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import java.util.Set;
1818

19+
import com.oracle.truffle.api.CompilerAsserts;
1920
import com.oracle.truffle.api.CompilerDirectives;
2021
import org.truffleruby.RubyContext;
2122
import org.truffleruby.RubyLanguage;
@@ -173,7 +174,7 @@ Object lookupOrDefault(Frame frame, RubyHash hash, Object key, PEBiFunction defa
173174
@Bind("$node") Node node) {
174175
int keyHash = hashFunction.execute(key, hash.compareByIdentity);
175176

176-
int indexPos = getIndexPosForKeyNode.execute(key, keyHash, hash.compareByIdentity, index, kvStore);
177+
int indexPos = getIndexPosForKeyNode.execute(key, keyHash, hash.compareByIdentity, index, kvStore, false);
177178
if (keyNotFound.profile(node, indexPos == KEY_NOT_FOUND)) {
178179
return defaultNode.accept(frame, hash, key);
179180
}
@@ -185,15 +186,15 @@ Object lookupOrDefault(Frame frame, RubyHash hash, Object key, PEBiFunction defa
185186
@ExportMessage
186187
boolean set(RubyHash hash, Object key, Object value, boolean byIdentity,
187188
@Cached @Shared HashingNodes.ToHash hashFunction,
188-
@Cached GetInsertionIndexPosForKeyNode getInsertionIndexPosForKeyNode,
189+
@Cached @Shared GetIndexPosForKeyNode getIndexPosForKeyNode,
189190
@Cached FreezeHashKeyIfNeededNode freezeKey,
190191
@Cached @Exclusive PropagateSharingNode propagateSharingForKey,
191192
@Cached @Exclusive PropagateSharingNode propagateSharingForVal,
192193
@Cached SetKvAtNode setKv,
193194
@Bind("$node") Node node) {
194195
var frozenKey = freezeKey.executeFreezeIfNeeded(node, key, byIdentity);
195196
int keyHash = hashFunction.execute(frozenKey, byIdentity);
196-
int indexPos = getInsertionIndexPosForKeyNode.execute(frozenKey, keyHash, byIdentity, index, kvStore);
197+
int indexPos = getIndexPosForKeyNode.execute(frozenKey, keyHash, byIdentity, index, kvStore, true);
197198
int keyPos = indexPosToKeyPos(index, indexPos); // can be < 0 if inserting new key
198199

199200
propagateSharingForKey.execute(node, hash, frozenKey);
@@ -209,7 +210,7 @@ Object delete(RubyHash hash, Object key,
209210
@Cached @Exclusive InlinedConditionProfile keyNotFound,
210211
@Bind("$node") Node node) {
211212
int keyHash = hashFunction.execute(key, hash.compareByIdentity);
212-
int indexPos = getIndexPosForKeyNode.execute(key, keyHash, hash.compareByIdentity, index, kvStore);
213+
int indexPos = getIndexPosForKeyNode.execute(key, keyHash, hash.compareByIdentity, index, kvStore, false);
213214
if (keyNotFound.profile(node, indexPos == KEY_NOT_FOUND)) {
214215
return null;
215216
}
@@ -470,24 +471,27 @@ public void getAdjacentObjects(Set<Object> reachable) {
470471
}
471472
}
472473

473-
/** Given a key and its hash, returns the index pos for this key's hashCode, or KEY_NOT_FOUND if not found. */
474+
/** Given a key and its hash, returns the index pos where this key's hashCode is found. If not found, returns where
475+
* it could be inserted if insert is true and KEY_NOT_FOUND otherwise. */
474476
@GenerateUncached
475477
abstract static class GetIndexPosForKeyNode extends RubyBaseNode {
476478

477-
public abstract int execute(Object key, int hash, boolean compareByIdentity, int[] index, Object[] kvStore);
479+
public abstract int execute(Object key, int hash, boolean compareByIdentity, int[] index, Object[] kvStore,
480+
boolean insert);
478481

479482
@Specialization
480-
int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, Object[] kvStore,
483+
int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, Object[] kvStore, boolean insert,
481484
@Cached CompareHashKeysNode.AssumingEqualHashes compareHashKeysNode,
482485
@Cached @Exclusive InlinedConditionProfile unused,
483486
@Cached @Exclusive InlinedConditionProfile sameHash,
484487
@Bind("$node") Node node) {
488+
CompilerAsserts.partialEvaluationConstant(insert);
485489
int startPos = indexPosFromHashCode(hash, index.length);
486490
int indexPos = startPos;
487491
while (true) {
488492
int valuePos = indexPosToValuePos(index, indexPos);
489493
if (unused.profile(node, valuePos == INDEX_SLOT_UNUSED)) {
490-
return KEY_NOT_FOUND;
494+
return insert ? indexPos : KEY_NOT_FOUND;
491495
} else if (sameHash.profile(node, index[indexPos] == hash) &&
492496
compareHashKeysNode.execute(compareByIdentity, key, kvStore[valuePos - 1])) { // keyPos == valuePos - 1
493497
return indexPos;
@@ -498,38 +502,6 @@ int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, O
498502
}
499503
}
500504

501-
/** Given a key and its hash, returns the index pos where this key's hashCode is found or where it could be
502-
* inserted. */
503-
@GenerateUncached
504-
abstract static class GetInsertionIndexPosForKeyNode extends RubyBaseNode {
505-
506-
public abstract int execute(Object key, int hash, boolean compareByIdentity, int[] index, Object[] kvStore);
507-
508-
@Specialization
509-
int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, Object[] kvStore,
510-
@Cached CompareHashKeysNode.AssumingEqualHashes compareHashKeysNode,
511-
@Cached @Exclusive InlinedConditionProfile unused,
512-
@Cached @Exclusive InlinedConditionProfile sameHash,
513-
@Bind("$node") Node node) {
514-
int startPos = indexPosFromHashCode(hash, index.length);
515-
int indexPos = startPos;
516-
while (true) {
517-
int valuePos = indexPosToValuePos(index, indexPos);
518-
if (unused.profile(node, valuePos == INDEX_SLOT_UNUSED)) {
519-
return indexPos;
520-
} else {
521-
int keyPos = valuePos - 1;
522-
if (sameHash.profile(node, index[indexPos] == hash) &&
523-
compareHashKeysNode.execute(compareByIdentity, key, kvStore[keyPos])) {
524-
return indexPos;
525-
}
526-
}
527-
indexPos = incrementIndexPos(indexPos, index.length);
528-
assert indexPos != startPos;
529-
}
530-
}
531-
}
532-
533505
@GenerateUncached
534506
abstract static class GetHashNextPosInIndexNode extends RubyBaseNode {
535507

0 commit comments

Comments
 (0)