Skip to content

Commit 84a0247

Browse files
committed
optimize the fast path in calling __new__ when the method is already a function
1 parent cb53b55 commit 84a0247

File tree

1 file changed

+18
-2
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type

1 file changed

+18
-2
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@
7171
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
7272
import com.oracle.graal.python.builtins.objects.common.PHashingCollection;
7373
import com.oracle.graal.python.builtins.objects.dict.PDict;
74+
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
75+
import com.oracle.graal.python.builtins.objects.function.PFunction;
7476
import com.oracle.graal.python.builtins.objects.function.PKeyword;
7577
import com.oracle.graal.python.builtins.objects.list.PList;
7678
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
@@ -108,12 +110,14 @@
108110
import com.oracle.graal.python.runtime.exception.PythonErrorType;
109111
import com.oracle.truffle.api.CompilerAsserts;
110112
import com.oracle.truffle.api.CompilerDirectives;
113+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
111114
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
112115
import com.oracle.truffle.api.dsl.Cached;
113116
import com.oracle.truffle.api.dsl.Fallback;
114117
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
115118
import com.oracle.truffle.api.dsl.ImportStatic;
116119
import com.oracle.truffle.api.dsl.NodeFactory;
120+
import com.oracle.truffle.api.dsl.ReportPolymorphism;
117121
import com.oracle.truffle.api.dsl.Specialization;
118122
import com.oracle.truffle.api.dsl.TypeSystemReference;
119123
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -191,6 +195,7 @@ Object doit(Object object,
191195

192196
@Builtin(name = __CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
193197
@GenerateNodeFactory
198+
@ReportPolymorphism
194199
public abstract static class CallNode extends PythonVarargsBuiltinNode {
195200
@Child private CallVarargsMethodNode dispatchNew = CallVarargsMethodNode.create();
196201
@Child private LookupAndCallTernaryNode callNewGet = LookupAndCallTernaryNode.create(__GET__);
@@ -199,9 +204,10 @@ public abstract static class CallNode extends PythonVarargsBuiltinNode {
199204
@Child private LookupAttributeInMRONode lookupInit = LookupAttributeInMRONode.create(__INIT__);
200205
@Child private TypeNodes.IsSameTypeNode isSameTypeNode;
201206
@Child private TypeNodes.GetNameNode getNameNode;
202-
203207
@Child private IsBuiltinClassProfile isClassClassProfile = IsBuiltinClassProfile.create();
204208

209+
@CompilationFinal private boolean newWasDescriptor = false;
210+
205211
public static CallNode create() {
206212
return CallNodeFactory.create();
207213
}
@@ -332,7 +338,17 @@ private Object op(VirtualFrame frame, Object self, Object[] arguments, PKeyword[
332338
if (newMethod != PNone.NO_VALUE) {
333339
CompilerAsserts.partialEvaluationConstant(doCreateArgs);
334340
Object[] newArgs = doCreateArgs ? PositionalArgumentsNode.prependArgument(self, arguments) : arguments;
335-
Object newInstance = dispatchNew.execute(frame, callNewGet.execute(frame, newMethod, PNone.NONE, self), newArgs, keywords);
341+
Object newInstance;
342+
if (!newWasDescriptor && (newMethod instanceof PFunction || newMethod instanceof PBuiltinFunction)) {
343+
newInstance = dispatchNew.execute(frame, newMethod, newArgs, keywords);
344+
} else {
345+
if (!newWasDescriptor) {
346+
CompilerDirectives.transferToInterpreterAndInvalidate();
347+
reportPolymorphicSpecialize();
348+
newWasDescriptor = true;
349+
}
350+
newInstance = dispatchNew.execute(frame, callNewGet.execute(frame, newMethod, PNone.NONE, self), newArgs, keywords);
351+
}
336352
Object newInstanceKlass = lib.getLazyPythonClass(newInstance);
337353
if (isSameType(newInstanceKlass, self)) {
338354
if (arguments.length == 2 && isClassClassProfile.profileClass(self, PythonBuiltinClassType.PythonClass)) {

0 commit comments

Comments
 (0)