@@ -2156,7 +2156,6 @@ public static ExtendNode create(Supplier<GeneralizationNode> genNodeProvider) {
21562156 public abstract static class RepeatNode extends SequenceStorageBaseNode {
21572157 private static final String ERROR_MSG = "can't multiply sequence by non-int of type '%p'" ;
21582158
2159- @ Child private SetItemScalarNode setItemNode ;
21602159 @ Child private GetItemScalarNode getItemNode ;
21612160 @ Child private GetItemScalarNode getRightItemNode ;
21622161 @ Child private IsIndexNode isIndexNode ;
@@ -2174,8 +2173,8 @@ SequenceStorage doEmpty(EmptySequenceStorage s, @SuppressWarnings("unused") int
21742173
21752174 @ Specialization (guards = "times <= 0" )
21762175 SequenceStorage doZeroRepeat (SequenceStorage s , @ SuppressWarnings ("unused" ) int times ,
2177- @ Cached ("createClassProfile ()" ) ValueProfile storageTypeProfile ) {
2178- return storageTypeProfile . profile ( s ). createEmpty ( 0 );
2176+ @ Cached ("create ()" ) CreateEmptyNode createEmptyNode ) {
2177+ return createEmptyNode . execute ( s , 0 );
21792178 }
21802179
21812180 @ Specialization (limit = "MAX_ARRAY_STORAGES" , guards = {"times > 0" , "!isNative(s)" , "s.getClass() == cachedClass" })
@@ -2200,21 +2199,26 @@ SequenceStorage doManaged(BasicSequenceStorage s, int times,
22002199
22012200 @ Specialization (replaces = "doManaged" , guards = "times > 0" )
22022201 SequenceStorage doGeneric (SequenceStorage s , int times ,
2202+ @ Cached ("create()" ) CreateEmptyNode createEmptyNode ,
22032203 @ Cached ("create()" ) BranchProfile outOfMemProfile ,
2204+ @ Cached ("create()" ) SetItemScalarNode setItemNode ,
2205+ @ Cached ("create()" ) GetItemScalarNode getDestItemNode ,
22042206 @ Cached ("create()" ) LenNode lenNode ) {
22052207 try {
22062208 int len = lenNode .execute (s );
2209+ SequenceStorage repeated = createEmptyNode .execute (s , Math .multiplyExact (len , times ));
22072210
2208- ObjectSequenceStorage repeated = new ObjectSequenceStorage (Math .multiplyExact (len , times ));
2209-
2210- // TODO avoid temporary array
2211- Object [] values = new Object [len ];
22122211 for (int i = 0 ; i < len ; i ++) {
2213- values [i ] = getGetItemNode ().execute (s , i );
2212+ setItemNode .execute (repeated , i , getGetItemNode ().execute (s , i ));
2213+ }
2214+
2215+ // read from destination since that is potentially faster
2216+ for (int j = 1 ; j < times ; j ++) {
2217+ for (int i = 0 ; i < len ; i ++) {
2218+ setItemNode .execute (repeated , j * len + i , getDestItemNode .execute (repeated , i ));
2219+ }
22142220 }
22152221
2216- Object destArr = repeated .getInternalArrayObject ();
2217- repeat (destArr , values , len , times );
22182222 return repeated ;
22192223 } catch (OutOfMemoryError | ArithmeticException e ) {
22202224 outOfMemProfile .enter ();
0 commit comments