252
252
@ ShortCircuitOperation (name = "PrimitiveBoolOr" , booleanConverter = PBytecodeDSLRootNode .BooleanIdentity .class , operator = Operator .OR_RETURN_CONVERTED )
253
253
@ SuppressWarnings ("unused" )
254
254
public abstract class PBytecodeDSLRootNode extends PRootNode implements BytecodeRootNode {
255
+ private static final int EXPLODE_LOOP_THRESHOLD = 32 ;
255
256
256
257
@ Child protected transient PythonObjectFactory factory = PythonObjectFactory .create ();
257
258
@ Child private transient CalleeContext calleeContext = CalleeContext .create ();
@@ -1474,7 +1475,6 @@ public static PList perform(Object[] elements,
1474
1475
@ Operation
1475
1476
public static final class MakeSet {
1476
1477
@ Specialization
1477
- @ ExplodeLoop
1478
1478
public static PSet perform (VirtualFrame frame , Object [] elements ,
1479
1479
@ Bind ("$root" ) PBytecodeDSLRootNode rootNode ,
1480
1480
@ Bind ("this" ) Node node ,
@@ -1485,11 +1485,26 @@ public static PSet perform(VirtualFrame frame, Object[] elements,
1485
1485
assert elements .length == length ;
1486
1486
1487
1487
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 );
1488
1499
for (int i = 0 ; i < length ; i ++) {
1489
1500
SetNodes .AddNode .add (frame , set , elements [i ], addNode , setItemNode );
1490
1501
}
1502
+ }
1491
1503
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
+ }
1493
1508
}
1494
1509
}
1495
1510
@@ -1505,22 +1520,43 @@ public static PSet perform(VirtualFrame frame,
1505
1520
@ Operation
1506
1521
public static final class MakeFrozenSet {
1507
1522
@ Specialization
1508
- @ ExplodeLoop
1509
- public static PFrozenSet doFrozenSet (VirtualFrame frame , @ Variadic Object [] elements ,
1523
+ public static PFrozenSet perform (VirtualFrame frame , @ Variadic Object [] elements ,
1510
1524
@ Cached (value = "elements.length" , neverDefault = false ) int length ,
1511
1525
@ Cached HashingStorageSetItem hashingStorageLibrary ,
1512
1526
@ Bind ("$root" ) PBytecodeDSLRootNode rootNode ,
1513
1527
@ Bind ("this" ) Node inliningTarget ) {
1514
1528
// TODO (GR-52217): make length a DSL constant.
1515
1529
assert elements .length == length ;
1516
1530
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 );
1517
1543
HashingStorage setStorage = EmptyStorage .INSTANCE ;
1518
1544
for (int i = 0 ; i < length ; ++i ) {
1519
1545
Object o = elements [i ];
1520
1546
setStorage = hashingStorageLibrary .execute (frame , inliningTarget , setStorage , o , PNone .NONE );
1521
1547
}
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 ;
1523
1558
}
1559
+
1524
1560
}
1525
1561
1526
1562
@ Operation
@@ -1534,13 +1570,24 @@ public static PList perform(@Bind("$root") PBytecodeDSLRootNode rootNode) {
1534
1570
@ Operation
1535
1571
public static final class MakeTuple {
1536
1572
@ Specialization
1537
- @ ExplodeLoop
1538
1573
public static Object perform (@ Variadic Object [] elements ,
1539
1574
@ Cached (value = "elements.length" , neverDefault = false ) int length ,
1540
1575
@ Bind ("$root" ) PBytecodeDSLRootNode rootNode ) {
1541
1576
// TODO (GR-52217): make length a DSL constant.
1542
1577
assert elements .length == length ;
1543
1578
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 );
1544
1591
int totalLength = 0 ;
1545
1592
for (int i = 0 ; i < length ; i ++) {
1546
1593
totalLength += ((Object []) elements [i ]).length ;
@@ -1554,8 +1601,24 @@ public static Object perform(@Variadic Object[] elements,
1554
1601
System .arraycopy (arr , 0 , elts , idx , len );
1555
1602
idx += len ;
1556
1603
}
1604
+ return elts ;
1605
+ }
1557
1606
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 ;
1559
1622
}
1560
1623
}
1561
1624
@@ -1697,13 +1760,31 @@ public static Object doGeneric(Object start, Object end, Object step,
1697
1760
@ Operation
1698
1761
public static final class MakeKeywords {
1699
1762
@ Specialization
1700
- @ ExplodeLoop
1701
1763
public static PKeyword [] perform (@ Variadic Object [] keysAndValues ,
1702
1764
@ Cached (value = "keysAndValues.length" , neverDefault = true ) int length ) {
1703
1765
// TODO (GR-52217): make length a DSL constant.
1704
1766
assert keysAndValues .length == length ;
1705
1767
assert length % 2 == 0 ;
1706
1768
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 ) {
1707
1788
PKeyword [] result = new PKeyword [length / 2 ];
1708
1789
for (int i = 0 ; i < length ; i += 2 ) {
1709
1790
CompilerAsserts .compilationConstant (keysAndValues [i ]);
@@ -1727,7 +1808,6 @@ public static PKeyword[] perform(Object sourceCollection,
1727
1808
@ Operation
1728
1809
public static final class MakeDict {
1729
1810
@ Specialization
1730
- @ ExplodeLoop
1731
1811
public static PDict perform (VirtualFrame frame , @ Variadic Object [] keysAndValues ,
1732
1812
@ Bind ("$root" ) PBytecodeDSLRootNode rootNode ,
1733
1813
@ Cached (value = "keysAndValues.length" , neverDefault = true ) int length ,
@@ -1736,6 +1816,17 @@ public static PDict perform(VirtualFrame frame, @Variadic Object[] keysAndValues
1736
1816
assert keysAndValues .length == length ;
1737
1817
1738
1818
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 );
1739
1830
for (int i = 0 ; i < length ; i += 2 ) {
1740
1831
Object key = keysAndValues [i ];
1741
1832
Object value = keysAndValues [i + 1 ];
@@ -1745,8 +1836,18 @@ public static PDict perform(VirtualFrame frame, @Variadic Object[] keysAndValues
1745
1836
dict .setItem (key , value );
1746
1837
}
1747
1838
}
1839
+ }
1748
1840
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
+ }
1750
1851
}
1751
1852
}
1752
1853
@@ -2569,18 +2670,27 @@ public static PCell[] doLoadClosure(VirtualFrame frame) {
2569
2670
2570
2671
@ Operation
2571
2672
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
+
2573
2683
@ ExplodeLoop
2574
- public static void doExploded (VirtualFrame frame , Object [] values ,
2684
+ private static void doExploded (VirtualFrame frame , Object [] values ,
2575
2685
LocalSetterRange locals ) {
2686
+ CompilerAsserts .partialEvaluationConstant (values .length );
2576
2687
assert values .length == locals .getLength ();
2577
2688
for (int i = 0 ; i < locals .length ; i ++) {
2578
2689
locals .setObject (frame , i , values [i ]);
2579
2690
}
2580
2691
}
2581
2692
2582
- @ Specialization (replaces = "doExploded" )
2583
- public static void doRegular (VirtualFrame frame , Object [] values ,
2693
+ private static void doRegular (VirtualFrame frame , Object [] values ,
2584
2694
LocalSetterRange locals ) {
2585
2695
assert values .length == locals .getLength ();
2586
2696
for (int i = 0 ; i < locals .length ; i ++) {
@@ -2603,12 +2713,21 @@ public static PCell[] doMakeCellArray(@Variadic Object[] cells) {
2603
2713
@ Operation
2604
2714
public static final class Unstar {
2605
2715
@ Specialization
2606
- @ ExplodeLoop
2607
- public static Object [] doUnstar (@ Variadic Object [] values ,
2716
+ public static Object [] perform (@ Variadic Object [] values ,
2608
2717
@ Cached (value = "values.length" , neverDefault = false ) int length ) {
2609
2718
// TODO (GR-52217): make length a DSL constant.
2610
2719
assert values .length == length ;
2611
2720
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 );
2612
2731
int totalLength = 0 ;
2613
2732
for (int i = 0 ; i < length ; i ++) {
2614
2733
totalLength += ((Object []) values [i ]).length ;
@@ -2620,7 +2739,21 @@ public static Object[] doUnstar(@Variadic Object[] values,
2620
2739
System .arraycopy (values [i ], 0 , result , idx , nl );
2621
2740
idx += nl ;
2622
2741
}
2742
+ return result ;
2743
+ }
2623
2744
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
+ }
2624
2757
return result ;
2625
2758
}
2626
2759
}
@@ -3112,8 +3245,7 @@ public static void doExceptional(VirtualFrame frame,
3112
3245
@ Operation
3113
3246
public static final class BuildString {
3114
3247
@ Specialization
3115
- @ ExplodeLoop
3116
- public static Object doBuildString (@ Variadic Object [] strings ,
3248
+ public static Object perform (@ Variadic Object [] strings ,
3117
3249
@ Cached (value = "strings.length" , neverDefault = false ) int length ,
3118
3250
@ Cached TruffleStringBuilder .AppendStringNode appendNode ,
3119
3251
@ Cached TruffleStringBuilder .ToStringNode toString ) {
@@ -3122,11 +3254,26 @@ public static Object doBuildString(@Variadic Object[] strings,
3122
3254
3123
3255
TruffleStringBuilder tsb = TruffleStringBuilder .create (PythonUtils .TS_ENCODING );
3124
3256
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 );
3125
3268
for (int i = 0 ; i < length ; i ++) {
3126
3269
appendNode .execute (tsb , (TruffleString ) strings [i ]);
3127
3270
}
3271
+ }
3128
3272
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
+ }
3130
3277
}
3131
3278
}
3132
3279
0 commit comments