127
127
import com .oracle .truffle .api .object .Location ;
128
128
import com .oracle .truffle .api .object .Property ;
129
129
import com .oracle .truffle .api .object .Shape ;
130
+ import com .oracle .truffle .api .profiles .BranchProfile ;
130
131
import com .oracle .truffle .api .profiles .ConditionProfile ;
131
132
import com .oracle .truffle .api .profiles .ValueProfile ;
132
133
133
134
@ GenerateNodeFactory
134
135
public abstract class HashingStorageNodes {
136
+ private static final int MAX_STORAGES = 8 ;
135
137
136
138
public static class PythonEquivalence extends Equivalence {
137
139
@ Child private PRaiseNode raise ;
@@ -1650,10 +1652,29 @@ public static ExclusiveOrNode create() {
1650
1652
}
1651
1653
1652
1654
public abstract static class KeysIsSubsetNode extends DictStorageBaseNode {
1655
+ protected static final int MAX_STORAGES = HashingStorageNodes .MAX_STORAGES ;
1653
1656
1654
1657
public abstract boolean execute (VirtualFrame frame , HashingStorage left , HashingStorage right );
1655
1658
1656
- @ Specialization
1659
+ @ Specialization (limit = "MAX_STORAGES" , guards = {"left.getClass() == leftClass" , "right.getClass() == rightClass" })
1660
+ public boolean isSubsetCached (VirtualFrame frame , HashingStorage left , HashingStorage right ,
1661
+ @ Cached ("left.getClass()" ) Class <? extends HashingStorage > leftClass ,
1662
+ @ Cached ("right.getClass()" ) Class <? extends HashingStorage > rightClass ,
1663
+ @ Cached ("create()" ) ContainsKeyNode containsKeyNode ,
1664
+ @ Cached ("createBinaryProfile()" ) ConditionProfile sizeProfile ) {
1665
+ if (sizeProfile .profile (leftClass .cast (left ).length () > rightClass .cast (right ).length ())) {
1666
+ return false ;
1667
+ }
1668
+
1669
+ for (Object leftKey : leftClass .cast (left ).keys ()) {
1670
+ if (!containsKeyNode .execute (frame , right , leftKey )) {
1671
+ return false ;
1672
+ }
1673
+ }
1674
+ return true ;
1675
+ }
1676
+
1677
+ @ Specialization (replaces = "isSubsetCached" )
1657
1678
public boolean isSubset (VirtualFrame frame , HashingStorage left , HashingStorage right ,
1658
1679
@ Cached ("create()" ) ContainsKeyNode containsKeyNode ,
1659
1680
@ Cached ("createBinaryProfile()" ) ConditionProfile sizeProfile ) {
@@ -1692,24 +1713,61 @@ public static KeysIsSupersetNode create() {
1692
1713
}
1693
1714
1694
1715
public abstract static class DiffNode extends DictStorageBaseNode {
1716
+ protected static final int MAX_STORAGES = HashingStorageNodes .MAX_STORAGES ;
1695
1717
1696
1718
public abstract HashingStorage execute (VirtualFrame frame , HashingStorage left , HashingStorage right );
1697
1719
1698
- @ Specialization (guards = "left.length() == 0" )
1720
+ protected boolean isEmpty (Class <? extends HashingStorage > theClass , HashingStorage s ) {
1721
+ return theClass .cast (s ).length () == 0 ;
1722
+ }
1723
+
1724
+ @ Specialization (limit = "MAX_STORAGES" , guards = {"left.getClass() == leftClass" , "isEmpty(leftClass, left)" })
1699
1725
@ SuppressWarnings ("unused" )
1700
- public HashingStorage doLeftEmpty (HashingStorage left , HashingStorage right ) {
1726
+ public HashingStorage doLeftEmpty (HashingStorage left , HashingStorage right ,
1727
+ @ SuppressWarnings ("unused" ) @ Cached ("left.getClass()" ) Class <? extends HashingStorage > leftClass ) {
1701
1728
return EconomicMapStorage .create (false );
1702
1729
}
1703
1730
1704
- @ Specialization (guards = "right.length() == 0" )
1731
+ @ Specialization (limit = "MAX_STORAGES" , guards = {"left.getClass() == leftClass" , "right.getClass() == rightClass" })
1732
+ @ SuppressWarnings ("try" )
1733
+ public HashingStorage doNonEmptyCached (VirtualFrame frame , HashingStorage left , HashingStorage right ,
1734
+ @ Cached ("left.getClass()" ) Class <? extends HashingStorage > leftClass ,
1735
+ @ Cached ("right.getClass()" ) Class <? extends HashingStorage > rightClass ,
1736
+ @ Cached ("create()" ) ContainsKeyNode containsKeyNode ,
1737
+ @ Cached BranchProfile leftEmpty ,
1738
+ @ Cached BranchProfile rightEmpty ,
1739
+ @ Cached BranchProfile neitherEmpty ,
1740
+ @ Cached ("create()" ) SetItemNode setItemNode ) {
1741
+ if (leftClass .cast (left ).length () == 0 ) {
1742
+ leftEmpty .enter ();
1743
+ return EconomicMapStorage .create (false );
1744
+ }
1745
+ if (rightClass .cast (right ).length () == 0 ) {
1746
+ rightEmpty .enter ();
1747
+ try (DefaultContextManager cm = withGlobalState (frame )) {
1748
+ return leftClass .cast (left ).copy (getEquivalence ());
1749
+ }
1750
+ }
1751
+ neitherEmpty .enter ();
1752
+ HashingStorage newStorage = EconomicMapStorage .create (false );
1753
+ for (Object leftKey : leftClass .cast (left ).keys ()) {
1754
+ if (!containsKeyNode .execute (frame , right , leftKey )) {
1755
+ newStorage = setItemNode .execute (frame , newStorage , leftKey , PNone .NO_VALUE );
1756
+ }
1757
+ }
1758
+ return newStorage ;
1759
+ }
1760
+
1761
+ @ Specialization (limit = "MAX_STORAGES" , guards = {"right.getClass() == rightClass" , "isEmpty(rightClass, right)" })
1705
1762
@ SuppressWarnings ("try" )
1706
- public HashingStorage doRightEmpty (VirtualFrame frame , HashingStorage left , @ SuppressWarnings ("unused" ) HashingStorage right ) {
1763
+ public HashingStorage doRightEmpty (VirtualFrame frame , HashingStorage left , @ SuppressWarnings ("unused" ) HashingStorage right ,
1764
+ @ SuppressWarnings ("unused" ) @ Cached ("right.getClass()" ) Class <? extends HashingStorage > rightClass ) {
1707
1765
try (DefaultContextManager cm = withGlobalState (frame )) {
1708
1766
return left .copy (getEquivalence ());
1709
1767
}
1710
1768
}
1711
1769
1712
- @ Specialization (guards = { "left.length() != 0" , "right.length() != 0" } )
1770
+ @ Specialization (replaces = "doNonEmptyCached" )
1713
1771
public HashingStorage doNonEmpty (VirtualFrame frame , HashingStorage left , HashingStorage right ,
1714
1772
@ Cached ("create()" ) ContainsKeyNode containsKeyNode ,
1715
1773
@ Cached ("create()" ) SetItemNode setItemNode ) {
@@ -1731,7 +1789,7 @@ public static DiffNode create() {
1731
1789
@ GenerateUncached
1732
1790
public abstract static class LenNode extends Node {
1733
1791
1734
- protected static final int MAX_STORAGES = 8 ;
1792
+ protected static final int MAX_STORAGES = HashingStorageNodes . MAX_STORAGES ;
1735
1793
1736
1794
public abstract int execute (HashingStorage s );
1737
1795
0 commit comments