Skip to content

Commit 1b5226e

Browse files
committed
[GR-30482] Move length message into a node
PullRequest: graalpython/1813
2 parents 8de4d62 + 8f33e91 commit 1b5226e

39 files changed

+430
-480
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@
196196
import com.oracle.graal.python.lib.PyNumberFloatNode;
197197
import com.oracle.graal.python.lib.PyNumberIndexNode;
198198
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
199+
import com.oracle.graal.python.lib.PyObjectSizeNode;
199200
import com.oracle.graal.python.nodes.BuiltinNames;
200201
import com.oracle.graal.python.nodes.ErrorMessages;
201202
import com.oracle.graal.python.nodes.PGuards;
@@ -1547,12 +1548,13 @@ abstract static class ReportAbstractClassNode extends PNodeWithContext {
15471548
@Specialization
15481549
static PException report(VirtualFrame frame, Object type,
15491550
@CachedLibrary(limit = "2") PythonObjectLibrary lib,
1551+
@Cached PyObjectSizeNode sizeNode,
15501552
@Cached ReadAttributeFromObjectNode readAttributeFromObjectNode,
15511553
@Cached CastToJavaStringNode cast,
15521554
@Cached ListNodes.ConstructListNode constructListNode,
15531555
@Cached PRaiseNode raiseNode) {
15541556
PList list = constructListNode.execute(frame, readAttributeFromObjectNode.execute(type, __ABSTRACTMETHODS__));
1555-
int methodCount = lib.lengthWithFrame(list, frame);
1557+
int methodCount = sizeNode.execute(frame, list);
15561558
lib.lookupAndCallRegularMethod(list, frame, "sort");
15571559
String joined = cast.execute(lib.lookupAndCallRegularMethod(", ", frame, "join", list));
15581560
throw raiseNode.raise(TypeError, "Can't instantiate abstract class %N with abstract method%s %s", type, methodCount > 1 ? "s" : "", joined);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
125125
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
126126
import com.oracle.graal.python.lib.PyNumberIndexNode;
127+
import com.oracle.graal.python.lib.PyObjectSizeNode;
127128
import com.oracle.graal.python.nodes.BuiltinNames;
128129
import com.oracle.graal.python.nodes.ErrorMessages;
129130
import com.oracle.graal.python.nodes.GraalPythonTranslationErrorNode;
@@ -1245,12 +1246,11 @@ Object iterNotCallable(Object callable, Object sentinel,
12451246
// len(s)
12461247
@Builtin(name = LEN, minNumOfPositionalArgs = 1)
12471248
@GenerateNodeFactory
1248-
@ReportPolymorphism
12491249
public abstract static class LenNode extends PythonUnaryBuiltinNode {
1250-
@Specialization(limit = "6")
1250+
@Specialization
12511251
public int len(VirtualFrame frame, Object obj,
1252-
@CachedLibrary("obj") PythonObjectLibrary lib) {
1253-
return lib.lengthWithFrame(obj, frame);
1252+
@Cached PyObjectSizeNode sizeNode) {
1253+
return sizeNode.execute(frame, obj);
12541254
}
12551255
}
12561256

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode;
7979
import com.oracle.graal.python.lib.PyLongAsLongNode;
8080
import com.oracle.graal.python.lib.PyNumberIndexNode;
81+
import com.oracle.graal.python.lib.PyObjectSizeNode;
8182
import com.oracle.graal.python.nodes.ErrorMessages;
8283
import com.oracle.graal.python.nodes.PGuards;
8384
import com.oracle.graal.python.nodes.PNodeWithRaise;
@@ -2199,13 +2200,13 @@ Object noCheck(VirtualFrame frame, Object obj, @SuppressWarnings("unused") boole
21992200
return stringOrBytesToOpaquePathNode.execute(fspathNode.call(frame, obj));
22002201
}
22012202

2202-
@Specialization(guards = "checkEmpty", limit = "2")
2203+
@Specialization(guards = "checkEmpty")
22032204
Object withCheck(VirtualFrame frame, Object obj, @SuppressWarnings("unused") boolean checkEmpty,
22042205
@Cached FspathNode fspathNode,
2205-
@CachedLibrary("obj") PythonObjectLibrary lib,
2206+
@Cached PyObjectSizeNode sizeNode,
22062207
@Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode) {
22072208
Object stringOrBytes = fspathNode.call(frame, obj);
2208-
if (lib.lengthWithFrame(obj, frame) == 0) {
2209+
if (sizeNode.execute(frame, obj) == 0) {
22092210
throw raise(ValueError, ErrorMessages.EXECV_ARG2_FIRST_ELEMENT_CANNOT_BE_EMPTY);
22102211
}
22112212
return stringOrBytesToOpaquePathNode.execute(stringOrBytes);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
6868
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
6969
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
70+
import com.oracle.graal.python.lib.PyObjectSizeNode;
7071
import com.oracle.graal.python.nodes.ErrorMessages;
7172
import com.oracle.graal.python.nodes.PGuards;
7273
import com.oracle.graal.python.nodes.builtins.ListNodes.FastConstructListNode;
@@ -77,11 +78,11 @@
7778
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
7879
import com.oracle.graal.python.nodes.util.CannotCastException;
7980
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
81+
import com.oracle.graal.python.runtime.GilNode;
8082
import com.oracle.graal.python.runtime.PosixSupportLibrary;
8183
import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
8284
import com.oracle.graal.python.runtime.PythonContext;
8385
import com.oracle.graal.python.runtime.PythonOptions;
84-
import com.oracle.graal.python.runtime.GilNode;
8586
import com.oracle.graal.python.runtime.exception.PException;
8687
import com.oracle.graal.python.runtime.sequence.PSequence;
8788
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
@@ -159,12 +160,13 @@ static Object doNone(@SuppressWarnings("unused") PNone env) {
159160

160161
@Specialization(limit = "1")
161162
Object doSequence(VirtualFrame frame, Object env,
163+
@Cached PyObjectSizeNode sizeNode,
162164
@CachedLibrary("env") PythonObjectLibrary lib,
163165
@Cached ToBytesNode toBytesNode,
164166
@CachedContext(PythonLanguage.class) PythonContext context,
165167
@CachedLibrary("context.getPosixSupport()") PosixSupportLibrary posixLib) {
166168
// TODO unlike CPython, this accepts a dict (if the keys are integers (0, 1, ..., len-1)
167-
int length = lib.lengthWithFrame(env, frame);
169+
int length = sizeNode.execute(frame, env);
168170
Object[] result = new Object[length];
169171
for (int i = 0; i < length; ++i) {
170172
Object o = lib.lookupAndCallSpecialMethod(env, frame, __GETITEM__, i);
@@ -238,6 +240,7 @@ int forkExec(VirtualFrame frame, Object[] args, Object executableList, boolean c
238240
@Cached("createNotNormalized()") GetItemNode getItemNode,
239241
@Cached CastToJavaIntExactNode castToIntNode,
240242
@Cached ObjectToOpaquePathNode objectToOpaquePathNode,
243+
@Cached PyObjectSizeNode sizeNode,
241244
@CachedLibrary("executableList") PythonObjectLibrary lib,
242245
@Cached GilNode gil,
243246
@Cached ToBytesNode toBytesNode) {
@@ -248,7 +251,7 @@ int forkExec(VirtualFrame frame, Object[] args, Object executableList, boolean c
248251

249252
byte[] sysExecutable = fsEncode(getContext().getOption(PythonOptions.Executable));
250253
// TODO unlike CPython, this accepts a dict (if the keys are integers (0, 1, ..., len-1)
251-
int length = lib.lengthWithFrame(executableList, frame);
254+
int length = sizeNode.execute(frame, executableList);
252255
Object[] executables = new Object[length];
253256
for (int i = 0; i < length; ++i) {
254257
byte[] bytes = toBytesNode.execute(lib.lookupAndCallSpecialMethod(executableList, frame, __GETITEM__, i));

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SelectModuleBuiltins.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
5858
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
5959
import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode;
60+
import com.oracle.graal.python.lib.PyObjectSizeNode;
6061
import com.oracle.graal.python.nodes.ErrorMessages;
6162
import com.oracle.graal.python.nodes.PGuards;
6263
import com.oracle.graal.python.nodes.PNodeWithRaise;
@@ -109,38 +110,34 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
109110
@GenerateNodeFactory
110111
abstract static class SelectNode extends PythonBuiltinNode {
111112

112-
@Specialization(limit = "3")
113+
@Specialization
113114
PTuple doWithoutTimeout(VirtualFrame frame, Object rlist, Object wlist, Object xlist, @SuppressWarnings("unused") PNone timeout,
114115
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
115-
@CachedLibrary("rlist") PythonObjectLibrary rlistLibrary,
116-
@CachedLibrary("wlist") PythonObjectLibrary wlistLibrary,
117-
@CachedLibrary("xlist") PythonObjectLibrary xlistLibrary,
116+
@Cached PyObjectSizeNode sizeNode,
118117
@Cached("createGetItem()") LookupAndCallBinaryNode callGetItemNode,
119118
@Cached FastConstructListNode constructListNode,
120119
@Cached PyTimeFromObjectNode pyTimeFromObjectNode,
121120
@CachedLibrary(limit = "3") PythonObjectLibrary itemLib,
122121
@Cached BranchProfile notSelectableBranch,
123122
@Cached GilNode gil) {
124-
return doGeneric(frame, rlist, wlist, xlist, PNone.NONE, posixLib, rlistLibrary, wlistLibrary, xlistLibrary,
123+
return doGeneric(frame, rlist, wlist, xlist, PNone.NONE, posixLib, sizeNode,
125124
callGetItemNode, constructListNode, pyTimeFromObjectNode, itemLib, notSelectableBranch, gil);
126125
}
127126

128-
@Specialization(replaces = "doWithoutTimeout", limit = "3")
127+
@Specialization(replaces = "doWithoutTimeout")
129128
PTuple doGeneric(VirtualFrame frame, Object rlist, Object wlist, Object xlist, Object timeout,
130129
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
131-
@CachedLibrary("rlist") PythonObjectLibrary rlistLibrary,
132-
@CachedLibrary("wlist") PythonObjectLibrary wlistLibrary,
133-
@CachedLibrary("xlist") PythonObjectLibrary xlistLibrary,
130+
@Cached PyObjectSizeNode sizeNode,
134131
@Cached("createGetItem()") LookupAndCallBinaryNode callGetItemNode,
135132
@Cached FastConstructListNode constructListNode,
136133
@Cached PyTimeFromObjectNode pyTimeFromObjectNode,
137134
@CachedLibrary(limit = "3") PythonObjectLibrary itemLib,
138135
@Cached BranchProfile notSelectableBranch,
139136
@Cached GilNode gil) {
140137
EmulatedPosixSupport emulatedPosixSupport = getContext().getResources();
141-
ObjAndFDList readFDs = seq2set(frame, rlist, rlistLibrary, itemLib, callGetItemNode, constructListNode, emulatedPosixSupport);
142-
ObjAndFDList writeFDs = seq2set(frame, wlist, wlistLibrary, itemLib, callGetItemNode, constructListNode, emulatedPosixSupport);
143-
ObjAndFDList xFDs = seq2set(frame, xlist, xlistLibrary, itemLib, callGetItemNode, constructListNode, emulatedPosixSupport);
138+
ObjAndFDList readFDs = seq2set(frame, rlist, sizeNode, itemLib, callGetItemNode, constructListNode, emulatedPosixSupport);
139+
ObjAndFDList writeFDs = seq2set(frame, wlist, sizeNode, itemLib, callGetItemNode, constructListNode, emulatedPosixSupport);
140+
ObjAndFDList xFDs = seq2set(frame, xlist, sizeNode, itemLib, callGetItemNode, constructListNode, emulatedPosixSupport);
144141

145142
Timeval timeoutval = null;
146143
if (!PGuards.isPNone(timeout)) {
@@ -191,17 +188,17 @@ private PList toList(boolean[] result, ObjAndFDList fds) {
191188
return factory().createList(PythonUtils.arrayCopyOf(resultObjs, resultObjsIdx));
192189
}
193190

194-
private ObjAndFDList seq2set(VirtualFrame frame, Object sequence, PythonObjectLibrary sequenceLib, PythonObjectLibrary itemLib, LookupAndCallBinaryNode callGetItemNode,
191+
private ObjAndFDList seq2set(VirtualFrame frame, Object sequence, PyObjectSizeNode sizeNode, PythonObjectLibrary itemLib, LookupAndCallBinaryNode callGetItemNode,
195192
FastConstructListNode constructListNode, PosixResources resources) {
196193
PArguments.ThreadState threadState = PArguments.getThreadState(frame);
197194
// We cannot assume any size of those two arrays, because the sequence may change as a
198-
// side effect of the invocation of fileno. We also need to call lengthWithState
195+
// side effect of the invocation of fileno. We also need to call PyObjectSizeNode
199196
// repeatedly in the loop condition
200197
ArrayBuilder<Object> objects = new ArrayBuilder<>();
201198
IntArrayBuilder fds = new IntArrayBuilder();
202199
PSequence pSequence = constructListNode.execute(frame, sequence);
203200
boolean containsSocket = false;
204-
for (int i = 0; i < sequenceLib.lengthWithState(sequence, threadState); i++) {
201+
for (int i = 0; i < sizeNode.execute(frame, sequence); i++) {
205202
Object pythonObject = callGetItemNode.executeObject(frame, pSequence, i);
206203
objects.add(pythonObject);
207204
int fd = itemLib.asFileDescriptorWithState(pythonObject, threadState);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
6464
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
6565
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
66+
import com.oracle.graal.python.lib.PyObjectSizeNode;
6667
import com.oracle.graal.python.nodes.ErrorMessages;
6768
import com.oracle.graal.python.nodes.IndirectCallNode;
6869
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -166,6 +167,7 @@ static final class WarningsModuleNode extends Node implements IndirectCallNode {
166167
@Child CastToJavaStringNode castStr;
167168
@Child PRaiseNode raiseNode;
168169
@Child PythonObjectLibrary pylib;
170+
@Child PyObjectSizeNode sizeNode;
169171
@Child GetClassNode getClassNode;
170172
@Child PyNumberAsSizeNode asSizeNode;
171173
@Child PyObjectIsTrueNode isTrueNode;
@@ -220,6 +222,14 @@ private PythonObjectLibrary getPyLib() {
220222
return pylib;
221223
}
222224

225+
private PyObjectSizeNode getSizeNode() {
226+
if (sizeNode == null) {
227+
CompilerDirectives.transferToInterpreterAndInvalidate();
228+
sizeNode = insert(PyObjectSizeNode.create());
229+
}
230+
return sizeNode;
231+
}
232+
223233
private Object getPythonClass(Object object) {
224234
if (getClassNode == null) {
225235
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -454,9 +464,9 @@ private String getFilter(VirtualFrame frame, PythonModule _warnings, Object cate
454464
if (filters == null || !(filters instanceof PList)) {
455465
throw getRaise().raise(PythonBuiltinClassType.ValueError, "warnings.filters must be a list");
456466
}
457-
for (int i = 0; i < getPyLib().length(filters); i++) {
467+
for (int i = 0; i < getSizeNode().execute(frame, filters); i++) {
458468
Object tmpItem = getPyLib().lookupAndCallSpecialMethod(filters, frame, SpecialMethodNames.__GETITEM__, i);
459-
if (!(tmpItem instanceof PTuple) || getPyLib().length(tmpItem) != 5) {
469+
if (!(tmpItem instanceof PTuple) || getSizeNode().execute(frame, tmpItem) != 5) {
460470
throw getRaise().raise(PythonBuiltinClassType.ValueError, "warnings.filters item %d isn't a 5-tuple", i);
461471
}
462472

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
import com.oracle.truffle.api.dsl.Specialization;
126126
import com.oracle.truffle.api.dsl.TypeSystemReference;
127127
import com.oracle.truffle.api.frame.VirtualFrame;
128+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
128129
import com.oracle.truffle.api.library.CachedLibrary;
129130
import com.oracle.truffle.api.profiles.ConditionProfile;
130131

@@ -360,7 +361,12 @@ Object readinto(VirtualFrame frame, PBytesIO self, Object buffer,
360361
return error(self, buffer);
361362
}
362363
/* adjust invalid sizes */
363-
int len = lib.length(buffer);
364+
int len;
365+
try {
366+
len = lib.getBufferLength(buffer);
367+
} catch (UnsupportedMessageException e) {
368+
throw CompilerDirectives.shouldNotReachHere();
369+
}
364370
int n = self.getStringSize() - self.getPos();
365371
if (len > n) {
366372
len = n;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/IOBaseBuiltins.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@
8686
import com.oracle.graal.python.builtins.objects.PNone;
8787
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
8888
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
89-
import com.oracle.graal.python.builtins.objects.function.PArguments;
9089
import com.oracle.graal.python.builtins.objects.object.PythonObject;
9190
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
9291
import com.oracle.graal.python.lib.PyObjectIsTrueNode;
92+
import com.oracle.graal.python.lib.PyObjectSizeNode;
9393
import com.oracle.graal.python.nodes.ErrorMessages;
9494
import com.oracle.graal.python.nodes.PGuards;
9595
import com.oracle.graal.python.nodes.PRaiseNode;
@@ -355,9 +355,9 @@ abstract static class NextNode extends PythonUnaryBuiltinNode {
355355
@Specialization(limit = "3")
356356
Object next(VirtualFrame frame, PythonObject self,
357357
@CachedLibrary("self") PythonObjectLibrary selfLib,
358-
@CachedLibrary(limit = "1") PythonObjectLibrary lineLib) {
358+
@Cached PyObjectSizeNode sizeNode) {
359359
Object line = selfLib.lookupAndCallRegularMethod(self, frame, READLINE);
360-
if (lineLib.lengthWithState(line, PArguments.getThreadState(frame)) <= 0) {
360+
if (sizeNode.execute(frame, line) <= 0) {
361361
throw raise(StopIteration);
362362
}
363363
return line;
@@ -466,24 +466,24 @@ Object doall(VirtualFrame frame, Object self, @SuppressWarnings("unused") int hi
466466
@Cached GetNextNode next,
467467
@Cached IsBuiltinClassProfile errorProfile,
468468
@CachedLibrary("self") PythonObjectLibrary libSelf,
469-
@CachedLibrary(limit = "1") PythonObjectLibrary libLen) {
470-
return withHint(frame, self, Integer.MAX_VALUE, next, errorProfile, libSelf, libLen);
469+
@Cached PyObjectSizeNode sizeNode) {
470+
return withHint(frame, self, Integer.MAX_VALUE, next, errorProfile, libSelf, sizeNode);
471471
}
472472

473473
@Specialization(guards = "hint > 0", limit = "1")
474474
Object withHint(VirtualFrame frame, Object self, int hint,
475475
@Cached GetNextNode next,
476476
@Cached IsBuiltinClassProfile errorProfile,
477477
@CachedLibrary("self") PythonObjectLibrary libSelf,
478-
@CachedLibrary(limit = "1") PythonObjectLibrary libLen) {
478+
@Cached PyObjectSizeNode sizeNode) {
479479
int length = 0;
480480
Object iterator = libSelf.getIteratorWithFrame(self, frame);
481481
ArrayBuilder<Object> list = new ArrayBuilder<>();
482482
while (true) {
483483
try {
484484
Object line = next.execute(frame, iterator);
485485
list.add(line);
486-
int lineLength = libLen.length(line);
486+
int lineLength = sizeNode.execute(frame, line);
487487
if (lineLength > hint - length) {
488488
break;
489489
}

0 commit comments

Comments
 (0)