@@ -222,37 +222,37 @@ Object delete(RubyHash hash, Object key,
222
222
@ ExportMessage
223
223
Object deleteLast (RubyHash hash , Object key ,
224
224
@ Cached @ Shared HashingNodes .ToHash hashFunction ,
225
- @ Cached @ Shared GetHashPosForKeyAtKvPosNode getHashPos ,
225
+ @ Cached @ Shared GetIndexPosFromKeyPosNode getIndexPosFromKeyPosNode ,
226
226
@ Cached @ Exclusive InlinedLoopConditionProfile nonNullKeyNotYetFound ,
227
227
@ Bind ("$node" ) Node node ) {
228
228
assert hash .size > 0 ;
229
- int lastKeyPos = firstNonNullKeyPosFromEnd (nonNullKeyNotYetFound , node );
230
- Object lastKey = kvStore [lastKeyPos ];
229
+ int keyPos = firstNonNullKeyPosFromEnd (nonNullKeyNotYetFound , node );
230
+ Object lastKey = kvStore [keyPos ];
231
231
if (key != lastKey ) {
232
232
CompilerDirectives .transferToInterpreterAndInvalidate ();
233
233
throw CompilerDirectives
234
234
.shouldNotReachHere ("The last key was not " + key + " as expected but was " + lastKey );
235
235
}
236
236
237
237
int keyHash = hashFunction .execute (key , hash .compareByIdentity );
238
- int indexPos = getHashPos .execute (keyHash , lastKeyPos , index );
238
+ int indexPos = getIndexPosFromKeyPosNode .execute (keyHash , keyPos , index );
239
239
240
- return deleteKvAndGetV (hash , indexPos , lastKeyPos );
240
+ return deleteKvAndGetV (hash , indexPos , keyPos );
241
241
}
242
242
243
243
@ ExportMessage
244
244
RubyArray shift (RubyHash hash ,
245
245
@ Cached @ Shared HashingNodes .ToHash hashFunction ,
246
- @ Cached @ Shared GetHashPosForKeyAtKvPosNode getHashPos ,
246
+ @ Cached @ Shared GetIndexPosFromKeyPosNode getIndexPosFromKeyPosNode ,
247
247
@ Cached @ Exclusive InlinedLoopConditionProfile nonNullKeyNotYetFound ,
248
248
@ Bind ("$node" ) Node node ) {
249
249
assert hash .size > 0 ;
250
- int firstKeyPos = firstNonNullKeyPosFromBeginning (nonNullKeyNotYetFound , node );
250
+ int keyPos = firstNonNullKeyPosFromBeginning (nonNullKeyNotYetFound , node );
251
251
252
- Object key = kvStore [firstKeyPos ];
252
+ Object key = kvStore [keyPos ];
253
253
int keyHash = hashFunction .execute (key , hash .compareByIdentity );
254
- int indexPos = getHashPos .execute (keyHash , firstKeyPos , index );
255
- Object val = deleteKvAndGetV (hash , indexPos , firstKeyPos );
254
+ int indexPos = getIndexPosFromKeyPosNode .execute (keyHash , keyPos , index );
255
+ Object val = deleteKvAndGetV (hash , indexPos , keyPos );
256
256
257
257
return ArrayHelpers .createArray (RubyContext .get (node ), RubyLanguage .get (node ), new Object []{ key , val });
258
258
}
@@ -503,59 +503,28 @@ int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, O
503
503
}
504
504
505
505
@ GenerateUncached
506
- abstract static class GetHashNextPosInIndexNode extends RubyBaseNode {
507
-
508
- public abstract int execute (int startingFromPos , int hash , int [] index , int stop );
509
-
510
- @ Specialization
511
- int getHashNextPos (int startingFromPos , int hash , int [] index , int stop ,
512
- @ Cached @ Exclusive InlinedConditionProfile slotIsUnused ,
513
- @ Cached @ Exclusive InlinedConditionProfile hashFound ,
514
- @ Cached @ Exclusive InlinedLoopConditionProfile stopNotYetReached ,
515
- @ Bind ("$node" ) Node node ) {
516
- int nextHashPos = startingFromPos ;
517
-
518
- do {
519
- if (slotIsUnused .profile (node , index [nextHashPos + 1 ] == INDEX_SLOT_UNUSED )) {
520
- return HASH_NOT_FOUND ;
521
- }
522
-
523
- if (hashFound .profile (node , index [nextHashPos ] == hash )) {
524
- return nextHashPos ;
525
- }
526
-
527
- nextHashPos = incrementIndexPos (nextHashPos , index .length );
528
- } while (stopNotYetReached .profile (node , nextHashPos != stop ));
529
-
530
- return HASH_NOT_FOUND ;
531
- }
532
- }
533
-
534
- @ GenerateUncached
535
- abstract static class GetHashPosForKeyAtKvPosNode extends RubyBaseNode {
506
+ abstract static class GetIndexPosFromKeyPosNode extends RubyBaseNode {
536
507
537
- public abstract int execute (int hash , int kvPos , int [] index );
508
+ public abstract int execute (int hash , int keyPos , int [] index );
538
509
539
510
@ Specialization
540
- int getHashPos (int hash , int kvPos , int [] index ,
541
- @ Cached @ Exclusive InlinedConditionProfile keyFound ,
542
- @ Cached @ Exclusive InlinedLoopConditionProfile keyHashFound ,
543
- @ Cached GetHashNextPosInIndexNode getNextHashPos ,
511
+ int findIndexPos (int hash , int keyPos , int [] index ,
512
+ @ Cached @ Exclusive InlinedConditionProfile unused ,
513
+ @ Cached @ Exclusive InlinedConditionProfile found ,
544
514
@ Bind ("$node" ) Node node ) {
515
+ int valuePosToSearch = keyPos + 1 ;
545
516
int startPos = indexPosFromHashCode (hash , index .length );
546
- int nextPos = getNextHashPos . execute ( startPos , hash , index , startPos ) ;
547
-
548
- while ( keyHashFound . profile ( node , nextPos != HASH_NOT_FOUND )) {
549
- int kvPosition = indexPosToKeyPos ( index , nextPos );
550
-
551
- if (keyFound .profile (node , kvPos == kvPosition )) {
552
- return nextPos ;
517
+ int indexPos = startPos ;
518
+ while ( true ) {
519
+ int valuePos = indexPosToValuePos ( index , indexPos );
520
+ if ( unused . profile ( node , valuePos == INDEX_SLOT_UNUSED )) {
521
+ // Keep going, this means the hash of the key changed
522
+ } else if (found .profile (node , valuePos == valuePosToSearch )) {
523
+ return indexPos ;
553
524
}
554
-
555
- int next = incrementIndexPos (nextPos , index .length );
556
- nextPos = getNextHashPos .execute (next , hash , index , startPos );
525
+ indexPos = incrementIndexPos (indexPos , index .length );
526
+ assert indexPos != startPos ;
557
527
}
558
- return HASH_NOT_FOUND ;
559
528
}
560
529
}
561
530
0 commit comments