Skip to content

Commit c1f00fa

Browse files
committed
CreateStorageFromIteratorNode: improve fast paths for builtin iterators
1 parent ed2e715 commit c1f00fa

File tree

9 files changed

+235
-64
lines changed

9 files changed

+235
-64
lines changed

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

Lines changed: 123 additions & 54 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/iterator/IteratorNodes.java

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,22 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.iterator;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.PIterator;
4344
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4445
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LENGTH_HINT__;
4546
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
4647

48+
import java.util.ArrayList;
49+
import java.util.List;
50+
4751
import com.oracle.graal.python.builtins.objects.PNone;
4852
import com.oracle.graal.python.builtins.objects.PNotImplemented;
4953
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetSequenceStorageNode;
5054
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
55+
import com.oracle.graal.python.builtins.objects.iterator.IteratorNodesFactory.GetInternalIteratorSequenceStorageNodeGen;
56+
import com.oracle.graal.python.builtins.objects.list.PList;
5157
import com.oracle.graal.python.builtins.objects.str.PString;
58+
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
5259
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
5360
import com.oracle.graal.python.lib.PyIndexCheckNode;
5461
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
@@ -74,6 +81,7 @@
7481
import com.oracle.truffle.api.CompilerDirectives;
7582
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
7683
import com.oracle.truffle.api.dsl.Cached;
84+
import com.oracle.truffle.api.dsl.Fallback;
7785
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
7886
import com.oracle.truffle.api.dsl.GenerateUncached;
7987
import com.oracle.truffle.api.dsl.ImportStatic;
@@ -85,8 +93,6 @@
8593
import com.oracle.truffle.api.nodes.Node;
8694
import com.oracle.truffle.api.profiles.ConditionProfile;
8795
import com.oracle.truffle.api.profiles.LoopConditionProfile;
88-
import java.util.ArrayList;
89-
import java.util.List;
9096

9197
public abstract class IteratorNodes {
9298

@@ -181,6 +187,102 @@ int length(VirtualFrame frame, Object iterable,
181187
}
182188
}
183189

190+
@ImportStatic(PGuards.class)
191+
public abstract static class GetInternalIteratorSequenceStorage extends Node {
192+
public static GetInternalIteratorSequenceStorage getUncached() {
193+
return GetInternalIteratorSequenceStorageNodeGen.getUncached();
194+
}
195+
196+
/**
197+
* The argument must be a builtin iterator, which points to the first element of the
198+
* internal sequence storage. Returns {@code null} if the sequence storage is not available
199+
* or if the iterator is not pointing to the first item in the storage.
200+
*/
201+
public final SequenceStorage execute(PBuiltinIterator iterator) {
202+
assert GetClassNode.getUncached().execute(iterator) == PIterator;
203+
assert iterator.index == 0;
204+
return executeInternal(iterator);
205+
}
206+
207+
protected abstract SequenceStorage executeInternal(PBuiltinIterator iterator);
208+
209+
@Specialization(guards = "isList(it.sequence)")
210+
static SequenceStorage doSequenceList(PSequenceIterator it) {
211+
return ((PList) it.sequence).getSequenceStorage();
212+
}
213+
214+
@Specialization
215+
static SequenceStorage doSequenceLong(PLongSequenceIterator it) {
216+
return it.sequence;
217+
}
218+
219+
@Specialization
220+
static SequenceStorage doSequenceDouble(PDoubleSequenceIterator it) {
221+
return it.sequence;
222+
}
223+
224+
@Specialization
225+
static SequenceStorage doSequenceObj(PObjectSequenceIterator it) {
226+
return it.sequence;
227+
}
228+
229+
@Specialization
230+
static SequenceStorage doSequenceIntSeq(PIntegerSequenceIterator it) {
231+
return it.sequence;
232+
}
233+
234+
@Specialization(guards = "isPTuple(it.sequence)")
235+
static SequenceStorage doSequenceTuple(PSequenceIterator it) {
236+
return ((PTuple) it.sequence).getSequenceStorage();
237+
}
238+
239+
@Fallback
240+
static SequenceStorage doOthers(PBuiltinIterator it) {
241+
return null;
242+
}
243+
}
244+
245+
@ImportStatic(PGuards.class)
246+
public abstract static class BuiltinIteratorLengthHint extends Node {
247+
@Child GetInternalIteratorSequenceStorage getSeqStorage = GetInternalIteratorSequenceStorageNodeGen.create();
248+
private final ConditionProfile noStorageProfile = ConditionProfile.createBinaryProfile();
249+
250+
/**
251+
* The argument must be a builtin iterator. Returns {@code -1} if the length hint is not
252+
* available.
253+
*/
254+
public final int execute(PBuiltinIterator iterator) {
255+
assert GetClassNode.getUncached().execute(iterator) == PIterator;
256+
SequenceStorage result = getSeqStorage.execute(iterator);
257+
if (noStorageProfile.profile(result != null)) {
258+
return result.length();
259+
}
260+
return executeInternal(iterator);
261+
}
262+
263+
protected abstract int executeInternal(PBuiltinIterator iterator);
264+
265+
@Specialization
266+
static int doString(PStringIterator it) {
267+
return it.value.length();
268+
}
269+
270+
@Specialization
271+
static int doSequenceArr(PArrayIterator it) {
272+
return it.array.getLength();
273+
}
274+
275+
@Specialization
276+
static int doSequenceIntRange(PIntRangeIterator it) {
277+
return it.getLength();
278+
}
279+
280+
@Fallback
281+
static int doOthers(PBuiltinIterator it) {
282+
return -1;
283+
}
284+
}
285+
184286
@GenerateUncached
185287
public abstract static class IsIteratorObjectNode extends Node {
186288

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/BoolSequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ protected void increaseCapacityExact(int newCapacity) {
6767

6868
@Override
6969
public SequenceStorage copy() {
70-
return new BoolSequenceStorage(Arrays.copyOf(values, length));
70+
return new BoolSequenceStorage(PythonUtils.arrayCopyOf(values, length));
7171
}
7272

7373
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ByteSequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected void increaseCapacityExact(int newCapacity) {
7575

7676
@Override
7777
public SequenceStorage copy() {
78-
return new ByteSequenceStorage(Arrays.copyOf(values, length));
78+
return new ByteSequenceStorage(PythonUtils.arrayCopyOf(values, length));
7979
}
8080

8181
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/DoubleSequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected void increaseCapacityExact(int newCapacity) {
6969

7070
@Override
7171
public SequenceStorage copy() {
72-
return new DoubleSequenceStorage(Arrays.copyOf(values, length));
72+
return new DoubleSequenceStorage(PythonUtils.arrayCopyOf(values, length));
7373
}
7474

7575
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/IntSequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected void increaseCapacityExact(int newCapacity) {
6969

7070
@Override
7171
public SequenceStorage copy() {
72-
return new IntSequenceStorage(Arrays.copyOf(values, length));
72+
return new IntSequenceStorage(PythonUtils.arrayCopyOf(values, length));
7373
}
7474

7575
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/LongSequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ protected void increaseCapacityExact(int newCapacity) {
7171

7272
@Override
7373
public SequenceStorage copy() {
74-
return new LongSequenceStorage(Arrays.copyOf(values, length));
74+
return new LongSequenceStorage(PythonUtils.arrayCopyOf(values, length));
7575
}
7676

7777
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/MroSequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public String getClassName() {
143143

144144
@Override
145145
public SequenceStorage copy() {
146-
return new MroSequenceStorage(getClassName(), Arrays.copyOf(values, length));
146+
return new MroSequenceStorage(getClassName(), PythonUtils.arrayCopyOf(values, length));
147147
}
148148

149149
@Override

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/ObjectSequenceStorage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ public Object[] getInternalArray() {
112112

113113
@Override
114114
public Object[] getCopyOfInternalArray() {
115-
return Arrays.copyOf(values, length);
115+
return PythonUtils.arrayCopyOf(values, length);
116116
}
117117

118118
@Override
119119
public void increaseCapacityExactWithCopy(int newCapacity) {
120-
values = Arrays.copyOf(values, newCapacity);
120+
values = PythonUtils.arrayCopyOf(values, newCapacity);
121121
capacity = values.length;
122122
}
123123

0 commit comments

Comments
 (0)