Skip to content

Commit da03314

Browse files
committed
[GR-76049] Put polymorphic getCallTarget behind boundary
PullRequest: graalpython/4583
2 parents e9c88c7 + 6e4fd2d commit da03314

17 files changed

Lines changed: 151 additions & 210 deletions

File tree

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

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@
113113
import com.oracle.graal.python.builtins.objects.cext.copying.NativeLibraryToolException;
114114
import com.oracle.graal.python.builtins.objects.cext.structs.CFields;
115115
import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
116-
import com.oracle.graal.python.builtins.objects.code.CodeNodes;
117116
import com.oracle.graal.python.builtins.objects.code.PCode;
118117
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
119118
import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
@@ -147,7 +146,6 @@
147146
import com.oracle.graal.python.nodes.PRaiseNode;
148147
import com.oracle.graal.python.nodes.arrow.ArrowArray;
149148
import com.oracle.graal.python.nodes.arrow.ArrowSchema;
150-
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode;
151149
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
152150
import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
153151
import com.oracle.graal.python.nodes.call.CallNode;
@@ -614,37 +612,27 @@ PBytes doString(VirtualFrame frame, Object filenameObj,
614612
public abstract static class DumpTruffleAstNode extends PythonUnaryBuiltinNode {
615613
@Specialization
616614
@TruffleBoundary
617-
public TruffleString doIt(PFunction func) {
618-
return toTruffleStringUncached(NodeUtil.printTreeToString(GetCallTargetNode.getUncached().execute(func).getRootNode()));
619-
}
620-
621-
@Specialization(guards = "isFunction(method.getFunction())")
622-
@TruffleBoundary
623-
public TruffleString doIt(PMethod method) {
624-
return toTruffleStringUncached(NodeUtil.printTreeToString(GetCallTargetNode.getUncached().execute(method).getRootNode()));
625-
}
626-
627-
@Specialization
628-
@TruffleBoundary
629-
public TruffleString doIt(PGenerator gen) {
630-
return toTruffleStringUncached(NodeUtil.printTreeToString(gen.getCurrentCallTarget().getRootNode()));
631-
}
632-
633-
@Specialization
634-
@TruffleBoundary
635-
public TruffleString doIt(PCode code) {
636-
return toTruffleStringUncached(NodeUtil.printTreeToString(CodeNodes.GetCodeRootNode.executeUncached(code)));
637-
}
638-
639-
@Fallback
640-
@TruffleBoundary
641-
public TruffleString doit(Object object) {
615+
public TruffleString doIt(Object object) {
616+
if (object instanceof PFunction func) {
617+
return toTruffleStringUncached(NodeUtil.printTreeToString(func.getCode().getRootNode()));
618+
}
619+
if (object instanceof PBuiltinFunction func) {
620+
return toTruffleStringUncached(NodeUtil.printTreeToString(func.getFunctionRootNode()));
621+
}
622+
if (object instanceof PMethod method) {
623+
return doIt(method.getFunction());
624+
}
625+
if (object instanceof PBuiltinMethod method) {
626+
return doIt(method.getBuiltinFunction());
627+
}
628+
if (object instanceof PGenerator gen) {
629+
return toTruffleStringUncached(NodeUtil.printTreeToString(gen.getCurrentCallTarget().getRootNode()));
630+
}
631+
if (object instanceof PCode code) {
632+
return toTruffleStringUncached(NodeUtil.printTreeToString(code.getRootNode()));
633+
}
642634
return toTruffleStringUncached("truffle ast dump not supported for " + object.toString());
643635
}
644-
645-
protected static boolean isFunction(Object callee) {
646-
return callee instanceof PFunction;
647-
}
648636
}
649637

650638
@Builtin(name = "current_import", minNumOfPositionalArgs = 0)
@@ -829,7 +817,7 @@ public Object doIt(VirtualFrame frame, PFunction func,
829817

830818
@TruffleBoundary
831819
public synchronized PFunction convertToBuiltin(PFunction func) {
832-
RootNode rootNode = CodeNodes.GetCodeRootNode.executeUncached(func.getCode());
820+
RootNode rootNode = func.getCode().getRootNode();
833821
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
834822
if (rootNode instanceof PBytecodeDSLRootNode r) {
835823
r.setPythonInternal(true);
@@ -846,10 +834,8 @@ public synchronized PFunction convertToBuiltin(PFunction func) {
846834
@GenerateNodeFactory
847835
public abstract static class BuiltinMethodNode extends PythonUnaryBuiltinNode {
848836
@Specialization
849-
public Object doIt(PFunction func,
850-
@Bind Node inliningTarget,
851-
@Cached CodeNodes.GetCodeRootNode getRootNode) {
852-
RootNode rootNode = getRootNode.execute(inliningTarget, func.getCode());
837+
public Object doIt(PFunction func) {
838+
RootNode rootNode = func.getCode().getRootNode();
853839
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
854840
if (rootNode instanceof PBytecodeDSLRootNode r) {
855841
r.setPythonInternal(true);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545
import com.oracle.graal.python.PythonLanguage;
4646
import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins;
47-
import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeRootNodeGen;
4847
import com.oracle.graal.python.builtins.objects.function.PFunction;
4948
import com.oracle.graal.python.builtins.objects.function.Signature;
5049
import com.oracle.graal.python.compiler.BytecodeCodeUnit;
@@ -271,22 +270,4 @@ static Signature doCode(PCode code) {
271270
return code.getSignature();
272271
}
273272
}
274-
275-
@GenerateUncached
276-
@GenerateInline
277-
@GenerateCached(false)
278-
public abstract static class GetCodeRootNode extends Node {
279-
280-
public abstract RootNode execute(Node inliningTarget, PCode code);
281-
282-
public static RootNode executeUncached(PCode code) {
283-
return GetCodeRootNodeGen.getUncached().execute(null, code);
284-
}
285-
286-
@Specialization
287-
static RootNode doIt(Node inliningTarget, PCode code,
288-
@Cached GetCodeCallTargetNode getCodeCallTargetNode) {
289-
return getCodeCallTargetNode.execute(inliningTarget, code).getRootNode();
290-
}
291-
}
292273
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ private static CodeUnit getCodeUnit(RootNode node) {
322322
return null;
323323
}
324324

325-
RootNode getRootNode() {
325+
public RootNode getRootNode() {
326326
return rootNode;
327327
}
328328

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343
import com.oracle.graal.python.PythonLanguage;
4444
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
45-
import com.oracle.graal.python.builtins.objects.code.CodeNodes.GetCodeRootNode;
4645
import com.oracle.graal.python.builtins.objects.code.PCode;
4746
import com.oracle.graal.python.builtins.objects.function.PArguments;
4847
import com.oracle.graal.python.builtins.objects.function.PFunction;
@@ -227,7 +226,7 @@ public PFrame(PythonLanguage lang, @SuppressWarnings("unused") long threadState,
227226
// TODO: frames: extract the information from the threadState object
228227
this.globals = globals;
229228
this.code = code;
230-
this.location = GetCodeRootNode.executeUncached(code);
229+
this.location = code.getRootNode();
231230
Reference curFrameInfo = new Reference(location != null ? location.getRootNode() : null, null);
232231
this.virtualFrameInfo = curFrameInfo;
233232
curFrameInfo.setPyFrame(this);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import com.oracle.graal.python.runtime.object.PFactory;
4949
import com.oracle.graal.python.util.PythonUtils;
5050
import com.oracle.truffle.api.CompilerAsserts;
51+
import com.oracle.truffle.api.CompilerDirectives;
5152
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5253
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5354
import com.oracle.truffle.api.RootCallTarget;
@@ -81,6 +82,8 @@ public final class PBuiltinFunction extends PythonBuiltinObject implements Bound
8182
@CompilationFinal(dimensions = 1) private final Object[] defaults;
8283
@CompilationFinal(dimensions = 1) private final PKeyword[] kwDefaults;
8384

85+
@CompilationFinal private RootCallTarget callTarget;
86+
8487
public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString name, Object enclosingType, Object[] defaults, PKeyword[] kwDefaults, int flags, RootNode functionRootNode,
8588
Signature signature,
8689
TpSlot slot, PExternalFunctionWrapper slotWrapper) {
@@ -196,7 +199,24 @@ public Signature getSignature() {
196199
}
197200

198201
public RootCallTarget getCallTarget() {
199-
return functionRootNode.getCallTarget();
202+
RootCallTarget ct = callTarget;
203+
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.SLOWPATH_PROBABILITY, ct == null)) {
204+
if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) {
205+
CompilerDirectives.transferToInterpreterAndInvalidate();
206+
}
207+
ct = initializeCallTarget();
208+
}
209+
return ct;
210+
}
211+
212+
@TruffleBoundary
213+
private RootCallTarget initializeCallTarget() {
214+
RootCallTarget ct = callTarget;
215+
if (ct == null) {
216+
ct = functionRootNode.getCallTarget();
217+
callTarget = ct;
218+
}
219+
return ct;
200220
}
201221

202222
public boolean declaresExplicitSelf() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,11 @@
2929
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3030
import com.oracle.graal.python.builtins.objects.PNone;
3131
import com.oracle.graal.python.builtins.objects.cell.PCell;
32-
import com.oracle.graal.python.builtins.objects.code.CodeNodes.GetCodeCallTargetNode;
3332
import com.oracle.graal.python.builtins.objects.code.PCode;
3433
import com.oracle.graal.python.builtins.objects.object.PythonObject;
3534
import com.oracle.graal.python.compiler.CodeUnit;
3635
import com.oracle.graal.python.lib.PyUnicodeCheckNode;
3736
import com.oracle.graal.python.nodes.PRootNode;
38-
import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode;
3937
import com.oracle.graal.python.runtime.GilNode;
4038
import com.oracle.graal.python.util.PythonUtils;
4139
import com.oracle.truffle.api.Assumption;
@@ -45,14 +43,12 @@
4543
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4644
import com.oracle.truffle.api.RootCallTarget;
4745
import com.oracle.truffle.api.Truffle;
48-
import com.oracle.truffle.api.dsl.Bind;
4946
import com.oracle.truffle.api.dsl.Cached;
5047
import com.oracle.truffle.api.dsl.Cached.Shared;
5148
import com.oracle.truffle.api.interop.InteropLibrary;
5249
import com.oracle.truffle.api.interop.UnsupportedMessageException;
5350
import com.oracle.truffle.api.library.ExportLibrary;
5451
import com.oracle.truffle.api.library.ExportMessage;
55-
import com.oracle.truffle.api.nodes.Node;
5652
import com.oracle.truffle.api.nodes.RootNode;
5753
import com.oracle.truffle.api.source.SourceSection;
5854
import com.oracle.truffle.api.strings.TruffleString;
@@ -221,7 +217,7 @@ public void setKwDefaults(PKeyword[] defaults) {
221217

222218
@TruffleBoundary
223219
String getSourceCode() {
224-
RootNode rootNode = GetCallTargetNode.getUncached().execute(this).getRootNode();
220+
RootNode rootNode = getCode().getRootNode();
225221
SourceSection sourceSection = rootNode.getSourceSection();
226222
if (sourceSection != null) {
227223
return sourceSection.getCharacters().toString();
@@ -248,12 +244,10 @@ String getExecutableName(@Shared("gil") @Cached GilNode gil,
248244

249245
@ExportMessage
250246
public SourceSection getSourceLocation(
251-
@Bind Node inliningTarget,
252-
@Shared("getCt") @Cached GetCodeCallTargetNode getCt,
253247
@Shared("gil") @Cached GilNode gil) throws UnsupportedMessageException {
254248
boolean mustRelease = gil.acquire();
255249
try {
256-
SourceSection result = getSourceLocationDirect(inliningTarget, getCt);
250+
SourceSection result = getSourceLocationDirect();
257251
if (result == null) {
258252
throw UnsupportedMessageException.create();
259253
} else {
@@ -265,8 +259,8 @@ public SourceSection getSourceLocation(
265259
}
266260

267261
@TruffleBoundary
268-
private SourceSection getSourceLocationDirect(Node inliningTarget, GetCodeCallTargetNode getCt) {
269-
RootNode rootNode = getCt.execute(inliningTarget, code).getRootNode();
262+
private SourceSection getSourceLocationDirect() {
263+
RootNode rootNode = code.getRootNode();
270264
SourceSection result;
271265
if (rootNode instanceof PRootNode) {
272266
result = ((PRootNode) rootNode).getSourceSection();
@@ -283,12 +277,10 @@ private static SourceSection getForeignSourceSection(RootNode rootNode) {
283277

284278
@ExportMessage
285279
public boolean hasSourceLocation(
286-
@Bind Node inliningTarget,
287-
@Shared("getCt") @Cached GetCodeCallTargetNode getCt,
288280
@Shared("gil") @Cached GilNode gil) {
289281
boolean mustRelease = gil.acquire();
290282
try {
291-
return getSourceLocationDirect(inliningTarget, getCt) != null;
283+
return getSourceLocationDirect() != null;
292284
} finally {
293285
gil.release(mustRelease);
294286
}

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

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -51,15 +51,12 @@
5151
import com.oracle.graal.python.builtins.objects.method.PMethodBase;
5252
import com.oracle.graal.python.nodes.PGuards;
5353
import com.oracle.graal.python.nodes.PNodeWithContext;
54-
import com.oracle.graal.python.nodes.builtins.FunctionNodesFactory.GetCallTargetNodeGen;
5554
import com.oracle.graal.python.nodes.builtins.FunctionNodesFactory.GetSignatureNodeGen;
5655
import com.oracle.truffle.api.CompilerAsserts;
5756
import com.oracle.truffle.api.CompilerDirectives;
58-
import com.oracle.truffle.api.RootCallTarget;
5957
import com.oracle.truffle.api.dsl.Bind;
6058
import com.oracle.truffle.api.dsl.Cached;
6159
import com.oracle.truffle.api.dsl.Cached.Shared;
62-
import com.oracle.truffle.api.dsl.Fallback;
6360
import com.oracle.truffle.api.dsl.GenerateCached;
6461
import com.oracle.truffle.api.dsl.GenerateInline;
6562
import com.oracle.truffle.api.dsl.GenerateUncached;
@@ -278,54 +275,4 @@ public static GetSignatureNode getUncached() {
278275
return GetSignatureNodeGen.getUncached();
279276
}
280277
}
281-
282-
@ImportStatic(PGuards.class)
283-
@GenerateUncached
284-
@GenerateInline(false) // used lazily
285-
public abstract static class GetCallTargetNode extends PNodeWithContext {
286-
287-
public abstract RootCallTarget execute(Object function);
288-
289-
@Specialization
290-
static RootCallTarget doFunction(PFunction function,
291-
@Bind Node inliningTarget,
292-
@Shared("getCode") @Cached GetFunctionCodeNode getFunctionCodeNode,
293-
@Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt) {
294-
return getCt.execute(inliningTarget, getFunctionCodeNode.execute(inliningTarget, function));
295-
}
296-
297-
@Specialization
298-
static RootCallTarget doBuiltinFunction(PBuiltinFunction builtinFunction) {
299-
return builtinFunction.getCallTarget();
300-
}
301-
302-
@Specialization(guards = "isPFunction(function)")
303-
static RootCallTarget doMethod(@SuppressWarnings("unused") PMethod method,
304-
@Bind Node inliningTarget,
305-
@Bind("method.getFunction()") Object function,
306-
@Shared("getCode") @Cached GetFunctionCodeNode getFunctionCodeNode,
307-
@Shared("getCt") @Cached CodeNodes.GetCodeCallTargetNode getCt) {
308-
return getCt.execute(inliningTarget, getFunctionCodeNode.execute(inliningTarget, (PFunction) function));
309-
}
310-
311-
@Specialization(guards = "isPBuiltinFunction(method.getFunction())")
312-
static RootCallTarget doMethod(@SuppressWarnings("unused") PMethod method,
313-
@Bind("method.getFunction()") Object function) {
314-
return ((PBuiltinFunction) function).getCallTarget();
315-
}
316-
317-
@Specialization
318-
static RootCallTarget doBuiltinMethod(PBuiltinMethod builtinMethod) {
319-
return builtinMethod.getBuiltinFunction().getCallTarget();
320-
}
321-
322-
@Fallback
323-
static RootCallTarget fallback(@SuppressWarnings("unused") Object callable) {
324-
return null;
325-
}
326-
327-
public static GetCallTargetNode getUncached() {
328-
return GetCallTargetNodeGen.getUncached();
329-
}
330-
}
331278
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,7 @@ protected static boolean isSingleContext(Node node) {
17821782

17831783
@NeverDefault
17841784
static Assumption getCodeStableAssumption(PCode code) {
1785-
PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) code.getRootCallTarget().getRootNode();
1785+
PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) code.getRootNode();
17861786
return rootNode.getFunctionCodeFinalAssumption();
17871787
}
17881788

0 commit comments

Comments
 (0)