Skip to content

Commit da10316

Browse files
committed
Fix: Sequence repeat must not generalize.
1 parent f39f227 commit da10316

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ public abstract static class MulNode extends PythonBinaryBuiltinNode {
291291
@Specialization
292292
public Object mul(PBytes self, int times,
293293
@Cached("create()") SequenceStorageNodes.RepeatNode repeatNode) {
294-
ByteSequenceStorage res = (ByteSequenceStorage) repeatNode.execute(self.getSequenceStorage(), times);
294+
SequenceStorage res = repeatNode.execute(self.getSequenceStorage(), times);
295295
return factory().createBytes(res);
296296
}
297297

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,11 @@ public PBytes createBytes(LazyPythonClass cls, byte[] array) {
280280
return trace(new PBytes(cls, array));
281281
}
282282

283-
public PBytes createBytes(ByteSequenceStorage storage) {
283+
public PBytes createBytes(SequenceStorage storage) {
284284
return trace(new PBytes(PythonBuiltinClassType.PBytes, storage));
285285
}
286286

287-
public PBytes createBytes(LazyPythonClass cls, ByteSequenceStorage storage) {
287+
public PBytes createBytes(LazyPythonClass cls, SequenceStorage storage) {
288288
return trace(new PBytes(cls, storage));
289289
}
290290

0 commit comments

Comments
 (0)