Skip to content

Commit a038424

Browse files
committed
added storage strategy when creating list or tuple from bytecode stack
1 parent b9ee4ae commit a038424

File tree

6 files changed

+359
-47
lines changed

6 files changed

+359
-47
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/PList.java

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -30,10 +30,10 @@
3030
import com.oracle.graal.python.builtins.objects.ints.PInt;
3131
import com.oracle.graal.python.nodes.ErrorMessages;
3232
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
33-
import com.oracle.graal.python.nodes.literal.ListLiteralNode;
3433
import com.oracle.graal.python.runtime.GilNode;
3534
import com.oracle.graal.python.runtime.exception.PException;
3635
import com.oracle.graal.python.runtime.sequence.PSequence;
36+
import com.oracle.graal.python.runtime.sequence.storage.BasicSequenceStorage;
3737
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
3838
import com.oracle.graal.python.util.OverflowException;
3939
import com.oracle.truffle.api.CompilerAsserts;
@@ -51,7 +51,7 @@
5151

5252
@ExportLibrary(InteropLibrary.class)
5353
public final class PList extends PSequence {
54-
private final ListLiteralNode origin;
54+
private final ListOrigin origin;
5555
private SequenceStorage store;
5656

5757
public PList(Object cls, Shape instanceShape, SequenceStorage store) {
@@ -60,7 +60,7 @@ public PList(Object cls, Shape instanceShape, SequenceStorage store) {
6060
this.store = store;
6161
}
6262

63-
public PList(Object cls, Shape instanceShape, SequenceStorage store, ListLiteralNode origin) {
63+
public PList(Object cls, Shape instanceShape, SequenceStorage store, ListOrigin origin) {
6464
super(cls, instanceShape);
6565
this.origin = origin;
6666
this.store = store;
@@ -117,15 +117,15 @@ public final int hashCode() {
117117
return super.hashCode();
118118
}
119119

120-
public ListLiteralNode getOrigin() {
120+
public ListOrigin getOrigin() {
121121
return origin;
122122
}
123123

124124
@ExportMessage
125125
public SourceSection getSourceLocation(@Exclusive @Cached GilNode gil) throws UnsupportedMessageException {
126126
boolean mustRelease = gil.acquire();
127127
try {
128-
ListLiteralNode node = getOrigin();
128+
ListOrigin node = getOrigin();
129129
SourceSection result = null;
130130
if (node != null) {
131131
result = node.getSourceSection();
@@ -229,4 +229,38 @@ public void removeArrayElement(long index,
229229
gil.release(mustRelease);
230230
}
231231
}
232+
233+
public interface ListOrigin {
234+
235+
/**
236+
* This class serves the purpose of updating the size estimate for the lists constructed
237+
* here over time. The estimate is updated slowly, it takes {@link #NUM_DIGITS_POW2} lists
238+
* to reach a size one larger than the current estimate to increase the estimate for new
239+
* lists.
240+
*/
241+
@CompilerDirectives.ValueType
242+
public static final class SizeEstimate {
243+
private static final int NUM_DIGITS = 3;
244+
private static final int NUM_DIGITS_POW2 = 1 << NUM_DIGITS;
245+
246+
@CompilerDirectives.CompilationFinal private int shiftedStorageSizeEstimate;
247+
248+
public SizeEstimate(int storageSizeEstimate) {
249+
shiftedStorageSizeEstimate = storageSizeEstimate * NUM_DIGITS_POW2;
250+
}
251+
252+
public int estimate() {
253+
return shiftedStorageSizeEstimate >> NUM_DIGITS;
254+
}
255+
256+
public int updateFrom(int newSizeEstimate) {
257+
shiftedStorageSizeEstimate = shiftedStorageSizeEstimate + newSizeEstimate - estimate();
258+
return shiftedStorageSizeEstimate;
259+
}
260+
}
261+
262+
void reportUpdatedCapacity(BasicSequenceStorage newStore);
263+
264+
SourceSection getSourceSection();
265+
}
232266
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/ListNodes.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@
4040
*/
4141
package com.oracle.graal.python.nodes.builtins;
4242

43-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
43+
import static com.oracle.graal.python.builtins.objects.str.StringUtils.cat;
4444
import static com.oracle.graal.python.nodes.BuiltinNames.T_LIST;
4545
import static com.oracle.graal.python.nodes.StringLiterals.T_SPACE;
46-
import static com.oracle.graal.python.builtins.objects.str.StringUtils.cat;
46+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
4747

4848
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4949
import com.oracle.graal.python.builtins.modules.MathGuards;
@@ -67,7 +67,6 @@
6767
import com.oracle.graal.python.nodes.builtins.ListNodesFactory.FastConstructListNodeGen;
6868
import com.oracle.graal.python.nodes.builtins.ListNodesFactory.IndexNodeGen;
6969
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
70-
import com.oracle.graal.python.nodes.literal.ListLiteralNode;
7170
import com.oracle.graal.python.nodes.object.GetClassNode;
7271
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
7372
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
@@ -289,7 +288,7 @@ Object doGeneric(VirtualFrame frame, Object object) {
289288
* interpreter, it will use a different {@link AppendNode} than in the compiled code, so the
290289
* specializations for the compiler are different. This is useful, because in the interpreter we
291290
* will report back type and size changes to the origin of the list via {@link PList#getOrigin}
292-
* and {@link ListLiteralNode#reportUpdatedCapacity}. Thus, there's a chance that the compiled
291+
* and {@link PList.ListOrigin#reportUpdatedCapacity}. Thus, there's a chance that the compiled
293292
* code will only see lists of the correct size and storage type.
294293
*/
295294
@GenerateUncached

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@
126126
import com.oracle.graal.python.nodes.builtins.ListNodesFactory;
127127
import com.oracle.graal.python.nodes.builtins.TupleNodes;
128128
import com.oracle.graal.python.nodes.builtins.TupleNodesFactory;
129+
import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNode.ListFromStackNode;
130+
import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNode.TupleFromStackNode;
131+
import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNodeFactory.ListFromStackNodeGen;
132+
import com.oracle.graal.python.nodes.bytecode.SequenceFromStackNodeFactory.TupleFromStackNodeGen;
129133
import com.oracle.graal.python.nodes.call.CallNode;
130134
import com.oracle.graal.python.nodes.call.CallNodeGen;
131135
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
@@ -3490,14 +3494,14 @@ private int bytecodeCollectionFromStack(VirtualFrame virtualFrame, int type, int
34903494
Object res = null;
34913495
switch (type) {
34923496
case CollectionBits.KIND_LIST: {
3493-
Object[] store = new Object[count];
3494-
moveFromStack(virtualFrame, stackTop - count + 1, stackTop + 1, store);
3495-
res = factory.createList(store);
3497+
ListFromStackNode storageFromStackNode = insertChildNodeInt(localNodes, nodeIndex, ListFromStackNodeGen.class, (int length) -> ListFromStackNodeGen.create(length), count);
3498+
SequenceStorage store = storageFromStackNode.execute(virtualFrame, stackTop - count + 1, stackTop + 1);
3499+
res = factory.createList(store, storageFromStackNode);
34963500
break;
34973501
}
34983502
case CollectionBits.KIND_TUPLE: {
3499-
Object[] store = new Object[count];
3500-
moveFromStack(virtualFrame, stackTop - count + 1, stackTop + 1, store);
3503+
TupleFromStackNode storageFromStackNode = insertChildNodeInt(localNodes, nodeIndex, TupleFromStackNodeGen.class, (int length) -> TupleFromStackNodeGen.create(length), count);
3504+
SequenceStorage store = storageFromStackNode.execute(virtualFrame, stackTop - count + 1, stackTop + 1);
35013505
res = factory.createTuple(store);
35023506
break;
35033507
}

0 commit comments

Comments
 (0)