18
18
19
19
import com .oracle .truffle .api .CompilerAsserts ;
20
20
import com .oracle .truffle .api .CompilerDirectives ;
21
+ import com .oracle .truffle .api .dsl .GenerateCached ;
22
+ import com .oracle .truffle .api .dsl .GenerateInline ;
21
23
import org .truffleruby .RubyContext ;
22
24
import org .truffleruby .RubyLanguage ;
23
25
import org .truffleruby .collections .PEBiFunction ;
38
40
import com .oracle .truffle .api .dsl .Cached ;
39
41
import com .oracle .truffle .api .dsl .Cached .Shared ;
40
42
import com .oracle .truffle .api .dsl .GenerateUncached ;
41
- import com .oracle .truffle .api .dsl .ImportStatic ;
42
43
import com .oracle .truffle .api .dsl .Specialization ;
43
44
import com .oracle .truffle .api .frame .Frame ;
44
45
import com .oracle .truffle .api .frame .VirtualFrame ;
@@ -174,7 +175,7 @@ Object lookupOrDefault(Frame frame, RubyHash hash, Object key, PEBiFunction defa
174
175
@ Bind ("$node" ) Node node ) {
175
176
int keyHash = hashFunction .execute (key , hash .compareByIdentity );
176
177
177
- int indexPos = getIndexPosForKeyNode .execute (key , keyHash , hash .compareByIdentity , index , kvStore , false );
178
+ int indexPos = getIndexPosForKeyNode .execute (node , key , keyHash , hash .compareByIdentity , index , kvStore , false );
178
179
if (keyNotFound .profile (node , indexPos == KEY_NOT_FOUND )) {
179
180
return defaultNode .accept (frame , hash , key );
180
181
}
@@ -194,13 +195,13 @@ boolean set(RubyHash hash, Object key, Object value, boolean byIdentity,
194
195
@ Bind ("$node" ) Node node ) {
195
196
var frozenKey = freezeKey .executeFreezeIfNeeded (node , key , byIdentity );
196
197
int keyHash = hashFunction .execute (frozenKey , byIdentity );
197
- int indexPos = getIndexPosForKeyNode .execute (frozenKey , keyHash , byIdentity , index , kvStore , true );
198
+ int indexPos = getIndexPosForKeyNode .execute (node , frozenKey , keyHash , byIdentity , index , kvStore , true );
198
199
int keyPos = indexPosToKeyPos (index , indexPos ); // can be < 0 if inserting new key
199
200
200
201
propagateSharingForKey .execute (node , hash , frozenKey );
201
202
propagateSharingForVal .execute (node , hash , value );
202
203
203
- return setKv .execute (hash , this , indexPos , keyPos , keyHash , frozenKey , value );
204
+ return setKv .execute (node , hash , this , indexPos , keyPos , keyHash , frozenKey , value );
204
205
}
205
206
206
207
@ ExportMessage
@@ -210,7 +211,7 @@ Object delete(RubyHash hash, Object key,
210
211
@ Cached @ Exclusive InlinedConditionProfile keyNotFound ,
211
212
@ Bind ("$node" ) Node node ) {
212
213
int keyHash = hashFunction .execute (key , hash .compareByIdentity );
213
- int indexPos = getIndexPosForKeyNode .execute (key , keyHash , hash .compareByIdentity , index , kvStore , false );
214
+ int indexPos = getIndexPosForKeyNode .execute (node , key , keyHash , hash .compareByIdentity , index , kvStore , false );
214
215
if (keyNotFound .profile (node , indexPos == KEY_NOT_FOUND )) {
215
216
return null ;
216
217
}
@@ -235,7 +236,7 @@ Object deleteLast(RubyHash hash, Object key,
235
236
}
236
237
237
238
int keyHash = hashFunction .execute (key , hash .compareByIdentity );
238
- int indexPos = getIndexPosFromKeyPosNode .execute (keyHash , keyPos , index );
239
+ int indexPos = getIndexPosFromKeyPosNode .execute (node , keyHash , keyPos , index );
239
240
240
241
return deleteKvAndGetV (hash , indexPos , keyPos );
241
242
}
@@ -251,7 +252,7 @@ RubyArray shift(RubyHash hash,
251
252
252
253
Object key = kvStore [keyPos ];
253
254
int keyHash = hashFunction .execute (key , hash .compareByIdentity );
254
- int indexPos = getIndexPosFromKeyPosNode .execute (keyHash , keyPos , index );
255
+ int indexPos = getIndexPosFromKeyPosNode .execute (node , keyHash , keyPos , index );
255
256
Object val = deleteKvAndGetV (hash , indexPos , keyPos );
256
257
257
258
return ArrayHelpers .createArray (RubyContext .get (node ), RubyLanguage .get (node ), new Object []{ key , val });
@@ -477,27 +478,36 @@ public void getAdjacentObjects(Set<Object> reachable) {
477
478
478
479
/** Given a key and its hash, returns the index pos where this key's hashCode is found. If not found, returns where
479
480
* it could be inserted if insert is true and KEY_NOT_FOUND otherwise. */
481
+ @ GenerateInline
482
+ @ GenerateCached (false )
480
483
@ GenerateUncached
481
484
abstract static class GetIndexPosForKeyNode extends RubyBaseNode {
482
485
483
- public abstract int execute (Object key , int hash , boolean compareByIdentity , int [] index , Object [] kvStore ,
484
- boolean insert );
486
+ public abstract int execute (Node node , Object key , int hash , boolean compareByIdentity , int [] index ,
487
+ Object [] kvStore , boolean insert );
485
488
486
489
@ Specialization
487
- int findIndexPos (Object key , int hash , boolean compareByIdentity , int [] index , Object [] kvStore , boolean insert ,
490
+ static int findIndexPos (
491
+ Node node ,
492
+ Object key ,
493
+ int hash ,
494
+ boolean compareByIdentity ,
495
+ int [] index ,
496
+ Object [] kvStore ,
497
+ boolean insert ,
488
498
@ Cached CompareHashKeysNode .AssumingEqualHashes compareHashKeysNode ,
489
499
@ Cached @ Exclusive InlinedConditionProfile unused ,
490
- @ Cached @ Exclusive InlinedConditionProfile sameHash ,
491
- @ Bind ("$node" ) Node node ) {
500
+ @ Cached @ Exclusive InlinedConditionProfile sameHash ) {
492
501
CompilerAsserts .partialEvaluationConstant (insert );
502
+
493
503
int startPos = indexPosFromHashCode (hash , index .length );
494
504
int indexPos = startPos ;
495
505
while (true ) {
496
506
int valuePos = indexPosToValuePos (index , indexPos );
497
507
if (unused .profile (node , valuePos == INDEX_SLOT_UNUSED )) {
498
508
return insert ? indexPos : KEY_NOT_FOUND ;
499
509
} else if (sameHash .profile (node , index [indexPos ] == hash ) &&
500
- compareHashKeysNode .execute (compareByIdentity , key , kvStore [valuePos - 1 ])) { // keyPos == valuePos - 1
510
+ compareHashKeysNode .execute (node , compareByIdentity , key , kvStore [valuePos - 1 ])) { // keyPos == valuePos - 1
501
511
return indexPos ;
502
512
}
503
513
indexPos = incrementIndexPos (indexPos , index .length );
@@ -506,16 +516,17 @@ int findIndexPos(Object key, int hash, boolean compareByIdentity, int[] index, O
506
516
}
507
517
}
508
518
519
+ @ GenerateInline
520
+ @ GenerateCached (false )
509
521
@ GenerateUncached
510
522
abstract static class GetIndexPosFromKeyPosNode extends RubyBaseNode {
511
523
512
- public abstract int execute (int hash , int keyPos , int [] index );
524
+ public abstract int execute (Node node , int hash , int keyPos , int [] index );
513
525
514
526
@ Specialization
515
- int findIndexPos (int hash , int keyPos , int [] index ,
527
+ static int findIndexPos (Node node , int hash , int keyPos , int [] index ,
516
528
@ Cached @ Exclusive InlinedConditionProfile unused ,
517
- @ Cached @ Exclusive InlinedConditionProfile found ,
518
- @ Bind ("$node" ) Node node ) {
529
+ @ Cached @ Exclusive InlinedConditionProfile found ) {
519
530
int valuePosToSearch = keyPos + 1 ;
520
531
int startPos = indexPosFromHashCode (hash , index .length );
521
532
int indexPos = startPos ;
@@ -532,16 +543,18 @@ int findIndexPos(int hash, int keyPos, int[] index,
532
543
}
533
544
}
534
545
546
+ @ GenerateInline
547
+ @ GenerateCached (false )
535
548
@ GenerateUncached
536
- @ ImportStatic (CompactHashStore .class )
537
549
abstract static class SetKvAtNode extends RubyBaseNode {
538
550
539
- public abstract boolean execute (RubyHash hash , CompactHashStore store , int indexPos , int keyPos , int keyHash ,
540
- Object key , Object value );
551
+ public abstract boolean execute (Node node , RubyHash hash , CompactHashStore store , int indexPos , int keyPos ,
552
+ int keyHash , Object key , Object value );
541
553
542
554
// key already exist, very fast because there is no need to touch the index
543
555
@ Specialization (guards = "keyPos >= 0" )
544
- boolean keyAlreadyExistsWithDifferentValue (
556
+ static boolean keyAlreadyExistsWithDifferentValue (
557
+ Node node ,
545
558
RubyHash hash ,
546
559
CompactHashStore store ,
547
560
int indexPos ,
@@ -556,10 +569,16 @@ boolean keyAlreadyExistsWithDifferentValue(
556
569
// setting a new key is more expensive
557
570
@ Specialization (guards = "keyPos < 0" )
558
571
static boolean keyDoesntExist (
559
- RubyHash hash , CompactHashStore store , int indexPos , int keyPos , int keyHash , Object key , Object value ,
572
+ Node node ,
573
+ RubyHash hash ,
574
+ CompactHashStore store ,
575
+ int indexPos ,
576
+ int keyPos ,
577
+ int keyHash ,
578
+ Object key ,
579
+ Object value ,
560
580
@ Cached @ Exclusive InlinedConditionProfile kvResizingIsNeeded ,
561
- @ Cached @ Exclusive InlinedConditionProfile indexResizingIsNeeded ,
562
- @ Bind ("$node" ) Node node ) {
581
+ @ Cached @ Exclusive InlinedConditionProfile indexResizingIsNeeded ) {
563
582
if (kvResizingIsNeeded .profile (node , store .kvStoreInsertionPos >= store .kvStore .length )) {
564
583
resizeKvStore (store );
565
584
}
0 commit comments