@@ -2156,7 +2156,6 @@ public static ExtendNode create(Supplier<GeneralizationNode> genNodeProvider) {
2156
2156
public abstract static class RepeatNode extends SequenceStorageBaseNode {
2157
2157
private static final String ERROR_MSG = "can't multiply sequence by non-int of type '%p'" ;
2158
2158
2159
- @ Child private SetItemScalarNode setItemNode ;
2160
2159
@ Child private GetItemScalarNode getItemNode ;
2161
2160
@ Child private GetItemScalarNode getRightItemNode ;
2162
2161
@ Child private IsIndexNode isIndexNode ;
@@ -2174,8 +2173,8 @@ SequenceStorage doEmpty(EmptySequenceStorage s, @SuppressWarnings("unused") int
2174
2173
2175
2174
@ Specialization (guards = "times <= 0" )
2176
2175
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 );
2179
2178
}
2180
2179
2181
2180
@ Specialization (limit = "MAX_ARRAY_STORAGES" , guards = {"times > 0" , "!isNative(s)" , "s.getClass() == cachedClass" })
@@ -2200,21 +2199,26 @@ SequenceStorage doManaged(BasicSequenceStorage s, int times,
2200
2199
2201
2200
@ Specialization (replaces = "doManaged" , guards = "times > 0" )
2202
2201
SequenceStorage doGeneric (SequenceStorage s , int times ,
2202
+ @ Cached ("create()" ) CreateEmptyNode createEmptyNode ,
2203
2203
@ Cached ("create()" ) BranchProfile outOfMemProfile ,
2204
+ @ Cached ("create()" ) SetItemScalarNode setItemNode ,
2205
+ @ Cached ("create()" ) GetItemScalarNode getDestItemNode ,
2204
2206
@ Cached ("create()" ) LenNode lenNode ) {
2205
2207
try {
2206
2208
int len = lenNode .execute (s );
2209
+ SequenceStorage repeated = createEmptyNode .execute (s , Math .multiplyExact (len , times ));
2207
2210
2208
- ObjectSequenceStorage repeated = new ObjectSequenceStorage (Math .multiplyExact (len , times ));
2209
-
2210
- // TODO avoid temporary array
2211
- Object [] values = new Object [len ];
2212
2211
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
+ }
2214
2220
}
2215
2221
2216
- Object destArr = repeated .getInternalArrayObject ();
2217
- repeat (destArr , values , len , times );
2218
2222
return repeated ;
2219
2223
} catch (OutOfMemoryError | ArithmeticException e ) {
2220
2224
outOfMemProfile .enter ();
0 commit comments