Skip to content

Commit f909a7c

Browse files
committed
[GR-26040] Fix performance regressions due to POL.getIterator
PullRequest: graalpython/1264
2 parents ba7824e + f31b372 commit f909a7c

File tree

4 files changed

+54
-4
lines changed

4 files changed

+54
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,7 @@ private Object[] getArray(PTuple tuple) {
12911291
// iter(object[, sentinel])
12921292
@Builtin(name = ITER, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2)
12931293
@GenerateNodeFactory
1294+
@ReportPolymorphism
12941295
public abstract static class IterNode extends PythonBinaryBuiltinNode {
12951296
@Specialization(guards = "isNoValue(sentinel)", limit = "getCallSiteInlineCacheMaxDepth()")
12961297
static Object iter(VirtualFrame frame, Object object, @SuppressWarnings("unused") PNone sentinel,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObjectLibrary.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ public Object asIndex(Object receiver) {
526526
/**
527527
* @see #asIndexWithState
528528
*/
529-
public Object asIndexWithFrame(Object receiver, VirtualFrame frame) {
529+
public final Object asIndexWithFrame(Object receiver, VirtualFrame frame) {
530530
if (profileHasFrame(frame)) {
531531
return asIndexWithState(receiver, PArguments.getThreadState(frame));
532532
} else {
@@ -1017,7 +1017,7 @@ public int length(Object receiver) {
10171017
/**
10181018
* @see #asIndexWithState
10191019
*/
1020-
public int lengthWithFrame(Object receiver, VirtualFrame frame) {
1020+
public final int lengthWithFrame(Object receiver, VirtualFrame frame) {
10211021
if (profileHasFrame(frame)) {
10221022
return lengthWithState(receiver, PArguments.getThreadState(frame));
10231023
} else {
@@ -1152,7 +1152,7 @@ public Object getIterator(Object receiver) {
11521152
/**
11531153
* @see #getIteratorWithState
11541154
*/
1155-
public Object getIteratorWithFrame(Object receiver, VirtualFrame frame) {
1155+
public final Object getIteratorWithFrame(Object receiver, VirtualFrame frame) {
11561156
if (profileHasFrame(frame)) {
11571157
return getIteratorWithState(receiver, PArguments.getThreadState(frame));
11581158
} else {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallSpecialMethodNode.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,23 @@ protected static boolean takesSelfArg(Object func) {
180180
return true;
181181
}
182182

183+
/**
184+
* Determines the minimum number of positional arguments accepted by the given built-in function
185+
* or method.
186+
*/
187+
protected static int getMinArgs(Object func) {
188+
CompilerAsserts.neverPartOfCompilation();
189+
if (func instanceof PBuiltinFunction) {
190+
RootNode functionRootNode = ((PBuiltinFunction) func).getFunctionRootNode();
191+
if (functionRootNode instanceof BuiltinFunctionRootNode) {
192+
return ((BuiltinFunctionRootNode) functionRootNode).getBuiltin().minNumOfPositionalArgs();
193+
}
194+
} else if (func instanceof PBuiltinMethod) {
195+
return getMinArgs(((PBuiltinMethod) func).getFunction());
196+
}
197+
return 0;
198+
}
199+
183200
protected static RootCallTarget getCallTarget(PMethod meth) {
184201
return getCallTargetOfFunction(meth.getFunction());
185202
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallUnaryMethodNode.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.nodes.call.special;
4242

43+
import com.oracle.graal.python.builtins.objects.PNone;
4344
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
4445
import com.oracle.graal.python.builtins.objects.function.PKeyword;
4546
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
@@ -220,8 +221,39 @@ Object callSelfMethod(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMe
220221
return builtinNode.call(frame, func.getSelf(), arg);
221222
}
222223

224+
@Specialization(guards = { //
225+
"func == cachedFunc", //
226+
"builtinNode != null", //
227+
"!takesSelfArg", //
228+
"minArgs == 1", //
229+
"frame != null || unusedFrame"}, //
230+
limit = "getCallSiteInlineCacheMaxDepth()", //
231+
assumptions = "singleContextAssumption()")
232+
static Object callBinaryMethodSingleContext(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object receiver,
233+
@SuppressWarnings("unused") @Cached("func") PBuiltinMethod cachedFunc,
234+
@SuppressWarnings("unused") @Cached("takesSelfArg(func)") boolean takesSelfArg,
235+
@SuppressWarnings("unused") @Cached("getMinArgs(func)") int minArgs,
236+
@Cached("getBinary(frame, func.getFunction())") PythonBinaryBuiltinNode builtinNode,
237+
@SuppressWarnings("unused") @Cached("frameIsUnused(builtinNode)") boolean unusedFrame) {
238+
return builtinNode.call(frame, receiver, PNone.NO_VALUE);
239+
}
240+
241+
/**
242+
* In case the function takes at least 1 argument (so is <it>at least</it> unary) we also try
243+
* higher orders.
244+
*/
245+
@Specialization(guards = {"builtinNode != null", "minArgs == 1", "getCallTarget(func) == ct", "!takesSelfArg", "frame != null || unusedFrame"}, limit = "getCallSiteInlineCacheMaxDepth()")
246+
static Object callBinaryMethod(VirtualFrame frame, @SuppressWarnings("unused") PBuiltinMethod func, Object arg,
247+
@SuppressWarnings("unused") @Cached("getCallTarget(func)") RootCallTarget ct,
248+
@SuppressWarnings("unused") @Cached("takesSelfArg(func)") boolean takesSelfArg,
249+
@SuppressWarnings("unused") @Cached("getMinArgs(func)") int minArgs,
250+
@Cached("getBinary(frame, func.getFunction())") PythonBinaryBuiltinNode builtinNode,
251+
@SuppressWarnings("unused") @Cached("frameIsUnused(builtinNode)") boolean unusedFrame) {
252+
return builtinNode.call(frame, arg, PNone.NO_VALUE);
253+
}
254+
223255
@Specialization(replaces = {"callIntSingle", "callInt", "callLongSingle", "callLong", "callDoubleSingle", "callDouble", "callBoolSingle", "callBool", "callObjectSingleContext",
224-
"callMethodSingleContext", "callSelfMethodSingleContext", "callMethod", "callSelfMethod"})
256+
"callMethodSingleContext", "callSelfMethodSingleContext", "callMethod", "callSelfMethod", "callBinaryMethodSingleContext", "callBinaryMethod"})
225257
static Object call(VirtualFrame frame, Object func, Object receiver,
226258
@Cached("create()") CallNode callNode,
227259
@Cached ConditionProfile isBoundProfile) {

0 commit comments

Comments
 (0)