diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java index 9fc3341abe..22a4e70942 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java @@ -314,18 +314,18 @@ public boolean isSingleContext() { public final Assumption noInteropTypeRegisteredAssumption = Truffle.getRuntime().createAssumption("No class for interop registered"); /** - * Call targets that are populated during native-image build time and then only read at image + * Root nodes that are populated during native-image build time and then only read at image * runtime. Using {@link EconomicMap} avoids embedding a large number of * {@link java.util.concurrent.ConcurrentHashMap.Node} objects into the image heap. */ - private final EconomicMap imageBuildtimeCachedCallTargets = ImageInfo.inImageCode() ? EconomicMap.create() : null; + private final EconomicMap imageBuildtimeCachedRootNodes = ImageInfo.inImageCode() ? EconomicMap.create() : null; /** - * Call targets added after image startup, or all cached call targets when running on the JVM. + * Root nodes added after image startup, or all cached root nodes when running on the JVM. */ - private final ConcurrentHashMap runtimeCachedCallTargets = new ConcurrentHashMap<>(); + private final ConcurrentHashMap runtimeCachedRootNodes = new ConcurrentHashMap<>(); - @CompilationFinal(dimensions = 1) private final RootCallTarget[] builtinSlotsCallTargets; @CompilationFinal(dimensions = 1) private RootCallTarget[] capiCallTargets; + @CompilationFinal(dimensions = 1) private final RootNode[] builtinSlotsRootNodes; /** * We cannot initialize call targets in language ctor and the next suitable hook is context @@ -388,7 +388,7 @@ public PythonLanguage() { if (PythonBuiltinClassType.PythonClass.getSlots() == null) { throw new IllegalStateException("Slots must be initialized in PythonBuiltinClassType static initializer"); } - builtinSlotsCallTargets = new RootCallTarget[TpSlot.getBuiltinsCallTargetsCount()]; + builtinSlotsRootNodes = new RootNode[TpSlot.getBuiltinsCallTargetsCount()]; } /** @@ -1068,12 +1068,14 @@ private Shape createBuiltinShape(PythonBuiltinClassType type, int ordinal) { } public RootCallTarget getBuiltinSlotCallTarget(int index) { - return builtinSlotsCallTargets[index]; + RootNode rootNode = builtinSlotsRootNodes[index]; + assert rootNode != null : index; + return rootNode.getCallTarget(); } - public void setBuiltinSlotCallTarget(int index, RootCallTarget callTarget) { + public void setBuiltinSlotRootNode(int index, RootNode rootNode) { VarHandle.storeStoreFence(); - builtinSlotsCallTargets[index] = callTarget; + builtinSlotsRootNodes[index] = rootNode; } public RootCallTarget getCapiCallTarget(int index) { @@ -1094,140 +1096,94 @@ public void setCapiCallTarget(int index, RootCallTarget ct) { capiCallTargets[index] = ct; } - /** - * Caches call target that wraps a node that is not parametrized, i.e., has only a parameterless - * ctor and all its instances implement the same logic. Parametrized nodes must include the - * parameters that alter their behavior as part of the cache key. - */ - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class key) { - // It's complicated with RootNodes, but regular nodes should have only parameterless ctor to - // be appropriate keys for the cache + public T createCachedRootNode(Function rootNodeFunction, Class key) { assert RootNode.class.isAssignableFrom(key) || key.getConstructors().length <= 1; assert RootNode.class.isAssignableFrom(key) || key.getConstructors().length == 0 || key.getConstructors()[0].getParameterCount() == 0; - return createCachedCallTargetUnsafe(rootNodeFunction, key, true); - } - - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Enum key) { - return createCachedCallTargetUnsafe(rootNodeFunction, key, true); + return createCachedRootNodeUnsafe(rootNodeFunction, key, true); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, int key) { - return createCachedCallTargetUnsafe(rootNodeFunction, key, true); + public RootNode createCachedRootNode(Function rootNodeFunction, Enum key) { + return createCachedRootNodeUnsafe(rootNodeFunction, key, true); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass, String key) { - // for builtins: name is needed to distinguish builtins that share the same underlying node - // in general: a String may be parameter of the node wrapped in the root node or the root - // node itself, there must be finite number of strings that can appear here (i.e., must not - // be dynamically generated unless their number is bounded). - return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, key); + public T createCachedRootNode(Function rootNodeFunction, Class nodeClass, String key) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, nodeClass, key); } - // Variant that should be called at most once per context, because it does not cache the target - // in single context mode - public RootCallTarget initBuiltinCallTarget(Function rootNodeFunction, Class nodeClass, String key) { - return createCachedCallTargetUnsafe(rootNodeFunction, false, nodeClass, key); + // Variant that should be called at most once per context, because it does not cache the root + // node in single context mode + public T initBuiltinRootNode(Function rootNodeFunction, Class nodeClass, String key) { + return createCachedRootNodeUnsafe(rootNodeFunction, false, nodeClass, key); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass, TruffleString key) { - // See the String overload - return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, key); + public RootNode createCachedRootNode(Function rootNodeFunction, Class nodeClass, TruffleString key) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, nodeClass, key); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass, int key) { - return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, key); + public RootNode createCachedRootNode(Function rootNodeFunction, Class nodeClass, int key) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, nodeClass, key); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass1, Class nodeClass2, String name) { - // for slot call targets and wrappers: the root node may be wrapping a helper wrapper node - // implementing the slot wrapper logic and the bare slot node itself - return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, name); + public T createCachedRootNode(Function rootNodeFunction, Class nodeClass1, Class nodeClass2, String name) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, name); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Class nodeClass1, Class nodeClass2, PythonBuiltinClassType type, String name) { - // for slot wrappers: the type is used for validation of "self" type - return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, type, name); + public T createCachedRootNode(Function rootNodeFunction, Class nodeClass1, Class nodeClass2, PythonBuiltinClassType type, String name) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, type, name); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, CodeUnit key) { - return createCachedCallTargetUnsafe(rootNodeFunction, true, key); + public T createCachedRootNode(Function rootNodeFunction, CodeUnit key) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, key); } - /** - * Caches call targets for external C functions created by extensions at runtime. - *

- * For the time being, we assume finite/limited number of extensions and their external - * functions. This may hold onto call targets created by one extension used in a context that - * was closed in the meanwhile and no other context ever loads the extension. - */ - public RootCallTarget createCachedExternalFunWrapperCallTarget(Function rootNodeFunction, + public T createCachedExternalFunWrapperRootNode(Function rootNodeFunction, Class klass, Enum signature, TruffleString name, boolean doArgumentAndResultConversion, boolean isStatic) { - return createCachedCallTargetUnsafe(rootNodeFunction, true, klass, signature, name, doArgumentAndResultConversion, isStatic); + return createCachedRootNodeUnsafe(rootNodeFunction, true, klass, signature, name, doArgumentAndResultConversion, isStatic); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Enum signature, TruffleString name, - boolean doArgumentAndResultConversion) { - return createCachedCallTargetUnsafe(rootNodeFunction, true, signature, name, doArgumentAndResultConversion); + public T createStructSeqIndexedMemberAccessCachedRootNode(Function rootNodeFunction, int memberIndex) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, StructSequence.class, memberIndex); } - public RootCallTarget createCachedCallTarget(Function rootNodeFunction, Enum signature, TruffleString name) { - return createCachedCallTargetUnsafe(rootNodeFunction, true, signature, name); + public T createCachedPropAccessRootNode(Function rootNodeFunction, Class nodeClass, String name, int type, int offset) { + return createCachedRootNodeUnsafe(rootNodeFunction, true, nodeClass, name, type, offset); } - public RootCallTarget createStructSeqIndexedMemberAccessCachedCallTarget(Function rootNodeFunction, int memberIndex) { - return createCachedCallTargetUnsafe(rootNodeFunction, true, StructSequence.class, memberIndex); - } - - public RootCallTarget createCachedPropAccessCallTarget(Function rootNodeFunction, Class nodeClass, String name, int type, int offset) { - // For the time being, we assume finite/limited number of cext/hpy types members, their - // types and offsets - return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, name, type, offset); - } - - /** - * Keys in any caches held by {@link PythonLanguage} must be context independent objects and - * there must be either finite number of their instances, or if the key is a context independent - * mirror of some runtime data structure, it must be cached weakly. This call targets cache is - * strong. - *

- * To avoid memory leaks, all key types must be known to have finite number of possible - * instances. Public methods for adding to the cache must take concrete key type(s) so that all - * possible cache keys are explicit and documented. - */ - private RootCallTarget createCachedCallTargetUnsafe(Function rootNodeFunction, Object key, boolean cacheInSingleContext) { + private T createCachedRootNodeUnsafe(Function rootNodeFunction, Object key, boolean cacheInSingleContext) { CompilerAsserts.neverPartOfCompilation(); if (cacheInSingleContext || !singleContext) { - return getOrCreateCachedCallTarget(rootNodeFunction, key); + return getOrCreateCachedRootNode(rootNodeFunction, key); } else { - return PythonUtils.getOrCreateCallTarget(rootNodeFunction.apply(this)); + return rootNodeFunction.apply(this); } } - private RootCallTarget createCachedCallTargetUnsafe(Function rootNodeFunction, boolean cacheInSingleContext, Object... cacheKeys) { - return createCachedCallTargetUnsafe(rootNodeFunction, Arrays.asList(cacheKeys), cacheInSingleContext); + private T createCachedRootNodeUnsafe(Function rootNodeFunction, boolean cacheInSingleContext, Object... cacheKeys) { + return createCachedRootNodeUnsafe(rootNodeFunction, Arrays.asList(cacheKeys), cacheInSingleContext); } - private RootCallTarget getOrCreateCachedCallTarget(Function rootNodeFunction, Object key) { + @SuppressWarnings("unchecked") + private T getOrCreateCachedRootNode(Function rootNodeFunction, Object key) { CompilerAsserts.neverPartOfCompilation(); if (ImageInfo.inImageRuntimeCode()) { - RootCallTarget preinitialized = imageBuildtimeCachedCallTargets.get(key); + RootNode preinitialized = imageBuildtimeCachedRootNodes.get(key); if (preinitialized != null) { - return preinitialized; + return (T) preinitialized; } - return runtimeCachedCallTargets.computeIfAbsent(key, k -> PythonUtils.getOrCreateCallTarget(rootNodeFunction.apply(this))); + return (T) runtimeCachedRootNodes.computeIfAbsent(key, k -> rootNodeFunction.apply(this)); } if (ImageInfo.inImageBuildtimeCode()) { - synchronized (imageBuildtimeCachedCallTargets) { - RootCallTarget cached = imageBuildtimeCachedCallTargets.get(key); + synchronized (imageBuildtimeCachedRootNodes) { + RootNode cached = imageBuildtimeCachedRootNodes.get(key); if (cached == null) { - cached = PythonUtils.getOrCreateCallTarget(rootNodeFunction.apply(this)); - imageBuildtimeCachedCallTargets.put(key, cached); + cached = rootNodeFunction.apply(this); + imageBuildtimeCachedRootNodes.put(key, cached); } - return cached; + return (T) cached; } } - return runtimeCachedCallTargets.computeIfAbsent(key, k -> PythonUtils.getOrCreateCallTarget(rootNodeFunction.apply(this))); + return (T) runtimeCachedRootNodes.computeIfAbsent(key, k -> rootNodeFunction.apply(this)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java index 9e32f371b8..0a5b3c4b47 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java @@ -42,6 +42,7 @@ import com.oracle.graal.python.builtins.modules.ImpModuleBuiltins.ExecBuiltin; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; +import com.oracle.graal.python.builtins.objects.function.Signature; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; @@ -49,7 +50,6 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.BiConsumer; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.strings.TruffleString; @@ -108,11 +108,12 @@ public void initialize(Python3Core core) { } TruffleString tsName = toInternedTruffleStringUncached(builtin.name()); PythonLanguage language = core.getLanguage(); - RootCallTarget callTarget = language.initBuiltinCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(), - builtin.name()); Object builtinDoc = builtin.doc().isEmpty() ? PNone.NONE : toTruffleStringUncached(builtin.doc()); - int flags = PBuiltinFunction.getFlags(builtin, callTarget); - PBuiltinFunction function = PFactory.createBuiltinFunction(language, tsName, null, numDefaults(builtin), flags, callTarget); + BuiltinFunctionRootNode rootNode = language.initBuiltinRootNode(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), + factory.getNodeClass(), builtin.name()); + Signature signature = rootNode.getSignature(); + int flags = PBuiltinFunction.getFlags(builtin, signature); + PBuiltinFunction function = PFactory.createBuiltinFunction(language, tsName, null, numDefaults(builtin), flags, rootNode); function.setAttribute(T___DOC__, builtinDoc); BoundBuiltinCallable callable = function; if (builtin.isGetter() || builtin.isSetter()) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AtexitModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AtexitModuleBuiltins.java index 16003763d2..7135fbc3d8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AtexitModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AtexitModuleBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -66,7 +66,6 @@ import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -135,8 +134,8 @@ private static void handleException(PythonContext context, PException e) { @Specialization static Object register(Object callable, Object[] arguments, PKeyword[] keywords) { PythonContext context = PythonContext.get(null); - RootCallTarget callTarget = context.getLanguage().createCachedCallTarget(AtExitRootNode::new, AtExitRootNode.class); - context.registerAtexitHook(callable, arguments, keywords, callTarget); + RootNode rootNode = context.getLanguage().createCachedRootNode(AtExitRootNode::new, AtExitRootNode.class); + context.registerAtexitHook(callable, arguments, keywords, rootNode); return callable; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java index 908ad9da5d..57ea497e80 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTypeBuiltins.java @@ -110,6 +110,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; @@ -124,7 +125,6 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLogger; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -132,7 +132,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.EncapsulatingNodeReference; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; @@ -392,17 +391,17 @@ public static GetSetDescriptor createGetSet(TruffleString name, Object cls, long PBuiltinFunction get = null; PythonLanguage language = PythonLanguage.get(null); if (getter != NULLPTR) { - RootCallTarget getterCT = getterCallTarget(name, language); + PRootNode getterRoot = getterRootNode(name, language); NativeFunctionPointer getterFun = CExtCommonNodes.bindFunctionPointer(getter, PExternalFunctionWrapper.GETTER); - get = PFactory.createBuiltinFunction(language, name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(getterFun, closure), 0, getterCT); + get = PFactory.createBuiltinFunction(language, name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(getterFun, closure), 0, getterRoot); } PBuiltinFunction set = null; boolean hasSetter = setter != NULLPTR; if (hasSetter) { - RootCallTarget setterCT = setterCallTarget(name, language); + PRootNode setterRoot = setterRootNode(name, language); NativeFunctionPointer setterFun = CExtCommonNodes.bindFunctionPointer(setter, PExternalFunctionWrapper.SETTER); - set = PFactory.createBuiltinFunction(language, name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(setterFun, closure), 0, setterCT); + set = PFactory.createBuiltinFunction(language, name, cls, EMPTY_OBJECT_ARRAY, ExternalFunctionNodes.createKwDefaults(setterFun, closure), 0, setterRoot); } GetSetDescriptor descriptor = PFactory.createGetSetDescriptor(language, get, set, name, cls, hasSetter); @@ -411,15 +410,15 @@ public static GetSetDescriptor createGetSet(TruffleString name, Object cls, long } @TruffleBoundary - private static RootCallTarget getterCallTarget(TruffleString name, PythonLanguage lang) { - Function rootNodeFunction = l -> WrapperDescriptorRootNodesGen.create(l, name, PExternalFunctionWrapper.GETTER); - return lang.createCachedExternalFunWrapperCallTarget(rootNodeFunction, GetterRoot.class, PExternalFunctionWrapper.GETTER, name, true, false); + private static PRootNode getterRootNode(TruffleString name, PythonLanguage lang) { + Function rootNodeFunction = l -> WrapperDescriptorRootNodesGen.create(l, name, PExternalFunctionWrapper.GETTER); + return lang.createCachedExternalFunWrapperRootNode(rootNodeFunction, GetterRoot.class, PExternalFunctionWrapper.GETTER, name, true, false); } @TruffleBoundary - private static RootCallTarget setterCallTarget(TruffleString name, PythonLanguage lang) { - Function rootNodeFunction = l -> WrapperDescriptorRootNodesGen.create(l, name, PExternalFunctionWrapper.SETTER); - return lang.createCachedExternalFunWrapperCallTarget(rootNodeFunction, SetterRoot.class, PExternalFunctionWrapper.SETTER, name, true, false); + private static PRootNode setterRootNode(TruffleString name, PythonLanguage lang) { + Function rootNodeFunction = l -> WrapperDescriptorRootNodesGen.create(l, name, PExternalFunctionWrapper.SETTER); + return lang.createCachedExternalFunWrapperRootNode(rootNodeFunction, SetterRoot.class, PExternalFunctionWrapper.SETTER, name, true, false); } @CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject, PyBufferProcs}, call = Ignored) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java index 796d661a83..350106b656 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiMemberAccessNodes.java @@ -91,7 +91,6 @@ import com.oracle.graal.python.util.PythonUtils.PrototypeNodeFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -251,11 +250,11 @@ Object doGeneric(@SuppressWarnings("unused") VirtualFrame frame, Object self, @TruffleBoundary public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Object owner, TruffleString propertyName, int type, int offset) { CExtToJavaNode asPythonObjectNode = getReadConverterNode(type); - RootCallTarget callTarget = language.createCachedPropAccessCallTarget( + BuiltinFunctionRootNode rootNode = language.createCachedPropAccessRootNode( l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(ReadMemberNodeGen.create(type, offset, asPythonObjectNode)), true), ReadMemberNode.class, BUILTIN.name(), type, offset); - int flags = PBuiltinFunction.getFlags(BUILTIN, callTarget); - return PFactory.createBuiltinFunction(language, propertyName, owner, 0, flags, callTarget); + int flags = PBuiltinFunction.getFlags(BUILTIN, rootNode.getSignature()); + return PFactory.createBuiltinFunction(language, propertyName, owner, 0, flags, rootNode); } } @@ -277,11 +276,11 @@ Object doGeneric(Object self, Object value, @TruffleBoundary public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString propertyName) { - RootCallTarget builtinCt = language.createCachedCallTarget( + BuiltinFunctionRootNode rootNode = language.createCachedRootNode( l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(ReadOnlyMemberNodeGen.create(propertyName)), true), ReadOnlyMemberNode.class, BUILTIN.name()); - int flags = PBuiltinFunction.getFlags(BUILTIN, builtinCt); - return PFactory.createBuiltinFunction(language, propertyName, null, 0, flags, builtinCt); + int flags = PBuiltinFunction.getFlags(BUILTIN, rootNode.getSignature()); + return PFactory.createBuiltinFunction(language, propertyName, null, 0, flags, rootNode); } } @@ -301,11 +300,11 @@ static Object doGeneric(Object self, @SuppressWarnings("unused") Object value, @TruffleBoundary public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString propertyName) { - RootCallTarget builtinCt = language.createCachedCallTarget( + BuiltinFunctionRootNode rootNode = language.createCachedRootNode( l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(BadMemberDescrNodeGen.create()), true), BadMemberDescrNode.class, BUILTIN.name()); - int flags = PBuiltinFunction.getFlags(BUILTIN, builtinCt); - return PFactory.createBuiltinFunction(language, propertyName, null, 0, flags, builtinCt); + int flags = PBuiltinFunction.getFlags(BUILTIN, rootNode.getSignature()); + return PFactory.createBuiltinFunction(language, propertyName, null, 0, flags, rootNode); } } @@ -600,11 +599,11 @@ public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, Ob return BadMemberDescrNode.createBuiltinFunction(language, propertyName); } // - RootCallTarget callTarget = language.createCachedPropAccessCallTarget( + BuiltinFunctionRootNode rootNode = language.createCachedPropAccessRootNode( l -> new BuiltinFunctionRootNode(l, BUILTIN, new PrototypeNodeFactory<>(WriteMemberNodeGen.create(type, offset)), true), WriteMemberNode.class, BUILTIN.name(), type, offset); - int flags = PBuiltinFunction.getFlags(BUILTIN, callTarget); - return PFactory.createBuiltinFunction(language, propertyName, owner, 0, flags, callTarget); + int flags = PBuiltinFunction.getFlags(BUILTIN, rootNode.getSignature()); + return PFactory.createBuiltinFunction(language, propertyName, owner, 0, flags, rootNode); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index 1eac8e6890..655b4cfa27 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -143,6 +143,7 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; @@ -164,7 +165,6 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLogger; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -1193,10 +1193,10 @@ static PBuiltinFunction createLegacyMethod(long methodDefPtr, int element, Pytho // CPy-style methods // TODO(fa) support static and class methods MethodDescriptorWrapper sig = MethodDescriptorWrapper.fromMethodFlags(flags); - RootCallTarget callTarget = MethodDescriptorWrapper.getOrCreateCallTarget(language, sig, methodName, CExtContext.isMethStatic(flags)); + PRootNode rootNode = MethodDescriptorWrapper.getOrCreateRootNode(language, sig, methodName, CExtContext.isMethStatic(flags)); NativeFunctionPointer fun = CExtCommonNodes.bindFunctionPointer(mlMethObj, sig); PKeyword[] kwDefaults = ExternalFunctionNodes.createKwDefaults(fun); - PBuiltinFunction function = PFactory.createBuiltinFunction(language, methodName, null, PythonUtils.EMPTY_OBJECT_ARRAY, kwDefaults, flags, callTarget); + PBuiltinFunction function = PFactory.createBuiltinFunction(language, methodName, null, PythonUtils.EMPTY_OBJECT_ARRAY, kwDefaults, flags, rootNode); HiddenAttr.WriteLongNode.executeUncached(function, METHOD_DEF_PTR, methodDefPtr); // write doc string; we need to directly write to the storage otherwise it is disallowed diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java index 0a309b63dd..124d0894c5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java @@ -168,7 +168,6 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLogger; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -482,8 +481,8 @@ public enum PExternalFunctionWrapper implements NativeCExtSymbol { } @TruffleBoundary - static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, PythonLanguage language, TruffleString name) { - return language.createCachedExternalFunWrapperCallTarget(l -> WrapperDescriptorRootNodesGen.create(l, name, sig), sig.rootNodeClass, sig, name, true, false); + static PRootNode getOrCreateRootNode(PExternalFunctionWrapper sig, PythonLanguage language, TruffleString name) { + return language.createCachedExternalFunWrapperRootNode(l -> WrapperDescriptorRootNodesGen.create(l, name, sig), sig.rootNodeClass, sig, name, true, false); } /** @@ -495,7 +494,7 @@ static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, Python * @param name The name of the method. * @param callable A reference denoting executable code. Currently, there are two * representations for that: a native function pointer or a - * {@link RootCallTarget} + * {@link PRootNode} * @param enclosingType The type the function belongs to (needed for checking of * {@code self}). * @param sig The wrapper/signature ID as defined in {@link PExternalFunctionWrapper}. @@ -506,7 +505,7 @@ static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, Python @TruffleBoundary public static PythonBuiltinObject createDescrWrapperFunction(TruffleString name, NativeFunctionPointer callable, Object enclosingType, PExternalFunctionWrapper sig, PythonLanguage language) { LOGGER.finer(() -> PythonUtils.formatJString("ExternalFunctions.createDescrWrapperFunction(%s, %s)", name, callable)); - RootCallTarget callTarget = getOrCreateCallTarget(sig, language, name); + PRootNode rootNode = getOrCreateRootNode(sig, language, name); // ensure that 'callable' is executable via InteropLibrary PKeyword[] kwDefaults = ExternalFunctionNodes.createKwDefaults(callable); @@ -517,9 +516,9 @@ public static PythonBuiltinObject createDescrWrapperFunction(TruffleString name, Object type = enclosingType == PNone.NO_VALUE ? null : enclosingType; if (sig == NEW) { - return PFactory.createNewWrapper(language, type, defaults, kwDefaults, callTarget, slot); + return PFactory.createNewWrapper(language, type, defaults, kwDefaults, rootNode, slot); } - return PFactory.createWrapperDescriptor(language, name, type, defaults, kwDefaults, 0, callTarget, slot, sig); + return PFactory.createWrapperDescriptor(language, name, type, defaults, kwDefaults, 0, rootNode, slot, sig); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/MethodDescriptorWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/MethodDescriptorWrapper.java index 0e1908e3d8..284bebc43b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/MethodDescriptorWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/MethodDescriptorWrapper.java @@ -67,9 +67,7 @@ import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.TruffleLogger; -import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.strings.TruffleString; public enum MethodDescriptorWrapper implements NativeCExtSymbol { @@ -125,9 +123,9 @@ public ArgDescriptor[] getArguments() { private static final TruffleLogger LOGGER = CApiContext.getLogger(MethodDescriptorWrapper.class); @TruffleBoundary - static RootCallTarget getOrCreateCallTarget(PythonLanguage language, MethodDescriptorWrapper sig, TruffleString name, boolean isStatic) { + static PRootNode getOrCreateRootNode(PythonLanguage language, MethodDescriptorWrapper sig, TruffleString name, boolean isStatic) { Class nodeKlass; - Function rootNodeFunction = switch (sig) { + Function rootNodeFunction = switch (sig) { case KEYWORDS -> { nodeKlass = MethKeywordsRoot.class; yield l -> new MethKeywordsRoot(l, name, isStatic, sig); @@ -157,7 +155,7 @@ static RootCallTarget getOrCreateCallTarget(PythonLanguage language, MethodDescr yield (l -> new MethMethodRoot(l, name, isStatic, sig)); } }; - return language.createCachedExternalFunWrapperCallTarget(rootNodeFunction, nodeKlass, sig, name, true, isStatic); + return language.createCachedExternalFunWrapperRootNode(rootNodeFunction, nodeKlass, sig, name, true, isStatic); } /** @@ -168,7 +166,7 @@ static RootCallTarget getOrCreateCallTarget(PythonLanguage language, MethodDescr * @param language The Python language object. * @param name The name of the method. * @param callable A reference denoting executable code. Currently, there are two - * representations for that: a native function pointer or a {@link RootCallTarget} + * representations for that: a native function pointer or a {@link PRootNode} * @param enclosingType The type the function belongs to (needed for checking of {@code self}). * @return A {@link PBuiltinFunction} implementing the semantics of the specified slot wrapper. */ @@ -180,7 +178,7 @@ public static PBuiltinFunction createWrapperFunction(PythonLanguage language, Tr return null; } - RootCallTarget callTarget = getOrCreateCallTarget(language, methodDescriptorWrapper, name, CExtContext.isMethStatic(flags)); + PRootNode rootNode = getOrCreateRootNode(language, methodDescriptorWrapper, name, CExtContext.isMethStatic(flags)); PKeyword[] kwDefaults = ExternalFunctionNodes.createKwDefaults(CExtCommonNodes.bindFunctionPointer(callable, methodDescriptorWrapper)); @@ -188,7 +186,7 @@ public static PBuiltinFunction createWrapperFunction(PythonLanguage language, Tr Object[] defaults = PBuiltinFunction.generateDefaults(0); Object type = enclosingType == PNone.NO_VALUE ? null : enclosingType; - return PFactory.createBuiltinFunction(language, name, type, defaults, kwDefaults, flags, callTarget); + return PFactory.createBuiltinFunction(language, name, type, defaults, kwDefaults, flags, rootNode); } /** diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java index ac5e582732..d26d848a8e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java @@ -141,10 +141,10 @@ private static PCode createCode(PythonLanguage language, int argCount, TruffleString name = PythonUtils.internString(uninternedName); qualname = PythonUtils.internString(qualname); - RootCallTarget ct; + PRootNode rootNode; Signature signature; if (codedata.length == 0) { - ct = language.createCachedCallTarget(l -> new BadOPCodeNode(l, name), BadOPCodeNode.class, name.toJavaStringUncached()); + rootNode = language.createCachedRootNode(l -> new BadOPCodeNode(l, name), BadOPCodeNode.class, name.toJavaStringUncached()); /* * We need to create a proper signature because this code path is used to create * fake code objects for duck-typed function-like objects, such as Cython functions. @@ -165,14 +165,15 @@ private static PCode createCode(PythonLanguage language, int argCount, varArgsIndex, parameterNames, kwOnlyNames); + return PFactory.createCode(language, rootNode, signature, nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, filename, name, qualname, firstlineno, linetable); } else { - ct = deserializeForBytecodeInterpreter(language, codedata, cellvars, freevars, flags); - signature = ((PRootNode) ct.getRootNode()).getSignature(); + rootNode = deserializeForBytecodeInterpreter(language, codedata, cellvars, freevars, flags); + signature = rootNode.getSignature(); } - return PFactory.createCode(language, ct, signature, nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, filename, name, qualname, firstlineno, linetable); + return PFactory.createCode(language, rootNode, signature, nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, filename, name, qualname, firstlineno, linetable); } - private static RootCallTarget deserializeForBytecodeInterpreter(PythonLanguage language, byte[] data, TruffleString[] cellvars, TruffleString[] freevars, int flags) { + private static PRootNode deserializeForBytecodeInterpreter(PythonLanguage language, byte[] data, TruffleString[] cellvars, TruffleString[] freevars, int flags) { CodeUnit codeUnit = MarshalModuleBuiltins.deserializeCodeUnit(null, language, data); RootNode rootNode; @@ -198,7 +199,7 @@ private static RootCallTarget deserializeForBytecodeInterpreter(PythonLanguage l rootNode = new PBytecodeGeneratorFunctionRootNode(language, rootNode.getFrameDescriptor(), (PBytecodeRootNode) rootNode, code.name); } } - return PythonUtils.getOrCreateCallTarget(rootNode); + return (PRootNode) rootNode; } @NeverDefault diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java index 1f10629bb3..55acb7cb66 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java @@ -70,6 +70,7 @@ import com.oracle.graal.python.runtime.sequence.storage.LongSequenceStorage; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.bytecode.BytecodeNode; @@ -100,7 +101,8 @@ public final class PCode extends PythonBuiltinObject { /* GraalPy-specific */ public static final int CO_GRAALPYHON_MODULE = 0x1000; - private final RootCallTarget callTarget; + private final RootNode rootNode; + @CompilationFinal private RootCallTarget callTarget; private final Signature signature; // number of local variables @@ -135,38 +137,7 @@ public final class PCode extends PythonBuiltinObject { // tuple of names of cell variables (referenced by containing scopes) private TruffleString[] cellvars; - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget) { - this(cls, instanceShape, callTarget, null); - } - - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, TruffleString filename) { - super(cls, instanceShape); - this.callTarget = callTarget; - this.signature = Signature.fromCallTarget(callTarget); - this.filename = filename; - } - - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, int flags, int firstlineno, byte[] linetable, TruffleString filename) { - this(cls, instanceShape, callTarget); - this.flags = flags; - this.firstlineno = firstlineno; - this.linetable = linetable; - this.filename = filename; - } - - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, BytecodeCodeUnit codeUnit, TruffleString filename) { - this(cls, instanceShape, callTarget, signature, codeUnit.varnames.length, -1, -1, null, null, - null, null, null, filename, - codeUnit.name, codeUnit.qualname, -1, codeUnit.srcOffsetTable); - } - - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, BytecodeDSLCodeUnit codeUnit, TruffleString filename) { - this(cls, instanceShape, callTarget, signature, codeUnit.varnames.length, -1, -1, null, null, - null, null, null, filename, - codeUnit.name, codeUnit.qualname, -1, null); - } - - public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signature signature, int nlocals, + public PCode(Object cls, Shape instanceShape, RootNode rootNode, Signature signature, int nlocals, int stacksize, int flags, Object[] constants, TruffleString[] names, TruffleString[] varnames, TruffleString[] freevars, TruffleString[] cellvars, TruffleString filename, TruffleString name, TruffleString qualname, @@ -185,7 +156,7 @@ public PCode(Object cls, Shape instanceShape, RootCallTarget callTarget, Signatu this.linetable = linetable; this.freevars = freevars; this.cellvars = cellvars; - this.callTarget = callTarget; + this.rootNode = rootNode; this.signature = signature; assert signature != null; } @@ -309,8 +280,8 @@ private static TruffleString[] extractNames(RootNode node) { return EMPTY_TRUFFLESTRING_ARRAY; } - private static RootNode rootNodeForExtraction(RootNode rootNode) { - rootNode = PythonLanguage.unwrapRootNode(rootNode); + private static RootNode rootNodeForExtraction(RootNode rootNodeArg) { + RootNode rootNode = PythonLanguage.unwrapRootNode(rootNodeArg); if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) { return PGenerator.unwrapContinuationRoot(rootNode); } else { @@ -347,7 +318,7 @@ private static CodeUnit getCodeUnit(RootNode node) { } RootNode getRootNode() { - return getRootCallTarget().getRootNode(); + return rootNode; } RootNode getRootNodeForExtraction() { @@ -369,9 +340,8 @@ public TruffleString[] getCellVars() { } @TruffleBoundary - public void fixCoFilename(TruffleString filename) { - filename = PythonUtils.internString(filename); - this.filename = filename; + public void fixCoFilename(TruffleString filenameArg) { + filename = PythonUtils.internString(filenameArg); /* * New code objects inherit the filename from parent, so no need to eagerly construct them * here @@ -471,9 +441,9 @@ public TruffleString[] getVarnames() { } public byte[] getCodestring(Node node) { - RootNode rootNode = getRootNode(); - if (rootNode instanceof PRootNode) { - return ((PRootNode) rootNode).getCode(node); + RootNode rN = getRootNode(); + if (rN instanceof PRootNode) { + return ((PRootNode) rN).getCode(node); } else { return PythonUtils.EMPTY_BYTE_ARRAY; } @@ -505,9 +475,8 @@ public PCode getOrCreateChildCode(int index, BytecodeDSLCodeUnit codeUnit) { private PCode createCode(BytecodeDSLCodeUnit codeUnit) { PBytecodeDSLRootNode outerRootNode = (PBytecodeDSLRootNode) getRootNodeForExtraction(); PythonLanguage language = outerRootNode.getLanguage(); - RootCallTarget callTarget = language.createCachedCallTarget(l -> codeUnit.createRootNode(l, outerRootNode.getSource()), codeUnit); - PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) callTarget.getRootNode(); - return PFactory.createCode(language, callTarget, rootNode.getSignature(), codeUnit, getFilename()); + PBytecodeDSLRootNode rN = language.createCachedRootNode(l -> codeUnit.createRootNode(l, outerRootNode.getSource()), codeUnit); + return PFactory.createCode(language, rN, rN.getSignature(), codeUnit, getFilename()); } public PCode getOrCreateChildCode(int index, BytecodeCodeUnit codeUnit) { @@ -524,13 +493,13 @@ public PCode getOrCreateChildCode(int index, BytecodeCodeUnit codeUnit) { private PCode createCode(BytecodeCodeUnit codeUnit) { PBytecodeRootNode outerRootNode = (PBytecodeRootNode) getRootNodeForExtraction(); PythonLanguage language = outerRootNode.getLanguage(); - RootCallTarget callTarget = language.createCachedCallTarget( - l -> PBytecodeRootNode.createMaybeGenerator(language, codeUnit, outerRootNode.getSource(), outerRootNode.isInternal()), codeUnit); - RootNode rootNode = callTarget.getRootNode(); - if (rootNode instanceof PBytecodeGeneratorFunctionRootNode generatorRoot) { - rootNode = generatorRoot.getBytecodeRootNode(); + PRootNode executableRootNode = language.createCachedRootNode( + l -> (PRootNode) PBytecodeRootNode.createMaybeGenerator(language, codeUnit, outerRootNode.getSource(), outerRootNode.isInternal()), codeUnit); + RootNode rN = executableRootNode; + if (executableRootNode instanceof PBytecodeGeneratorFunctionRootNode generatorRoot) { + rN = generatorRoot.getBytecodeRootNode(); } - return PFactory.createCode(language, callTarget, ((PBytecodeRootNode) rootNode).getSignature(), codeUnit, getFilename()); + return PFactory.createCode(language, executableRootNode, ((PBytecodeRootNode) rN).getSignature(), codeUnit, getFilename()); } @TruffleBoundary @@ -611,7 +580,24 @@ public Signature getSignature() { } public RootCallTarget getRootCallTarget() { - return callTarget; + RootCallTarget ct = callTarget; + if (CompilerDirectives.injectBranchProbability(CompilerDirectives.SLOWPATH_PROBABILITY, ct == null)) { + if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(this)) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + } + ct = initializeCallTarget(); + } + return ct; + } + + @TruffleBoundary + private RootCallTarget initializeCallTarget() { + RootCallTarget ct = callTarget; + if (ct == null) { + ct = rootNode.getCallTarget(); + callTarget = ct; + } + return ct; } @ExportMessage @@ -662,15 +648,15 @@ public String toString() { @TruffleBoundary public String toDisassembledString(boolean quickened) { - RootNode rootNode = getRootCallTarget().getRootNode(); - if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER && rootNode instanceof PBytecodeDSLRootNode dslRoot) { + RootNode rN = getRootNode(); + if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER && rN instanceof PBytecodeDSLRootNode dslRoot) { return dslRoot.getCodeUnit().toString(quickened, dslRoot); - } else if (rootNode instanceof PBytecodeGeneratorRootNode r) { - rootNode = r.getBytecodeRootNode(); - } else if (rootNode instanceof PBytecodeGeneratorFunctionRootNode r) { - rootNode = r.getBytecodeRootNode(); + } else if (rN instanceof PBytecodeGeneratorRootNode r) { + rN = r.getBytecodeRootNode(); + } else if (rN instanceof PBytecodeGeneratorFunctionRootNode r) { + rN = r.getBytecodeRootNode(); } - if (rootNode instanceof PBytecodeRootNode bytecodeRootNode) { + if (rN instanceof PBytecodeRootNode bytecodeRootNode) { return bytecodeRootNode.getCodeUnit().toString(quickened, bytecodeRootNode); } return J_EMPTY_STRING; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java index 972dee05cb..392fd0ee4f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -43,7 +43,6 @@ import com.oracle.graal.python.builtins.objects.str.StringUtils; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; -import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.runtime.object.PFactory; @@ -71,11 +70,10 @@ */ @ExportLibrary(InteropLibrary.class) public final class PBuiltinFunction extends PythonBuiltinObject implements BoundBuiltinCallable { - private final PString name; private final TruffleString qualname; private final Object enclosingType; - private final RootCallTarget callTarget; + private final RootNode functionRootNode; private final Signature signature; private final int flags; private final TpSlot slot; @@ -83,7 +81,8 @@ public final class PBuiltinFunction extends PythonBuiltinObject implements Bound @CompilationFinal(dimensions = 1) private final Object[] defaults; @CompilationFinal(dimensions = 1) private final PKeyword[] kwDefaults; - public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString name, Object enclosingType, Object[] defaults, PKeyword[] kwDefaults, int flags, RootCallTarget callTarget, + public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString name, Object enclosingType, Object[] defaults, PKeyword[] kwDefaults, int flags, RootNode functionRootNode, + Signature signature, TpSlot slot, PExternalFunctionWrapper slotWrapper) { super(cls, shape); this.name = PythonUtils.toPString(name); @@ -93,8 +92,8 @@ public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString n this.qualname = name; } this.enclosingType = enclosingType; - this.callTarget = callTarget; - this.signature = ((PRootNode) callTarget.getRootNode()).getSignature(); + this.functionRootNode = functionRootNode; + this.signature = signature; this.flags = flags; this.defaults = defaults; this.kwDefaults = kwDefaults != null ? kwDefaults : generateKwDefaults(signature); @@ -102,10 +101,6 @@ public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString n this.slotWrapper = slotWrapper; } - public PBuiltinFunction(PythonBuiltinClassType cls, Shape shape, TruffleString name, Object enclosingType, Object[] defaults, PKeyword[] kwDefaults, int flags, RootCallTarget callTarget) { - this(cls, shape, name, enclosingType, defaults, kwDefaults, flags, callTarget, null, null); - } - public static PKeyword[] generateKwDefaults(Signature signature) { TruffleString[] keywordNames = signature.getKeywordNames(); PKeyword[] kwDefaults = PKeyword.create(keywordNames.length); @@ -129,7 +124,7 @@ public static Object[] generateDefaults(int numDefaults) { } public RootNode getFunctionRootNode() { - return callTarget.getRootNode(); + return functionRootNode; } /** @@ -149,12 +144,7 @@ public PExternalFunctionWrapper getSlotWrapper() { } public NodeFactory getBuiltinNodeFactory() { - RootNode functionRootNode = getFunctionRootNode(); - if (functionRootNode instanceof BuiltinFunctionRootNode builtinRoot) { - return builtinRoot.getFactory(); - } else { - return null; - } + return functionRootNode instanceof BuiltinFunctionRootNode builtinRoot ? builtinRoot.getFactory() : null; } public int getFlags() { @@ -169,11 +159,6 @@ public boolean needsDeclaringType() { return (flags & CExtContext.METH_METHOD) != 0; } - @TruffleBoundary - public static int getFlags(Builtin builtin, RootCallTarget callTarget) { - return getFlags(builtin, ((PRootNode) callTarget.getRootNode()).getSignature()); - } - @TruffleBoundary public static int getFlags(Builtin builtin, Signature signature) { if (builtin == null) { @@ -211,7 +196,15 @@ public Signature getSignature() { } public RootCallTarget getCallTarget() { - return callTarget; + return functionRootNode.getCallTarget(); + } + + public boolean declaresExplicitSelf() { + return !(functionRootNode instanceof BuiltinFunctionRootNode builtinRoot) || builtinRoot.declaresExplicitSelf(); + } + + public boolean forceSplitDirectCalls() { + return functionRootNode instanceof BuiltinFunctionRootNode builtinRoot && builtinRoot.getBuiltin().forceSplitDirectCalls(); } public TruffleString getName() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java index 5bd0acfece..a23486255d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. * Copyright (c) 2013, Regents of the University of California * * All rights reserved. @@ -90,7 +90,6 @@ public PFunction(PythonLanguage lang, TruffleString name, TruffleString qualname this.qualname = qualname; assert code != null; this.code = this.finalCode = code; - this.callTarget = code.getRootCallTarget(); this.globals = globals; this.defaultValues = this.finalDefaultValues = defaultValues == null ? PythonUtils.EMPTY_OBJECT_ARRAY : defaultValues; this.kwDefaultValues = this.finalKwDefaultValues = kwDefaultValues == null ? PKeyword.EMPTY_KEYWORDS : kwDefaultValues; @@ -171,7 +170,12 @@ public PCode getCode() { } public RootCallTarget getCallTarget() { - return callTarget; + RootCallTarget ct = callTarget; + if (CompilerDirectives.injectBranchProbability(CompilerDirectives.SLOWPATH_PROBABILITY, ct == null)) { + ct = getCode().getRootCallTarget(); + callTarget = ct; + } + return ct; } @TruffleBoundary @@ -180,7 +184,7 @@ public void setCode(PCode code) { assert code != null : "code cannot be null"; this.finalCode = null; this.code = code; - this.callTarget = code.getRootCallTarget(); + this.callTarget = null; } public Object[] getDefaults() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java index b05ca02ab9..5e12562602 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -136,7 +136,6 @@ import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.util.OverflowException; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.ThreadLocalAction.Access; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.dsl.Bind; @@ -961,8 +960,9 @@ public void execute(PythonContext context, Access access) { return; } PythonLanguage language = context.getLanguage(); - CallTarget callTarget = language.createCachedCallTarget(MMapBuiltins.ReleaseCallback.ReleaserRootNode::new, MMapBuiltins.ReleaseCallback.ReleaserRootNode.class); - callTarget.call(ref); + ReleaserRootNode rootNode = language.createCachedRootNode(MMapBuiltins.ReleaseCallback.ReleaserRootNode::new, + MMapBuiltins.ReleaseCallback.ReleaserRootNode.class); + rootNode.getCallTarget().call(ref); } private static class ReleaserRootNode extends RootNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java index 275519195b..6e5b03fee1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/ScandirIteratorBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -65,7 +65,6 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; -import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.ThreadLocalAction.Access; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.dsl.Bind; @@ -170,8 +169,8 @@ public void execute(PythonContext context, Access access) { return; } PythonLanguage language = context.getLanguage(); - CallTarget callTarget = language.createCachedCallTarget(ReleaserRootNode::new, ReleaserRootNode.class); - callTarget.call(ref); + ReleaserRootNode rootNode = language.createCachedRootNode(ReleaserRootNode::new, ReleaserRootNode.class); + rootNode.getCallTarget().call(ref); } private static class ReleaserRootNode extends RootNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java index 537008db32..968507476a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -81,7 +81,6 @@ import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.strings.TruffleString; @@ -224,8 +223,8 @@ private static void copyMethod(PythonLanguage language, PythonAbstractClass klas } private static void createMember(PythonLanguage language, Object klass, TruffleString name, TruffleString doc, int idx) { - RootCallTarget callTarget = language.createStructSeqIndexedMemberAccessCachedCallTarget((l) -> new GetStructMemberNode(l, idx), idx); - PBuiltinFunction getter = PFactory.createBuiltinFunction(language, name, klass, 0, 0, callTarget); + GetStructMemberNode rootNode = language.createStructSeqIndexedMemberAccessCachedRootNode((l) -> new GetStructMemberNode(l, idx), idx); + PBuiltinFunction getter = PFactory.createBuiltinFunction(language, name, klass, 0, 0, rootNode); GetSetDescriptor callable = PFactory.createGetSetDescriptor(language, getter, null, name, klass, false); if (doc != null) { callable.setAttribute(T___DOC__, doc); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java index ff923f403a..5ad7999c80 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java @@ -228,7 +228,6 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -2328,9 +2327,9 @@ private static void addDictDescrAttribute(PythonAbstractClass[] basesArray, Pyth // initialized yet if ((!hasPythonClassBases(basesArray) && LookupAttributeInMRONode.lookupSlowPath(pythonClass, T___DICT__) == PNone.NO_VALUE) || basesHaveSlots(basesArray)) { Builtin dictBuiltin = ObjectBuiltins.DictNode.class.getAnnotation(Builtin.class); - RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget( + BuiltinFunctionRootNode rootNode = PythonLanguage.get(null).createCachedRootNode( l -> new BuiltinFunctionRootNode(l, dictBuiltin, ObjectBuiltinsFactory.DictNodeFactory.getInstance(), true), ObjectBuiltins.DictNode.class); - setAttribute(T___DICT__, dictBuiltin, callTarget, pythonClass, language); + setAttribute(T___DICT__, dictBuiltin, rootNode, pythonClass, language); } } @@ -2338,15 +2337,15 @@ private static void addDictDescrAttribute(PythonAbstractClass[] basesArray, Pyth private static void addWeakrefDescrAttribute(PythonClass pythonClass, PythonLanguage language) { if (LookupAttributeInMRONode.lookupSlowPath(pythonClass, T___WEAKREF__) == PNone.NO_VALUE) { Builtin builtin = GetWeakRefsNode.class.getAnnotation(Builtin.class); - RootCallTarget callTarget = PythonLanguage.get(null).createCachedCallTarget( + BuiltinFunctionRootNode rootNode = PythonLanguage.get(null).createCachedRootNode( l -> new BuiltinFunctionRootNode(l, builtin, WeakRefModuleBuiltinsFactory.GetWeakRefsNodeFactory.getInstance(), true), GetWeakRefsNode.class); - setAttribute(T___WEAKREF__, builtin, callTarget, pythonClass, language); + setAttribute(T___WEAKREF__, builtin, rootNode, pythonClass, language); } } - private static void setAttribute(TruffleString name, Builtin builtin, RootCallTarget callTarget, PythonClass pythonClass, PythonLanguage language) { - int flags = PBuiltinFunction.getFlags(builtin, callTarget); - PBuiltinFunction function = PFactory.createBuiltinFunction(language, name, pythonClass, 1, flags, callTarget); + private static void setAttribute(TruffleString name, Builtin builtin, BuiltinFunctionRootNode rootNode, PythonClass pythonClass, PythonLanguage language) { + int flags = PBuiltinFunction.getFlags(builtin, rootNode.getSignature()); + PBuiltinFunction function = PFactory.createBuiltinFunction(language, name, pythonClass, 1, flags, rootNode); GetSetDescriptor desc = PFactory.createGetSetDescriptor(language, function, function, name, pythonClass, true); pythonClass.setAttribute(name, desc); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java index 1474f74336..ce71b0569c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlot.java @@ -309,10 +309,10 @@ final PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleStrin Class nodeClass = NodeFactoryBase.getWrappedNodeClass(factory); validateSlotNode(factory, nodeClass, slotSignature); PythonBuiltinClassType builtinType = type instanceof PythonBuiltinClassType bt ? bt : null; - RootCallTarget callTarget = core.getLanguage().createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, true, builtinType), factory.getNodeClass(), nodeClass, - builtinType, name); + BuiltinFunctionRootNode rootNode = core.getLanguage().createCachedRootNode( + l -> new BuiltinFunctionRootNode(l, builtin, factory, true, builtinType), factory.getNodeClass(), nodeClass, builtinType, name); - PBuiltinFunction function = PFactory.createWrapperDescriptor(core.getLanguage(), tsName, type, numDefaults(builtin), 0, callTarget, this, wrapper); + PBuiltinFunction function = PFactory.createWrapperDescriptor(core.getLanguage(), tsName, type, numDefaults(builtin), 0, rootNode, this, wrapper); function.setAttribute(T___DOC__, SlotWrapperDocstrings.getDocstring(name)); return function; } @@ -322,12 +322,12 @@ final PBuiltinFunction createBuiltin(Python3Core core, Object type, TruffleStrin * {@link #initialize(PythonLanguage)} to create the slot call target if the slot node can * be wrapped by {@link BuiltinFunctionRootNode}. */ - static RootCallTarget createSlotCallTarget(PythonLanguage language, BuiltinSlotWrapperSignature signature, NodeFactory factory, String name) { + static BuiltinFunctionRootNode createSlotRootNode(PythonLanguage language, BuiltinSlotWrapperSignature signature, NodeFactory factory, String name) { SlotSignature slotSignature = factory.getNodeClass().getAnnotation(SlotSignature.class); Builtin builtin = new Slot2Builtin(slotSignature, name, signature); Class nodeClass = NodeFactoryBase.getWrappedNodeClass(factory); validateSlotNode(factory, nodeClass, slotSignature); - return language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, true), factory.getNodeClass(), nodeClass, name); + return language.createCachedRootNode(l -> new BuiltinFunctionRootNode(l, builtin, factory, true), factory.getNodeClass(), nodeClass, name); } private static void validateSlotNode(NodeFactory factory, Class nodeClass, SlotSignature slotSignature) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java index 379ebab99c..0cd49cba36 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryFunc.java @@ -99,8 +99,7 @@ final PythonBinaryBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java index 5bfa9e2226..aa974134a6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotBinaryOp.java @@ -246,8 +246,7 @@ final BinaryOpBuiltinNode createOpSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), builtinName)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java index 14495445b8..53b0239c54 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrGet.java @@ -149,8 +149,7 @@ protected TpSlotDescrGetBuiltinComplex(NodeFactory nodeFactory) { public void initialize(PythonLanguage language) { // We need a different call-target for the "raw" slot. It must not normalize None to // NO_VALUE (NULL in CPython) like the __get__ wrapper. - RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___GET__); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SIGNATURE, getNodeFactory(), J___GET__)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java index f3d0fc8af9..21b2ab5c7c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotDescrSet.java @@ -118,8 +118,7 @@ final DescrSetBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SET__); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SET_SIGNATURE, getNodeFactory(), J___SET__)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java index 048b9d0087..3d3ae4267b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotGetAttr.java @@ -120,8 +120,7 @@ final GetAttrBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), J___GETATTRIBUTE__); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), J___GETATTRIBUTE__)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java index b6aac455d3..69f5c89176 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotHashFun.java @@ -134,8 +134,7 @@ HashBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___HASH__); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SIGNATURE, getNodeFactory(), J___HASH__)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java index 3268aaa9c1..8c6bd1f099 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotInquiry.java @@ -123,8 +123,7 @@ protected TpSlotInquiryBuiltinComplex(NodeFactory nodeFactory) { @Override public final void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___BOOL__); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SIGNATURE, getNodeFactory(), J___BOOL__)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java index 59efb7052f..b4560e1c81 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotIterNext.java @@ -114,8 +114,7 @@ final PythonUnaryBuiltinNode createSlotNode() { @Override public final void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), J___NEXT__); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), J___NEXT__)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java index cb8fed064e..171c1dd639 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotLen.java @@ -133,8 +133,7 @@ protected TpSlotLenBuiltinComplex(NodeFactory nodeFactory) { @Override public final void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___LEN__); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SIGNATURE, getNodeFactory(), J___LEN__)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java index a7e57d6c06..dd4d651f1a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotMpAssSubscript.java @@ -112,8 +112,7 @@ final MpAssSubscriptBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java index 333af4b608..454c52dda9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotNbPower.java @@ -113,8 +113,7 @@ final PythonTernaryBuiltinNode createOpSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), J___POW__); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SIGNATURE, getNodeFactory(), J___POW__)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java index c5cd3529e2..b8fcaaf5c1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotRichCompare.java @@ -137,8 +137,7 @@ protected TpSlotRichCmpBuiltinComplex(NodeFactory nodeFactory) { @Override public final void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, SIGNATURE, getNodeFactory(), "tp_richcompare"); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SIGNATURE, getNodeFactory(), "tp_richcompare")); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java index 81f50bee0a..1ffcaef0f1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSetAttr.java @@ -125,8 +125,7 @@ final SetAttrBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETATTR__); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SET_SIGNATURE, getNodeFactory(), J___SETATTR__)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java index 23e641aaf9..6be12fad54 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSizeArgFun.java @@ -112,8 +112,7 @@ final SizeArgFunBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), name); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, BuiltinSlotWrapperSignature.BINARY, getNodeFactory(), name)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java index f818060fdc..c4933fabc7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotSqAssItem.java @@ -119,8 +119,7 @@ final SqAssItemBuiltinNode createSlotNode() { @Override public void initialize(PythonLanguage language) { - RootCallTarget target = createSlotCallTarget(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__); - language.setBuiltinSlotCallTarget(callTargetIndex, target); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, SET_SIGNATURE, getNodeFactory(), J___SETITEM__)); } @Override diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java index 04ed4ec5d5..fb1832e1be 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotUnaryFunc.java @@ -97,8 +97,7 @@ final PythonUnaryBuiltinNode createSlotNode() { @Override public final void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), builtinName); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, BuiltinSlotWrapperSignature.UNARY, getNodeFactory(), builtinName)); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java index fd7a8d2ac1..bf8813f3f0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/slots/TpSlotVarargs.java @@ -181,8 +181,7 @@ public TruffleString getName() { @Override public final void initialize(PythonLanguage language) { - RootCallTarget callTarget = createSlotCallTarget(language, null, getNodeFactory(), name); - language.setBuiltinSlotCallTarget(callTargetIndex, callTarget); + language.setBuiltinSlotRootNode(callTargetIndex, createSlotRootNode(language, null, getNodeFactory(), name)); } @Override @@ -213,9 +212,9 @@ public PBuiltinMethod createBuiltin(Python3Core core, Object type, TruffleString * 'WrapTpNew' holds the type in a field and uses that to do the check. The dropping is * achieved by using `declaresExplicitSelf = false`. */ - RootCallTarget callTarget = language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, false, builtinType), + BuiltinFunctionRootNode rootNode = language.createCachedRootNode(l -> new BuiltinFunctionRootNode(l, builtin, factory, false, builtinType), nodeClass, nodeClass, builtinType, J___NEW__); - return PFactory.createNewWrapper(language, type, defaults, kwDefaults, callTarget, this); + return PFactory.createNewWrapper(language, type, defaults, kwDefaults, rootNode, this); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java index 4930eae2f5..af53f81826 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java @@ -246,7 +246,6 @@ import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.HostCompilerDirectives.BytecodeInterpreterSwitch; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -2919,10 +2918,10 @@ public void materializeContainedFunctionsForInstrumentation(Set PBytecodeRootNode.createMaybeGenerator(language, codeUnit, getSource(), isInternal()), codeUnit); - RootNode rootNode = callTarget.getRootNode(); + rootNode.getCallTarget(); // make sure the calltarget is initialized if (rootNode instanceof PBytecodeGeneratorFunctionRootNode) { rootNode = ((PBytecodeGeneratorFunctionRootNode) rootNode).getBytecodeRootNode(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java index bca9133a6c..745a33e299 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java @@ -59,6 +59,7 @@ import java.math.BigInteger; import java.util.Iterator; +import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import com.oracle.graal.python.PythonLanguage; @@ -444,6 +445,19 @@ public static void updateAllToTracingConfig(PythonLanguage language) { PBytecodeDSLRootNodeGen.BYTECODE.update(language, TRACE_AND_PROFILE_CONFIG); } + @Override + @TruffleBoundary + protected void prepareForInstrumentation(Set> materializedTags) { + super.prepareForInstrumentation(materializedTags); + PythonLanguage language = getLanguage(); + for (Object constant : co.constants) { + if (constant instanceof BytecodeDSLCodeUnit codeUnit) { + PBytecodeDSLRootNode rootNode = language.createCachedRootNode(l -> codeUnit.createRootNode(l, getSource()), codeUnit); + rootNode.getCallTarget(); + } + } + } + public final PythonLanguage getLanguage() { return getLanguage(PythonLanguage.class); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java index f53d5afb22..5f5628e329 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -51,7 +51,6 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.argument.CreateArgumentsNode; import com.oracle.graal.python.nodes.call.CallDispatchersFactory.FunctionIndirectInvokeNodeGen; -import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.runtime.ExecutionContext; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCalleeContext; import com.oracle.graal.python.runtime.PythonContext; @@ -83,8 +82,7 @@ public class CallDispatchers { @NeverDefault public static DirectCallNode createDirectCallNodeFor(PBuiltinFunction callee) { DirectCallNode callNode = Truffle.getRuntime().createDirectCallNode(callee.getCallTarget()); - if (PythonLanguage.get(null).getEngineOption(PythonOptions.EnableForcedSplits) || - (callee.getFunctionRootNode() instanceof BuiltinFunctionRootNode root && root.getBuiltin().forceSplitDirectCalls())) { + if (PythonLanguage.get(null).getEngineOption(PythonOptions.EnableForcedSplits) || callee.forceSplitDirectCalls()) { callNode.cloneCallTarget(); } return callNode; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java index 6f05ec45a5..ef35d0ed11 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/AbstractCallMethodNode.java @@ -50,7 +50,6 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetCallTargetNode; -import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; @@ -64,7 +63,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.RootNode; @ImportStatic({PythonOptions.class, PGuards.class}) @NodeField(name = "maxSizeExceeded", type = boolean.class) @@ -150,10 +148,7 @@ private boolean callerExceedsMaxSize(T builtin protected static boolean takesSelfArg(Object func) { if (func instanceof PBuiltinFunction) { - RootNode functionRootNode = ((PBuiltinFunction) func).getFunctionRootNode(); - if (functionRootNode instanceof BuiltinFunctionRootNode) { - return ((BuiltinFunctionRootNode) functionRootNode).declaresExplicitSelf(); - } + return ((PBuiltinFunction) func).declaresExplicitSelf(); } else if (func instanceof PBuiltinMethod) { return takesSelfArg(((PBuiltinMethod) func).getFunction()); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java index 82e97615d9..82f84611ea 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/AsyncHandler.java @@ -73,7 +73,6 @@ import com.oracle.graal.python.util.SuppressFBWarnings; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.ThreadLocalAction; import com.oracle.truffle.api.ThreadLocalAction.Access; import com.oracle.truffle.api.TruffleLanguage; @@ -201,7 +200,7 @@ public final void execute(PythonContext context, Access access) { } } try { - CallDispatchers.SimpleIndirectInvokeNode.executeUncached(context.getAsyncHandler().callTarget, args); + CallDispatchers.SimpleIndirectInvokeNode.executeUncached(context.getAsyncHandler().getCallTarget(), args); } catch (PException e) { handleException(e); } finally { @@ -341,11 +340,11 @@ public boolean setsUpCalleeContext() { } } - private final RootCallTarget callTarget; + private final CallRootNode rootNode; AsyncHandler(PythonContext context) { this.context = new WeakReference<>(context); - this.callTarget = context.getLanguage().createCachedCallTarget(CallRootNode::new, CallRootNode.class); + this.rootNode = context.getLanguage().createCachedRootNode(CallRootNode::new, CallRootNode.class); if (PythonOptions.AUTOMATIC_ASYNC_ACTIONS) { this.executorService = Executors.newScheduledThreadPool(6, runnable -> { Thread t = Executors.defaultThreadFactory().newThread(runnable); @@ -380,6 +379,10 @@ void registerAction(Supplier actionSupplier) { } } + private com.oracle.truffle.api.RootCallTarget getCallTarget() { + return rootNode.getCallTarget(); + } + void poll() { if (!PythonOptions.AUTOMATIC_ASYNC_ACTIONS) { for (AsyncRunnable r : registeredActions) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java index 5f8d75d561..0ed9c6099d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java @@ -211,6 +211,7 @@ import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.Encoding; @@ -683,13 +684,13 @@ private static final class AtExitHook { final Object callable; final Object[] arguments; final PKeyword[] keywords; - final CallTarget ct; + final RootNode rootNode; - AtExitHook(Object callable, Object[] arguments, PKeyword[] keywords, CallTarget ct) { + AtExitHook(Object callable, Object[] arguments, PKeyword[] keywords, RootNode rootNode) { this.callable = callable; this.arguments = arguments; this.keywords = keywords; - this.ct = ct; + this.rootNode = rootNode; } } @@ -2129,8 +2130,8 @@ public void registerAtexitHook(ShutdownHook shutdownHook) { } @TruffleBoundary - public void registerAtexitHook(Object callable, Object[] arguments, PKeyword[] keywords, CallTarget ct) { - atExitHooks.add(new AtExitHook(callable, arguments, keywords, ct)); + public void registerAtexitHook(Object callable, Object[] arguments, PKeyword[] keywords, RootNode rootNode) { + atExitHooks.add(new AtExitHook(callable, arguments, keywords, rootNode)); } @TruffleBoundary @@ -2245,7 +2246,7 @@ public void runAtexitHooks() { for (int i = atExitHooks.size() - 1; i >= 0; i--) { AtExitHook hook = atExitHooks.get(i); try { - hook.ct.call(hook.callable, hook.arguments, hook.keywords); + hook.rootNode.getCallTarget().call(hook.callable, hook.arguments, hook.keywords); } catch (PException e) { lastException = e; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java index d778a74756..e1eb2448de 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PFactory.java @@ -233,6 +233,7 @@ import com.oracle.graal.python.builtins.objects.typing.PTypeVar; import com.oracle.graal.python.builtins.objects.typing.PTypeVarTuple; import com.oracle.graal.python.compiler.BytecodeCodeUnit; +import com.oracle.graal.python.nodes.PRootNode; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode; @@ -257,6 +258,7 @@ import com.oracle.truffle.api.bytecode.ContinuationRootNode; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.tools.profiler.CPUSampler; @@ -514,29 +516,30 @@ public static PFunction createFunction(PythonLanguage language, TruffleString na return new PFunction(language, name, qualname, code, globals, defaultValues, kwDefaultValues, closure, codeStableAssumption); } - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString name, Object type, int numDefaults, int flags, RootCallTarget callTarget) { + public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString name, Object type, int numDefaults, int flags, PRootNode rootNode) { return new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(language), name, type, - PBuiltinFunction.generateDefaults(numDefaults), null, flags, callTarget); + PBuiltinFunction.generateDefaults(numDefaults), null, flags, rootNode, rootNode.getSignature(), null, null); } - public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, RootCallTarget callTarget) { - return new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(language), name, type, defaults, kw, flags, callTarget); + public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, PRootNode rootNode) { + return new PBuiltinFunction(PythonBuiltinClassType.PBuiltinFunction, PythonBuiltinClassType.PBuiltinFunction.getInstanceShape(language), name, type, defaults, kw, flags, rootNode, + rootNode.getSignature(), null, null); } - public static PBuiltinFunction createWrapperDescriptor(PythonLanguage language, TruffleString name, Object type, int numDefaults, int flags, RootCallTarget callTarget, TpSlot slot, + public static PBuiltinFunction createWrapperDescriptor(PythonLanguage language, TruffleString name, Object type, int numDefaults, int flags, PRootNode rootNode, TpSlot slot, PExternalFunctionWrapper slotWrapper) { return new PBuiltinFunction(PythonBuiltinClassType.WrapperDescriptor, PythonBuiltinClassType.WrapperDescriptor.getInstanceShape(language), name, type, - PBuiltinFunction.generateDefaults(numDefaults), null, flags, callTarget, slot, slotWrapper); + PBuiltinFunction.generateDefaults(numDefaults), null, flags, rootNode, rootNode.getSignature(), slot, slotWrapper); } - public static PBuiltinFunction createWrapperDescriptor(PythonLanguage language, TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, RootCallTarget callTarget, + public static PBuiltinFunction createWrapperDescriptor(PythonLanguage language, TruffleString name, Object type, Object[] defaults, PKeyword[] kw, int flags, PRootNode rootNode, TpSlot slot, PExternalFunctionWrapper slotWrapper) { return new PBuiltinFunction(PythonBuiltinClassType.WrapperDescriptor, PythonBuiltinClassType.WrapperDescriptor.getInstanceShape(language), name, type, defaults, kw, flags, - callTarget, slot, slotWrapper); + rootNode, rootNode.getSignature(), slot, slotWrapper); } - public static PBuiltinMethod createNewWrapper(PythonLanguage language, Object type, Object[] defaults, PKeyword[] kwdefaults, RootCallTarget callTarget, TpSlot slot) { - PBuiltinFunction func = createWrapperDescriptor(language, T___NEW__, type, defaults, kwdefaults, CExtContext.METH_VARARGS | CExtContext.METH_KEYWORDS, callTarget, slot, + public static PBuiltinMethod createNewWrapper(PythonLanguage language, Object type, Object[] defaults, PKeyword[] kwdefaults, PRootNode rootNode, TpSlot slot) { + PBuiltinFunction func = createWrapperDescriptor(language, T___NEW__, type, defaults, kwdefaults, CExtContext.METH_VARARGS | CExtContext.METH_KEYWORDS, rootNode, slot, PExternalFunctionWrapper.NEW); return createBuiltinMethod(language, type, func); } @@ -544,7 +547,7 @@ public static PBuiltinMethod createNewWrapper(PythonLanguage language, Object ty public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, PBuiltinFunction function, Object klass) { PythonBuiltinClassType type = (PythonBuiltinClassType) function.getPythonClass(); return new PBuiltinFunction(type, type.getInstanceShape(language), function.getName(), klass, - function.getDefaults(), function.getKwDefaults(), function.getFlags(), function.getCallTarget(), + function.getDefaults(), function.getKwDefaults(), function.getFlags(), function.getFunctionRootNode(), function.getSignature(), function.getSlot(), function.getSlotWrapper()); } @@ -1073,32 +1076,40 @@ public static PZip createZip(Object cls, Shape shape, Object[] iterables, boolea } public static PCode createCode(PythonLanguage language, RootCallTarget ct) { - return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct); + return createCode(language, ct, null); } public static PCode createCode(PythonLanguage language, RootCallTarget ct, TruffleString filename) { - return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct, filename); + return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct.getRootNode(), Signature.fromCallTarget(ct), + -1, -1, -1, null, null, null, null, null, filename, null, null, -1, null); } public static PCode createCode(PythonLanguage language, RootCallTarget ct, int flags, int firstlineno, byte[] linetable, TruffleString filename) { - return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct, flags, firstlineno, linetable, filename); + return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), ct.getRootNode(), Signature.fromCallTarget(ct), + -1, -1, flags, null, null, null, null, null, filename, null, null, firstlineno, linetable); } public static PCode createCode(PythonLanguage language, RootCallTarget callTarget, Signature signature, BytecodeCodeUnit codeUnit, TruffleString filename) { - return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), callTarget, signature, codeUnit, filename); + return createCode(language, callTarget.getRootNode(), signature, codeUnit, filename); } - public static PCode createCode(PythonLanguage language, RootCallTarget callTarget, Signature signature, BytecodeDSLCodeUnit codeUnit, TruffleString filename) { - return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), callTarget, signature, codeUnit, filename); + public static PCode createCode(PythonLanguage language, RootNode rootNode, Signature signature, BytecodeCodeUnit codeUnit, TruffleString filename) { + return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), rootNode, signature, + codeUnit.varnames.length, -1, -1, null, null, null, null, null, filename, codeUnit.name, codeUnit.qualname, -1, codeUnit.srcOffsetTable); } - public static PCode createCode(PythonLanguage language, RootCallTarget callTarget, Signature signature, int nlocals, + public static PCode createCode(PythonLanguage language, RootNode rootNode, Signature signature, BytecodeDSLCodeUnit codeUnit, TruffleString filename) { + return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), rootNode, signature, + codeUnit.varnames.length, -1, -1, null, null, null, null, null, filename, codeUnit.name, codeUnit.qualname, -1, null); + } + + public static PCode createCode(PythonLanguage language, RootNode rootNode, Signature signature, int nlocals, int stacksize, int flags, Object[] constants, TruffleString[] names, TruffleString[] varnames, TruffleString[] freevars, TruffleString[] cellvars, TruffleString filename, TruffleString name, TruffleString qualname, int firstlineno, byte[] linetable) { - return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), callTarget, signature, + return new PCode(PythonBuiltinClassType.PCode, PythonBuiltinClassType.PCode.getInstanceShape(language), rootNode, signature, nlocals, stacksize, flags, constants, names, varnames, freevars, cellvars, filename, name, qualname, firstlineno, linetable); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java index df419f01da..da3fae1f89 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/PythonUtils.java @@ -758,18 +758,16 @@ public static Object[] toArray(List list) { public static PBuiltinFunction createMethod(PythonLanguage language, Object klass, NodeFactory nodeFactory, Object type, int numDefaults) { Class nodeClass = nodeFactory.getNodeClass(); Builtin builtin = nodeClass.getAnnotation(Builtin.class); - RootCallTarget callTarget = language.createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, nodeFactory, true), nodeClass); - return createMethod(klass, builtin, callTarget, type, numDefaults); + BuiltinFunctionRootNode rootNode = language.createCachedRootNode(l -> new BuiltinFunctionRootNode(l, builtin, nodeFactory, true), nodeClass); + return createMethod(klass, builtin, rootNode, type, numDefaults); } @TruffleBoundary - public static PBuiltinFunction createMethod(Object klass, Builtin builtin, RootCallTarget callTarget, Object type, int numDefaults) { - RootNode rootNode = callTarget.getRootNode(); - assert rootNode instanceof BuiltinFunctionRootNode : String.format("root: %s, builtin: %s, klass: %s", rootNode, builtin, klass); - assert ((BuiltinFunctionRootNode) rootNode).getBuiltin() == builtin : String.format("%s != %s, klass: %s", ((BuiltinFunctionRootNode) rootNode).getBuiltin(), builtin, klass); - int flags = PBuiltinFunction.getFlags(builtin, callTarget); + public static PBuiltinFunction createMethod(Object klass, Builtin builtin, BuiltinFunctionRootNode rootNode, Object type, int numDefaults) { + assert rootNode.getBuiltin() == builtin : String.format("%s != %s, klass: %s", rootNode.getBuiltin(), builtin, klass); + int flags = PBuiltinFunction.getFlags(builtin, rootNode.getSignature()); TruffleString name = toInternedTruffleStringUncached(builtin.name()); - PBuiltinFunction function = PFactory.createBuiltinFunction(PythonLanguage.get(null), name, type, numDefaults, flags, callTarget); + PBuiltinFunction function = PFactory.createBuiltinFunction(PythonLanguage.get(null), name, type, numDefaults, flags, rootNode); if (klass != null) { WriteAttributeToObjectNode.getUncached().execute(klass, name, function); }