7171import com .oracle .truffle .api .library .ExportLibrary ;
7272import com .oracle .truffle .api .library .ExportMessage ;
7373import com .oracle .truffle .api .nodes .LoopNode ;
74+ import com .oracle .truffle .api .profiles .BranchProfile ;
7475import com .oracle .truffle .api .profiles .ConditionProfile ;
7576import com .oracle .truffle .api .profiles .LoopConditionProfile ;
7677import com .oracle .truffle .api .strings .TruffleString ;
@@ -219,6 +220,7 @@ static HashingStorage setItemGeneric(EconomicMapStorage self, Object key, Object
219220 @ Shared ("putNode" ) @ Cached ObjectHashMap .PutNode putNode ,
220221 @ Shared ("hashNode" ) @ Cached PyObjectHashNode hashNode ,
221222 @ Shared ("gotState" ) @ Cached ConditionProfile gotState ) {
223+ convertToSideEffectMap (self );
222224 VirtualFrame frame = gotState .profile (state == null ) ? null : PArguments .frameForCall (state );
223225 putNode .put (state , self .map , key , hashNode .execute (frame , key ), assertNoJavaString (value ));
224226 return self ;
@@ -401,14 +403,12 @@ static int compareSameType(EconomicMapStorage self, EconomicMapStorage other, Th
401403 @ CachedLibrary ("self" ) HashingStorageLibrary thisLib ,
402404 @ Shared ("selfEntriesLoop" ) @ Cached LoopConditionProfile loopProfile ,
403405 @ Shared ("selfEntriesLoopExit" ) @ Cached LoopConditionProfile earlyExitProfile ,
404- @ Shared ("getNode" ) @ Cached ObjectHashMap .GetNode getNode ,
405- @ Shared ("gotState" ) @ Cached ConditionProfile gotState ) {
406+ @ Shared ("getNode" ) @ Cached ObjectHashMap .GetNode getNode ) {
406407 int size = self .map .size ();
407408 int size2 = other .map .size ();
408409 if (size > size2 ) {
409410 return 1 ;
410411 }
411- VirtualFrame frame = gotState .profile (state == null ) ? null : PArguments .frameForCall (state );
412412 MapCursor cursor = self .map .getEntries ();
413413 int counter = 0 ;
414414 try {
@@ -477,17 +477,22 @@ static HashingStorage intersectSameType(EconomicMapStorage self, EconomicMapStor
477477 @ Shared ("putNode" ) @ Cached ObjectHashMap .PutNode putNode ,
478478 @ Shared ("getNode" ) @ Cached ObjectHashMap .GetNode getNode ,
479479 @ Shared ("selfEntriesLoop" ) @ Cached LoopConditionProfile loopProfile ,
480- @ Shared ("gotState " ) @ Cached ConditionProfile gotState ) {
480+ @ Shared ("setSideEffect " ) @ Cached BranchProfile setSideEffectFlag ) {
481481 EconomicMapStorage result = EconomicMapStorage .create ();
482- VirtualFrame frame = gotState .profile (state == null ) ? null : PArguments .frameForCall (state );
482+ ObjectHashMap resultMap = result .map ;
483+ ObjectHashMap otherMap = other .map ;
484+ if (self .map .hasSideEffect () || otherMap .hasSideEffect ()) {
485+ setSideEffectFlag .enter ();
486+ resultMap .setSideEffectingKeysFlag ();
487+ }
483488 MapCursor cursor = self .map .getEntries ();
484489 // get/put may throw, but we ignore that small inaccuracy
485490 final int size = self .map .size ();
486491 loopProfile .profileCounted (size );
487492 LoopNode .reportLoopCount (thisLib , size );
488493 while (loopProfile .inject (advance (cursor ))) {
489- if (getNode .get (state , other . map , getDictKey (cursor )) != null ) {
490- putNode .put (state , result . map , getDictKey (cursor ), getValue (cursor ));
494+ if (getNode .get (state , otherMap , getDictKey (cursor )) != null ) {
495+ putNode .put (state , resultMap , getDictKey (cursor ), getValue (cursor ));
491496 }
492497 }
493498 return result ;
@@ -498,18 +503,18 @@ static HashingStorage intersectGeneric(EconomicMapStorage self, HashingStorage o
498503 @ CachedLibrary ("self" ) HashingStorageLibrary thisLib ,
499504 @ Shared ("putNode" ) @ Cached ObjectHashMap .PutNode putNode ,
500505 @ Shared ("selfEntriesLoop" ) @ Cached LoopConditionProfile loopProfile ,
501- @ Shared ("otherHLib" ) @ CachedLibrary (limit = "2" ) HashingStorageLibrary hlib ,
502- @ Shared ("gotState" ) @ Cached ConditionProfile gotState ) {
506+ @ Shared ("otherHLib" ) @ CachedLibrary (limit = "2" ) HashingStorageLibrary hlib ) {
503507 EconomicMapStorage result = EconomicMapStorage .create ();
504- VirtualFrame frame = gotState .profile (state == null ) ? null : PArguments .frameForCall (state );
508+ ObjectHashMap resultMap = result .map ;
509+ resultMap .setSideEffectingKeysFlag ();
505510 MapCursor cursor = self .map .getEntries ();
506511 // get/put may throw, but we ignore that small inaccuracy
507512 final int size = self .map .size ();
508513 loopProfile .profileCounted (size );
509514 LoopNode .reportLoopCount (thisLib , size );
510515 while (loopProfile .inject (advance (cursor ))) {
511516 if (hlib .hasKey (other , getKey (cursor ))) {
512- putNode .put (state , result . map , getDictKey (cursor ), getValue (cursor ));
517+ putNode .put (state , resultMap , getDictKey (cursor ), getValue (cursor ));
513518 }
514519 }
515520 return result ;
@@ -524,17 +529,22 @@ static HashingStorage diffSameType(EconomicMapStorage self, EconomicMapStorage o
524529 @ Shared ("putNode" ) @ Cached ObjectHashMap .PutNode putNode ,
525530 @ Shared ("getNode" ) @ Cached ObjectHashMap .GetNode getNode ,
526531 @ Shared ("selfEntriesLoop" ) @ Cached LoopConditionProfile loopProfile ,
527- @ Shared ("gotState " ) @ Cached ConditionProfile gotState ) {
532+ @ Shared ("setSideEffect " ) @ Cached BranchProfile setSideEffectFlag ) {
528533 EconomicMapStorage result = EconomicMapStorage .create ();
529- VirtualFrame frame = gotState .profile (state == null ) ? null : PArguments .frameForCall (state );
534+ ObjectHashMap resultMap = result .map ;
535+ ObjectHashMap otherMap = other .map ;
536+ if (self .map .hasSideEffect () || otherMap .hasSideEffect ()) {
537+ setSideEffectFlag .enter ();
538+ resultMap .setSideEffectingKeysFlag ();
539+ }
530540 MapCursor cursor = self .map .getEntries ();
531541 // get/put may throw, but we ignore that small inaccuracy
532542 final int size = self .map .size ();
533543 loopProfile .profileCounted (size );
534544 LoopNode .reportLoopCount (thisLib , size );
535545 while (loopProfile .inject (advance (cursor ))) {
536- if (getNode .get (state , other . map , getDictKey (cursor )) == null ) {
537- putNode .put (state , result . map , getDictKey (cursor ), getValue (cursor ));
546+ if (getNode .get (state , otherMap , getDictKey (cursor )) == null ) {
547+ putNode .put (state , resultMap , getDictKey (cursor ), getValue (cursor ));
538548 }
539549 }
540550 return result ;
@@ -545,18 +555,18 @@ static HashingStorage diffGeneric(EconomicMapStorage self, HashingStorage other,
545555 @ CachedLibrary ("self" ) HashingStorageLibrary thisLib ,
546556 @ Shared ("putNode" ) @ Cached ObjectHashMap .PutNode putNode ,
547557 @ Shared ("selfEntriesLoop" ) @ Cached LoopConditionProfile loopProfile ,
548- @ Shared ("otherHLib" ) @ CachedLibrary (limit = "2" ) HashingStorageLibrary hlib ,
549- @ Shared ("gotState" ) @ Cached ConditionProfile gotState ) {
558+ @ Shared ("otherHLib" ) @ CachedLibrary (limit = "2" ) HashingStorageLibrary hlib ) {
550559 EconomicMapStorage result = EconomicMapStorage .create ();
551- VirtualFrame frame = gotState .profile (state == null ) ? null : PArguments .frameForCall (state );
560+ ObjectHashMap resultMap = result .map ;
561+ resultMap .setSideEffectingKeysFlag ();
552562 MapCursor cursor = self .map .getEntries ();
553563 // get/put may throw, but we ignore that small inaccuracy
554564 final int size = self .map .size ();
555565 loopProfile .profileCounted (size );
556566 LoopNode .reportLoopCount (thisLib , size );
557567 while (loopProfile .profile (advance (cursor ))) {
558568 if (!hlib .hasKey (other , getKey (cursor ))) {
559- putNode .put (state , result . map , getDictKey (cursor ), getValue (cursor ));
569+ putNode .put (state , resultMap , getDictKey (cursor ), getValue (cursor ));
560570 }
561571 }
562572 return result ;
0 commit comments