252252@ ShortCircuitOperation (name = "PrimitiveBoolOr" , booleanConverter = PBytecodeDSLRootNode .BooleanIdentity .class , operator = Operator .OR_RETURN_CONVERTED )
253253@ SuppressWarnings ("unused" )
254254public abstract class PBytecodeDSLRootNode extends PRootNode implements BytecodeRootNode {
255+ private static final int EXPLODE_LOOP_THRESHOLD = 32 ;
255256
256257 @ Child protected transient PythonObjectFactory factory = PythonObjectFactory .create ();
257258 @ Child private transient CalleeContext calleeContext = CalleeContext .create ();
@@ -1474,7 +1475,6 @@ public static PList perform(Object[] elements,
14741475 @ Operation
14751476 public static final class MakeSet {
14761477 @ Specialization
1477- @ ExplodeLoop
14781478 public static PSet perform (VirtualFrame frame , Object [] elements ,
14791479 @ Bind ("$root" ) PBytecodeDSLRootNode rootNode ,
14801480 @ Bind ("this" ) Node node ,
@@ -1485,11 +1485,26 @@ public static PSet perform(VirtualFrame frame, Object[] elements,
14851485 assert elements .length == length ;
14861486
14871487 PSet set = rootNode .factory .createSet ();
1488+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
1489+ doExploded (frame , set , elements , length , addNode , setItemNode );
1490+ } else {
1491+ doRegular (frame , set , elements , length , addNode , setItemNode );
1492+ }
1493+ return set ;
1494+ }
1495+
1496+ @ ExplodeLoop
1497+ private static void doExploded (VirtualFrame frame , PSet set , Object [] elements , int length , SetNodes .AddNode addNode , HashingCollectionNodes .SetItemNode setItemNode ) {
1498+ CompilerAsserts .partialEvaluationConstant (length );
14881499 for (int i = 0 ; i < length ; i ++) {
14891500 SetNodes .AddNode .add (frame , set , elements [i ], addNode , setItemNode );
14901501 }
1502+ }
14911503
1492- return set ;
1504+ private static void doRegular (VirtualFrame frame , PSet set , Object [] elements , int length , SetNodes .AddNode addNode , HashingCollectionNodes .SetItemNode setItemNode ) {
1505+ for (int i = 0 ; i < length ; i ++) {
1506+ SetNodes .AddNode .add (frame , set , elements [i ], addNode , setItemNode );
1507+ }
14931508 }
14941509 }
14951510
@@ -1505,22 +1520,43 @@ public static PSet perform(VirtualFrame frame,
15051520 @ Operation
15061521 public static final class MakeFrozenSet {
15071522 @ Specialization
1508- @ ExplodeLoop
1509- public static PFrozenSet doFrozenSet (VirtualFrame frame , @ Variadic Object [] elements ,
1523+ public static PFrozenSet perform (VirtualFrame frame , @ Variadic Object [] elements ,
15101524 @ Cached (value = "elements.length" , neverDefault = false ) int length ,
15111525 @ Cached HashingStorageSetItem hashingStorageLibrary ,
15121526 @ Bind ("$root" ) PBytecodeDSLRootNode rootNode ,
15131527 @ Bind ("this" ) Node inliningTarget ) {
15141528 // TODO (GR-52217): make length a DSL constant.
15151529 assert elements .length == length ;
15161530
1531+ HashingStorage setStorage ;
1532+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
1533+ setStorage = doExploded (frame , inliningTarget , elements , length , hashingStorageLibrary );
1534+ } else {
1535+ setStorage = doRegular (frame , inliningTarget , elements , length , hashingStorageLibrary );
1536+ }
1537+ return rootNode .factory .createFrozenSet (setStorage );
1538+ }
1539+
1540+ @ ExplodeLoop
1541+ private static HashingStorage doExploded (VirtualFrame frame , Node inliningTarget , Object [] elements , int length , HashingStorageSetItem hashingStorageLibrary ) {
1542+ CompilerAsserts .partialEvaluationConstant (length );
15171543 HashingStorage setStorage = EmptyStorage .INSTANCE ;
15181544 for (int i = 0 ; i < length ; ++i ) {
15191545 Object o = elements [i ];
15201546 setStorage = hashingStorageLibrary .execute (frame , inliningTarget , setStorage , o , PNone .NONE );
15211547 }
1522- return rootNode .factory .createFrozenSet (setStorage );
1548+ return setStorage ;
1549+ }
1550+
1551+ private static HashingStorage doRegular (VirtualFrame frame , Node inliningTarget , Object [] elements , int length , HashingStorageSetItem hashingStorageLibrary ) {
1552+ HashingStorage setStorage = EmptyStorage .INSTANCE ;
1553+ for (int i = 0 ; i < length ; ++i ) {
1554+ Object o = elements [i ];
1555+ setStorage = hashingStorageLibrary .execute (frame , inliningTarget , setStorage , o , PNone .NONE );
1556+ }
1557+ return setStorage ;
15231558 }
1559+
15241560 }
15251561
15261562 @ Operation
@@ -1534,13 +1570,24 @@ public static PList perform(@Bind("$root") PBytecodeDSLRootNode rootNode) {
15341570 @ Operation
15351571 public static final class MakeTuple {
15361572 @ Specialization
1537- @ ExplodeLoop
15381573 public static Object perform (@ Variadic Object [] elements ,
15391574 @ Cached (value = "elements.length" , neverDefault = false ) int length ,
15401575 @ Bind ("$root" ) PBytecodeDSLRootNode rootNode ) {
15411576 // TODO (GR-52217): make length a DSL constant.
15421577 assert elements .length == length ;
15431578
1579+ Object [] elts ;
1580+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
1581+ elts = doExploded (elements , length );
1582+ } else {
1583+ elts = doRegular (elements , length );
1584+ }
1585+ return rootNode .factory .createTuple (elts );
1586+ }
1587+
1588+ @ ExplodeLoop
1589+ private static Object [] doExploded (Object [] elements , int length ) {
1590+ CompilerAsserts .partialEvaluationConstant (length );
15441591 int totalLength = 0 ;
15451592 for (int i = 0 ; i < length ; i ++) {
15461593 totalLength += ((Object []) elements [i ]).length ;
@@ -1554,8 +1601,24 @@ public static Object perform(@Variadic Object[] elements,
15541601 System .arraycopy (arr , 0 , elts , idx , len );
15551602 idx += len ;
15561603 }
1604+ return elts ;
1605+ }
15571606
1558- return rootNode .factory .createTuple (elts );
1607+ private static Object [] doRegular (Object [] elements , int length ) {
1608+ int totalLength = 0 ;
1609+ for (int i = 0 ; i < length ; i ++) {
1610+ totalLength += ((Object []) elements [i ]).length ;
1611+ }
1612+
1613+ Object [] elts = new Object [totalLength ];
1614+ int idx = 0 ;
1615+ for (int i = 0 ; i < length ; i ++) {
1616+ Object [] arr = (Object []) elements [i ];
1617+ int len = arr .length ;
1618+ System .arraycopy (arr , 0 , elts , idx , len );
1619+ idx += len ;
1620+ }
1621+ return elts ;
15591622 }
15601623 }
15611624
@@ -1697,13 +1760,31 @@ public static Object doGeneric(Object start, Object end, Object step,
16971760 @ Operation
16981761 public static final class MakeKeywords {
16991762 @ Specialization
1700- @ ExplodeLoop
17011763 public static PKeyword [] perform (@ Variadic Object [] keysAndValues ,
17021764 @ Cached (value = "keysAndValues.length" , neverDefault = true ) int length ) {
17031765 // TODO (GR-52217): make length a DSL constant.
17041766 assert keysAndValues .length == length ;
17051767 assert length % 2 == 0 ;
17061768
1769+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
1770+ return doExploded (keysAndValues , length );
1771+ } else {
1772+ return doRegular (keysAndValues , length );
1773+ }
1774+ }
1775+
1776+ @ ExplodeLoop
1777+ private static PKeyword [] doExploded (Object [] keysAndValues , int length ) {
1778+ CompilerAsserts .partialEvaluationConstant (length );
1779+ PKeyword [] result = new PKeyword [length / 2 ];
1780+ for (int i = 0 ; i < length ; i += 2 ) {
1781+ CompilerAsserts .compilationConstant (keysAndValues [i ]);
1782+ result [i / 2 ] = new PKeyword ((TruffleString ) keysAndValues [i ], keysAndValues [i + 1 ]);
1783+ }
1784+ return result ;
1785+ }
1786+
1787+ private static PKeyword [] doRegular (Object [] keysAndValues , int length ) {
17071788 PKeyword [] result = new PKeyword [length / 2 ];
17081789 for (int i = 0 ; i < length ; i += 2 ) {
17091790 CompilerAsserts .compilationConstant (keysAndValues [i ]);
@@ -1727,7 +1808,6 @@ public static PKeyword[] perform(Object sourceCollection,
17271808 @ Operation
17281809 public static final class MakeDict {
17291810 @ Specialization
1730- @ ExplodeLoop
17311811 public static PDict perform (VirtualFrame frame , @ Variadic Object [] keysAndValues ,
17321812 @ Bind ("$root" ) PBytecodeDSLRootNode rootNode ,
17331813 @ Cached (value = "keysAndValues.length" , neverDefault = true ) int length ,
@@ -1736,6 +1816,17 @@ public static PDict perform(VirtualFrame frame, @Variadic Object[] keysAndValues
17361816 assert keysAndValues .length == length ;
17371817
17381818 PDict dict = rootNode .factory .createDict ();
1819+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
1820+ doExploded (frame , keysAndValues , length , updateNode , dict );
1821+ } else {
1822+ doRegular (frame , keysAndValues , length , updateNode , dict );
1823+ }
1824+ return dict ;
1825+ }
1826+
1827+ @ ExplodeLoop
1828+ private static void doExploded (VirtualFrame frame , Object [] keysAndValues , int length , DictNodes .UpdateNode updateNode , PDict dict ) {
1829+ CompilerAsserts .partialEvaluationConstant (length );
17391830 for (int i = 0 ; i < length ; i += 2 ) {
17401831 Object key = keysAndValues [i ];
17411832 Object value = keysAndValues [i + 1 ];
@@ -1745,8 +1836,18 @@ public static PDict perform(VirtualFrame frame, @Variadic Object[] keysAndValues
17451836 dict .setItem (key , value );
17461837 }
17471838 }
1839+ }
17481840
1749- return dict ;
1841+ private static void doRegular (VirtualFrame frame , Object [] keysAndValues , int length , DictNodes .UpdateNode updateNode , PDict dict ) {
1842+ for (int i = 0 ; i < length ; i += 2 ) {
1843+ Object key = keysAndValues [i ];
1844+ Object value = keysAndValues [i + 1 ];
1845+ if (key == PNone .NO_VALUE ) {
1846+ updateNode .execute (frame , dict , value );
1847+ } else {
1848+ dict .setItem (key , value );
1849+ }
1850+ }
17501851 }
17511852 }
17521853
@@ -2569,18 +2670,27 @@ public static PCell[] doLoadClosure(VirtualFrame frame) {
25692670
25702671 @ Operation
25712672 public static final class StoreRange {
2572- @ Specialization (guards = {"locals.length <= 32" })
2673+ @ Specialization
2674+ public static void perform (VirtualFrame frame , Object [] values ,
2675+ LocalSetterRange locals ) {
2676+ if (values .length <= EXPLODE_LOOP_THRESHOLD ) {
2677+ doExploded (frame , values , locals );
2678+ } else {
2679+ doRegular (frame , values , locals );
2680+ }
2681+ }
2682+
25732683 @ ExplodeLoop
2574- public static void doExploded (VirtualFrame frame , Object [] values ,
2684+ private static void doExploded (VirtualFrame frame , Object [] values ,
25752685 LocalSetterRange locals ) {
2686+ CompilerAsserts .partialEvaluationConstant (values .length );
25762687 assert values .length == locals .getLength ();
25772688 for (int i = 0 ; i < locals .length ; i ++) {
25782689 locals .setObject (frame , i , values [i ]);
25792690 }
25802691 }
25812692
2582- @ Specialization (replaces = "doExploded" )
2583- public static void doRegular (VirtualFrame frame , Object [] values ,
2693+ private static void doRegular (VirtualFrame frame , Object [] values ,
25842694 LocalSetterRange locals ) {
25852695 assert values .length == locals .getLength ();
25862696 for (int i = 0 ; i < locals .length ; i ++) {
@@ -2603,12 +2713,21 @@ public static PCell[] doMakeCellArray(@Variadic Object[] cells) {
26032713 @ Operation
26042714 public static final class Unstar {
26052715 @ Specialization
2606- @ ExplodeLoop
2607- public static Object [] doUnstar (@ Variadic Object [] values ,
2716+ public static Object [] perform (@ Variadic Object [] values ,
26082717 @ Cached (value = "values.length" , neverDefault = false ) int length ) {
26092718 // TODO (GR-52217): make length a DSL constant.
26102719 assert values .length == length ;
26112720
2721+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
2722+ return doExploded (values , length );
2723+ } else {
2724+ return doRegular (values , length );
2725+ }
2726+ }
2727+
2728+ @ ExplodeLoop
2729+ private static Object [] doExploded (Object [] values , int length ) {
2730+ CompilerAsserts .partialEvaluationConstant (length );
26122731 int totalLength = 0 ;
26132732 for (int i = 0 ; i < length ; i ++) {
26142733 totalLength += ((Object []) values [i ]).length ;
@@ -2620,7 +2739,21 @@ public static Object[] doUnstar(@Variadic Object[] values,
26202739 System .arraycopy (values [i ], 0 , result , idx , nl );
26212740 idx += nl ;
26222741 }
2742+ return result ;
2743+ }
26232744
2745+ private static Object [] doRegular (Object [] values , int length ) {
2746+ int totalLength = 0 ;
2747+ for (int i = 0 ; i < length ; i ++) {
2748+ totalLength += ((Object []) values [i ]).length ;
2749+ }
2750+ Object [] result = new Object [totalLength ];
2751+ int idx = 0 ;
2752+ for (int i = 0 ; i < length ; i ++) {
2753+ int nl = ((Object []) values [i ]).length ;
2754+ System .arraycopy (values [i ], 0 , result , idx , nl );
2755+ idx += nl ;
2756+ }
26242757 return result ;
26252758 }
26262759 }
@@ -3112,8 +3245,7 @@ public static void doExceptional(VirtualFrame frame,
31123245 @ Operation
31133246 public static final class BuildString {
31143247 @ Specialization
3115- @ ExplodeLoop
3116- public static Object doBuildString (@ Variadic Object [] strings ,
3248+ public static Object perform (@ Variadic Object [] strings ,
31173249 @ Cached (value = "strings.length" , neverDefault = false ) int length ,
31183250 @ Cached TruffleStringBuilder .AppendStringNode appendNode ,
31193251 @ Cached TruffleStringBuilder .ToStringNode toString ) {
@@ -3122,11 +3254,26 @@ public static Object doBuildString(@Variadic Object[] strings,
31223254
31233255 TruffleStringBuilder tsb = TruffleStringBuilder .create (PythonUtils .TS_ENCODING );
31243256
3257+ if (length <= EXPLODE_LOOP_THRESHOLD ) {
3258+ doExploded (strings , length , appendNode , tsb );
3259+ } else {
3260+ doRegular (strings , length , appendNode , tsb );
3261+ }
3262+ return toString .execute (tsb );
3263+ }
3264+
3265+ @ ExplodeLoop
3266+ private static void doExploded (Object [] strings , int length , TruffleStringBuilder .AppendStringNode appendNode , TruffleStringBuilder tsb ) {
3267+ CompilerAsserts .partialEvaluationConstant (length );
31253268 for (int i = 0 ; i < length ; i ++) {
31263269 appendNode .execute (tsb , (TruffleString ) strings [i ]);
31273270 }
3271+ }
31283272
3129- return toString .execute (tsb );
3273+ private static void doRegular (Object [] strings , int length , TruffleStringBuilder .AppendStringNode appendNode , TruffleStringBuilder tsb ) {
3274+ for (int i = 0 ; i < length ; i ++) {
3275+ appendNode .execute (tsb , (TruffleString ) strings [i ]);
3276+ }
31303277 }
31313278 }
31323279
0 commit comments