diff --git a/ci/graal/common.json b/ci/graal/common.json index 86497d63f4..83b9c68d83 100644 --- a/ci/graal/common.json +++ b/ci/graal/common.json @@ -53,13 +53,13 @@ "labsjdk-ee-25Debug": {"name": "labsjdk", "version": "ee-25+30-jvmci-b01-debug", "platformspecific": true }, "labsjdk-ee-25-llvm": {"name": "labsjdk", "version": "ee-25+30-jvmci-b01-sulong", "platformspecific": true }, - "oraclejdk-latest": {"name": "jpg-jdk", "version": "26", "build_id": "jdk-26+7", "platformspecific": true, "extrabundles": ["static-libs"]}, - "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-26+7-jvmci-b01", "platformspecific": true }, - "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-26+7-jvmci-b01-debug", "platformspecific": true }, - "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-26+7-jvmci-b01-sulong", "platformspecific": true }, - "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-26+7-jvmci-b01", "platformspecific": true }, - "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-26+7-jvmci-b01-debug", "platformspecific": true }, - "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-26+7-jvmci-b01-sulong", "platformspecific": true } + "oraclejdk-latest": {"name": "jpg-jdk", "version": "26", "build_id": "jdk-26+8", "platformspecific": true, "extrabundles": ["static-libs"]}, + "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-26+8-jvmci-b01", "platformspecific": true }, + "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-26+8-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-26+8-jvmci-b01-sulong", "platformspecific": true }, + "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-26+8-jvmci-b01", "platformspecific": true }, + "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-26+8-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-26+8-jvmci-b01-sulong", "platformspecific": true } }, "eclipse": { diff --git a/docs/contributor/CONTRIBUTING.md b/docs/contributor/CONTRIBUTING.md index 7b5d80b559..f5f1432d38 100644 --- a/docs/contributor/CONTRIBUTING.md +++ b/docs/contributor/CONTRIBUTING.md @@ -127,10 +127,10 @@ If the IDE was initialized properly by using the command mentioned above, the ex Both of these commands also work when you have a `graalpy` executable, e.g. inside a `venv`. -For debugging the C API and native extensions, first make sure you rebuild (`mx clean` first!) graalpything with the environment variable `CFLAGS=-g` set. +For debugging the C API and native extensions, first make sure you rebuild (`mx clean` first!) graalpython with the environment variable `CFLAGS=-g` set. This will keep debug symbols in our C API implementation which should allow you to use `gdb` or [`rr`](https://rr-project.org/) to debug. When you build an SVM image, debugging the entire application is possible, and there are [docs](https://www.graalvm.org/reference-manual/native-image/guides/debug-native-image-process/) to see Java code when inside the native debugger. -Make sure you find and keep the `libpythonvm.so.debug` file around next to your GraalPy build, you can find it somewhere under `graal/sdk/mxbuild`. +Make sure you find and keep the `libpythonvm.so.debug` file around next to your GraalPy build, you can find it under `mxbuild/*/libpythonvm`. ## Advanced Commands to Develop and Debug @@ -149,6 +149,7 @@ mx python-gate --tags python-unittest If some of the tests fail, you can re-run just a single test like this, substituting TEST-SELECTOR with the test you want to run. You can use the whole failed test name including the path as the selector. Note that you can insert `-d` to debug on the Java level or use `--inspect` to debug in the Chrome debugger. +Use `com.oracle.graal.python.runtime.exception.ExceptionUtils.printPythonLikeStackTrace()` in the Java debugger to print the current Python traceback on `stderr`. ```bash mx [-d] graalpytest [--inspect] TEST-SELECTOR diff --git a/graalpython/com.oracle.graal.python.cext/src/capi.c b/graalpython/com.oracle.graal.python.cext/src/capi.c index cb2bd845be..30321ff113 100644 --- a/graalpython/com.oracle.graal.python.cext/src/capi.c +++ b/graalpython/com.oracle.graal.python.cext/src/capi.c @@ -616,10 +616,6 @@ PyAPI_FUNC(void*) GraalPyPrivate_PointerAddOffset(void* x, Py_ssize_t y) { return (char *)x + y; } -PyAPI_FUNC(int) GraalPyPrivate_SubclassCheck(PyObject* type) { - return PyType_FastSubclass(Py_TYPE(type), Py_TPFLAGS_TYPE_SUBCLASS); -} - // Implements the basesisze check in typeobject.c:_PyObject_GetState PyAPI_FUNC(int) GraalPyPrivate_CheckBasicsizeForGetstate(PyTypeObject* type, int slot_num) { Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize; 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 bd72b0ef5d..4737d12371 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 @@ -82,7 +82,6 @@ import com.oracle.graal.python.compiler.ParserCallbacksImpl; import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler; import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler.BytecodeDSLCompilerResult; -import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode; import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit; import com.oracle.graal.python.nodes.call.CallDispatchers; @@ -1043,7 +1042,7 @@ public Shape getEmptyShape() { public Shape getShapeForClass(PythonAbstractClass klass) { if (isSingleContext()) { - return Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttr.getClassHiddenKey(), klass, 0).build(); + return Shape.newBuilder(getEmptyShape()).dynamicType(klass).build(); } else { return getEmptyShape(); } @@ -1065,7 +1064,7 @@ public Shape getBuiltinTypeInstanceShape(PythonBuiltinClassType type) { private Shape createBuiltinShape(PythonBuiltinClassType type, int ordinal) { Shape shape; - Shape.DerivedBuilder shapeBuilder = Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttr.getClassHiddenKey(), type, 0); + Shape.DerivedBuilder shapeBuilder = Shape.newBuilder(getEmptyShape()).dynamicType(type); if (!type.isBuiltinWithDict()) { shapeBuilder.shapeFlags(PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java index eca264cca0..f7a76378ac 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/AsyncioModuleBuiltins.java @@ -72,7 +72,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; @@ -178,8 +178,8 @@ static Object getCurrentLoop(VirtualFrame frame, Object ignored, @Cached CallNode callGetPolicy, @Cached CallNode callGetLoop, @Cached AbstractImportNode.ImportName importName, - @Cached(parameters = "T_GET_EVENT_LOOP") GetAttributeNode.GetFixedAttributeNode getGetLoop, - @Cached(parameters = "T_GET_EVENT_LOOP_POLICY") GetAttributeNode.GetFixedAttributeNode getGetLoopPolicy) { + @Cached(parameters = "T_GET_EVENT_LOOP") GetFixedAttributeNode getGetLoop, + @Cached(parameters = "T_GET_EVENT_LOOP_POLICY") GetFixedAttributeNode getGetLoopPolicy) { Object eventLoop = context.getThreadState(context.getLanguage(inliningTarget)).getRunningEventLoop(); if (eventLoop == null) { Object asyncio = importName.execute(frame, context, context.getBuiltins(), T_ASYNCIO_EVENTS, PNone.NONE, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, 0); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java index 1e41bb73cd..adb3725352 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java @@ -208,7 +208,8 @@ import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.StringLiterals; import com.oracle.graal.python.nodes.argument.ReadArgumentNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; @@ -1730,7 +1731,7 @@ static Object ord(@SuppressWarnings("unused") Object obj, "flush: whether to forcibly flush the stream.") @GenerateNodeFactory public abstract static class PrintNode extends PythonBuiltinNode { - @Child private ReadAttributeFromObjectNode readStdout; + @Child private ReadAttributeFromModuleNode readStdout; @CompilationFinal private PythonModule cachedSys; @Specialization @@ -1836,7 +1837,7 @@ private Object getStdout() { } if (readStdout == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - readStdout = insert(ReadAttributeFromObjectNode.create()); + readStdout = insert(ReadAttributeFromModuleNode.create()); } Object stdout = readStdout.execute(sys, T_STDOUT); if (stdout == NO_VALUE) { @@ -2435,7 +2436,7 @@ protected Object doItNonFunction(VirtualFrame frame, Object function, Object[] a @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached("createFor($node)") IndirectCallData indirectCallData, @Cached CalculateMetaclassNode calculateMetaClass, - @Cached("create(T___PREPARE__)") GetAttributeNode getPrepare, + @Cached("create(T___PREPARE__)") GetFixedAttributeNode getPrepare, @Cached PyMappingCheckNode pyMappingCheckNode, @Cached CallNode callPrep, @Cached CallNode callType, @@ -2527,7 +2528,7 @@ class InitializeBuildClass { Object ns; try { - Object prep = getPrepare.executeObject(frame, init.meta); + Object prep = getPrepare.execute(frame, init.meta); ns = callPrep.execute(frame, prep, new Object[]{name, init.bases}, init.mkw); } catch (PException p) { p.expectAttributeError(inliningTarget, noAttributeProfile); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java index 86c10ebc6f..74e6538850 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PolyglotModuleBuiltins.java @@ -102,7 +102,7 @@ import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; @@ -352,10 +352,10 @@ Object exportSymbol(PBuiltinFunction fun, @SuppressWarnings("unused") PNone name @Specialization(guards = "isModuleMethod(fun)") static Object exportSymbol(VirtualFrame frame, Object fun, @SuppressWarnings("unused") PNone name, @Bind Node inliningTarget, - @Cached("create(T___NAME__)") GetAttributeNode.GetFixedAttributeNode getNameAttributeNode, + @Cached("create(T___NAME__)") GetFixedAttributeNode getNameAttributeNode, @Cached CastToJavaStringNode castToStringNode, @Cached PRaiseNode raiseNode) { - Object attrNameValue = getNameAttributeNode.executeObject(frame, fun); + Object attrNameValue = getNameAttributeNode.execute(frame, fun); String methodName; try { methodName = castToStringNode.execute(attrNameValue); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java index f81f030085..2d0ff3db5a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java @@ -49,6 +49,7 @@ import java.util.List; import java.util.Objects; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import org.graalvm.collections.EconomicMap; import com.oracle.graal.python.builtins.Builtin; @@ -79,8 +80,7 @@ import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonSenaryBuiltinNode; @@ -622,7 +622,7 @@ static Object doSingleContext( @Specialization(replaces = "doSingleContext") static Object doRead( @Bind PythonContext context, - @Cached ReadAttributeFromObjectNode read) { + @Cached ReadAttributeFromModuleNode read) { PythonModule module = context.lookupBuiltinModule(BuiltinNames.T__SRE); return read.execute(module, T_MATCH_CONSTRUCTOR); } @@ -643,7 +643,7 @@ abstract static class TRegexSearch extends PythonSenaryBuiltinNode { protected static final TruffleString T__PATTERN__FALLBACK_COMPILE = tsLiteral("_Pattern__fallback_compile"); @Child private HiddenAttr.ReadNode readCacheNode = HiddenAttr.ReadNode.create(); - @Child private GetAttributeNode getFallbackCompileNode; + @Child private GetFixedAttributeNode getFallbackCompileNode; @Child private CallNode callFallbackCompileNode; @Child private CallNode callFallbackMethodNode; @Child private SliceNodes.CreateSliceNode createSliceNode; @@ -666,7 +666,7 @@ protected Object doCached(VirtualFrame frame, PythonObject pattern, Object input @Cached @Shared PyNumberAsSizeNode asSizeNode, @Cached @Shared PyObjectSizeNode lengthNode, @CachedLibrary(limit = "1") @Shared InteropLibrary libCompiledRegex, - @Cached("create(method.getMethodName())") GetAttributeNode getFallbackMethodNode, + @Cached("create(method.getMethodName())") GetFixedAttributeNode getFallbackMethodNode, @Cached @Shared TRegexCallExec tRegexCallExec, @Cached @Shared CreateMatchFromTRegexResultNode createMatchFromTRegexResultNode) { int pos = asSizeNode.executeExact(frame, inliningTarget, indexNode.execute(frame, inliningTarget, posArg)); @@ -686,8 +686,9 @@ protected Object doCached(VirtualFrame frame, PythonObject pattern, Object input reCheckInputTypeNode.execute(frame, input, tRegexCache.isBinary()); if (fallbackProfile.profile(inliningTarget, libCompiledRegex.isNull(compiledRegex))) { - Object fallbackRegex = getCallFallbackCompileNode().executeWithoutFrame(getGetFallbackCompileNode().executeObject(frame, pattern)); - return getCallFallbackMethodNode().executeWithoutFrame(getFallbackMethodNode.executeObject(frame, fallbackRegex), input, pos, endPos); + GetFixedAttributeNode getFixedAttributeNode = getGetFallbackCompileNode(); + Object fallbackRegex = getCallFallbackCompileNode().executeWithoutFrame(getFixedAttributeNode.execute(frame, pattern)); + return getCallFallbackMethodNode().executeWithoutFrame(getFallbackMethodNode.execute(frame, fallbackRegex), input, pos, endPos); } Object truncatedInput = input; @@ -716,7 +717,7 @@ protected Object doCachedRegex(VirtualFrame frame, PythonObject pattern, Object @Cached @Shared PyNumberAsSizeNode asSizeNode, @Cached @Shared PyObjectSizeNode lengthNode, @CachedLibrary(limit = "1") @Shared InteropLibrary libCompiledRegex, - @Cached("create(method.getMethodName())") GetAttributeNode getFallbackMethodNode, + @Cached("create(method.getMethodName())") GetFixedAttributeNode getFallbackMethodNode, @Cached @Shared TRegexCallExec tRegexCallExec, @Cached @Shared CreateMatchFromTRegexResultNode createMatchFromTRegexResultNode) { return doCached(frame, pattern, input, posArg, endPosArg, method, mustAdvance, inliningTarget, pattern, cachedMethod, mustAdvance, tRegexCompileNode, tRegexCache, @@ -738,7 +739,7 @@ protected Object doDynamic(VirtualFrame frame, PythonObject pattern, Object inpu @Cached @Shared InlinedConditionProfile fallbackProfile, @Cached @Shared InlinedConditionProfile truncatingInputProfile, @CachedLibrary(limit = "1") @Shared InteropLibrary libCompiledRegex, - @Cached("create(method.getMethodName())") GetAttributeNode getFallbackMethodNode, + @Cached("create(method.getMethodName())") GetFixedAttributeNode getFallbackMethodNode, @Cached @Shared TRegexCallExec tRegexCallExec, @Cached @Shared CreateMatchFromTRegexResultNode createMatchFromTRegexResultNode) { TRegexCache tRegexCache = getTRegexCache(pattern); @@ -752,10 +753,10 @@ protected TRegexCache getTRegexCache(PythonObject pattern) { return (TRegexCache) readCacheNode.executeCached(pattern, HiddenAttr.TREGEX_CACHE, null); } - private GetAttributeNode getGetFallbackCompileNode() { + private GetFixedAttributeNode getGetFallbackCompileNode() { if (getFallbackCompileNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - getFallbackCompileNode = insert(GetAttributeNode.create(T__PATTERN__FALLBACK_COMPILE)); + getFallbackCompileNode = insert(GetFixedAttributeNode.create(T__PATTERN__FALLBACK_COMPILE)); } return getFallbackCompileNode; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java index ed74c933fa..3c364f0cc7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java @@ -1001,7 +1001,7 @@ Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Object categ @Bind Node inliningTarget, @Cached("createFor($node)") IndirectCallData indirectCallData, @Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode, - @Cached StringNodes.CastToTruffleStringCheckedNode castToStringChecked, + @Cached StringNodes.CastToTruffleStringChecked1Node castToStringChecked, @Cached PRaiseNode raiseNode, @Cached WarningsModuleNode moduleFunctionsNode) { // warnings_warn_impl diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java index 0d6758a8ca..8a65ca99e2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java @@ -1014,19 +1014,19 @@ abstract static class PyObjectSetAttrNode extends PNodeWithContext { @Specialization static void doBuiltinClass(PythonBuiltinClass object, TruffleString key, Object value, - @Exclusive @Cached(value = "createForceType()", inline = false) WriteAttributeToObjectNode writeAttrNode) { + @Exclusive @Cached WriteAttributeToObjectNode writeAttrNode) { writeAttrNode.execute(object, key, value); } @Specialization static void doNativeClass(PythonNativeClass object, TruffleString key, Object value, - @Exclusive @Cached(value = "createForceType()", inline = false) WriteAttributeToObjectNode writeAttrNode) { + @Exclusive @Cached WriteAttributeToObjectNode writeAttrNode) { writeAttrNode.execute(object, key, value); } @Specialization(guards = {"!isPythonBuiltinClass(object)"}) static void doObject(PythonObject object, TruffleString key, Object value, - @Exclusive @Cached(inline = false) WriteAttributeToPythonObjectNode writeAttrToPythonObjectNode) { + @Exclusive @Cached WriteAttributeToPythonObjectNode writeAttrToPythonObjectNode) { writeAttrToPythonObjectNode.execute(object, key, value); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java index 921283f9bb..57fca05976 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextModuleBuiltins.java @@ -85,7 +85,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.StringLiterals; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.call.CallNode; @@ -172,7 +172,7 @@ static Object getName(PythonModule module, @Cached PythonCextBuiltins.PromoteBorrowedValue promoteBorrowedValue, @Cached PyUnicodeCheckNode pyUnicodeCheckNode, // CPython reads from the module dict directly - @Cached ReadAttributeFromObjectNode read, + @Cached ReadAttributeFromModuleNode read, @Cached WriteAttributeToObjectNode write) { /* * Even thought the function returns a new reference, CPython assumes that the unicode @@ -308,7 +308,7 @@ abstract static class PyModule_GetFilenameObject extends CApiUnaryBuiltinNode { @Specialization static Object getFilename(PythonModule module, @Bind Node inliningTarget, - @Cached ReadAttributeFromObjectNode read, + @Cached ReadAttributeFromModuleNode read, @Cached PyUnicodeCheckNode check, @Cached PRaiseNode raiseNode) { Object file = read.execute(module, T___FILE__); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java index c23f69cc92..d1fb62ea24 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextSlotBuiltins.java @@ -120,7 +120,7 @@ import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.sequence.PSequence; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java index 31cffab05a..c16287b838 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextStructSeqBuiltins.java @@ -74,6 +74,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.util.CannotCastException; @@ -137,7 +138,7 @@ abstract static class GraalPyPrivate_StructSequence_NewType extends CApiQuaterna @TruffleBoundary Object doGeneric(TruffleString typeName, TruffleString typeDoc, Object fields, int nInSequence, @Cached GraalPyPrivate_StructSequence_InitType2 initNode, - @Cached ReadAttributeFromObjectNode readTypeBuiltinNode, + @Cached ReadAttributeFromModuleNode readTypeBuiltinNode, @CachedLibrary(limit = "1") DynamicObjectLibrary dylib, @Cached CallNode callTypeNewNode, @Bind PythonLanguage language) { @@ -159,7 +160,7 @@ abstract static class PyStructSequence_New extends CApiUnaryBuiltinNode { @Specialization static Object doGeneric(Object cls, @Bind Node inliningTarget, - @Cached("createForceType()") ReadAttributeFromObjectNode readRealSizeNode, + @Cached ReadAttributeFromObjectNode readRealSizeNode, @Cached CastToJavaIntExactNode castToIntNode, @Bind PythonLanguage language, @Cached TypeNodes.GetInstanceShape getInstanceShape, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java index 20c459ab27..d4dc935831 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java @@ -79,7 +79,7 @@ import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetEndNode; import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetObjectNode; import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetStartNode; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyObjectSizeNode; @@ -852,7 +852,7 @@ abstract static class ParseDecodingErrorHandlerResultNode extends Node { static DecodingErrorHandlerResult doTuple(Node inliningTarget, PTuple result, @Cached SequenceNodes.LenNode lenNode, @Cached SequenceNodes.GetObjectArrayNode getObjectArrayNode, - @Cached CastToTruffleStringCheckedNode castToTruffleStringCheckedNode, + @Cached CastToTruffleStringChecked0Node castToTruffleStringCheckedNode, @Cached CastToJavaIntExactNode castToJavaIntExactNode, @Cached PRaiseNode raiseNode) { if (lenNode.execute(inliningTarget, result) != 2) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java index d3fd753b22..1523a421e8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/csv/CSVModuleBuiltins.java @@ -74,7 +74,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -134,7 +134,7 @@ public abstract static class CSVRegisterDialectNode extends PythonBuiltinNode { static PNone register(VirtualFrame frame, PythonModule module, Object nameObj, Object dialectObj, PKeyword[] keywords, @Bind Node inliningTarget, @Cached CastToTruffleStringNode nameNode, - @Cached ReadAttributeFromObjectNode readNode, + @Cached ReadAttributeFromModuleNode readNode, @Cached CallNode callNode, @Cached PyDictSetItem setItem, @Cached PRaiseNode raiseNode) { @@ -164,7 +164,7 @@ public abstract static class CSVUnregisterDialectNode extends PythonBuiltinNode @Specialization static PNone unregister(VirtualFrame frame, PythonModule module, Object nameObj, @Bind Node inliningTarget, - @Cached ReadAttributeFromObjectNode readNode, + @Cached ReadAttributeFromModuleNode readNode, @Cached PyDictDelItem delItem, @Cached HashingStorageGetItem getItem, @Cached PRaiseNode raiseNode) { @@ -198,7 +198,7 @@ protected static CSVGetDialectNode create() { static CSVDialect get(VirtualFrame frame, PythonModule module, Object nameObj, @Bind Node inliningTarget, @Cached PyDictGetItem getItemNode, - @Cached ReadAttributeFromObjectNode readNode, + @Cached ReadAttributeFromModuleNode readNode, @Cached PRaiseNode raiseNode) { // TODO GR-38165: unchecked cast to PDict @@ -220,7 +220,7 @@ static CSVDialect get(VirtualFrame frame, PythonModule module, Object nameObj, public abstract static class CSVListDialectsNode extends PythonBuiltinNode { @Specialization PList listDialects(VirtualFrame frame, PythonModule module, - @Cached ReadAttributeFromObjectNode readNode, + @Cached ReadAttributeFromModuleNode readNode, @Cached ListNodes.ConstructListNode constructListNode) { Object dialects = readNode.execute(module, T__DIALECTS); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java index 9c051a144d..d3ee0d66e9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataBuiltins.java @@ -81,7 +81,7 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -175,7 +175,7 @@ static Object reduce(VirtualFrame frame, CDataObject self, @Bind Node inliningTarget, @Bind PythonLanguage language, @Cached PyObjectStgDictNode pyObjectStgDictNode, - @Cached("create(T___DICT__)") GetAttributeNode getAttributeNode, + @Cached("create(T___DICT__)") GetFixedAttributeNode getAttributeNode, @Cached ReadAttributeFromPythonObjectNode readAttrNode, @Cached PointerNodes.ReadBytesNode readBytesNode, @Cached GetClassNode getClassNode, @@ -184,7 +184,7 @@ static Object reduce(VirtualFrame frame, CDataObject self, if ((stgDict.flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) != 0) { throw raiseNode.raise(inliningTarget, ValueError, CTYPES_OBJECTS_CONTAINING_POINTERS_CANNOT_BE_PICKLED); } - Object dict = getAttributeNode.executeObject(frame, self); + Object dict = getAttributeNode.execute(frame, self); Object[] t1 = new Object[]{dict, null}; t1[1] = PFactory.createBytes(language, readBytesNode.execute(inliningTarget, self.b_ptr, self.b_size)); Object clazz = getClassNode.execute(inliningTarget, self); @@ -209,7 +209,7 @@ abstract static class SetStateNode extends PythonBinaryBuiltinNode { static Object PyCData_setstate(VirtualFrame frame, CDataObject self, PTuple args, @Bind Node inliningTarget, @Cached SequenceStorageNodes.GetInternalObjectArrayNode getArray, - @Cached("create(T___DICT__)") GetAttributeNode getAttributeNode, + @Cached("create(T___DICT__)") GetFixedAttributeNode getAttributeNode, @Cached PyNumberAsSizeNode asSizeNode, @Cached HashingStorageAddAllToOther addAllToOtherNode, @Cached PRaiseNode raiseNode) { @@ -227,7 +227,7 @@ static Object PyCData_setstate(VirtualFrame frame, CDataObject self, PTuple args len = self.b_size; } memmove(inliningTarget, self.b_ptr, data, len); - Object mydict = getAttributeNode.executeObject(frame, self); + Object mydict = getAttributeNode.execute(frame, self); if (!PGuards.isDict(mydict)) { throw raiseNode.raise(inliningTarget, TypeError, P_DICT_MUST_BE_A_DICTIONARY_NOT_P, self, mydict); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java index 0ed57e8c71..9501b4a1cc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CDataTypeBuiltins.java @@ -93,7 +93,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; @@ -327,14 +327,14 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object CDataType_in_dll(VirtualFrame frame, Object type, Object dll, TruffleString name, @Bind Node inliningTarget, @Cached PyLongCheckNode longCheckNode, - @Cached("create(T__HANDLE)") GetAttributeNode getAttributeNode, + @Cached("create(T__HANDLE)") GetFixedAttributeNode getAttributeNode, @Cached PyCDataAtAddress atAddress, @Cached AuditNode auditNode, @Cached PointerNodes.PointerFromLongNode pointerFromLongNode, @Cached CtypesDlSymNode dlSymNode, @Cached PRaiseNode raiseNode) { auditNode.audit(inliningTarget, "ctypes.dlsym", dll, name); - Object obj = getAttributeNode.executeObject(frame, dll); + Object obj = getAttributeNode.execute(frame, dll); if (!longCheckNode.execute(inliningTarget, obj)) { throw raiseNode.raise(inliningTarget, TypeError, THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java index e0a5577eab..690d295e1c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java @@ -144,8 +144,8 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.StringLiterals; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode; @@ -269,7 +269,7 @@ public void postInitialize(Python3Core core) { handle = DlOpenNode.loadNFILibrary(context, NFIBackend.NATIVE, J_DEFAULT_LIBRARY, rtldLocal); if (PythonOS.getPythonOS() == PythonOS.PLATFORM_WIN32) { PythonModule sysModule = context.getSysModule(); - Object loadLibraryMethod = ReadAttributeFromObjectNode.getUncached().execute(ctypesModule, toTruffleStringUncached("LoadLibrary")); + Object loadLibraryMethod = ReadAttributeFromModuleNode.getUncached().execute(ctypesModule, toTruffleStringUncached("LoadLibrary")); Object pythonLib = CallNode.executeUncached(loadLibraryMethod, toTruffleStringUncached(PythonContext.getSupportLibName("python-native")), 0); WriteAttributeToPythonObjectNode.getUncached().execute(sysModule, toTruffleStringUncached("dllhandle"), pythonLib); } @@ -546,9 +546,9 @@ Object unpickle(VirtualFrame frame, Object typ, PTuple state, // This shouldn't call the slot directly to make sure the check in the // wrapper runs @Cached("create(T___NEW__)") LookupAndCallUnaryNode lookupAndCallUnaryNode, - @Cached("create(T___SETSTATE__)") GetAttributeNode setStateAttr) { + @Cached("create(T___SETSTATE__)") GetFixedAttributeNode setStateAttr) { Object obj = lookupAndCallUnaryNode.executeObject(frame, typ); - Object meth = setStateAttr.executeObject(frame, obj); + Object meth = setStateAttr.execute(frame, obj); callNode.execute(frame, meth, state); return obj; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java index 55dbe15053..c3e9d4fc7e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCArrayTypeBuiltins.java @@ -135,7 +135,7 @@ private static void createGetSet(PythonLanguage language, Object type, NodeFacto PBuiltinFunction getter = PFactory.createBuiltinFunction(language, name, type, 1, flags, rawCallTarget); GetSetDescriptor callable = PFactory.createGetSetDescriptor(language, getter, getter, name, type, false); callable.setAttribute(T___DOC__, toTruffleStringUncached(builtin.doc())); - WriteAttributeToObjectNode.getUncached(true).execute(type, name, callable); + WriteAttributeToObjectNode.getUncached().execute(type, name, callable); } @Builtin(name = "raw", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, isGetter = true, isSetter = true, doc = "value") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java index d0d7dc527c..c95f216be5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java @@ -132,7 +132,7 @@ private static void addClassMethod(PythonLanguage language, Object type, NodeFac PBuiltinFunction function = PFactory.createBuiltinFunction(language, name, type, 1, flags, callTarget); PDecoratedMethod classMethod = PFactory.createClassmethodFromCallableObj(language, function); function.setAttribute(T___DOC__, builtinDoc); - WriteAttributeToObjectNode.getUncached(true).execute(type, name, classMethod); + WriteAttributeToObjectNode.getUncached().execute(type, name, classMethod); } @ImportStatic(CDataTypeBuiltins.class) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java index c626125ab8..70bc866c5a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCStructTypeBuiltins.java @@ -51,7 +51,7 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.ctypes.StructUnionTypeBuiltins.PyCStructUnionTypeUpdateStgDict; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode; @@ -96,7 +96,7 @@ void doStringKey(VirtualFrame frame, Object object, TruffleString key, Object va @InliningCutoff void doGeneric(VirtualFrame frame, Object object, Object keyObject, Object value, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castKeyToStringNode, + @Cached CastToTruffleStringChecked1Node castKeyToStringNode, @Shared @Cached TypeBuiltins.SetattrNode typeSetAttr, @Shared @Cached TruffleString.EqualNode equalNode, @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java index 41bdf076e4..2a1973eedf 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictBuiltins.java @@ -82,7 +82,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.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; @@ -184,11 +184,11 @@ static void MakeFields(VirtualFrame frame, Object type, CFieldObject descr, int @Cached PyObjectSizeNode sizeNode, @Cached PyObjectGetItem getItemNode, @Cached GetInternalObjectArrayNode getArray, - @Cached("create(T__FIELDS_)") GetAttributeNode getAttrString, + @Cached("create(T__FIELDS_)") GetFixedAttributeNode getAttrString, @Cached MakeFieldsNode recursiveNode, @Cached("createFor($node)") IndirectCallData indirectCallData, @Cached PRaiseNode raiseNode) { - Object fields = getAttrString.executeObject(frame, descr.proto); + Object fields = getAttrString.execute(frame, descr.proto); if (!sequenceCheckNode.execute(inliningTarget, fields)) { throw raiseNode.raise(inliningTarget, TypeError, FIELDS_MUST_BE_A_SEQUENCE); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictObject.java index 4c8f74c76c..025b9be923 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/StgDictObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2025, 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 @@ -48,6 +48,10 @@ import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; +/** + * Extra information for ctypes stored in a type's dict. See + * https://github.com/python/cpython/blob/fece15d29f28e89f1231afa80508c80ed28dc37d/Modules/_ctypes/ctypes.h#L333 + */ public final class StgDictObject extends PDict { protected static final int VOID_PTR_SIZE = Long.BYTES; // sizeof(void *) diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java index 3fd652cfdb..64a13a518f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/UnionTypeBuiltins.java @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.modules.ctypes; +import static com.oracle.graal.python.nodes.ErrorMessages.ATTR_NAME_MUST_BE_STRING; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; @@ -53,25 +54,19 @@ import com.oracle.graal.python.builtins.modules.ctypes.StructUnionTypeBuiltins.PyCStructUnionTypeUpdateStgDict; import com.oracle.graal.python.builtins.modules.ctypes.StructUnionTypeBuiltins.StructUnionTypeNewNode; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; -import com.oracle.graal.python.builtins.objects.object.ObjectNodes.GenericSetAttrNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; -import com.oracle.truffle.api.strings.TruffleString.EqualNode; @CoreFunctions(extendClasses = PythonBuiltinClassType.UnionType) public final class UnionTypeBuiltins extends PythonBuiltins { @@ -96,38 +91,20 @@ protected boolean isStruct() { @GenerateNodeFactory protected abstract static class SetattrNode extends SetAttrBuiltinNode { @Specialization - static void doStringKey(VirtualFrame frame, Object object, TruffleString key, Object value, - @Bind Node inliningTarget, - @Exclusive @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, - @Shared @Cached WriteAttributeToObjectNode write, - @Shared @Cached TruffleString.EqualNode equalNode, - @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { - genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); - updateStgDictIfNecessary(frame, object, key, value, equalNode, updateStgDict); - } - - // @Exclusive to address warning - @Specialization - @InliningCutoff static void doGenericKey(VirtualFrame frame, Object object, Object keyObject, Object value, @Bind Node inliningTarget, - @Cached CastToTruffleStringNode castKeyNode, - @Cached PRaiseNode raiseNode, - @Exclusive @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, - @Shared @Cached WriteAttributeToObjectNode write, - @Shared @Cached TruffleString.EqualNode equalNode, - @Shared @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { - TruffleString key = GenericSetAttrNode.castAttributeKey(inliningTarget, keyObject, castKeyNode, raiseNode); + @Cached CastToTruffleStringChecked0Node castKeyNode, + @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, + @Cached WriteAttributeToObjectNode write, + @Cached TruffleString.EqualNode equalNode, + @Cached PyCStructUnionTypeUpdateStgDict updateStgDict) { + TruffleString key = castKeyNode.cast(inliningTarget, keyObject, ATTR_NAME_MUST_BE_STRING); genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); - updateStgDictIfNecessary(frame, object, key, value, equalNode, updateStgDict); - } - - private static void updateStgDictIfNecessary(VirtualFrame frame, Object object, TruffleString key, Object value, - EqualNode equalNode, PyCStructUnionTypeUpdateStgDict updateStgDict) { if (equalNode.execute(key, StructUnionTypeBuiltins.T__FIELDS_, TS_ENCODING)) { updateStgDict.execute(frame, object, value, false); } } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java index 180a253237..9ae3f00753 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObject.java @@ -81,7 +81,7 @@ public static DigestObject create(PythonBuiltinClassType digestType, Shape insta } public PythonBuiltinClassType getType() { - return (PythonBuiltinClassType) getInitialPythonClass(); + return (PythonBuiltinClassType) getPythonClass(); } // The JDK does not expose the block sizes used by digests, so diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java index 34635c2162..fbcbd707e4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java @@ -85,7 +85,7 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; @@ -620,7 +620,7 @@ protected abstract static class DecodeNode extends Node { @Specialization static TruffleString decodeGeneric(VirtualFrame frame, Object decoder, Object o, boolean eof, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castNode, + @Cached CastToTruffleStringChecked1Node castNode, @Cached PyObjectCallMethodObjArgs callMethodDecode) { Object decoded = callMethodDecode.execute(frame, inliningTarget, decoder, T_DECODE, o, eof); return castNode.cast(inliningTarget, decoded, DECODER_SHOULD_RETURN_A_STRING_RESULT_NOT_P, decoded); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java index 940948248d..9635513880 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/json/JSONScannerBuiltins.java @@ -36,7 +36,7 @@ import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -79,12 +79,12 @@ protected List> getNodeFa @GenerateNodeFactory public abstract static class MakeScanner extends PythonBinaryBuiltinNode { - @Child private GetAttributeNode.GetFixedAttributeNode getStrict = GetAttributeNode.GetFixedAttributeNode.create(T_STRICT); - @Child private GetAttributeNode.GetFixedAttributeNode getObjectHook = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("object_hook")); - @Child private GetAttributeNode.GetFixedAttributeNode getObjectPairsHook = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("object_pairs_hook")); - @Child private GetAttributeNode.GetFixedAttributeNode getParseFloat = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("parse_float")); - @Child private GetAttributeNode.GetFixedAttributeNode getParseInt = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("parse_int")); - @Child private GetAttributeNode.GetFixedAttributeNode getParseConstant = GetAttributeNode.GetFixedAttributeNode.create(tsLiteral("parse_constant")); + @Child private GetFixedAttributeNode getStrict = GetFixedAttributeNode.create(T_STRICT); + @Child private GetFixedAttributeNode getObjectHook = GetFixedAttributeNode.create(tsLiteral("object_hook")); + @Child private GetFixedAttributeNode getObjectPairsHook = GetFixedAttributeNode.create(tsLiteral("object_pairs_hook")); + @Child private GetFixedAttributeNode getParseFloat = GetFixedAttributeNode.create(tsLiteral("parse_float")); + @Child private GetFixedAttributeNode getParseInt = GetFixedAttributeNode.create(tsLiteral("parse_int")); + @Child private GetFixedAttributeNode getParseConstant = GetFixedAttributeNode.create(tsLiteral("parse_constant")); @Specialization public PJSONScanner doNew(VirtualFrame frame, Object cls, Object context, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java index af1b65f61a..ca0e8b025b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java @@ -126,6 +126,7 @@ import com.oracle.graal.python.nodes.argument.keywords.NonMappingException; import com.oracle.graal.python.nodes.argument.keywords.SameDictKeyException; import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; @@ -1165,7 +1166,7 @@ public abstract static class PKeyInfoNode extends Node { @Specialization static boolean access(Object object, TruffleString attrKeyName, int type, @Bind Node inliningTarget, - @Cached("createForceType()") ReadAttributeFromObjectNode readTypeAttrNode, + @Cached ReadAttributeFromObjectNode readTypeAttrNode, @Cached ReadAttributeFromObjectNode readObjectAttrNode, @Cached PyCallableCheckNode callableCheck, @Cached LookupInheritedAttributeNode.Dynamic getGetNode, @@ -1477,7 +1478,7 @@ public abstract static class ToDisplaySideEffectingNode extends Node { @Specialization public static TruffleString doDefault(Node inliningTarget, PythonAbstractObject receiver, - @Cached(inline = false) ReadAttributeFromObjectNode readStr, + @Cached ReadAttributeFromModuleNode readStr, @Cached(inline = false) CallNode callNode, @Cached CastToTruffleStringNode castStr, @Cached InlinedConditionProfile toStringUsed) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java index 2c61d5e9f4..1f723e4265 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java @@ -81,7 +81,7 @@ import com.oracle.graal.python.builtins.objects.range.PIntRange; import com.oracle.graal.python.builtins.objects.slice.PSlice; import com.oracle.graal.python.builtins.objects.slice.SliceNodes; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; @@ -185,7 +185,7 @@ static Object array2(VirtualFrame frame, Object cls, Object[] args, PKeyword[] k @Bind Node inliningTarget, @Cached InlinedConditionProfile hasInitializerProfile, @Cached IsBuiltinClassExactProfile isNotSubtypeProfile, - @Cached CastToTruffleStringCheckedNode cast, + @Cached CastToTruffleStringChecked1Node cast, @Cached ArrayNodeInternal arrayNodeInternal, @Cached PRaiseNode raise) { if (isNotSubtypeProfile.profileClass(inliningTarget, cls, PythonBuiltinClassType.PArray)) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java index 1e268bfbff..46c32b79c8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/ANextAwaitableBuiltins.java @@ -95,7 +95,7 @@ abstract static class GetIterNode extends Node { static Object getIter(VirtualFrame frame, Node inliningTarget, PANextAwaitable self, @Cached GetAwaitableNode getAwaitableNode) { Object awaitable = getAwaitableNode.execute(frame, self.getWrapped()); - if (awaitable instanceof PGenerator coroutine && coroutine.getInitialPythonClass() == PythonBuiltinClassType.PCoroutine) { + if (awaitable instanceof PGenerator coroutine && coroutine.getPythonClass() == PythonBuiltinClassType.PCoroutine) { return PFactory.createCoroutineWrapper(PythonLanguage.get(inliningTarget), coroutine); } return awaitable; 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 7f932115fa..b6afb03253 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 @@ -943,7 +943,7 @@ public static long lookupNativeI64MemberInMRO(Object cls, CFields nativeMemberNa if (managedMemberName instanceof HiddenAttr ha) { attr = HiddenAttr.ReadNode.executeUncached((PythonAbstractObject) mroCls, ha, NO_VALUE); } else { - attr = ReadAttributeFromObjectNode.getUncachedForceType().execute(mroCls, CompilerDirectives.castExact(managedMemberName, TruffleString.class)); + attr = ReadAttributeFromObjectNode.getUncached().execute(mroCls, CompilerDirectives.castExact(managedMemberName, TruffleString.class)); } if (attr != NO_VALUE) { return PyNumberAsSizeNode.executeExactUncached(attr); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java index 553e9f5296..5652f38f61 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java @@ -123,7 +123,6 @@ public enum NativeCAPISymbol implements NativeCExtSymbol { FUN_FLOAT_SUBTYPE_NEW("GraalPyPrivate_Float_SubtypeNew", PyObjectTransfer, PyTypeObject, ArgDescriptor.Double), FUN_COMPLEX_SUBTYPE_FROM_DOUBLES("GraalPyPrivate_Complex_SubtypeFromDoubles", PyObjectTransfer, PyTypeObject, ArgDescriptor.Double, ArgDescriptor.Double), FUN_EXCEPTION_SUBTYPE_NEW("GraalPyPrivate_Exception_SubtypeNew", PyObjectTransfer, PyTypeObject, PyObject), - FUN_SUBCLASS_CHECK("GraalPyPrivate_SubclassCheck", Int, PyObject), FUN_UNICODE_SUBTYPE_NEW("GraalPyPrivate_Unicode_SubtypeNew", PyObjectTransfer, PyTypeObject, PyObject), FUN_CHECK_BASICSIZE_FOR_GETSTATE("GraalPyPrivate_CheckBasicsizeForGetstate", Int, PyTypeObject, Int), FUN_MMAP_INIT_BUFFERPROTOCOL("GraalPyPrivate_MMap_InitBufferProtocol", ArgDescriptor.Void, PyTypeObject), diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java index 14993f3c03..304c4d3a62 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/BufferStorageNodes.java @@ -344,7 +344,7 @@ static void packChar(Node inliningTarget, BufferFormat format, Object object, Ob @Specialization(guards = "format == UNICODE") static void packDouble(Node inliningTarget, @SuppressWarnings("unused") BufferFormat format, Object object, Object buffer, int offset, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached StringNodes.CastToTruffleStringCheckedNode cast, + @Cached StringNodes.CastToTruffleStringChecked0Node cast, @Cached(inline = false) TruffleString.CodePointLengthNode codePointLengthNode, @Cached(inline = false) TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Exclusive @Cached PRaiseNode raiseNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseException.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseException.java index ae2ae740e7..a4d7ae3817 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseException.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseException.java @@ -234,7 +234,7 @@ public Object[] getMessageArgs() { public String toString() { CompilerAsserts.neverPartOfCompilation(); // We *MUST NOT* call anything here that may need a context! - StringBuilder sb = new StringBuilder(this.getInitialPythonClass().toString()); + StringBuilder sb = new StringBuilder(this.getPythonClass().toString()); if (messageArgs != null && messageArgs.length > 0) { sb.append("(fmt=\"").append(messageFormat.toJavaStringUncached()).append("\", args = ("); for (Object arg : messageArgs) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java index 25a7bbd88c..0d2fcafed8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeDecodeErrorBuiltins.java @@ -65,7 +65,7 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectSizeNode; @@ -301,7 +301,7 @@ public abstract static class PyUnicodeDecodeErrorGetEncodingNode extends Node { @Specialization static TruffleString doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked1Node castToStringNode, @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_ENCODING, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java index 57ea0cc797..1efa6b7fbb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeEncodeErrorBuiltins.java @@ -62,7 +62,7 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.function.PKeyword; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode; @@ -218,7 +218,7 @@ public abstract static class PyUnicodeEncodeOrTranslateErrorGetObjectNode extend @Specialization static TruffleString doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked1Node castToStringNode, @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_OBJECT, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { @@ -298,7 +298,7 @@ public abstract static class PyUnicodeEncodeErrorGetEncodingNode extends Node { @Specialization static TruffleString doIt(Node inliningTarget, PBaseException exceptionObject, @Cached(inline = false) BaseExceptionAttrNode attrNode, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked1Node castToStringNode, @Cached PRaiseNode raiseNode) { Object obj = attrNode.get(exceptionObject, IDX_ENCODING, UNICODE_ERROR_ATTR_FACTORY); if (obj == null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java index 350cb13005..443a80cd77 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/FunctionBuiltins.java @@ -223,7 +223,7 @@ static Object setName(PFunction self, TruffleString value) { @Specialization(guards = "!isNoValue(value)") static Object setName(PFunction self, Object value, @Bind Node inliningTarget, - @Cached StringNodes.CastToTruffleStringCheckedNode cast) { + @Cached StringNodes.CastToTruffleStringChecked2Node cast) { return setName(self, cast.cast(inliningTarget, value, ErrorMessages.MUST_BE_SET_TO_S_OBJ, T___NAME__, "string")); } } @@ -245,7 +245,7 @@ static Object setQualname(PFunction self, TruffleString value) { @Specialization(guards = "!isNoValue(value)") static Object setQualname(PFunction self, Object value, @Bind Node inliningTarget, - @Cached StringNodes.CastToTruffleStringCheckedNode cast) { + @Cached StringNodes.CastToTruffleStringChecked2Node cast) { return setQualname(self, cast.cast(inliningTarget, value, ErrorMessages.MUST_BE_SET_TO_S_OBJ, T___QUALNAME__, "string")); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java index d547249cc4..360cd9d8f7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java @@ -109,7 +109,7 @@ static Object setName(PGenerator self, TruffleString value) { @Specialization(guards = "!isNoValue(value)") static Object setName(PGenerator self, Object value, @Bind Node inliningTarget, - @Cached StringNodes.CastToTruffleStringCheckedNode cast) { + @Cached StringNodes.CastToTruffleStringChecked2Node cast) { return setName(self, cast.cast(inliningTarget, value, ErrorMessages.MUST_BE_SET_TO_S_OBJ, T___NAME__, "string")); } } @@ -131,7 +131,7 @@ static Object setQualname(PGenerator self, TruffleString value) { @Specialization(guards = "!isNoValue(value)") static Object setQualname(PGenerator self, Object value, @Bind Node inliningTarget, - @Cached StringNodes.CastToTruffleStringCheckedNode cast) { + @Cached StringNodes.CastToTruffleStringChecked2Node cast) { return setQualname(self, cast.cast(inliningTarget, value, ErrorMessages.MUST_BE_SET_TO_S_OBJ, T___QUALNAME__, "string")); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java index dbc4c2b045..27d91080e3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/DescriptorBuiltins.java @@ -57,7 +57,7 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetIndexedSlotsCountNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode; import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; @@ -99,14 +99,14 @@ public abstract static class QualnameNode extends PythonUnaryBuiltinNode { static TruffleString doGetSetDescriptor(VirtualFrame frame, GetSetDescriptor self, @Shared @Cached("create(T___QUALNAME__)") GetFixedAttributeNode readQualNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { - return simpleTruffleStringFormatNode.format("%s.%s", toStr(readQualNameNode.executeObject(frame, self.getType())), self.getName()); + return simpleTruffleStringFormatNode.format("%s.%s", toStr(readQualNameNode.execute(frame, self.getType())), self.getName()); } @Specialization static TruffleString doIndexedSlotDescriptor(VirtualFrame frame, IndexedSlotDescriptor self, @Shared @Cached("create(T___QUALNAME__)") GetFixedAttributeNode readQualNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { - return simpleTruffleStringFormatNode.format("%s.%s", toStr(readQualNameNode.executeObject(frame, self.getType())), self.getName()); + return simpleTruffleStringFormatNode.format("%s.%s", toStr(readQualNameNode.execute(frame, self.getType())), self.getName()); } @TruffleBoundary diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java index 3555d429eb..7cb6408b4f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/getsetdescriptor/MemberDescriptorBuiltins.java @@ -63,7 +63,7 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.DescrGetBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.DescrSetBuiltinNode; import com.oracle.graal.python.nodes.BuiltinNames; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.runtime.object.PFactory; @@ -107,7 +107,7 @@ static TruffleString repr(GetSetDescriptor descr, abstract static class MemberDescriptorReduceNode extends PythonUnaryBuiltinNode { @Specialization Object doGeneric(GetSetDescriptor descr, - @Cached ReadAttributeFromObjectNode readAttributeFromObjectNode, + @Cached ReadAttributeFromModuleNode readAttributeFromObjectNode, @Cached GetIdNode getIdNode, @Bind PythonLanguage language) { Object getattr = readAttributeFromObjectNode.execute(getContext().getBuiltins(), BuiltinNames.T_GETATTR); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java index 9a7b27d146..6b150391bb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractBuiltinMethodBuiltins.java @@ -45,7 +45,7 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; 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.PythonUnaryBuiltinNode; @@ -92,14 +92,14 @@ Object getTextSignature(VirtualFrame frame, PMethod self, Object value) { public abstract static class MethodName extends PythonUnaryBuiltinNode { @Specialization static Object getName(VirtualFrame frame, PBuiltinMethod method, - @Shared @Cached("create(T___NAME__)") GetAttributeNode getNameAttrNode) { - return getNameAttrNode.executeObject(frame, method.getFunction()); + @Shared @Cached("create(T___NAME__)") GetFixedAttributeNode getNameAttrNode) { + return getNameAttrNode.execute(frame, method.getFunction()); } @Specialization static Object getName(VirtualFrame frame, PMethod method, - @Shared @Cached("create(T___NAME__)") GetAttributeNode getNameAttrNode) { - return getNameAttrNode.executeObject(frame, method.getFunction()); + @Shared @Cached("create(T___NAME__)") GetFixedAttributeNode getNameAttrNode) { + return getNameAttrNode.execute(frame, method.getFunction()); } } @@ -109,8 +109,8 @@ public abstract static class MethodQualName extends PythonUnaryBuiltinNode { @Specialization static TruffleString getQualName(VirtualFrame frame, PMethod method, @Bind Node inliningTarget, - @Shared @Cached("create(T___NAME__)") GetAttributeNode getNameAttrNode, - @Shared @Cached("create(T___QUALNAME__)") GetAttributeNode getQualNameAttrNode, + @Shared @Cached("create(T___NAME__)") GetFixedAttributeNode getNameAttrNode, + @Shared @Cached("create(T___QUALNAME__)") GetFixedAttributeNode getQualNameAttrNode, @Shared @Cached TypeNodes.IsTypeNode isTypeNode, @Shared @Cached CastToTruffleStringNode castToStringNode, @Shared @Cached InlinedConditionProfile isGlobalProfile, @@ -124,8 +124,8 @@ static TruffleString getQualName(VirtualFrame frame, PMethod method, @Specialization static TruffleString getQualName(VirtualFrame frame, PBuiltinMethod method, @Bind Node inliningTarget, - @Shared @Cached("create(T___NAME__)") GetAttributeNode getNameAttrNode, - @Shared @Cached("create(T___QUALNAME__)") GetAttributeNode getQualNameAttrNode, + @Shared @Cached("create(T___NAME__)") GetFixedAttributeNode getNameAttrNode, + @Shared @Cached("create(T___QUALNAME__)") GetFixedAttributeNode getQualNameAttrNode, @Shared @Cached TypeNodes.IsTypeNode isTypeNode, @Shared @Cached CastToTruffleStringNode castToStringNode, @Shared @Cached InlinedConditionProfile isGlobalProfile, @@ -136,12 +136,12 @@ static TruffleString getQualName(VirtualFrame frame, PBuiltinMethod method, simpleTruffleStringFormatNode, raiseNode); } - private static TruffleString makeQualname(VirtualFrame frame, Node inliningTarget, Object method, Object self, GetAttributeNode getQualNameAttrNode, GetAttributeNode getNameAttrNode, + private static TruffleString makeQualname(VirtualFrame frame, Node inliningTarget, Object method, Object self, GetFixedAttributeNode getQualNameAttrNode, GetFixedAttributeNode getNameAttrNode, CastToTruffleStringNode castToStringNode, GetClassNode getClassNode, TypeNodes.IsTypeNode isTypeNode, InlinedConditionProfile isGlobalProfile, SimpleTruffleStringFormatNode simpleTruffleStringFormatNode, PRaiseNode raiseNode) { TruffleString methodName; try { - methodName = castToStringNode.execute(inliningTarget, getNameAttrNode.executeObject(frame, method)); + methodName = castToStringNode.execute(inliningTarget, getNameAttrNode.execute(frame, method)); } catch (CannotCastException e) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___NAME__); } @@ -152,7 +152,7 @@ private static TruffleString makeQualname(VirtualFrame frame, Node inliningTarge Object type = isTypeNode.execute(inliningTarget, self) ? self : getClassNode.execute(inliningTarget, self); TruffleString typeQualName; try { - typeQualName = castToStringNode.execute(inliningTarget, getQualNameAttrNode.executeObject(frame, type)); + typeQualName = castToStringNode.execute(inliningTarget, getQualNameAttrNode.execute(frame, type)); } catch (CannotCastException e) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.IS_NOT_A_UNICODE_OBJECT, T___QUALNAME__); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java index 77cc55d972..20856fed8e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/AbstractMethodBuiltins.java @@ -67,7 +67,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromPythonObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode; import com.oracle.graal.python.nodes.call.CallDispatchers; @@ -256,8 +256,8 @@ static Object getModule(PBuiltinMethod self, Object value, @Specialization(guards = "isNoValue(value)") static Object getModule(VirtualFrame frame, PMethod self, @SuppressWarnings("unused") Object value, - @Cached("create(T___MODULE__)") GetAttributeNode getAttributeNode) { - return getAttributeNode.executeObject(frame, self.getFunction()); + @Cached("create(T___MODULE__)") GetFixedAttributeNode getAttributeNode) { + return getAttributeNode.execute(frame, self.getFunction()); } @Specialization(guards = "!isNoValue(value)") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java index 58ffd303c0..2092ed25ef 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinFunctionOrMethodBuiltins.java @@ -64,7 +64,7 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.builtins.FunctionNodes.GetSignatureNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; @@ -104,28 +104,28 @@ static boolean isBuiltinFunction(PMethod self) { @Specialization(guards = "isBuiltinFunction(self)") static TruffleString reprBuiltinFunction(VirtualFrame frame, PMethod self, - @Shared @Cached("createGetAttributeNode()") GetAttributeNode getNameNode, + @Shared @Cached("createGetAttributeNode()") GetFixedAttributeNode getNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { // (tfel): this only happens for builtin modules ... I think - return simpleTruffleStringFormatNode.format("", getNameNode.executeObject(frame, self.getFunction())); + return simpleTruffleStringFormatNode.format("", getNameNode.execute(frame, self.getFunction())); } @Specialization(guards = "isBuiltinFunction(self)") static TruffleString reprBuiltinFunction(VirtualFrame frame, PBuiltinMethod self, - @Shared @Cached("createGetAttributeNode()") GetAttributeNode getNameNode, + @Shared @Cached("createGetAttributeNode()") GetFixedAttributeNode getNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { - return simpleTruffleStringFormatNode.format("", getNameNode.executeObject(frame, self.getFunction())); + return simpleTruffleStringFormatNode.format("", getNameNode.execute(frame, self.getFunction())); } @Specialization(guards = "!isBuiltinFunction(self)") static TruffleString reprBuiltinMethod(VirtualFrame frame, PBuiltinMethod self, @Bind Node inliningTarget, @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("createGetAttributeNode()") GetAttributeNode getNameNode, + @Shared @Cached("createGetAttributeNode()") GetFixedAttributeNode getNameNode, @Shared @Cached GetNameNode getTypeNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { TruffleString typeName = getTypeNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self.getSelf())); - return simpleTruffleStringFormatNode.format("", getNameNode.executeObject(frame, self.getFunction()), typeName, + return simpleTruffleStringFormatNode.format("", getNameNode.execute(frame, self.getFunction()), typeName, PythonAbstractObject.systemHashCodeAsHexString(self.getSelf())); } @@ -133,17 +133,17 @@ static TruffleString reprBuiltinMethod(VirtualFrame frame, PBuiltinMethod self, static TruffleString reprBuiltinMethod(VirtualFrame frame, PMethod self, @Bind Node inliningTarget, @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("createGetAttributeNode()") GetAttributeNode getNameNode, + @Shared @Cached("createGetAttributeNode()") GetFixedAttributeNode getNameNode, @Shared @Cached GetNameNode getTypeNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { TruffleString typeName = getTypeNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self.getSelf())); - return simpleTruffleStringFormatNode.format("", getNameNode.executeObject(frame, self.getFunction()), typeName, + return simpleTruffleStringFormatNode.format("", getNameNode.execute(frame, self.getFunction()), typeName, PythonAbstractObject.systemHashCodeAsHexString(self.getSelf())); } @NeverDefault - protected static GetAttributeNode createGetAttributeNode() { - return GetAttributeNode.create(T___NAME__); + protected static GetFixedAttributeNode createGetAttributeNode() { + return GetFixedAttributeNode.create(T___NAME__); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java index 9617daf677..bcdb1de472 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodWrapperBuiltins.java @@ -55,7 +55,7 @@ import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; @@ -96,11 +96,11 @@ abstract static class ReprNode extends PythonUnaryBuiltinNode { static TruffleString reprBuiltinMethod(VirtualFrame frame, PBuiltinMethod self, @Bind Node inliningTarget, @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("createGetAttributeNode()") GetAttributeNode getNameNode, + @Shared @Cached("createGetAttributeNode()") GetFixedAttributeNode getNameNode, @Shared @Cached GetNameNode getTypeNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { TruffleString typeName = getTypeNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self.getSelf())); - return simpleTruffleStringFormatNode.format("", getNameNode.executeObject(frame, self.getFunction()), typeName, + return simpleTruffleStringFormatNode.format("", getNameNode.execute(frame, self.getFunction()), typeName, PythonAbstractObject.systemHashCodeAsHexString(self.getSelf())); } @@ -108,17 +108,17 @@ static TruffleString reprBuiltinMethod(VirtualFrame frame, PBuiltinMethod self, static TruffleString reprBuiltinMethod(VirtualFrame frame, PMethod self, @Bind Node inliningTarget, @Shared @Cached GetClassNode getClassNode, - @Shared @Cached("createGetAttributeNode()") GetAttributeNode getNameNode, + @Shared @Cached("createGetAttributeNode()") GetFixedAttributeNode getNameNode, @Shared @Cached GetNameNode getTypeNameNode, @Shared("formatter") @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { TruffleString typeName = getTypeNameNode.execute(inliningTarget, getClassNode.execute(inliningTarget, self.getSelf())); - return simpleTruffleStringFormatNode.format("", getNameNode.executeObject(frame, self.getFunction()), typeName, + return simpleTruffleStringFormatNode.format("", getNameNode.execute(frame, self.getFunction()), typeName, PythonAbstractObject.systemHashCodeAsHexString(self.getSelf())); } @NeverDefault - protected static GetAttributeNode createGetAttributeNode() { - return GetAttributeNode.create(T___NAME__); + protected static GetFixedAttributeNode createGetAttributeNode() { + return GetFixedAttributeNode.create(T___NAME__); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java index f18b46b6e7..634d012365 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleBuiltins.java @@ -75,7 +75,7 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.module.ModuleBuiltinsClinicProviders.ModuleNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode; @@ -86,6 +86,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes; @@ -98,8 +99,6 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; -import com.oracle.graal.python.nodes.object.SetDictNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; @@ -111,6 +110,7 @@ import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; @@ -139,8 +139,7 @@ public abstract static class ModuleNewNode extends PythonBuiltinNode { @Specialization @SuppressWarnings("unused") - static Object doGeneric(Object cls, Object[] varargs, PKeyword[] kwargs, - @Bind Node inliningTarget, + static PythonModule doGeneric(Object cls, Object[] varargs, PKeyword[] kwargs, @Bind PythonLanguage language, @Cached TypeNodes.GetInstanceShape getInstanceShape) { return PFactory.createPythonModule(language, cls, getInstanceShape.execute(cls)); @@ -159,15 +158,12 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization public PNone module(PythonModule self, TruffleString name, Object doc, - @Bind Node inliningTarget, @Cached WriteAttributeToObjectNode writeName, @Cached WriteAttributeToObjectNode writeDoc, @Cached WriteAttributeToObjectNode writePackage, @Cached WriteAttributeToObjectNode writeLoader, - @Cached WriteAttributeToObjectNode writeSpec, - @Cached GetOrCreateDictNode getDict) { - // create dict if missing - getDict.execute(inliningTarget, self); + @Cached WriteAttributeToObjectNode writeSpec) { + assert GetDictIfExistsNode.getUncached().execute(self) != null : "PythonModule always have a dict"; // init writeName.execute(self, T___NAME__, name); @@ -214,19 +210,14 @@ public abstract static class ModuleDictNode extends PythonBinaryBuiltinNode { @Specialization(guards = "isNoValue(none)") static Object doManaged(PythonModule self, @SuppressWarnings("unused") PNone none, - @Bind Node inliningTarget, - @Exclusive @Cached GetDictIfExistsNode getDict, - @Cached SetDictNode setDict) { + @Exclusive @Cached GetDictIfExistsNode getDict) { PDict dict = getDict.execute(self); - if (dict == null) { - dict = createDict(inliningTarget, self, setDict); - } + assert dict != null : "PythonModule always have a dict"; return dict; } @Specialization(guards = "isNoValue(none)") static Object doNativeObject(PythonAbstractNativeObject self, @SuppressWarnings("unused") PNone none, - @Bind Node inliningTarget, @Exclusive @Cached GetDictIfExistsNode getDict, @Cached PRaiseNode raiseNode) { PDict dict = getDict.execute(self); @@ -241,91 +232,96 @@ static Object doError(Object self, @SuppressWarnings("unused") Object dict, @Bind Node inliningTarget) { throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.DESCRIPTOR_DICT_FOR_MOD_OBJ_DOES_NOT_APPLY_FOR_P, self); } - - private static PDict createDict(Node inliningTarget, PythonModule self, SetDictNode setDict) { - PDict dict = PFactory.createDictFixedStorage(PythonLanguage.get(inliningTarget), self); - setDict.execute(inliningTarget, self, dict); - return dict; - } } @Slot(value = SlotKind.tp_getattro, isComplex = true) @GenerateNodeFactory public abstract static class ModuleGetattributeNode extends GetAttrBuiltinNode { @Specialization - static Object getattributeStr(VirtualFrame frame, PythonModule self, TruffleString key, - @Shared @Cached ObjectBuiltins.GetAttributeNode objectGetattrNode, - @Shared @Cached HandleGetattrExceptionNode handleException) { + static Object getattribute(VirtualFrame frame, PythonModule self, Object keyObj, + @Bind Node inliningTarget, + @Cached CastToTruffleStringChecked1Node castToString, + @Cached ObjectBuiltins.GetAttributeNode objectGetattrNode, + @Cached LazyHandleGetattrExceptionNode handleException) { + TruffleString key = castToString.cast(inliningTarget, keyObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); try { return objectGetattrNode.execute(frame, self, key); } catch (PException e) { - return handleException.execute(frame, self, key, e); + return handleException.get(inliningTarget).execute(frame, self, key, e); } } - @Specialization(replaces = "getattributeStr") + @Specialization(guards = "!isPythonModule(self)") + static Object getattribute(Object self, @SuppressWarnings("unused") Object key, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETATTRIBUTE__, "module", self); + } + } + + // Note: this is similar to the "use __getattribute__, if error fallback to __getattr__" + // dance that is normally done in the slot wrapper of __getattribute__/__getattr__ Python + // level methods. This case is, however, slightly different. + @GenerateInline(false) + public abstract static class HandleGetattrExceptionNode extends PNodeWithContext { @InliningCutoff - static Object getattribute(VirtualFrame frame, PythonModule self, Object keyObj, - @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castKeyToStringNode, - @Shared @Cached ObjectBuiltins.GetAttributeNode objectGetattrNode, - @Shared @Cached HandleGetattrExceptionNode handleException) { - TruffleString key = castKeyToStringNode.cast(inliningTarget, keyObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); - try { - return objectGetattrNode.execute(frame, self, key); - } catch (PException e) { - return handleException.execute(frame, self, key, e); - } + public final Object execute(VirtualFrame frame, PythonModule self, TruffleString key, PException e) { + return executeInternal(frame, self, key, e); } - // Note: this is similar to the "use __getattribute__, if error fallback to __getattr__" - // dance that is normally done in the slot wrapper of __getattribute__/__getattr__ Python - // level methods. This case is, however, slightly different. - @GenerateInline(false) // footprint reduction 56 -> 37 - protected abstract static class HandleGetattrExceptionNode extends PNodeWithContext { - public abstract Object execute(VirtualFrame frame, PythonModule self, TruffleString key, PException e); + abstract Object executeInternal(VirtualFrame frame, PythonModule self, TruffleString key, PException e); - @Specialization - static Object getattribute(VirtualFrame frame, PythonModule self, TruffleString key, PException e, - @Bind Node inliningTarget, - @Cached IsBuiltinObjectProfile isAttrError, - @Cached ReadAttributeFromObjectNode readGetattr, - @Cached InlinedConditionProfile customGetAttr, - @Cached CallNode callNode, - @Cached PyObjectIsTrueNode castToBooleanNode, - @Cached CastToTruffleStringNode castNameToStringNode, - @Cached PRaiseNode raiseNode) { - e.expect(inliningTarget, PythonBuiltinClassType.AttributeError, isAttrError); - Object getAttr = readGetattr.execute(self, T___GETATTR__); - if (customGetAttr.profile(inliningTarget, getAttr != PNone.NO_VALUE)) { - return callNode.execute(frame, getAttr, key); - } else { - TruffleString moduleName; - try { - moduleName = castNameToStringNode.execute(inliningTarget, readGetattr.execute(self, T___NAME__)); - } catch (CannotCastException ce) { - // we just don't have the module name - moduleName = null; - } - if (moduleName != null) { - Object moduleSpec = readGetattr.execute(self, T___SPEC__); - if (moduleSpec != PNone.NO_VALUE) { - Object isInitializing = readGetattr.execute(moduleSpec, T__INITIALIZING); - if (isInitializing != PNone.NO_VALUE && castToBooleanNode.execute(frame, isInitializing)) { - throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_PARTIALLY_INITIALIZED_S_HAS_NO_ATTR_S, moduleName, key); - } + @Specialization + static Object getattribute(VirtualFrame frame, PythonModule self, TruffleString key, PException e, + @Bind Node inliningTarget, + @Cached IsBuiltinObjectProfile isAttrError, + @Cached ReadAttributeFromModuleNode readGetattr, + @Cached ReadAttributeFromObjectNode readInitializing, + @Cached InlinedConditionProfile customGetAttr, + @Cached CallNode callNode, + @Cached PyObjectIsTrueNode castToBooleanNode, + @Cached CastToTruffleStringNode castNameToStringNode, + @Cached PRaiseNode raiseNode) { + e.expect(inliningTarget, PythonBuiltinClassType.AttributeError, isAttrError); + Object getAttr = readGetattr.execute(self, T___GETATTR__); + if (customGetAttr.profile(inliningTarget, getAttr != PNone.NO_VALUE)) { + return callNode.execute(frame, getAttr, key); + } else { + TruffleString moduleName; + try { + moduleName = castNameToStringNode.execute(inliningTarget, readGetattr.execute(self, T___NAME__)); + } catch (CannotCastException ce) { + // we just don't have the module name + moduleName = null; + } + if (moduleName != null) { + Object moduleSpec = readGetattr.execute(self, T___SPEC__); + if (moduleSpec != PNone.NO_VALUE) { + Object isInitializing = readInitializing.execute(moduleSpec, T__INITIALIZING); + if (isInitializing != PNone.NO_VALUE && castToBooleanNode.execute(frame, isInitializing)) { + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_PARTIALLY_INITIALIZED_S_HAS_NO_ATTR_S, moduleName, key); } - throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_S_HAS_NO_ATTR_S, moduleName, key); } - throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_HAS_NO_ATTR_S, key); + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_S_HAS_NO_ATTR_S, moduleName, key); } + throw raiseNode.raise(inliningTarget, AttributeError, ErrorMessages.MODULE_HAS_NO_ATTR_S, key); } } + } - @Specialization(guards = "!isPythonModule(self)") - static Object getattribute(Object self, @SuppressWarnings("unused") Object key, - @Bind Node inliningTarget) { - throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETATTRIBUTE__, "module", self); + // GR-67751: Should be HandleGetattrExceptionNode.Lazy but that fails to compile + @GenerateInline + @GenerateCached(false) + public abstract static class LazyHandleGetattrExceptionNode extends Node { + + public final HandleGetattrExceptionNode get(Node inliningTarget) { + return execute(inliningTarget); + } + + abstract HandleGetattrExceptionNode execute(Node inliningTarget); + + @Specialization + static HandleGetattrExceptionNode doIt(@Cached(inline = false) HandleGetattrExceptionNode node) { + return node; } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java index 88118ab53b..ec50558e10 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/ModuleGetNameNode.java @@ -44,7 +44,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.truffle.api.dsl.Cached; @@ -67,7 +67,7 @@ public abstract class ModuleGetNameNode extends Node { @Specialization static TruffleString doPythonModule(Node inliningTarget, PythonModule module, - @Cached(inline = false) ReadAttributeFromObjectNode readNameNode, + @Cached ReadAttributeFromModuleNode readNameNode, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached PRaiseNode raiseNode) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java index ba26300675..1eff04dab1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/module/PythonModule.java @@ -37,11 +37,9 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.nodes.PGuards; -import com.oracle.graal.python.nodes.object.SetDictNode; -import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; @@ -78,6 +76,7 @@ public final class PythonModule extends PythonObject { private PythonBuiltins builtins; private Object moduleState; + @TruffleBoundary public PythonModule(Object clazz, Shape instanceShape) { super(clazz, instanceShape); setAttribute(T___NAME__, PNone.NO_VALUE); @@ -87,6 +86,7 @@ public PythonModule(Object clazz, Shape instanceShape) { setAttribute(T___SPEC__, PNone.NO_VALUE); setAttribute(T___CACHED__, PNone.NO_VALUE); setAttribute(T___FILE__, PNone.NO_VALUE); + GetOrCreateDictNode.executeUncached(this); } /** @@ -102,6 +102,7 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) { setAttribute(T___SPEC__, PNone.NONE); setAttribute(T___CACHED__, PNone.NO_VALUE); setAttribute(T___FILE__, PNone.NO_VALUE); + GetOrCreateDictNode.executeUncached(this); } /** @@ -110,10 +111,7 @@ private PythonModule(PythonLanguage lang, TruffleString moduleName) { @TruffleBoundary public static PythonModule createInternal(TruffleString moduleName) { PythonLanguage language = PythonLanguage.get(null); - PythonModule pythonModule = new PythonModule(language, moduleName); - PDict dict = PFactory.createDictFixedStorage(language, pythonModule); - SetDictNode.executeUncached(pythonModule, dict); - return pythonModule; + return new PythonModule(language, moduleName); } public PythonBuiltins getBuiltins() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java index 188e318f49..ff400146e8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectBuiltins.java @@ -26,8 +26,10 @@ package com.oracle.graal.python.builtins.objects.object; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_NEW; import static com.oracle.graal.python.nodes.BuiltinNames.J_OBJECT; +import static com.oracle.graal.python.nodes.ErrorMessages.ATTR_NAME_MUST_BE_STRING; import static com.oracle.graal.python.nodes.PGuards.isDeleteMarker; import static com.oracle.graal.python.nodes.PGuards.isDict; import static com.oracle.graal.python.nodes.PGuards.isNoValue; @@ -52,9 +54,6 @@ import static com.oracle.graal.python.nodes.SpecialMethodNames.T___REDUCE__; import static com.oracle.graal.python.nodes.StringLiterals.T_NONE; import static com.oracle.graal.python.nodes.StringLiterals.T_SINGLE_QUOTE_COMMA_SPACE; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.AttributeError; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import java.util.List; @@ -89,11 +88,15 @@ import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory.GetAttributeNodeFactory; import com.oracle.graal.python.builtins.objects.set.PSet; import com.oracle.graal.python.builtins.objects.set.SetBuiltins; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; +import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; import com.oracle.graal.python.builtins.objects.type.TypeFlags; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode; @@ -113,11 +116,11 @@ import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.HiddenAttr; 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.attributes.LookupAttributeInMRONode; +import com.oracle.graal.python.nodes.attributes.MergedObjectTypeModuleGetAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes; @@ -140,15 +143,13 @@ import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; import com.oracle.graal.python.nodes.object.IsNode; import com.oracle.graal.python.nodes.object.SetDictNode; -import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext; import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.object.PFactory; -import com.oracle.truffle.api.CompilerAsserts; 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.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; @@ -159,13 +160,14 @@ import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateNodeFactory; -import com.oracle.truffle.api.dsl.Idempotent; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.object.DynamicObjectLibrary; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; @@ -223,9 +225,12 @@ abstract static class SetClassNode extends Node { public abstract void execute(Node inliningTarget, Object self, Object newClass); @Specialization - static void doPythonObject(Node inliningTarget, PythonObject self, Object newClass, - @Cached HiddenAttr.WriteNode writeHiddenAttrNode) { - writeHiddenAttrNode.execute(inliningTarget, self, HiddenAttr.CLASS, newClass); + static void doPythonObject(PythonObject self, Object newClass, + @CachedLibrary(limit = "3") DynamicObjectLibrary dylib) { + // Clear the dynamic type when setting the class, so further class changes do not + // create new shapes + dylib.setDynamicType(self, PNone.NO_VALUE); + self.setPythonClass(newClass); } @Specialization @@ -502,94 +507,64 @@ static TruffleString repr(VirtualFrame frame, Object self, @Slot(value = SlotKind.tp_getattro, isComplex = true) @GenerateNodeFactory public abstract static class GetAttributeNode extends GetAttrBuiltinNode { - @CompilationFinal private int profileFlags = 0; - private static final int HAS_DESCR = 1; - private static final int HAS_VALUE = 2; - private static final int HAS_NO_VALUE = 4; - @Child private CallSlotDescrGet callSlotDescrGet; @Child private ReadAttributeFromObjectNode attrRead; - @Idempotent - protected static int tsLen(TruffleString ts) { - CompilerAsserts.neverPartOfCompilation(); - return TruffleString.CodePointLengthNode.getUncached().execute(ts, TS_ENCODING) + 1; - } - - // Shortcut, only useful for interpreter performance, but doesn't hurt peak - @Specialization(guards = {"keyObj == cachedKey", "tsLen(cachedKey) < 32"}, limit = "1") - @SuppressWarnings("truffle-static-method") - Object doItTruffleString(VirtualFrame frame, Object object, @SuppressWarnings("unused") TruffleString keyObj, - @Bind Node inliningTarget, - @SuppressWarnings("unused") @Cached("keyObj") TruffleString cachedKey, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached GetObjectSlotsNode getSlotsNode, - @Cached("create(cachedKey)") LookupAttributeInMRONode lookup, - @Exclusive @Cached PRaiseNode raiseNode) { - Object type = getClassNode.execute(inliningTarget, object); - Object descr = lookup.execute(type); - return fullLookup(frame, inliningTarget, object, cachedKey, type, descr, getSlotsNode, raiseNode); - } - + /** + * Keep in sync with {@link TypeBuiltins.GetattributeNode} and + * {@link ThreadLocalBuiltins.GetAttributeNode} and + * {@link MergedObjectTypeModuleGetAttributeNode} + */ @Specialization @SuppressWarnings("truffle-static-method") Object doIt(VirtualFrame frame, Object object, Object keyObj, @Bind Node inliningTarget, + @Cached GetClassNode getClassNode, + @Cached GetObjectSlotsNode getDescrSlotsNode, @Cached LookupAttributeInMRONode.Dynamic lookup, - @Exclusive @Cached GetClassNode getClassNode, - @Exclusive @Cached GetObjectSlotsNode getSlotsNode, - @Cached CastToTruffleStringNode castKeyToStringNode, - @Exclusive @Cached PRaiseNode raiseNode) { - TruffleString key; - try { - key = castKeyToStringNode.execute(inliningTarget, keyObj); - } catch (CannotCastException e) { - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); - } + @Cached CastToTruffleStringChecked1Node castToString, + @Cached InlinedBranchProfile hasDescProfile, + @Cached InlinedConditionProfile hasDescrGetProfile, + @Cached InlinedBranchProfile hasValueProfile, + @Cached PRaiseNode raiseNode) { + TruffleString key = castToString.cast(inliningTarget, keyObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); Object type = getClassNode.execute(inliningTarget, object); Object descr = lookup.execute(type, key); - return fullLookup(frame, inliningTarget, object, key, type, descr, getSlotsNode, raiseNode); - } - - private Object fullLookup(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, Object type, Object descr, GetObjectSlotsNode getSlotsNode, PRaiseNode raiseNode) { boolean hasDescr = descr != PNone.NO_VALUE; - if (hasDescr && (profileFlags & HAS_DESCR) == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - profileFlags |= HAS_DESCR; - } - TpSlot descrGetSlot = null; + + TpSlot get = null; + boolean hasDescrGet = false; if (hasDescr) { - var descrSlots = getSlotsNode.execute(inliningTarget, descr); - descrGetSlot = descrSlots.tp_descr_get(); - if (descrGetSlot != null && TpSlotDescrSet.PyDescr_IsData(descrSlots)) { - return dispatch(frame, object, type, descr, descrGetSlot); + hasDescProfile.enter(inliningTarget); + var descrSlots = getDescrSlotsNode.execute(inliningTarget, descr); + get = descrSlots.tp_descr_get(); + hasDescrGet = hasDescrGetProfile.profile(inliningTarget, get != null); + if (hasDescrGet && TpSlotDescrSet.PyDescr_IsData(descrSlots)) { + return dispatchDescrGet(frame, object, type, descr, get); } } - Object value = readAttribute(object, key); - boolean hasValue = value != PNone.NO_VALUE; - if (hasValue && (profileFlags & HAS_VALUE) == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - profileFlags |= HAS_VALUE; - } - if (hasValue) { + + // The only difference between all 3 nodes + Object value = readAttributeOfObject(object, key); + if (value != PNone.NO_VALUE) { + hasValueProfile.enter(inliningTarget); return value; } - if ((profileFlags & HAS_NO_VALUE) == 0) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - profileFlags |= HAS_NO_VALUE; - } + if (hasDescr) { - if (descrGetSlot == null) { + hasDescProfile.enter(inliningTarget); + if (!hasDescrGet) { return descr; } else { - return dispatch(frame, object, type, descr, descrGetSlot); + return dispatchDescrGet(frame, object, type, descr, get); } } - throw raiseNode.raiseAttributeError(inliningTarget, object, key); + + throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } - private Object readAttribute(Object object, TruffleString key) { + private Object readAttributeOfObject(Object object, TruffleString key) { if (attrRead == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); attrRead = insert(ReadAttributeFromObjectNode.create()); @@ -597,7 +572,7 @@ private Object readAttribute(Object object, TruffleString key) { return attrRead.execute(object, key); } - private Object dispatch(VirtualFrame frame, Object object, Object type, Object descr, TpSlot getSlot) { + private Object dispatchDescrGet(VirtualFrame frame, Object object, Object type, Object descr, TpSlot getSlot) { if (callSlotDescrGet == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); callSlotDescrGet = insert(CallSlotDescrGet.create()); @@ -616,19 +591,12 @@ public static GetAttributeNode create() { @GenerateNodeFactory public abstract static class SetattrNode extends SetAttrBuiltinNode { @Specialization - void setString(VirtualFrame frame, Object object, TruffleString key, Object value, - @Bind Node inliningTarget, - @Shared @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, - @Shared @Cached WriteAttributeToObjectNode write) { - genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); - } - - @Specialization - @InliningCutoff - void setGeneric(VirtualFrame frame, Object object, Object key, Object value, + void set(VirtualFrame frame, Object object, Object keyObject, Object value, @Bind Node inliningTarget, - @Shared @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, - @Shared @Cached WriteAttributeToObjectNode write) { + @Cached CastToTruffleStringChecked0Node castKeyNode, + @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, + @Cached WriteAttributeToObjectNode write) { + TruffleString key = castKeyNode.cast(inliningTarget, keyObject, ATTR_NAME_MUST_BE_STRING); genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); } @@ -749,7 +717,7 @@ static Object raise(Object self, Object mapping, @Exclusive @Cached IsOtherBuiltinClassProfile otherBuiltinClassProfile, @Exclusive @Cached IsBuiltinClassExactProfile isBuiltinClassProfile, @Exclusive @Cached GetClassNode getClassNode) { - throw PRaiseNode.raiseStatic(inliningTarget, AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, "__dict__"); + throw PRaiseNode.raiseStatic(inliningTarget, PythonErrorType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, self, "__dict__"); } static boolean isFallback(Object self, Object mapping, Node inliningTarget, @@ -907,7 +875,7 @@ static Object dir(VirtualFrame frame, Object obj, if (klass != PNone.NO_VALUE) { Object state = IndirectCallContext.enter(frame, inliningTarget, indirectCallData); try { - com.oracle.graal.python.builtins.objects.type.TypeBuiltins.DirNode.dir(names, klass); + TypeBuiltins.DirNode.dir(names, klass); } finally { IndirectCallContext.exit(frame, inliningTarget, indirectCallData, state); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java index 1ac1e4da16..a8881ac04e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/ObjectNodes.java @@ -43,7 +43,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_CHECK_BASICSIZE_FOR_GETSTATE; import static com.oracle.graal.python.nodes.BuiltinNames.T_COPYREG; -import static com.oracle.graal.python.nodes.ErrorMessages.ATTR_NAME_MUST_BE_STRING; import static com.oracle.graal.python.nodes.ErrorMessages.CANNOT_PICKLE_OBJECT_TYPE; import static com.oracle.graal.python.nodes.ErrorMessages.MUST_BE_TYPE_A_NOT_TYPE_B; import static com.oracle.graal.python.nodes.ErrorMessages.SHOULD_RETURN_A_NOT_B; @@ -137,7 +136,6 @@ import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsAnyBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.object.IsForeignObjectNode; -import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; @@ -518,7 +516,7 @@ public abstract static class GetSlotNamesNode extends Node { @Specialization static Object[] getstate(VirtualFrame frame, Node inliningTarget, Object type, - @Cached(value = "createForceType()", inline = false) ReadAttributeFromObjectNode read, + @Cached ReadAttributeFromObjectNode read, @Cached SequenceStorageNodes.ToArrayNode toArrayNode, @Cached PyImportImport importNode, @Cached PyObjectCallMethodObjArgs callMethod, @@ -839,56 +837,16 @@ public abstract static class GenericSetAttrNode extends Node { */ public abstract void execute(Node inliningTarget, VirtualFrame frame, Object object, TruffleString key, Object value, WriteAttributeToObjectNode writeNode); - public abstract void execute(Node inliningTarget, VirtualFrame frame, Object object, Object key, Object value, WriteAttributeToObjectNode writeNode); - - @Specialization - static void doStringKey(Node inliningTarget, VirtualFrame frame, Object object, TruffleString key, Object value, WriteAttributeToObjectNode writeNode, - @SuppressWarnings("unused") @Shared @Cached CastToTruffleStringNode castKeyToStringNode, - @Shared @Cached GetClassNode getClassNode, - @Shared @Cached InlinedConditionProfile hasDescriptor, - @Shared @Cached GetObjectSlotsNode getDescrSlotsNode, - @Shared @Cached CallSlotDescrSet callSetNode, - @Shared @Cached(inline = false) LookupAttributeInMRONode.Dynamic getExisting, - @Shared @Cached(inline = false) ReadAttributeFromObjectNode attrRead, - @Shared @Cached InlinedBranchProfile deleteNonExistingBranchProfile, - @Shared @Cached PRaiseNode raiseNode) { - setAttr(inliningTarget, frame, object, key, value, writeNode, getClassNode, hasDescriptor, - getDescrSlotsNode, callSetNode, getExisting, attrRead, deleteNonExistingBranchProfile, - raiseNode); - } - @Specialization - @InliningCutoff - static void doGeneric(Node inliningTarget, VirtualFrame frame, Object object, Object keyObject, Object value, WriteAttributeToObjectNode writeNode, - @Shared @Cached CastToTruffleStringNode castKeyToStringNode, - @Shared @Cached GetClassNode getClassNode, - @Shared @Cached InlinedConditionProfile hasDescriptor, - @Shared @Cached GetObjectSlotsNode getDescrSlotsNode, - @Shared @Cached CallSlotDescrSet callSetNode, - @Shared @Cached(inline = false) LookupAttributeInMRONode.Dynamic getExisting, - @Shared @Cached(inline = false) ReadAttributeFromObjectNode attrRead, - @Shared @Cached InlinedBranchProfile deleteNonExistingBranchProfile, - @Shared @Cached PRaiseNode raiseNode) { - TruffleString key = castAttributeKey(inliningTarget, keyObject, castKeyToStringNode, raiseNode); - setAttr(inliningTarget, frame, object, key, value, writeNode, getClassNode, hasDescriptor, - getDescrSlotsNode, callSetNode, getExisting, attrRead, deleteNonExistingBranchProfile, - raiseNode); - } - - public static TruffleString castAttributeKey(Node inliningTarget, Object keyObject, CastToTruffleStringNode castKeyToStringNode, PRaiseNode raiseNode) { - try { - return castKeyToStringNode.execute(inliningTarget, keyObject); - } catch (CannotCastException e) { - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ATTR_NAME_MUST_BE_STRING, keyObject); - } - } - - private static void setAttr(Node inliningTarget, VirtualFrame frame, Object object, TruffleString key, - Object value, WriteAttributeToObjectNode writeNode, GetClassNode getClassNode, - InlinedConditionProfile hasDescriptor, GetObjectSlotsNode getDescrSlotsNode, - CallSlotDescrSet callSetNode, LookupAttributeInMRONode.Dynamic getExisting, - ReadAttributeFromObjectNode attrRead, InlinedBranchProfile deleteNonExistingBranchProfile, - PRaiseNode raiseNode) { + static void doGeneric(Node inliningTarget, VirtualFrame frame, Object object, TruffleString key, Object value, WriteAttributeToObjectNode writeNode, + @Cached GetClassNode getClassNode, + @Cached InlinedConditionProfile hasDescriptor, + @Cached GetObjectSlotsNode getDescrSlotsNode, + @Cached CallSlotDescrSet callSetNode, + @Cached(inline = false) LookupAttributeInMRONode.Dynamic getExisting, + @Cached ReadAttributeFromObjectNode attrRead, + @Cached InlinedBranchProfile deleteNonExistingBranchProfile, + @Cached PRaiseNode raiseNode) { Object type = getClassNode.execute(inliningTarget, object); Object descr = getExisting.execute(type, key); if (hasDescriptor.profile(inliningTarget, !PGuards.isNoValue(descr))) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java index b2366ab49d..30a2d88dd3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java @@ -33,10 +33,9 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.runtime.PythonOptions; @@ -49,49 +48,34 @@ import com.oracle.truffle.api.strings.TruffleString; public class PythonObject extends PythonAbstractObject { - public static final byte CLASS_CHANGED_FLAG = 0b1; /** * Indicates that the object doesn't allow {@code __dict__}, but may have slots */ - public static final byte HAS_SLOTS_BUT_NO_DICT_FLAG = 0b10; + public static final byte HAS_SLOTS_BUT_NO_DICT_FLAG = 0b1; /** * Indicates that the shape has some properties that may contain {@link PNone#NO_VALUE} and * therefore the shape itself is not enough to resolve any lookups. */ - public static final byte HAS_NO_VALUE_PROPERTIES = 0b100; + public static final byte HAS_NO_VALUE_PROPERTIES = 0b10; /** * Indicates that the object has a dict in the form of an actual dictionary */ - public static final byte HAS_MATERIALIZED_DICT = 0b1000; + public static final byte HAS_MATERIALIZED_DICT = 0b100; /** * Indicates that the object is a static base in the CPython's tp_new_wrapper sense. * * @see com.oracle.graal.python.nodes.function.builtins.WrapTpNew */ - public static final byte IS_STATIC_BASE = 0b10000; + public static final byte IS_STATIC_BASE = 0b1000; - private final Object initialPythonClass; + private Object pythonClass; @SuppressWarnings("this-escape") // escapes in the assertion public PythonObject(Object pythonClass, Shape instanceShape) { super(instanceShape); assert pythonClass != null; - assert consistentStorage(pythonClass); - this.initialPythonClass = pythonClass; - } - - private boolean consistentStorage(Object pythonClass) { - Object constantClass = HiddenAttr.ReadNode.executeUncached(this, HiddenAttr.CLASS, null); - if (constantClass == null) { - return true; - } - if (constantClass instanceof PythonBuiltinClass) { - constantClass = ((PythonBuiltinClass) constantClass).getType(); - } - if (constantClass instanceof PythonAbstractNativeObject && pythonClass instanceof PythonAbstractNativeObject) { - return true; - } - return constantClass == (pythonClass instanceof PythonBuiltinClass ? ((PythonBuiltinClass) pythonClass).getType() : pythonClass); + assert !PGuards.isPythonClass(getShape().getDynamicType()) || IsSameTypeNode.executeUncached(getShape().getDynamicType(), pythonClass) : getShape().getDynamicType() + " vs " + pythonClass; + this.pythonClass = pythonClass; } public void setDict(Node inliningTarget, HiddenAttr.WriteNode writeNode, PDict dict) { @@ -99,8 +83,13 @@ public void setDict(Node inliningTarget, HiddenAttr.WriteNode writeNode, PDict d } @NeverDefault - public Object getInitialPythonClass() { - return initialPythonClass; + public Object getPythonClass() { + return pythonClass; + } + + public void setPythonClass(Object pythonClass) { + assert getShape().getDynamicType() == PNone.NO_VALUE; + this.pythonClass = pythonClass; } @TruffleBoundary @@ -141,12 +130,11 @@ public int compareTo(Object o) { @Override public String toString() { String className = "unknown"; - Object storedPythonClass = HiddenAttr.ReadNode.executeUncached(this, HiddenAttr.CLASS, null); - if (storedPythonClass instanceof PythonManagedClass) { - className = ((PythonManagedClass) storedPythonClass).getQualName().toJavaStringUncached(); - } else if (storedPythonClass instanceof PythonBuiltinClassType) { - className = ((PythonBuiltinClassType) storedPythonClass).getName().toJavaStringUncached(); - } else if (PGuards.isNativeClass(storedPythonClass)) { + if (pythonClass instanceof PythonManagedClass managedClass) { + className = managedClass.getQualName().toJavaStringUncached(); + } else if (pythonClass instanceof PythonBuiltinClassType pbct) { + className = pbct.getName().toJavaStringUncached(); + } else if (PGuards.isNativeClass(pythonClass)) { className = "native"; } return "<" + className + " object at 0x" + Integer.toHexString(hashCode()) + ">"; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java index 67e35a863a..cac643f291 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java @@ -289,7 +289,7 @@ abstract static class WrapSocketNode extends PythonClinicBuiltinNode { static Object wrap(PSSLContext context, PSocket sock, boolean serverSide, Object serverHostnameObj, Object owner, @SuppressWarnings("unused") PNone session, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached StringNodes.CastToTruffleStringCheckedNode cast, + @Cached StringNodes.CastToTruffleStringChecked2Node cast, @Cached TruffleString.ToJavaStringNode toJavaStringNode) { TruffleString serverHostname = null; if (!(serverHostnameObj instanceof PNone)) { @@ -326,7 +326,7 @@ static Object wrap(PSSLContext context, PMemoryBIO incoming, PMemoryBIO outgoing @SuppressWarnings("unused") PNone session, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached StringNodes.CastToTruffleStringCheckedNode cast, + @Cached StringNodes.CastToTruffleStringChecked2Node cast, @Cached TruffleString.ToJavaStringNode toJavaStringNode) { TruffleString serverHostname = null; if (!(serverHostnameObj instanceof PNone)) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java index b1a4f992c5..8f788bd730 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java @@ -62,6 +62,11 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked2Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked3Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked4Node; import org.graalvm.shadowed.com.ibm.icu.lang.UCharacter; import org.graalvm.shadowed.com.ibm.icu.lang.UProperty; import org.graalvm.shadowed.com.ibm.icu.text.CaseMap; @@ -110,7 +115,6 @@ import com.oracle.graal.python.builtins.objects.str.StringBuiltinsClinicProviders.FormatNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.str.StringBuiltinsClinicProviders.SplitNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToJavaStringCheckedNode; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; import com.oracle.graal.python.builtins.objects.str.StringNodes.JoinInternalNode; import com.oracle.graal.python.builtins.objects.str.StringNodes.SpliceNode; import com.oracle.graal.python.builtins.objects.str.StringNodes.StringLenNode; @@ -393,7 +397,7 @@ static TruffleString doString(TruffleString self) { @Specialization(guards = "!isTruffleString(self)") static TruffleString doGeneric(Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castToTruffleStringNode) { + @Cached CastToTruffleStringChecked2Node castToTruffleStringNode) { return castToTruffleStringNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, T___STR__, self); } } @@ -510,7 +514,7 @@ abstract static class ReprNode extends PythonUnaryBuiltinNode { @Specialization static TruffleString doGeneric(Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked2Node castToStringNode, @Cached StringNodes.StringReprNode reprNode) { return reprNode.execute(castToStringNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, T___REPR__, self)); } @@ -523,7 +527,7 @@ public abstract static class GetNewargsNode extends PythonUnaryBuiltinNode { PTuple doGeneric(Object self, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached CastToTruffleStringCheckedNode cast) { + @Cached CastToTruffleStringChecked2Node cast) { TruffleString selfStr = cast.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, T___GETNEWARGS__, self); // CPython requires the resulting string not to be the same object as the original for // some reason @@ -578,7 +582,7 @@ public abstract static class ContainsNode extends SqContainsBuiltinNode { @Specialization static boolean doit(Object self, Object other, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castStr, + @Cached CastToTruffleStringChecked1Node castStr, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.IndexOfStringNode indexOfStringNode) { TruffleString selfStr = castStr.cast(inliningTarget, self, ErrorMessages.REQUIRES_STRING_AS_LEFT_OPERAND, other); @@ -645,8 +649,8 @@ public final boolean endsWith(Object self, Object subStr, int start, int end) { @Specialization(guards = "!isPTuple(subStrObj)") static boolean doString(Object selfObj, Object subStrObj, int start, int end, Op op, @Bind Node inliningTarget, - @Exclusive @Cached CastToTruffleStringCheckedNode castSelfNode, - @Exclusive @Cached CastToTruffleStringCheckedNode castPrefixNode, + @Exclusive @Cached CastToTruffleStringChecked2Node castSelfNode, + @Exclusive @Cached CastToTruffleStringChecked3Node castPrefixNode, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared @Cached TruffleString.RegionEqualNode regionEqualNode) { TruffleString self = castSelfNode.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, op.methodName(), selfObj); @@ -660,8 +664,8 @@ static boolean doString(Object selfObj, Object subStrObj, int start, int end, Op static boolean doTuple(Object selfObj, PTuple subStrs, int start, int end, Op op, @Bind Node inliningTarget, @Cached GetObjectArrayNode getObjectArrayNode, - @Exclusive @Cached CastToTruffleStringCheckedNode castSelfNode, - @Exclusive @Cached CastToTruffleStringCheckedNode castPrefixNode, + @Exclusive @Cached CastToTruffleStringChecked2Node castSelfNode, + @Exclusive @Cached CastToTruffleStringChecked2Node castPrefixNode, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared @Cached TruffleString.RegionEqualNode regionEqualNode) { TruffleString self = castSelfNode.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, op.methodName(), selfObj); @@ -755,11 +759,12 @@ static int rfind(TruffleString self, TruffleString sub, int start, int end, @Specialization static int rfind(Object self, Object sub, int start, int end, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castNode, + @Cached CastToTruffleStringChecked1Node cast1Node, + @Cached CastToTruffleStringChecked2Node cast2Node, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("lastIndexOf") @Cached TruffleString.LastIndexOfStringNode lastIndexOfStringNode) { - TruffleString selfStr = castNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "rfind", self); - TruffleString subStr = castNode.cast(inliningTarget, sub, ErrorMessages.MUST_BE_STR_NOT_P, sub); + TruffleString selfStr = cast2Node.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "rfind", self); + TruffleString subStr = cast1Node.cast(inliningTarget, sub, ErrorMessages.MUST_BE_STR_NOT_P, sub); return rfind(selfStr, subStr, start, end, codePointLengthNode, lastIndexOfStringNode); } } @@ -787,11 +792,12 @@ static int find(TruffleString self, TruffleString sub, int start, int end, @Specialization static int find(Object self, Object sub, int start, int end, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castNode, + @Cached CastToTruffleStringChecked1Node cast1Node, + @Cached CastToTruffleStringChecked2Node cast2Node, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("indexOf") @Cached TruffleString.IndexOfStringNode indexOfStringNode) { - TruffleString selfStr = castNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "find", self); - TruffleString subStr = castNode.cast(inliningTarget, sub, ErrorMessages.MUST_BE_STR_NOT_P, sub); + TruffleString selfStr = cast2Node.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "find", self); + TruffleString subStr = cast1Node.cast(inliningTarget, sub, ErrorMessages.MUST_BE_STR_NOT_P, sub); return find(selfStr, subStr, start, end, codePointLengthNode, indexOfStringNode); } } @@ -845,11 +851,12 @@ static int count(TruffleString self, TruffleString sub, int start, int end, @Specialization static int count(Object self, Object sub, int start, int end, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castNode, + @Cached CastToTruffleStringChecked1Node cast1Node, + @Cached CastToTruffleStringChecked2Node cast2Node, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("indexOf") @Cached TruffleString.IndexOfStringNode indexOfStringNode) { - TruffleString selfStr = castNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "count", self); - TruffleString subStr = castNode.cast(inliningTarget, sub, ErrorMessages.MUST_BE_STR_NOT_P, sub); + TruffleString selfStr = cast2Node.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "count", self); + TruffleString subStr = cast1Node.cast(inliningTarget, sub, ErrorMessages.MUST_BE_STR_NOT_P, sub); return count(selfStr, subStr, start, end, codePointLengthNode, indexOfStringNode); } } @@ -862,7 +869,7 @@ public abstract static class JoinNode extends PythonBinaryBuiltinNode { @Specialization static TruffleString join(VirtualFrame frame, Object self, Object iterable, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked2Node castToStringNode, @Cached JoinInternalNode join) { return join.execute(frame, castToStringNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "join", self), iterable); } @@ -906,7 +913,7 @@ static TruffleString lower(TruffleString self, @Specialization static Object doGeneric(VirtualFrame frame, Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked2Node castToStringNode, @Cached LowerNode lowerNode) { return lowerNode.execute(frame, castToStringNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "lower", self)); } @@ -962,7 +969,7 @@ static TruffleString upper(TruffleString self, @Specialization static Object doGeneric(VirtualFrame frame, Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castToStringNode, + @Cached CastToTruffleStringChecked2Node castToStringNode, @Cached UpperNode upperNode) { return upperNode.execute(frame, castToStringNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "upper", self)); } @@ -989,9 +996,9 @@ public abstract static class MakeTransNode extends PythonQuaternaryBuiltinNode { @SuppressWarnings("unused") static PDict doString(VirtualFrame frame, Object cls, Object from, Object to, Object z, @Bind Node inliningTarget, - @Exclusive @Cached CastToTruffleStringCheckedNode castFromNode, - @Exclusive @Cached CastToTruffleStringCheckedNode castToNode, - @Exclusive @Cached CastToTruffleStringCheckedNode castZNode, + @Exclusive @Cached CastToTruffleStringChecked0Node castFromNode, + @Exclusive @Cached CastToTruffleStringChecked3Node castToNode, + @Exclusive @Cached CastToTruffleStringChecked4Node castZNode, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Cached TruffleStringIterator.NextNode nextNode, @@ -1035,7 +1042,7 @@ static PDict doString(VirtualFrame frame, Object cls, Object from, Object to, Ob @SuppressWarnings("unused") static PDict doDict(VirtualFrame frame, Object cls, PDict from, Object to, Object z, @Bind Node inliningTarget, - @Exclusive @Cached CastToTruffleStringCheckedNode cast, + @Exclusive @Cached CastToTruffleStringChecked0Node cast, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Exclusive @Cached HashingStorageSetItem setHashingStorageItem, @@ -1101,7 +1108,7 @@ static TruffleString doStringString(TruffleString self, TruffleString table, @Specialization static TruffleString doGeneric(VirtualFrame frame, Object self, Object table, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached PyObjectGetItem getItemNode, @Cached GetClassNode getClassNode, @Cached IsSubtypeNode isSubtypeNode, @@ -1186,8 +1193,8 @@ public abstract static class PartitionNode extends PythonBinaryBuiltinNode { @Specialization static PTuple doGeneric(Object self, Object sep, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, - @Cached CastToTruffleStringCheckedNode castSepNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, + @Cached CastToTruffleStringChecked1Node castSepNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.IndexOfStringNode indexOfStringNode, @Cached TruffleString.SubstringNode substringNode, @@ -1222,8 +1229,8 @@ public abstract static class RPartitionNode extends PythonBinaryBuiltinNode { @Specialization static Object doGeneric(Object self, Object sep, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, - @Cached CastToTruffleStringCheckedNode castSepNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, + @Cached CastToTruffleStringChecked1Node castSepNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.LastIndexOfStringNode lastIndexOfStringNode, @Cached TruffleString.SubstringNode substringNode, @@ -1540,7 +1547,7 @@ private static Matcher getMatcher(String self) { @Specialization(replaces = {"doString", "doStringKeepends"}) static PList doGeneric(Object self, Object keepends, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached CastToJavaIntExactNode castToJavaIntNode, @Shared("ts2js") @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Shared("js2ts") @Cached TruffleString.FromJavaStringNode fromJavaStringNode, @@ -1571,12 +1578,13 @@ static TruffleString doReplace(TruffleString self, TruffleString old, TruffleStr @Specialization static TruffleString doGeneric(VirtualFrame frame, Object self, Object old, Object with, Object maxCount, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node cast2Node, + @Cached CastToTruffleStringChecked4Node cast4Node, @Cached PyNumberAsSizeNode asSizeNode, @Shared("replace") @Cached StringReplaceNode replaceNode) { - TruffleString selfStr = castSelfNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "replace", self); - TruffleString oldStr = castSelfNode.cast(inliningTarget, old, ErrorMessages.S_BRACKETS_ARG_S_MUST_BE_S_NOT_P, "replace", "1", "str", old); - TruffleString withStr = castSelfNode.cast(inliningTarget, with, ErrorMessages.S_BRACKETS_ARG_S_MUST_BE_S_NOT_P, "replace", "2", "str", with); + TruffleString selfStr = cast2Node.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "replace", self); + TruffleString oldStr = cast4Node.cast(inliningTarget, old, ErrorMessages.S_BRACKETS_ARG_S_MUST_BE_S_NOT_P, "replace", "1", "str", old); + TruffleString withStr = cast4Node.cast(inliningTarget, with, ErrorMessages.S_BRACKETS_ARG_S_MUST_BE_S_NOT_P, "replace", "2", "str", with); int iMaxCount; if (PGuards.isPNone(maxCount)) { iMaxCount = -1; @@ -1610,8 +1618,8 @@ static TruffleString doStringNone(TruffleString self, @SuppressWarnings("unused" @Specialization(replaces = {"doStringString", "doStringNone"}) static TruffleString doGeneric(Object self, Object chars, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, - @Cached CastToTruffleStringCheckedNode castCharsNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, + @Cached CastToTruffleStringChecked2Node castCharsNode, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Shared("indexOf") @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode, @@ -1648,8 +1656,8 @@ static TruffleString doStringNone(TruffleString self, @SuppressWarnings("unused" @Specialization(replaces = {"doStringString", "doStringNone"}) static TruffleString doGeneric(Object self, Object chars, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, - @Cached CastToTruffleStringCheckedNode castCharsNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, + @Cached CastToTruffleStringChecked2Node castCharsNode, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Shared("indexOf") @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode, @@ -1686,8 +1694,8 @@ static TruffleString doStringNone(TruffleString self, @SuppressWarnings("unused" @Specialization(replaces = {"doStringString", "doStringNone"}) static TruffleString doGeneric(Object self, Object chars, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, - @Cached CastToTruffleStringCheckedNode castCharsNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, + @Cached CastToTruffleStringChecked2Node castCharsNode, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Shared("indexOf") @Cached TruffleString.IndexOfCodePointNode indexOfCodePointNode, @@ -1750,12 +1758,13 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static int index(Object selfObj, Object subObj, int start, int end, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castNode, + @Cached CastToTruffleStringChecked1Node cast1Node, + @Cached CastToTruffleStringChecked2Node cast2Node, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.IndexOfStringNode indexOfStringNode, @Cached PRaiseNode raiseNode) { - TruffleString self = castNode.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "index", selfObj); - TruffleString sub = castNode.cast(inliningTarget, subObj, ErrorMessages.MUST_BE_STR_NOT_P, subObj); + TruffleString self = cast2Node.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "index", selfObj); + TruffleString sub = cast1Node.cast(inliningTarget, subObj, ErrorMessages.MUST_BE_STR_NOT_P, subObj); int idx = indexOf(self, sub, start, end, codePointLengthNode, indexOfStringNode); if (idx < 0) { @@ -1778,12 +1787,13 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static int rindex(Object selfObj, Object subObj, int start, int end, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castNode, + @Cached CastToTruffleStringChecked1Node cast1Node, + @Cached CastToTruffleStringChecked2Node cast2Node, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.LastIndexOfStringNode lastIndexOfStringNode, @Cached PRaiseNode raiseNode) { - TruffleString self = castNode.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "rindex", selfObj); - TruffleString sub = castNode.cast(inliningTarget, subObj, ErrorMessages.MUST_BE_STR_NOT_P, subObj); + TruffleString self = cast2Node.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "rindex", selfObj); + TruffleString sub = cast1Node.cast(inliningTarget, subObj, ErrorMessages.MUST_BE_STR_NOT_P, subObj); int idx = lastIndexOf(self, sub, start, end, codePointLengthNode, lastIndexOfStringNode); if (idx < 0) { throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.SUBSTRING_NOT_FOUND); @@ -1814,7 +1824,7 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization static Object doIt(VirtualFrame frame, Object selfObj, TruffleString encoding, TruffleString errors, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached CodecsModuleBuiltins.EncodeNode encodeNode, @Cached SequenceStorageNodes.CopyNode copyNode, @Cached InlinedBranchProfile convertByteArray, @@ -1850,7 +1860,7 @@ static TruffleString doStringIntPositive(TruffleString left, int right, @Specialization static TruffleString doGeneric(Object self, int right, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached InlinedConditionProfile isNegativeProfile, @Shared("repeat") @Cached TruffleString.RepeatNode repeatNode) { TruffleString selfStr = castSelfNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "index", self); @@ -1900,7 +1910,7 @@ boolean doString(TruffleString self, @Specialization(replaces = "doString") boolean doGeneric(Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Shared("getCodeRange") @Cached TruffleString.GetCodeRangeNode getCodeRangeNode) { return doString(castSelfNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "isascii", self), getCodeRangeNode); } @@ -1910,7 +1920,7 @@ abstract static class IsCategoryBaseNode extends PythonUnaryBuiltinNode { @Specialization boolean doGeneric(Object selfObj, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached InlinedConditionProfile isEmptyProfile, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Cached TruffleStringIterator.NextNode nextNode) { @@ -2026,7 +2036,7 @@ public abstract static class IsIdentifierNode extends PythonUnaryBuiltinNode { @Specialization boolean doGeneric(Object selfObj, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached StringUtils.IsIdentifierNode isIdentifierNode) { TruffleString self = castSelfNode.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "isidentifier", selfObj); return isIdentifierNode.execute(inliningTarget, self); @@ -2049,7 +2059,7 @@ private static boolean isLower(int codePoint) { @Specialization static boolean doIt(Object selfObj, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Cached TruffleStringIterator.NextNode nextNode) { TruffleString self = castSelfNode.cast(inliningTarget, selfObj, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "islower", selfObj); @@ -2146,7 +2156,7 @@ private static boolean isLower(int codePoint) { @Specialization(replaces = "doString") static boolean doGeneric(Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Shared("createCpIterator") @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Shared("next") @Cached TruffleStringIterator.NextNode nextNode) { return doString(castSelfNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "istitle", self), createCodePointIteratorNode, nextNode); @@ -2187,7 +2197,7 @@ private static boolean isUpper(int codePoint) { @Specialization(replaces = "doString") static boolean doGeneric(Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Shared("createCpIterator") @Cached TruffleString.CreateCodePointIteratorNode createCodePointIteratorNode, @Shared("next") @Cached TruffleStringIterator.NextNode nextNode) { return doString(castSelfNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "isupper", self), createCodePointIteratorNode, nextNode); @@ -2201,7 +2211,7 @@ abstract static class ZFillNode extends PythonBinaryBuiltinNode { @Specialization static TruffleString doGeneric(VirtualFrame frame, Object selfObj, Object widthObj, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached PyNumberAsSizeNode asSizeNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @@ -2300,9 +2310,9 @@ abstract static class CenterNode extends PythonBuiltinNode { @Specialization TruffleString doIt(VirtualFrame frame, Object selfObj, Object width, Object fill, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode, + @Cached CastToTruffleStringChecked2Node castSelfNode, @Cached PyNumberAsSizeNode asSizeNode, - @Cached CastToTruffleStringCheckedNode castFillNode, + @Cached CastToTruffleStringChecked1Node castFillNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @@ -2441,7 +2451,7 @@ public abstract static class StrSqItemNode extends SqItemBuiltinNode { @Specialization static Object doIt(VirtualFrame frame, Object self, int index, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castToString, + @Cached CastToTruffleStringChecked3Node castToString, @Cached TruffleString.SubstringNode substringNode) { TruffleString str = castToString.cast(inliningTarget, self, ErrorMessages.DESCRIPTOR_S_REQUIRES_S_OBJ_RECEIVED_P, T___GETITEM__, "str", self); return substringNode.execute(str, index, 1, TS_ENCODING, false); @@ -2455,7 +2465,7 @@ public abstract static class StrGetItemNode extends MpSubscriptBuiltinNode { @Specialization static TruffleString doString(VirtualFrame frame, Object self, PSlice slice, @Bind Node inliningTarget, - @Exclusive @Cached CastToTruffleStringCheckedNode castToString, + @Exclusive @Cached CastToTruffleStringChecked3Node castToString, @Cached CoerceToIntSlice sliceCast, @Cached ComputeIndices compute, @Cached StrGetItemNodeWithSlice getItemNodeWithSlice, @@ -2468,7 +2478,7 @@ static TruffleString doString(VirtualFrame frame, Object self, PSlice slice, @Specialization(guards = "!isPSlice(idx)") static TruffleString doString(VirtualFrame frame, Object self, Object idx, @Bind Node inliningTarget, - @Exclusive @Cached CastToTruffleStringCheckedNode castToString, + @Exclusive @Cached CastToTruffleStringChecked3Node castToString, @Cached PyIndexCheckNode indexCheckNode, @Cached PyNumberAsSizeNode asSizeNode, @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, @@ -2502,7 +2512,7 @@ public abstract static class IterNode extends PythonUnaryBuiltinNode { @Specialization static PStringIterator doGeneric(Object self, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode castSelfNode) { + @Cached CastToTruffleStringChecked2Node castSelfNode) { TruffleString string = castSelfNode.cast(inliningTarget, self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, T___ITER__, self); return PFactory.createStringIterator(PythonLanguage.get(inliningTarget), string); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringNodes.java index 5c520e6cb7..331e6e2f2c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringNodes.java @@ -61,6 +61,7 @@ import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.builtins.objects.str.StringNodesFactory.CastToTruffleStringChecked0NodeGen; import com.oracle.graal.python.builtins.objects.str.StringNodesFactory.IsInternedStringNodeGen; import com.oracle.graal.python.builtins.objects.str.StringNodesFactory.StringMaterializeNodeGen; import com.oracle.graal.python.lib.IteratorExhausted; @@ -202,7 +203,7 @@ static int doNativeObject(PythonNativeObject x, @InliningCutoff static int other(Object x, @Bind Node inliningTarget, - @Cached CastToTruffleStringCheckedNode cast, + @Cached CastToTruffleStringChecked2Node cast, @Shared @Cached TruffleString.CodePointLengthNode codePointLengthNode) { TruffleString tstring = cast.cast(inliningTarget, x, ErrorMessages.DESCRIPTOR_REQUIRES_S_OBJ_RECEIVED_P, "str", x); return doString(tstring, codePointLengthNode); @@ -242,30 +243,152 @@ static String doConvert(Node inliningTarget, Object self, TruffleString errMsgFo } } + // One variant per arity to avoid extra Object[] allocations @GenerateUncached @GenerateInline @GenerateCached(false) - public abstract static class CastToTruffleStringCheckedNode extends PNodeWithContext { - public final TruffleString cast(Node inliningTarget, Object object, TruffleString errMsgFormat, Object... errMsgArgs) { - return execute(inliningTarget, object, errMsgFormat, errMsgArgs); + public abstract static class CastToTruffleStringChecked0Node extends PNodeWithContext { + public static CastToTruffleStringChecked0Node getUncached() { + return CastToTruffleStringChecked0NodeGen.getUncached(); } - abstract TruffleString execute(Node inliningTarget, Object object, TruffleString errMsgFormat, Object[] errMsgArgs); + public final TruffleString cast(Node inliningTarget, Object object, TruffleString errMsg) { + return execute(inliningTarget, object, errMsg); + } + + abstract TruffleString execute(Node inliningTarget, Object object, TruffleString errMsg); + @SuppressWarnings("unused") @Specialization - static TruffleString doTruffleString(TruffleString self, @SuppressWarnings("unused") TruffleString errMsgFormat, @SuppressWarnings("unused") Object[] errMsgArgs) { + static TruffleString doTruffleString(TruffleString self, TruffleString errMsg) { return self; } @Specialization(guards = "!isTruffleString(self)") @InliningCutoff - static TruffleString doConvert(Node inliningTarget, Object self, TruffleString errMsgFormat, Object[] errMsgArgs, + static TruffleString doConvert(Node inliningTarget, Object self, TruffleString errMsg, @Cached CastToTruffleStringNode castToTruffleStringNode, @Cached PRaiseNode raiseNode) { try { return castToTruffleStringNode.execute(inliningTarget, self); } catch (CannotCastException e) { - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, errMsgFormat, errMsgArgs); + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, errMsg); + } + } + } + + @GenerateUncached + @GenerateInline + @GenerateCached(false) + public abstract static class CastToTruffleStringChecked1Node extends PNodeWithContext { + public final TruffleString cast(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1) { + return execute(inliningTarget, object, errMsgFormat, errMsgArg1); + } + + abstract TruffleString execute(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1); + + @SuppressWarnings("unused") + @Specialization + static TruffleString doTruffleString(TruffleString self, TruffleString errMsgFormat, Object errMsgArg1) { + return self; + } + + @Specialization(guards = "!isTruffleString(self)") + @InliningCutoff + static TruffleString doConvert(Node inliningTarget, Object self, TruffleString errMsgFormat, Object errMsgArg1, + @Cached CastToTruffleStringNode castToTruffleStringNode, + @Cached PRaiseNode raiseNode) { + try { + return castToTruffleStringNode.execute(inliningTarget, self); + } catch (CannotCastException e) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, errMsgFormat, errMsgArg1); + } + } + } + + @GenerateUncached + @GenerateInline + @GenerateCached(false) + public abstract static class CastToTruffleStringChecked2Node extends PNodeWithContext { + public final TruffleString cast(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2) { + return execute(inliningTarget, object, errMsgFormat, errMsgArg1, errMsgArg2); + } + + abstract TruffleString execute(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2); + + @SuppressWarnings("unused") + @Specialization + static TruffleString doTruffleString(TruffleString self, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2) { + return self; + } + + @Specialization(guards = "!isTruffleString(self)") + @InliningCutoff + static TruffleString doConvert(Node inliningTarget, Object self, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, + @Cached CastToTruffleStringNode castToTruffleStringNode, + @Cached PRaiseNode raiseNode) { + try { + return castToTruffleStringNode.execute(inliningTarget, self); + } catch (CannotCastException e) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, errMsgFormat, errMsgArg1, errMsgArg2); + } + } + } + + @GenerateUncached + @GenerateInline + @GenerateCached(false) + public abstract static class CastToTruffleStringChecked3Node extends PNodeWithContext { + public final TruffleString cast(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3) { + return execute(inliningTarget, object, errMsgFormat, errMsgArg1, errMsgArg2, errMsgArg3); + } + + abstract TruffleString execute(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3); + + @SuppressWarnings("unused") + @Specialization + static TruffleString doTruffleString(TruffleString self, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3) { + return self; + } + + @Specialization(guards = "!isTruffleString(self)") + @InliningCutoff + static TruffleString doConvert(Node inliningTarget, Object self, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3, + @Cached CastToTruffleStringNode castToTruffleStringNode, + @Cached PRaiseNode raiseNode) { + try { + return castToTruffleStringNode.execute(inliningTarget, self); + } catch (CannotCastException e) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, errMsgFormat, errMsgArg1, errMsgArg2, errMsgArg3); + } + } + } + + @GenerateUncached + @GenerateInline + @GenerateCached(false) + public abstract static class CastToTruffleStringChecked4Node extends PNodeWithContext { + public final TruffleString cast(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3, Object errMsgArg4) { + return execute(inliningTarget, object, errMsgFormat, errMsgArg1, errMsgArg2, errMsgArg3, errMsgArg4); + } + + abstract TruffleString execute(Node inliningTarget, Object object, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3, Object errMsgArg4); + + @SuppressWarnings("unused") + @Specialization + static TruffleString doTruffleString(TruffleString self, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3, Object errMsgArg4) { + return self; + } + + @Specialization(guards = "!isTruffleString(self)") + @InliningCutoff + static TruffleString doConvert(Node inliningTarget, Object self, TruffleString errMsgFormat, Object errMsgArg1, Object errMsgArg2, Object errMsgArg3, Object errMsgArg4, + @Cached CastToTruffleStringNode castToTruffleStringNode, + @Cached PRaiseNode raiseNode) { + try { + return castToTruffleStringNode.execute(inliningTarget, self); + } catch (CannotCastException e) { + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, errMsgFormat, errMsgArg1, errMsgArg2, errMsgArg3, errMsgArg4); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java index d90f9576f7..7cf0b37326 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java @@ -48,6 +48,8 @@ import java.util.List; import java.util.Locale; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Fallback; import org.graalvm.nativeimage.ImageInfo; import org.graalvm.shadowed.com.ibm.icu.lang.UCharacter; import org.graalvm.shadowed.com.ibm.icu.lang.UCharacterCategory; @@ -582,4 +584,28 @@ public static int getCodePoint(String characterName) { return UCharacter.getCharFromName(characterName); } } + + /** + * Like {@link TruffleString.EqualNode} but with the proper {@link InliningCutoff} since + * {@link TruffleString.EqualNode} is too big for host inlining, at least when used in node + * guards. + */ + @GenerateInline + @GenerateCached(false) + @GenerateUncached + public abstract static class EqualNode extends Node { + public abstract boolean execute(Node inliningTarget, TruffleString left, TruffleString right); + + @Specialization(guards = "left == right") + static boolean doIdentity(TruffleString left, TruffleString right) { + return true; + } + + @InliningCutoff + @Fallback + static boolean doEquality(TruffleString left, TruffleString right, + @Cached TruffleString.EqualNode equalNode) { + return equalNode.execute(left, right, TS_ENCODING); + } + } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java index 846bb62e4c..f4b5dd04b6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/superobject/SuperBuiltins.java @@ -67,7 +67,7 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory; -import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringCheckedNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltinsFactory.GetObjectNodeGen; import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltinsFactory.GetTypeNodeGen; @@ -472,7 +472,7 @@ static Object doIt(Node inliningTarget, SuperObject self, Object obj, @Slot(value = SlotKind.tp_getattro, isComplex = true) @GenerateNodeFactory public abstract static class GetattributeNode extends GetAttrBuiltinNode { - @Child private ReadAttributeFromObjectNode readFromDict = ReadAttributeFromObjectNode.createForceType(); + @Child private ReadAttributeFromObjectNode readFromDict = ReadAttributeFromObjectNode.create(); @Child private CallSlotDescrGet callGetSlotNode; @Child private GetTypeNode getType; @Child private GetObjectNode getObject = GetObjectNodeGen.create(); @@ -494,7 +494,7 @@ Object get(VirtualFrame frame, SuperObject self, Object attr, @Cached GetObjectSlotsNode getSlotsNode, @Cached TruffleString.EqualNode equalNode, @Cached GetObjectTypeNode getObjectType, - @Cached CastToTruffleStringCheckedNode castToTruffleStringNode, + @Cached CastToTruffleStringChecked1Node castToTruffleStringNode, @Cached InlinedConditionProfile hasDescrGetProfile, @Cached InlinedConditionProfile getObjectIsStartObjectProfile, @Cached IsForeignObjectNode isForeignObjectNode, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java index c673405948..6e2dc4c8b2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/thread/ThreadLocalBuiltins.java @@ -40,6 +40,7 @@ */ package com.oracle.graal.python.builtins.objects.thread; +import static com.oracle.graal.python.nodes.ErrorMessages.ATTR_NAME_MUST_BE_STRING; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___DICT__; import java.util.List; @@ -57,10 +58,12 @@ import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; -import com.oracle.graal.python.builtins.objects.object.ObjectNodes; import com.oracle.graal.python.builtins.objects.object.ObjectNodes.GenericSetAttrWithDictNode; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet; @@ -71,12 +74,11 @@ import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; +import com.oracle.graal.python.nodes.attributes.MergedObjectTypeModuleGetAttributeNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -89,6 +91,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; @@ -138,6 +141,10 @@ PDict repr(VirtualFrame frame, PThreadLocal self, public abstract static class GetAttributeNode extends GetAttrBuiltinNode { @Child private CallSlotDescrGet callGetNode; + /** + * Keep in sync with {@link ObjectBuiltins.GetAttributeNode} and + * {@link TypeBuiltins.GetattributeNode} and {@link MergedObjectTypeModuleGetAttributeNode} + */ @Specialization Object doIt(VirtualFrame frame, PThreadLocal object, Object keyObj, @Bind Node inliningTarget, @@ -145,49 +152,52 @@ Object doIt(VirtualFrame frame, PThreadLocal object, Object keyObj, @Cached LookupAttributeInMRONode.Dynamic lookup, @Cached GetClassNode getClassNode, @Cached GetObjectSlotsNode getDescrSlotsNode, - @Cached CastToTruffleStringNode castKeyToStringNode, + @Cached CastToTruffleStringChecked1Node castToString, @Cached HashingStorageGetItem getDictStorageItem, - @Cached InlinedConditionProfile hasDescrProfile, + @Cached InlinedBranchProfile hasDescProfile, @Cached InlinedConditionProfile hasDescrGetProfile, @Cached InlinedConditionProfile hasValueProfile, @Cached PRaiseNode raiseNode) { // Note: getting thread local dict has potential side-effects, don't move PDict localDict = getThreadLocalDict.execute(frame, object); - TruffleString key; - try { - key = castKeyToStringNode.execute(inliningTarget, keyObj); - } catch (CannotCastException e) { - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); - } + + TruffleString key = castToString.cast(inliningTarget, keyObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); Object type = getClassNode.execute(inliningTarget, object); Object descr = lookup.execute(type, key); - TpSlot descrGetSlot = null; - boolean hasDescr = hasDescrProfile.profile(inliningTarget, descr != PNone.NO_VALUE); + boolean hasDescr = descr != PNone.NO_VALUE; + + TpSlot get = null; boolean hasDescrGet = false; if (hasDescr) { + hasDescProfile.enter(inliningTarget); var descrSlots = getDescrSlotsNode.execute(inliningTarget, descr); - descrGetSlot = descrSlots.tp_descr_get(); - hasDescrGet = hasDescrGetProfile.profile(inliningTarget, descrGetSlot != null); + get = descrSlots.tp_descr_get(); + hasDescrGet = hasDescrGetProfile.profile(inliningTarget, get != null); if (hasDescrGet && TpSlotDescrSet.PyDescr_IsData(descrSlots)) { - return dispatch(frame, object, type, descr, descrGetSlot); + return dispatchDescrGet(frame, object, type, descr, get); } } + + // The only difference between all 3 nodes Object value = getDictStorageItem.execute(frame, inliningTarget, localDict.getDictStorage(), key); if (hasValueProfile.profile(inliningTarget, value != null)) { return value; } + if (hasDescr) { + hasDescProfile.enter(inliningTarget); if (!hasDescrGet) { return descr; } else { - return dispatch(frame, object, type, descr, descrGetSlot); + return dispatchDescrGet(frame, object, type, descr, get); } } - throw raiseNode.raiseAttributeError(inliningTarget, object, key); + + throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); } - private Object dispatch(VirtualFrame frame, Object object, Object type, Object descr, TpSlot get) { + private Object dispatchDescrGet(VirtualFrame frame, Object object, Object type, Object descr, TpSlot get) { if (callGetNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); callGetNode = insert(CallSlotDescrGet.create()); @@ -200,27 +210,16 @@ private Object dispatch(VirtualFrame frame, Object object, Object type, Object d @Slot(value = SlotKind.tp_setattro, isComplex = true) @GenerateNodeFactory public abstract static class SetattrNode extends SetAttrBuiltinNode { - @Specialization - static void doStringKey(VirtualFrame frame, PThreadLocal object, TruffleString key, Object value, - @Bind Node inliningTarget, - @Exclusive @Cached ThreadLocalNodes.GetThreadLocalDict getThreadLocalDict, - @Exclusive @Cached GenericSetAttrWithDictNode setAttrWithDictNode) { - // Note: getting thread local dict has potential side-effects, don't move - PDict localDict = getThreadLocalDict.execute(frame, object); - setAttrWithDictNode.execute(inliningTarget, frame, object, key, value, localDict); - } - @Specialization @InliningCutoff static void doGeneric(VirtualFrame frame, PThreadLocal object, Object keyObject, Object value, @Bind Node inliningTarget, @Exclusive @Cached ThreadLocalNodes.GetThreadLocalDict getThreadLocalDict, - @Cached CastToTruffleStringNode castKeyToStringNode, - @Exclusive @Cached PRaiseNode raiseNode, + @Cached CastToTruffleStringChecked0Node castKeyNode, @Exclusive @Cached GenericSetAttrWithDictNode setAttrWithDictNode) { // Note: getting thread local dict has potential side-effects, don't move PDict localDict = getThreadLocalDict.execute(frame, object); - TruffleString key = ObjectNodes.GenericSetAttrNode.castAttributeKey(inliningTarget, keyObject, castKeyToStringNode, raiseNode); + TruffleString key = castKeyNode.cast(inliningTarget, keyObject, ATTR_NAME_MUST_BE_STRING); setAttrWithDictNode.execute(inliningTarget, frame, object, key, value, localDict); } } 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 71ae4abd50..a8390b41f0 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 @@ -182,7 +182,7 @@ public static void initType(PythonContext context, PythonAbstractClass klass, De unnamedFields++; } } - WriteAttributeToObjectNode writeAttrNode = WriteAttributeToObjectNode.getUncached(true); + WriteAttributeToObjectNode writeAttrNode = WriteAttributeToObjectNode.getUncached(); if (klass instanceof PythonManagedClass managedClass) { /* * The methods and slots are already set for each PBCT, but we need to store the field @@ -220,7 +220,7 @@ public static void initType(PythonContext context, PythonAbstractClass klass, De private static void copyMethod(PythonLanguage language, PythonAbstractClass klass, TruffleString name, PythonBuiltinClass template) { PBuiltinFunction templateMethod = (PBuiltinFunction) template.getAttribute(name); PBuiltinFunction method = PFactory.createBuiltinFunction(language, templateMethod, klass); - WriteAttributeToObjectNode.getUncached(true).execute(klass, name, method); + WriteAttributeToObjectNode.getUncached().execute(klass, name, method); } private static void createMember(PythonLanguage language, Object klass, TruffleString name, TruffleString doc, int idx) { @@ -230,7 +230,7 @@ private static void createMember(PythonLanguage language, Object klass, TruffleS if (doc != null) { callable.setAttribute(T___DOC__, doc); } - WriteAttributeToObjectNode.getUncached(true).execute(klass, name, callable); + WriteAttributeToObjectNode.getUncached().execute(klass, name, callable); } private static class GetStructMemberNode extends PRootNode { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java index 77ef8b3f0b..877d71d52b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tuple/StructSequenceBuiltins.java @@ -133,14 +133,14 @@ abstract static class GetSizeNode extends Node { @Specialization static int doPBCT(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassType type, TruffleString key, - @Shared @Cached("createForceType()") ReadAttributeFromObjectNode read, + @Shared @Cached ReadAttributeFromObjectNode read, @Shared @Cached PyNumberAsSizeNode asSizeNode) { return doGeneric(frame, inliningTarget, PythonContext.get(inliningTarget).lookupType(type), key, read, asSizeNode); } @Fallback static int doGeneric(VirtualFrame frame, Node inliningTarget, Object type, TruffleString key, - @Shared @Cached("createForceType()") ReadAttributeFromObjectNode read, + @Shared @Cached ReadAttributeFromObjectNode read, @Shared @Cached PyNumberAsSizeNode asSizeNode) { return asSizeNode.executeExact(frame, inliningTarget, read.execute(type, key)); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java index d8de4a4914..afb2eb7ead 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonClass.java @@ -247,8 +247,8 @@ public void makeStaticBase(DynamicObjectLibrary dylib) { dylib.setShapeFlags(this, dylib.getShapeFlags(this) | IS_STATIC_BASE); } - public boolean isStaticBase(DynamicObjectLibrary dylib) { - return (dylib.getShapeFlags(this) & IS_STATIC_BASE) != 0; + public boolean isStaticBase() { + return (getShape().getFlags() & IS_STATIC_BASE) != 0; } public MroShape getMroShape() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java index 5d1334dd19..76694f0f76 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TpSlots.java @@ -1736,7 +1736,7 @@ private static boolean checkNoMagicOverrides(Python3Core core, PythonBuiltinClas // Check that no one is trying to define magic methods directly // If the assertion fires: you should define @Slot instead of @Builtin // We do not look in MRO, we may have already called addOperatorsToBuiltin on super - var readAttr = ReadAttributeFromObjectNode.getUncachedForceType(); + var readAttr = ReadAttributeFromObjectNode.getUncached(); PythonBuiltinClass typeObj = core.lookupType(type); for (TruffleString name : SPECIAL2SLOT.keySet()) { assert readAttr.execute(typeObj, name) == PNone.NO_VALUE : type.name() + ":" + name; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java index 026803da3e..67c4830833 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java @@ -31,6 +31,7 @@ import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyHeapTypeObject__ht_qualname; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_name; import static com.oracle.graal.python.nodes.BuiltinNames.T_BUILTINS; +import static com.oracle.graal.python.nodes.ErrorMessages.ATTR_NAME_MUST_BE_STRING; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___ABSTRACTMETHODS__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___ANNOTATIONS__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___BASES__; @@ -95,15 +96,18 @@ import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToArrayNode; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.getsetdescriptor.DescriptorDeleteMarker; import com.oracle.graal.python.builtins.objects.list.PList; +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.object.ObjectNodes; import com.oracle.graal.python.builtins.objects.set.PSet; import com.oracle.graal.python.builtins.objects.set.SetBuiltins.UpdateSingleNode; import com.oracle.graal.python.builtins.objects.str.PString; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; +import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; @@ -135,8 +139,9 @@ import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; +import com.oracle.graal.python.nodes.attributes.MergedObjectTypeModuleGetAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode; @@ -160,7 +165,6 @@ 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.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -201,8 +205,8 @@ static TruffleString repr(VirtualFrame frame, Object self, @Cached CastToTruffleStringNode castToStringNode, @Cached TruffleString.EqualNode equalNode, @Cached SimpleTruffleStringFormatNode simpleTruffleStringFormatNode) { - Object moduleNameObj = readModuleNode.executeObject(frame, self); - Object qualNameObj = readQualNameNode.executeObject(frame, self); + Object moduleNameObj = readModuleNode.execute(frame, self); + Object qualNameObj = readQualNameNode.execute(frame, self); TruffleString moduleName = null; if (moduleNameObj != NO_VALUE) { try { @@ -255,7 +259,7 @@ static Object getDoc(VirtualFrame frame, PythonClass self, @SuppressWarnings("un @Specialization static Object getDoc(PythonAbstractNativeObject self, @SuppressWarnings("unused") PNone value) { - return ReadAttributeFromObjectNode.getUncachedForceType().execute(self, T___DOC__); + return ReadAttributeFromObjectNode.getUncached().execute(self, T___DOC__); } @Specialization(guards = {"!isNoValue(value)", "!isDeleteMarker(value)", "!isPythonBuiltinClass(self)"}) @@ -522,6 +526,11 @@ public abstract static class GetattributeNode extends GetAttrBuiltinNode { @Child private CallSlotDescrGet callSlotValueGet; @Child private LookupAttributeInMRONode.Dynamic lookupAsClass; + /** + * Keep in sync with {@link ObjectBuiltins.GetAttributeNode} and + * {@link ThreadLocalBuiltins.GetAttributeNode} and + * {@link MergedObjectTypeModuleGetAttributeNode} + */ @Specialization protected Object doIt(VirtualFrame frame, Object object, Object keyObj, @Bind Node inliningTarget, @@ -529,38 +538,35 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj, @Cached GetObjectSlotsNode getDescrSlotsNode, @Cached GetObjectSlotsNode getValueSlotsNode, @Cached LookupAttributeInMRONode.Dynamic lookup, - @Cached CastToTruffleStringNode castToString, + @Cached CastToTruffleStringChecked1Node castToString, @Cached InlinedBranchProfile hasDescProfile, @Cached InlinedConditionProfile hasDescrGetProfile, @Cached InlinedBranchProfile hasValueProfile, @Cached InlinedBranchProfile hasNonDescriptorValueProfile, - @Cached InlinedBranchProfile errorProfile, @Cached PRaiseNode raiseNode) { - TruffleString key; - try { - key = castToString.execute(inliningTarget, keyObj); - } catch (CannotCastException e) { - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); - } + TruffleString key = castToString.cast(inliningTarget, keyObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); + + Object type = getClassNode.execute(inliningTarget, object); + Object descr = lookup.execute(type, key); + boolean hasDescr = descr != PNone.NO_VALUE; - Object metatype = getClassNode.execute(inliningTarget, object); - Object descr = lookup.execute(metatype, key); TpSlot get = null; boolean hasDescrGet = false; - if (descr != NO_VALUE) { - // acts as a branch profile + if (hasDescr) { + hasDescProfile.enter(inliningTarget); var descrSlots = getDescrSlotsNode.execute(inliningTarget, descr); get = descrSlots.tp_descr_get(); hasDescrGet = hasDescrGetProfile.profile(inliningTarget, get != null); if (hasDescrGet && TpSlotDescrSet.PyDescr_IsData(descrSlots)) { - return dispatchDescrGet(frame, object, metatype, descr, get); + return dispatchDescrGet(frame, object, type, descr, get); } } - Object value = readAttribute(object, key); - if (value != NO_VALUE) { + + // The only difference between all 3 nodes + Object value = readAttributeOfClass(object, key); + if (value != PNone.NO_VALUE) { hasValueProfile.enter(inliningTarget); - var valueSlots = getValueSlotsNode.execute(inliningTarget, value); - var valueGet = valueSlots.tp_descr_get(); + var valueGet = getValueSlotsNode.execute(inliningTarget, value).tp_descr_get(); if (valueGet == null) { hasNonDescriptorValueProfile.enter(inliningTarget); return value; @@ -568,19 +574,20 @@ protected Object doIt(VirtualFrame frame, Object object, Object keyObj, return dispatchValueGet(frame, object, value, valueGet); } } - if (descr != NO_VALUE) { + + if (hasDescr) { hasDescProfile.enter(inliningTarget); if (!hasDescrGet) { return descr; } else { - return dispatchDescrGet(frame, object, metatype, descr, get); + return dispatchDescrGet(frame, object, type, descr, get); } } - errorProfile.enter(inliningTarget); - throw raiseNode.raiseWithData(inliningTarget, AttributeError, AttributeErrorBuiltins.dataForObjKey(object, key), ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key); + + throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_N_HAS_NO_ATTR_S, object, key); } - private Object readAttribute(Object object, TruffleString key) { + private Object readAttributeOfClass(Object object, TruffleString key) { if (lookupAsClass == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); lookupAsClass = insert(LookupAttributeInMRONode.Dynamic.create()); @@ -603,7 +610,7 @@ private Object dispatchValueGet(VirtualFrame frame, Object type, Object descr, T } // NO_VALUE 2nd argument indicates the descriptor was found on the target object itself // (or a base) - return callSlotValueGet.executeCached(frame, getSlot, descr, NO_VALUE, type); + return callSlotValueGet.executeCached(frame, getSlot, descr, PNone.NO_VALUE, type); } } @@ -611,29 +618,22 @@ private Object dispatchValueGet(VirtualFrame frame, Object type, Object descr, T @GenerateNodeFactory public abstract static class SetattrNode extends SetAttrBuiltinNode { @Specialization(guards = "!isImmutable(object)") - void setString(VirtualFrame frame, Object object, TruffleString key, Object value, + static void set(VirtualFrame frame, Object object, Object keyObject, Object value, @Bind Node inliningTarget, - @Shared @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, - @Shared @Cached("createForceType()") WriteAttributeToObjectNode write) { + @Cached CastToTruffleStringChecked0Node castKeyNode, + @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, + @Cached WriteAttributeToObjectNode write) { + TruffleString key = castKeyNode.cast(inliningTarget, keyObject, ATTR_NAME_MUST_BE_STRING); genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); } - @Specialization(guards = "!isImmutable(object)") - @InliningCutoff - static void set(VirtualFrame frame, Object object, Object key, Object value, - @Bind Node inliningTarget, - @Shared @Cached ObjectNodes.GenericSetAttrNode genericSetAttrNode, - @Shared @Cached("createForceType()") WriteAttributeToObjectNode write) { - genericSetAttrNode.execute(inliningTarget, frame, object, key, value, write); - } - - @Specialization(guards = "isImmutable(object)") @TruffleBoundary + @Specialization(guards = "isImmutable(object)") void setBuiltin(Object object, Object key, Object value) { if (PythonContext.get(this).isInitialized()) { throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, PyObjectReprAsTruffleStringNode.executeUncached(key), object); } else { - set(null, object, key, value, null, ObjectNodes.GenericSetAttrNode.getUncached(), WriteAttributeToObjectNode.getUncached(true)); + set(null, object, key, value, null, CastToTruffleStringChecked0Node.getUncached(), ObjectNodes.GenericSetAttrNode.getUncached(), WriteAttributeToObjectNode.getUncached()); } } @@ -942,7 +942,7 @@ static TruffleString getModuleBuiltin(PythonBuiltinClass cls, @SuppressWarnings( @Specialization(guards = "isNoValue(value)") static Object getModule(PythonClass cls, @SuppressWarnings("unused") PNone value, @Bind Node inliningTarget, - @Cached ReadAttributeFromObjectNode readAttrNode, + @Shared @Cached ReadAttributeFromObjectNode readAttrNode, @Shared @Cached PRaiseNode raiseNode) { Object module = readAttrNode.execute(cls, T___MODULE__); if (module == NO_VALUE) { @@ -953,7 +953,7 @@ static Object getModule(PythonClass cls, @SuppressWarnings("unused") PNone value @Specialization(guards = "!isNoValue(value)") static Object setModule(PythonClass cls, Object value, - @Cached WriteAttributeToObjectNode writeAttrNode) { + @Shared @Cached WriteAttributeToObjectNode writeAttrNode) { writeAttrNode.execute(cls, T___MODULE__, value); return PNone.NONE; } @@ -961,7 +961,7 @@ static Object setModule(PythonClass cls, Object value, @Specialization(guards = "isNoValue(value)") static Object getModule(PythonAbstractNativeObject cls, @SuppressWarnings("unused") PNone value, @Bind Node inliningTarget, - @Cached("createForceType()") ReadAttributeFromObjectNode readAttr, + @Shared @Cached ReadAttributeFromObjectNode readAttrNode, @Shared @Cached GetTypeFlagsNode getFlags, @Cached CStructAccess.ReadCharPtrNode getTpNameNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, @@ -970,7 +970,7 @@ static Object getModule(PythonAbstractNativeObject cls, @SuppressWarnings("unuse @Shared @Cached PRaiseNode raiseNode) { // see function 'typeobject.c: type_module' if ((getFlags.execute(cls) & TypeFlags.HEAPTYPE) != 0) { - Object module = readAttr.execute(cls, T___MODULE__); + Object module = readAttrNode.execute(cls, T___MODULE__); if (module == NO_VALUE) { throw raiseNode.raise(inliningTarget, AttributeError); } @@ -991,13 +991,13 @@ static Object getModule(PythonAbstractNativeObject cls, @SuppressWarnings("unuse static Object setNative(PythonAbstractNativeObject cls, Object value, @Bind Node inliningTarget, @Shared @Cached GetTypeFlagsNode getFlags, - @Cached("createForceType()") WriteAttributeToObjectNode writeAttr, + @Shared @Cached WriteAttributeToObjectNode writeAttrNode, @Shared @Cached PRaiseNode raiseNode) { long flags = getFlags.execute(cls); if ((flags & TypeFlags.HEAPTYPE) == 0) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_N_S, cls, T___MODULE__); } - writeAttr.execute(cls, T___MODULE__, value); + writeAttrNode.execute(cls, T___MODULE__, value); return PNone.NONE; } 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 a6280fe41c..145070c42d 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 @@ -43,7 +43,6 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE; -import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_SUBCLASS_CHECK; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyHeapTypeObject__ht_qualname; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_base; import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_bases; @@ -188,7 +187,7 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.SpecialAttributeNames; import com.oracle.graal.python.nodes.SpecialMethodNames; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; import com.oracle.graal.python.nodes.call.CallNode; @@ -241,7 +240,6 @@ import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.ControlFlowException; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.DynamicObjectLibrary; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -1241,7 +1239,7 @@ private boolean instancesHaveDict(Object type) { private ReadAttributeFromObjectNode getReadAttr() { if (readAttr == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - readAttr = insert(ReadAttributeFromObjectNode.createForceType()); + readAttr = insert(ReadAttributeFromObjectNode.create()); } return readAttr; } @@ -1323,7 +1321,7 @@ public static boolean executeUncached(Object type) { @Specialization static boolean check(Node inliningTarget, Object type, @Cached NeedsNativeAllocationNode needsNativeAllocationNode, - @Cached(inline = false) ReadAttributeFromObjectNode read, + @Cached ReadAttributeFromObjectNode read, @Cached GetWeakListOffsetNode getWeakListOffsetNode) { if (needsNativeAllocationNode.execute(inliningTarget, type)) { return getWeakListOffsetNode.execute(inliningTarget, type) != 0; @@ -1378,7 +1376,7 @@ static Object executeUncached(Object type) { @Specialization protected static Object getSolid(Node inliningTarget, Object type, @Cached GetBaseClassNode getBaseClassNode, - @Cached(value = "createForceType()", inline = false) ReadAttributeFromObjectNode readAttr, + @Cached ReadAttributeFromObjectNode readAttr, @Cached InlinedBranchProfile typeIsNotBase, @Cached InlinedBranchProfile hasBase, @Cached InlinedBranchProfile hasNoBase) { @@ -1388,7 +1386,7 @@ protected static Object getSolid(Node inliningTarget, Object type, @TruffleBoundary protected static Object solidBaseTB(Object type, Node inliningTarget, GetBaseClassNode getBaseClassNode, PythonContext context, int depth) { - return solidBase(type, inliningTarget, getBaseClassNode, context, ReadAttributeFromObjectNode.getUncachedForceType(), InlinedBranchProfile.getUncached(), + return solidBase(type, inliningTarget, getBaseClassNode, context, ReadAttributeFromObjectNode.getUncached(), InlinedBranchProfile.getUncached(), InlinedBranchProfile.getUncached(), InlinedBranchProfile.getUncached(), depth); } @@ -1438,10 +1436,8 @@ static boolean shapeDiffers(Object type, Object base, ReadAttributeFromObjectNod if (typeSlots != null && length(typeSlots) != 0) { return true; } - Object typeNewMethod = LookupAttributeInMRONode.lookup(T___NEW__, GetMroStorageNode.executeUncached(type), ReadAttributeFromObjectNode.getUncached(), true, - DynamicObjectLibrary.getUncached()); - Object baseNewMethod = LookupAttributeInMRONode.lookup(T___NEW__, GetMroStorageNode.executeUncached(base), ReadAttributeFromObjectNode.getUncached(), true, - DynamicObjectLibrary.getUncached()); + Object typeNewMethod = LookupAttributeInMRONode.lookup(T___NEW__, GetMroStorageNode.executeUncached(type), ReadAttributeFromObjectNode.getUncached(), true); + Object baseNewMethod = LookupAttributeInMRONode.lookup(T___NEW__, GetMroStorageNode.executeUncached(base), ReadAttributeFromObjectNode.getUncached(), true); return typeNewMethod != baseNewMethod; } @@ -1755,17 +1751,19 @@ static boolean doBuiltinType(@SuppressWarnings("unused") PythonBuiltinClassType } @Specialization - @InliningCutoff static boolean doNativeClass(Node inliningTarget, PythonAbstractNativeObject obj, @Cached IsBuiltinClassProfile profile, @Cached GetPythonObjectClassNode getClassNode, - @Cached(inline = false) CExtNodes.PCallCapiFunction nativeTypeCheck) { + @Cached CStructAccess.ReadI64Node getTpFlagsNode) { Object type = getClassNode.execute(inliningTarget, obj); if (profile.profileClass(inliningTarget, type, PythonBuiltinClassType.PythonClass)) { return true; } + if (PythonNativeClass.isInstance(type)) { - return (int) nativeTypeCheck.call(FUN_SUBCLASS_CHECK, obj.getPtr()) == 1; + // Equivalent of PyType_FastSubclass(Py_TYPE(type), Py_TPFLAGS_TYPE_SUBCLASS); + long tp_flags = getTpFlagsNode.readFromObj(PythonNativeClass.cast(type), PyTypeObject__tp_flags); + return (tp_flags & TYPE_SUBCLASS) != 0; } return false; } @@ -1946,7 +1944,7 @@ protected PythonClass makeType(VirtualFrame frame, PDict namespaceOrig, TruffleS @Cached("create(T___SET_NAME__)") LookupSpecialMethodNode getSetNameNode, @Cached CallNode callSetNameNode, @Cached CallNode callInitSubclassNode, - @Cached("create(T___INIT_SUBCLASS__)") GetAttributeNode getInitSubclassNode, + @Cached("create(T___INIT_SUBCLASS__)") GetFixedAttributeNode getInitSubclassNode, @Cached GetMroStorageNode getMroStorageNode, @Bind PythonLanguage language, @Cached PRaiseNode raise, @@ -2062,7 +2060,7 @@ protected PythonClass makeType(VirtualFrame frame, PDict namespaceOrig, TruffleS // Call __init_subclass__ on the parent of a newly generated type SuperObject superObject = PFactory.createSuperObject(language); superObject.init(newType, newType, newType); - callInitSubclassNode.execute(frame, getInitSubclassNode.executeObject(frame, superObject), PythonUtils.EMPTY_OBJECT_ARRAY, kwds); + callInitSubclassNode.execute(frame, getInitSubclassNode.execute(frame, superObject), PythonUtils.EMPTY_OBJECT_ARRAY, kwds); newType.initializeMroShape(language); 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 7ee448e3ab..505c6954e0 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 @@ -81,6 +81,7 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; @@ -196,6 +197,7 @@ public final Object executeCached(VirtualFrame frame, TpSlot slot, Object self, return execute(frame, this, slot, self, obj, type); } + @NeverDefault public static CallSlotDescrGet create() { return CallSlotDescrGetNodeGen.create(); } @@ -249,6 +251,22 @@ static Object callGenericBuiltin(VirtualFrame frame, Node inliningTarget, TpSlot RootCallTarget callTarget = PythonLanguage.get(inliningTarget).getBuiltinSlotCallTarget(slot.callTargetIndex); return invoke.execute(frame, inliningTarget, callTarget, arguments); } + + @GenerateInline + @GenerateCached(false) + public abstract static class Lazy extends Node { + + public final CallSlotDescrGet get(Node inliningTarget) { + return execute(inliningTarget); + } + + abstract CallSlotDescrGet execute(Node inliningTarget); + + @Specialization + static CallSlotDescrGet doIt(@Cached(inline = false) CallSlotDescrGet node) { + return node; + } + } } /** 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 1d4f19d977..24a5ec9013 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 @@ -122,8 +122,8 @@ public abstract static class GetAttrBuiltinNode extends PythonBinaryBuiltinNode // "__getattr__" can be AST inlined, and such that when the Python wrapper is explicitly // called, the builtin does the conversion of the second argument to TruffleString itself. // - // The builtins should have a @Specialization that does the coercion to TruffleString and - // also fast-path specialization for TruffleString as the 2nd argument. + // The builtins should have a single @Specialization that does the coercion to + // TruffleString. } public static final class TpSlotGetAttrPython extends TpSlotPython { 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 14499295bf..0b13ed9c58 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 @@ -374,7 +374,7 @@ static Object doStaticmethod(PDecoratedMethod descriptor, @SuppressWarnings("unu } protected static boolean isStaticmethod(PDecoratedMethod descriptor) { - return descriptor.getInitialPythonClass() == PythonBuiltinClassType.PStaticmethod; + return descriptor.getPythonClass() == PythonBuiltinClassType.PStaticmethod; } @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java index 632e2ee604..6f4c7d7614 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/types/UnionTypeBuiltins.java @@ -64,6 +64,7 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; import com.oracle.graal.python.builtins.objects.set.PFrozenSet; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; @@ -84,8 +85,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.nodes.util.CannotCastException; -import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -192,17 +191,12 @@ abstract static class GetAttributeNode extends GetAttrBuiltinNode { @Specialization Object getattribute(VirtualFrame frame, PUnionType self, Object nameObj, @Bind Node inliningTarget, - @Cached CastToTruffleStringNode cast, + @Cached CastToTruffleStringChecked1Node castToString, @Cached TruffleString.EqualNode equalNode, @Cached GetClassNode getClassNode, @Cached PyObjectGetAttr getAttr, @Cached ObjectBuiltins.GetAttributeNode genericGetAttribute) { - TruffleString name; - try { - name = cast.execute(inliningTarget, nameObj); - } catch (CannotCastException e) { - return genericGetAttribute.execute(frame, self, nameObj); - } + TruffleString name = castToString.cast(inliningTarget, nameObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, nameObj); if (equalNode.execute(name, T___MODULE__, TS_ENCODING)) { return getAttr.execute(frame, inliningTarget, getClassNode.execute(inliningTarget, self), name); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java index 19944d57aa..9910df78d5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java @@ -44,8 +44,9 @@ import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.CallSlotGetAttrNode; +import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; @@ -106,7 +107,7 @@ static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, Object result = PyObjectLookupAttr.readAttributeQuickly(type, slots, receiver, name, codePointLengthNode, codePointAtIndexNode); if (result != null) { if (result == PNone.NO_VALUE) { - throw PRaiseNode.raiseAttributeErrorStatic(inliningTarget, receiver, name); + throw PRaiseNode.raiseAttributeErrorStatic(inliningTarget, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); } return result; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java index 5cc725f3a2..695a081960 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java @@ -50,6 +50,7 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet; +import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; @@ -66,7 +67,6 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; -import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -104,24 +104,23 @@ protected static boolean isObjectGetAttribute(Node inliningTarget, GetCachedTpSl } // isObjectGetAttribute implies not foreign - @Specialization(guards = {"isObjectGetAttribute(inliningTarget, getTypeSlotsNode, lazyClass)", "name == cachedName"}, limit = "1") - static Object getFixedAttr(VirtualFrame frame, Node inliningTarget, Object receiver, @SuppressWarnings("unused") TruffleString name, - @SuppressWarnings("unused") /* Truffle bug: @Shared("getClassNode") */ @Exclusive @Cached GetClassNode getClass, - @SuppressWarnings("unused") @Exclusive @Cached GetCachedTpSlotsNode getTypeSlotsNode, + @Specialization(guards = "isObjectGetAttribute(inliningTarget, getTypeSlotsNode, lazyClass)", limit = "1") + static Object getAttr(VirtualFrame frame, Node inliningTarget, Object receiver, TruffleString name, + @Cached GetClassNode getClass, + @Cached GetCachedTpSlotsNode getTypeSlotsNode, @Bind("getClass.execute(inliningTarget, receiver)") Object lazyClass, - @SuppressWarnings("unused") @Cached("name") TruffleString cachedName, - @Cached("create(name)") LookupAttributeInMRONode lookupNode, - @Exclusive @Cached GetObjectSlotsNode getSlotsNode, - @Exclusive @Cached CallSlotDescrGet callGetNode, - @Shared("readAttr") @Cached(inline = false) ReadAttributeFromObjectNode readAttr, - @Exclusive @Cached PRaiseNode raiseNode, + @Cached LookupAttributeInMRONode.Dynamic lookupNode, + @Cached GetObjectSlotsNode getSlotsNode, + @Cached CallSlotDescrGet callGetNode, + @Cached ReadAttributeFromObjectNode readAttr, + @Cached PRaiseNode raiseNode, @Cached InlinedBranchProfile hasDescr, @Cached InlinedBranchProfile returnDataDescr, @Cached InlinedBranchProfile returnAttr, @Cached InlinedBranchProfile returnUnboundMethod, @Cached InlinedBranchProfile returnBoundDescr) { boolean methodFound = false; - Object descr = lookupNode.execute(lazyClass); + Object descr = lookupNode.execute(lazyClass, name); TpSlot getMethod = null; if (descr != PNone.NO_VALUE) { hasDescr.enter(inliningTarget); @@ -157,52 +156,7 @@ static Object getFixedAttr(VirtualFrame frame, Node inliningTarget, Object recei if (descr != PNone.NO_VALUE) { return new BoundDescriptor(descr); } - throw raiseNode.raiseAttributeError(inliningTarget, receiver, name); - } - - // No explicit branch profiling when we're looking up multiple things - // isObjectGetAttribute implies not foreign - @Specialization(guards = "isObjectGetAttribute(inliningTarget, getTypeSlotsNode, lazyClass)", replaces = "getFixedAttr", limit = "1") - @InliningCutoff - static Object getDynamicAttr(Frame frame, Node inliningTarget, Object receiver, TruffleString name, - @SuppressWarnings("unused") @Exclusive @Cached GetClassNode getClass, - @SuppressWarnings("unused") @Exclusive @Cached GetCachedTpSlotsNode getTypeSlotsNode, - @Bind("getClass.execute(inliningTarget, receiver)") Object lazyClass, - @Cached(inline = false) LookupAttributeInMRONode.Dynamic lookupNode, - @Exclusive @Cached GetObjectSlotsNode getSlotsNode, - @Exclusive @Cached CallSlotDescrGet callGetNode, - @Shared("readAttr") @Cached(inline = false) ReadAttributeFromObjectNode readAttr, - /* Truffle bug: @Shared("raiseNode") */ @Exclusive @Cached PRaiseNode raiseNode) { - boolean methodFound = false; - Object descr = lookupNode.execute(lazyClass, name); - TpSlot getMethod = null; - if (descr != PNone.NO_VALUE) { - if (MaybeBindDescriptorNode.isMethodDescriptor(descr)) { - methodFound = true; - } else { - var descrSlots = getSlotsNode.execute(inliningTarget, descr); - getMethod = descrSlots.tp_descr_get(); - if (getMethod != null && TpSlotDescrSet.PyDescr_IsData(descrSlots)) { - return new BoundDescriptor(callGetNode.execute((VirtualFrame) frame, inliningTarget, getMethod, descr, receiver, lazyClass)); - } - } - } - if (receiver instanceof PythonAbstractObject) { - Object attr = readAttr.execute(receiver, name); - if (attr != PNone.NO_VALUE) { - return new BoundDescriptor(attr); - } - } - if (methodFound) { - return descr; - } - if (getMethod != null) { - return new BoundDescriptor(callGetNode.execute((VirtualFrame) frame, inliningTarget, getMethod, descr, receiver, lazyClass)); - } - if (descr != PNone.NO_VALUE) { - return new BoundDescriptor(descr); - } - throw raiseNode.raiseAttributeError(inliningTarget, receiver, name); + throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name); } @Specialization(guards = "isForeignObject(inliningTarget, isForeignObjectNode, receiver)", limit = "1") diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java index f537089835..5cde8dbecb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java @@ -66,6 +66,7 @@ import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; @@ -106,7 +107,7 @@ public final Object executeCached(Frame frame, Object receiver, TruffleString na public abstract Object execute(Frame frame, Node inliningTarget, Object receiver, TruffleString name); protected static boolean hasNoGetAttr(Object lazyClass) { - // only used in asserts + CompilerAsserts.neverPartOfCompilation("only used in asserts"); return LookupAttributeInMRONode.Dynamic.getUncached().execute(lazyClass, T___GETATTR__) == PNone.NO_VALUE; } @@ -145,7 +146,7 @@ static Object doBuiltinObject(VirtualFrame frame, Node inliningTarget, Object ob @Bind("getClass.execute(inliningTarget, object)") Object type, @Cached("create(name)") LookupAttributeInMRONode lookupName, @Bind("lookupName.execute(type)") Object descr, - @Shared @Cached(inline = false) ReadAttributeFromObjectNode readNode) { + @Shared @Cached ReadAttributeFromObjectNode readNode) { // It should not have __getattr__, because otherwise it would not have builtin // object#tp_getattro, but slot wrapper dispatching to __getattribute__ or __getattr__ assert hasNoGetAttr(type); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java index eef07b14b5..703bb29735 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/HiddenAttr.java @@ -40,7 +40,6 @@ */ package com.oracle.graal.python.nodes; -import static com.oracle.graal.python.builtins.objects.object.PythonObject.CLASS_CHANGED_FLAG; import static com.oracle.graal.python.builtins.objects.object.PythonObject.HAS_MATERIALIZED_DICT; import static com.oracle.graal.python.nodes.BuiltinNames.J___GRAALPYTHON_INTEROP_BEHAVIOR__; import static com.oracle.graal.python.nodes.SpecialAttributeNames.J___BASICSIZE__; @@ -69,7 +68,6 @@ public final class HiddenAttr { public static final HiddenAttr OBJECT_ID = new HiddenAttr("_id"); // ObjectNodes - public static final HiddenAttr CLASS = new HiddenAttr("ob_type"); public static final HiddenAttr DICT = new HiddenAttr("ob_dict"); public static final HiddenAttr DICTOFFSET = new HiddenAttr(J___DICTOFFSET__); public static final HiddenAttr WEAKLISTOFFSET = new HiddenAttr(J___WEAKLISTOFFSET__); @@ -111,11 +109,6 @@ private HiddenAttr(String keyName) { key = new HiddenKey(keyName); } - // temporary, will be removed when we have no DynamicObjects and Shapes - public static HiddenKey getClassHiddenKey() { - return CLASS.key; - } - public String getName() { return key.getName(); } @@ -178,18 +171,7 @@ static void doPythonObjectDict(PythonObject self, HiddenAttr attr, Object value, dylib.put(self, DICT.key, value); } - @Specialization(guards = "attr == CLASS") - static void doPythonObjectClass(PythonObject self, HiddenAttr attr, Object value, - @Shared @CachedLibrary(limit = "3") DynamicObjectLibrary dylib) { - // n.b.: the CLASS property is usually a constant property that is stored in the shape - // in - // single-context-mode. If we change it for the first time, there's an implicit shape - // transition - dylib.setShapeFlags(self, dylib.getShapeFlags(self) | CLASS_CHANGED_FLAG); - dylib.put(self, CLASS.key, value); - } - - @Specialization(guards = "!isSpecialCaseAttr(attr) || !isPythonObject(self)") + @Specialization(guards = "attr != DICT || !isPythonObject(self)") static void doGeneric(PythonAbstractObject self, HiddenAttr attr, Object value, @Shared @CachedLibrary(limit = "3") DynamicObjectLibrary dylib) { dylib.put(self, attr.key, value); @@ -199,10 +181,6 @@ protected static boolean isPythonObject(Object object) { return object instanceof PythonObject; } - protected static boolean isSpecialCaseAttr(HiddenAttr attr) { - return attr == DICT || attr == CLASS; - } - @NeverDefault public static WriteNode create() { return WriteNodeGen.create(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java index b25e29ddaf..582abf13d2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java @@ -96,6 +96,7 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode; +import com.oracle.graal.python.nodes.object.IsForeignObjectNode; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.sequence.PSequence; @@ -254,6 +255,7 @@ public static boolean isNativeClass(Object klass) { return PythonNativeClass.isInstance(klass); } + @Idempotent public static boolean isPythonClass(Object klass) { return PythonAbstractClass.isInstance(klass) || klass instanceof PythonBuiltinClassType; } @@ -294,6 +296,10 @@ public static boolean isAnyPythonObject(Object obj) { return obj instanceof PythonAbstractObject; } + public static boolean isForeignObject(Object obj) { + return IsForeignObjectNode.executeUncached(obj); + } + public static boolean canBeInteger(Object idx) { return isBoolean(idx) || isInteger(idx) || isPInt(idx); } @@ -307,12 +313,7 @@ public static boolean isPInt(Object obj) { } public static boolean isBuiltinPInt(PInt obj) { - /* - * int's __class__ cannot be reassigned and other objects cannot have their class assigned - * to builtin int, so it is enough to look at the initial class. PInt constructor ensures - * that it cannot be PythonBuiltinClass. - */ - return obj.getInitialPythonClass() == PythonBuiltinClassType.PInt; + return obj.getPythonClass() == PythonBuiltinClassType.PInt; } public static boolean isPString(Object obj) { @@ -460,14 +461,7 @@ public static double expectDouble(Object result) throws UnexpectedResultExceptio } private static boolean isBuiltinImmutableTypeInstance(PythonObject dict, PythonBuiltinClassType type) { - /* - * Immutable types' __class__ cannot be reassigned and other objects cannot have their class - * assigned to immutable types, so it is enough to look at the initial class. The Java - * constructor of the object must ensure that it cannot be PythonBuiltinClass, see PDict for - * an example. - */ - assert !(dict.getInitialPythonClass() instanceof PythonBuiltinClass pbc) || pbc.getType() != type; - return dict.getInitialPythonClass() == type; + return dict.getPythonClass() == type; } public static boolean isBuiltinDict(PythonObject dict) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java index 4193ff53e6..69fce9795d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseNode.java @@ -52,6 +52,7 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; @@ -80,6 +81,7 @@ public final PException raise(Node inliningTarget, PythonBuiltinClassType type) throw raiseStatic(inliningTarget, type); } + @InliningCutoff public static PException raiseStatic(Node node, PythonBuiltinClassType type) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type); @@ -91,6 +93,7 @@ public final PException raise(Node inliningTarget, PythonBuiltinClassType type, throw raiseStatic(inliningTarget, type, message); } + @InliningCutoff public static PException raiseStatic(Node node, PythonBuiltinClassType type, TruffleString message) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, message); @@ -102,6 +105,7 @@ public final PException raise(Node inliningTarget, PythonBuiltinClassType type, throw raiseStatic(inliningTarget, type, format, formatArgs); } + @InliningCutoff public static PException raiseStatic(Node node, PythonBuiltinClassType type, TruffleString message, Object... formatArgs) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, message, formatArgs); @@ -113,6 +117,7 @@ public final PException raise(Node inliningTarget, PythonBuiltinClassType type, throw raiseStatic(inliningTarget, type, arguments); } + @InliningCutoff public static PException raiseStatic(Node node, PythonBuiltinClassType type, Object[] arguments) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, PFactory.createTuple(language, arguments)); @@ -124,19 +129,21 @@ public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassTyp throw raiseWithDataStatic(inliningTarget, type, data); } + @InliningCutoff public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, data, null); throw raiseExceptionObjectStatic(node, pythonException, language); } - public final PException raiseAttributeError(Node inliningTarget, Object obj, Object key) { + public final PException raiseAttributeError(Node inliningTarget, TruffleString errorMessage, Object obj, Object key) { executeEnterProfile(inliningTarget); - throw raiseAttributeErrorStatic(inliningTarget, obj, key); + throw raiseAttributeErrorStatic(inliningTarget, errorMessage, obj, key); } - public static PException raiseAttributeErrorStatic(Node inliningTarget, Object obj, Object key) { - throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.AttributeError, AttributeErrorBuiltins.dataForObjKey(obj, key), ErrorMessages.OBJ_P_HAS_NO_ATTR_S, obj, key); + @InliningCutoff + public static PException raiseAttributeErrorStatic(Node inliningTarget, TruffleString errorMessage, Object obj, Object key) { + throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.AttributeError, AttributeErrorBuiltins.dataForObjKey(obj, key), errorMessage, obj, key); } public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) { @@ -144,6 +151,7 @@ public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassTyp throw raiseWithDataStatic(inliningTarget, type, data, format, formatArgs); } + @InliningCutoff public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data, TruffleString format, Object... formatArgs) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, data, format, formatArgs); @@ -155,6 +163,7 @@ public final PException raiseWithData(Node inliningTarget, PythonBuiltinClassTyp throw raiseWithDataStatic(inliningTarget, type, data, arguments); } + @InliningCutoff public static PException raiseWithDataStatic(Node node, PythonBuiltinClassType type, Object[] data, Object[] arguments) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, data, PFactory.createTuple(language, arguments)); @@ -166,6 +175,7 @@ public final PException raise(Node inliningTarget, PythonBuiltinClassType type, throw raiseStatic(inliningTarget, type, e); } + @InliningCutoff public static PException raiseStatic(Node node, PythonBuiltinClassType type, Exception e) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, ErrorMessages.M, new Object[]{e}); @@ -184,6 +194,7 @@ public final PException raiseWithCause(Node inliningTarget, PythonBuiltinClassTy throw raiseWithCauseStatic(inliningTarget, type, cause, format); } + @InliningCutoff public static PException raiseWithCauseStatic(Node node, PythonBuiltinClassType type, PException cause, TruffleString format) { PythonLanguage language = PythonLanguage.get(node); PBaseException pythonException = PFactory.createBaseException(language, type, format); @@ -197,6 +208,7 @@ public final PException raiseWithCause(Node inliningTarget, PythonBuiltinClassTy throw raiseWithCauseStatic(inliningTarget, type, cause, format, arguments); } + @InliningCutoff public static PException raiseWithCauseStatic(Node node, PythonBuiltinClassType type, PException cause, TruffleString format, Object... formatArgs) { assert PyExceptionInstanceCheckNode.executeUncached(cause); PythonLanguage language = PythonLanguage.get(node); @@ -209,6 +221,7 @@ public final PException raiseOverflow(Node inliningTarget) { throw raise(inliningTarget, OverflowError, ErrorMessages.CANNOT_FIT_P_INTO_INDEXSIZED_INT, 0); } + @InliningCutoff public static PException raiseSystemExitStatic(Node inliningTarget, Object code) { throw raiseWithDataStatic(inliningTarget, PythonBuiltinClassType.SystemExit, new Object[]{code}, new Object[]{code}); } @@ -229,18 +242,28 @@ public final PException raiseBadInternalCall(Node inliningTarget) { throw raise(inliningTarget, PythonBuiltinClassType.SystemError, BAD_ARG_TO_INTERNAL_FUNC); } - public final PException raiseExceptionObject(Node raisingNode, Object exc) { - throw raiseExceptionObjectStatic(raisingNode, exc); + public final PException raiseExceptionObject(Node inliningTarget, Object exc) { + executeEnterProfile(inliningTarget); + throw raiseExceptionObjectStaticCutoff(inliningTarget, exc); + } + + @InliningCutoff + private static PException raiseExceptionObjectStaticCutoff(Node inliningTarget, Object exc) { + return raiseExceptionObjectStatic(inliningTarget, exc); } + // No @InliningCutoff, callers either cutoff already, or they are nodes which only throw an + // exception and so we want to host inline public static PException raiseExceptionObjectStatic(Node raisingNode, Object exc) { throw raiseExceptionObjectStatic(raisingNode, exc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(raisingNode))); } - public static PException raiseExceptionObjectStatic(Node raisingNode, Object exc, PythonLanguage language) { + // No @InliningCutoff, done in callers already + private static PException raiseExceptionObjectStatic(Node raisingNode, Object exc, PythonLanguage language) { throw raiseExceptionObjectStatic(raisingNode, exc, PythonOptions.isPExceptionWithJavaStacktrace(language)); } + // No @InliningCutoff, done in callers already public static PException raiseExceptionObjectStatic(Node raisingNode, Object exc, boolean withJavaStacktrace) { if (raisingNode != null && raisingNode.isAdoptable()) { throw PException.fromObject(exc, raisingNode, withJavaStacktrace); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java index 48130441df..b6247f006a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/keywords/ConcatDictToStorageNode.java @@ -100,7 +100,7 @@ static HashingStorage doBuiltinDict(VirtualFrame frame, HashingStorage dest, PDi @Cached HashingStorageNodes.HashingStorageIteratorKey iterKey, @Cached HashingStorageNodes.HashingStorageIteratorValue iterValue, @Exclusive @Cached InlinedLoopConditionProfile loopProfile, - @Exclusive @Cached StringNodes.CastToTruffleStringCheckedNode castToStringNode, + @Exclusive @Cached StringNodes.CastToTruffleStringChecked0Node castToStringNode, @Exclusive @Cached InlinedBranchProfile sameKeyProfile) throws SameDictKeyException { HashingStorage result = dest; HashingStorage otherStorage = other.getDictStorage(); @@ -129,7 +129,7 @@ static HashingStorage doMapping(VirtualFrame frame, HashingStorage dest, Object @SuppressWarnings("unused") @Exclusive @Cached GetPythonObjectClassNode getClassNode, @SuppressWarnings("unused") @Exclusive @Cached GetCachedTpSlotsNode getSlots, @Exclusive @Cached InlinedBranchProfile sameKeyProfile, - @Exclusive @Cached StringNodes.CastToTruffleStringCheckedNode castToStringNode, + @Exclusive @Cached StringNodes.CastToTruffleStringChecked0Node castToStringNode, @Cached PyObjectCallMethodObjArgs callKeys, @Cached IsBuiltinObjectProfile errorProfile, @Cached ListNodes.FastConstructListNode asList, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java deleted file mode 100644 index 16d5eb25b3..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2017, 2025, 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 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.nodes.attributes; - -import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTR__; - -import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; -import com.oracle.graal.python.builtins.objects.module.ModuleBuiltins; -import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; -import com.oracle.graal.python.builtins.objects.type.TpSlots; -import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; -import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; -import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.CallSlotGetAttrNode; -import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.GetAttributeNodeFactory.GetFixedAttributeNodeGen; -import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NeverDefault; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -public final class GetAttributeNode extends PNodeWithContext { - - @Child private GetFixedAttributeNode getFixedAttributeNode; - - public Object executeObject(VirtualFrame frame, Object object) { - return getFixedAttributeNode.executeObject(frame, object); - } - - protected GetAttributeNode(TruffleString key) { - getFixedAttributeNode = GetFixedAttributeNode.create(key); - } - - @NeverDefault - public static GetAttributeNode create(TruffleString key) { - return new GetAttributeNode(key); - } - - @SuppressWarnings("truffle-static-method") - public abstract static class GetFixedAttributeNode extends PNodeWithContext { - private final TruffleString key; - @Child private GetObjectSlotsNode getSlotsNode = GetObjectSlotsNode.create(); - - public GetFixedAttributeNode(TruffleString key) { - this.key = key; - } - - public final TruffleString getKey() { - return key; - } - - public final Object executeObject(VirtualFrame frame, Object object) { - return execute(frame, object); - } - - public final Object execute(VirtualFrame frame, Object object) { - return executeImpl(frame, object, getSlotsNode.executeCached(object)); - } - - abstract Object executeImpl(VirtualFrame frame, Object object, TpSlots slots); - - protected static boolean hasNoGetAttr(Object obj) { - // only used in asserts - return LookupAttributeInMRONode.Dynamic.getUncached().execute(GetClassNode.executeUncached(obj), T___GETATTR__) == PNone.NO_VALUE; - } - - protected static boolean isObjectGetAttribute(TpSlots slots) { - return slots.tp_getattro() == ObjectBuiltins.SLOTS.tp_getattro(); - } - - protected static boolean isModuleGetAttribute(TpSlots slots) { - return slots.tp_getattro() == ModuleBuiltins.SLOTS.tp_getattro(); - } - - protected static boolean isTypeGetAttribute(TpSlots slots) { - return slots.tp_getattro() == TypeBuiltins.SLOTS.tp_getattro(); - } - - @Specialization(guards = "isObjectGetAttribute(slots)") - final Object doBuiltinObject(VirtualFrame frame, Object object, @SuppressWarnings("unused") TpSlots slots, - @Cached ObjectBuiltins.GetAttributeNode getAttributeNode) { - assert hasNoGetAttr(object); - return getAttributeNode.execute(frame, object, key); - } - - @Specialization(guards = "isTypeGetAttribute(slots)") - final Object doBuiltinType(VirtualFrame frame, Object object, @SuppressWarnings("unused") TpSlots slots, - @Cached TypeBuiltins.GetattributeNode getAttributeNode) { - assert hasNoGetAttr(object); - return getAttributeNode.execute(frame, object, key); - } - - @Specialization(guards = "isModuleGetAttribute(slots)") - final Object doBuiltinModule(VirtualFrame frame, Object object, @SuppressWarnings("unused") TpSlots slots, - @Cached ModuleBuiltins.ModuleGetattributeNode getAttributeNode) { - assert hasNoGetAttr(object); - return getAttributeNode.execute(frame, object, key); - } - - @Specialization(replaces = {"doBuiltinObject", "doBuiltinType", "doBuiltinModule"}) - final Object doGeneric(VirtualFrame frame, Object object, TpSlots slots, - @Bind Node inliningTarget, - @Cached CallSlotGetAttrNode callGetAttrNode, - @Cached AttributeErrorBuiltins.SetAttributeErrorContext setContext) { - try { - return callGetAttrNode.execute(frame, inliningTarget, slots, object, key); - } catch (PException e) { - throw setContext.execute(inliningTarget, e, object, key); - } - } - - @NeverDefault - public static GetFixedAttributeNode create(TruffleString key) { - return GetFixedAttributeNodeGen.create(key); - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetFixedAttributeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetFixedAttributeNode.java new file mode 100644 index 0000000000..5f8aa4aa6b --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetFixedAttributeNode.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017, 2025, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.attributes; + +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; + +public abstract class GetFixedAttributeNode extends PNodeWithContext { + private final TruffleString key; + + GetFixedAttributeNode(TruffleString key) { + this.key = key; + } + + public abstract Object execute(VirtualFrame frame, Object object); + + @Specialization + Object doIt(VirtualFrame frame, Object object, + @Bind Node inliningTarget, + @Cached GetClassNode getClassNode, + @Cached GetCachedTpSlotsNode getSlotsNode, + @Cached MergedObjectTypeModuleGetAttributeInnerNode innerNode) { + Object type = getClassNode.execute(inliningTarget, object); + TpSlots slots = getSlotsNode.execute(inliningTarget, type); + return innerNode.execute(frame, inliningTarget, object, key, type, slots); + } + + @NeverDefault + public static GetFixedAttributeNode create(TruffleString key) { + return GetFixedAttributeNodeGen.create(key); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java index 9010e15245..62e11326e7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/LookupAttributeInMRONode.java @@ -44,13 +44,13 @@ import com.oracle.graal.python.builtins.Python3Core; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.str.StringUtils; import com.oracle.graal.python.builtins.objects.type.MroShape; import com.oracle.graal.python.builtins.objects.type.MroShape.MroShapeLookupResult; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.builtins.objects.type.PythonClass; -import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode; -import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.IsSameTypeNodeGen; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; @@ -62,7 +62,6 @@ import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; @@ -71,12 +70,12 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.ReportPolymorphism.Megamorphic; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.ControlFlowException; import com.oracle.truffle.api.nodes.ExplodeLoop; +import com.oracle.truffle.api.nodes.ExplodeLoop.LoopExplosionKind; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.DynamicObjectLibrary; import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; @ImportStatic(PythonOptions.class) @@ -89,28 +88,29 @@ public abstract class LookupAttributeInMRONode extends PNodeWithContext { public abstract static class Dynamic extends PNodeWithContext { public abstract Object execute(Object klass, TruffleString key); - @Specialization(guards = "stringEquals(key, cachedKey, equalNode)", limit = "2") - protected static Object lookupConstantMRO(Object klass, @SuppressWarnings("unused") TruffleString key, - @Cached("key") @SuppressWarnings("unused") TruffleString cachedKey, - @Cached @SuppressWarnings("unused") TruffleString.EqualNode equalNode, - @Cached("create(key)") LookupAttributeInMRONode lookup) { + @Specialization(guards = "equalNode.execute(inliningTarget, key, cachedKey)", limit = "2") + static Object lookupConstantMROEquals(Object klass, TruffleString key, + @Bind Node inliningTarget, + @Cached("key") TruffleString cachedKey, + @Cached @Shared StringUtils.EqualNode equalNode, + @Cached("create(cachedKey)") LookupAttributeInMRONode lookup) { return lookup.execute(klass); } - @Specialization(replaces = "lookupConstantMRO") - @InliningCutoff - protected Object lookupInBuiltinType(PythonBuiltinClassType klass, TruffleString key, - @Cached ReadAttributeFromPythonObjectNode readAttrNode) { - return findAttr(PythonContext.get(this), klass, key, readAttrNode); - } - - @Specialization(replaces = "lookupConstantMRO") + // Merged PythonBuiltinClassType and generic cases to have single @InliningCutoff @InliningCutoff - protected static Object lookupGeneric(Object klass, TruffleString key, + @Specialization(replaces = "lookupConstantMROEquals") + static Object lookupGeneric(Object klass, TruffleString key, @Bind Node inliningTarget, + @Cached InlinedConditionProfile pbctProfile, + @Cached ReadAttributeFromPythonObjectNode readPBCTAttrNode, @Cached GetMroStorageNode getMroNode, - @Cached(value = "createForceType()", uncached = "getUncachedForceType()") ReadAttributeFromObjectNode readAttrNode) { - return lookup(key, getMroNode.execute(inliningTarget, klass), readAttrNode, false, DynamicObjectLibrary.getUncached()); + @Cached ReadAttributeFromObjectNode readAttrNode) { + if (pbctProfile.profile(inliningTarget, klass instanceof PythonBuiltinClassType)) { + return findAttr(PythonContext.get(inliningTarget), (PythonBuiltinClassType) klass, key, readPBCTAttrNode); + } else { + return lookup(key, getMroNode.execute(inliningTarget, klass), readAttrNode, false); + } } @NeverDefault @@ -124,9 +124,7 @@ public static LookupAttributeInMRONode.Dynamic getUncached() { } private final boolean skipNonStaticBases; - protected final TruffleString key; - @Child private TypeNodes.IsSameTypeNode isSameTypeNode; - @Child private GetMroStorageNode getMroNode; + final TruffleString key; public LookupAttributeInMRONode(TruffleString key, boolean skipNonStaticBases) { this.key = key; @@ -147,7 +145,7 @@ public static LookupAttributeInMRONode createForLookupOfUnmanagedClasses(Truffle return LookupAttributeInMRONodeGen.create(key, true); } - protected static Object findAttr(Python3Core core, PythonBuiltinClassType klass, TruffleString key) { + static Object findAttr(Python3Core core, PythonBuiltinClassType klass, TruffleString key) { return findAttr(core, klass, key, ReadAttributeFromPythonObjectNode.getUncached()); } @@ -164,15 +162,8 @@ public static Object findAttr(Python3Core core, PythonBuiltinClassType klass, Tr return value; } - @Specialization(guards = {"isSingleContext()", "klass == cachedKlass"}, limit = "getAttributeAccessInlineCacheMaxDepth()") - protected static Object lookupPBCTCached(@SuppressWarnings("unused") PythonBuiltinClassType klass, - @Cached("klass") @SuppressWarnings("unused") PythonBuiltinClassType cachedKlass, - @Cached("findAttr(getContext(), cachedKlass, key)") Object cachedValue) { - return cachedValue; - } - @Idempotent - protected static boolean canCache(Object value) { + static boolean canCache(Object value) { return value instanceof Long || value instanceof Integer || value instanceof Boolean || @@ -180,46 +171,13 @@ protected static boolean canCache(Object value) { value instanceof PNone; } - @Specialization(guards = {"klass == cachedKlass", "canCache(cachedValue)"}, limit = "getAttributeAccessInlineCacheMaxDepth()") - protected static Object lookupPBCTCachedMulti(@SuppressWarnings("unused") PythonBuiltinClassType klass, - @Cached("klass") @SuppressWarnings("unused") PythonBuiltinClassType cachedKlass, + @Specialization(guards = {"klass == cachedKlass", "isSingleContext() || canCache(cachedValue)"}, limit = "getAttributeAccessInlineCacheMaxDepth()") + static Object lookupPBCTCached(PythonBuiltinClassType klass, + @Cached("klass") PythonBuiltinClassType cachedKlass, @Cached("findAttr(getContext(), cachedKlass, key)") Object cachedValue) { return cachedValue; } - public static PythonBuiltinClassType findOwnerInMro(Python3Core core, PythonBuiltinClassType klass, TruffleString key) { - PythonBuiltinClassType current = klass; - ReadAttributeFromPythonObjectNode readNode = ReadAttributeFromPythonObjectNode.getUncached(); - while (current != null) { - if (readNode.execute(core.lookupType(current), key) != PNone.NO_VALUE) { - return current; - } - current = current.getBase(); - } - return null; - } - - @Specialization(replaces = {"lookupPBCTCached", "lookupPBCTCachedMulti"}, guards = "klass == cachedKlass", // - limit = "getAttributeAccessInlineCacheMaxDepth()") - @InliningCutoff - protected Object lookupPBCTCachedOwner(@SuppressWarnings("unused") PythonBuiltinClassType klass, - @Cached("klass") @SuppressWarnings("unused") PythonBuiltinClassType cachedKlass, - @Cached("findOwnerInMro(getContext(), cachedKlass, key)") PythonBuiltinClassType ownerKlass, - @Shared @Cached ReadAttributeFromPythonObjectNode readAttrNode) { - if (ownerKlass == null) { - return PNone.NO_VALUE; - } else { - return readAttrNode.execute(PythonContext.get(this).lookupType(ownerKlass), key); - } - } - - @Specialization(replaces = "lookupPBCTCachedOwner") - @InliningCutoff - protected Object lookupPBCTGeneric(PythonBuiltinClassType klass, - @Shared @Cached ReadAttributeFromPythonObjectNode readAttrNode) { - return findAttr(PythonContext.get(this), klass, key, readAttrNode); - } - // PythonClass specializations: record AttributeAssumptionPair(Assumption assumption, Object value, boolean invalidate) { @@ -230,32 +188,31 @@ static final class InvalidateLookupException extends ControlFlowException { private static final InvalidateLookupException INSTANCE = new InvalidateLookupException(); } - private static boolean skipNonStaticBase(Object clsObj, boolean skipNonStaticBases, DynamicObjectLibrary dylib) { - return skipNonStaticBases && clsObj instanceof PythonClass && !((PythonClass) clsObj).isStaticBase(dylib); + private static boolean skipNonStaticBase(Object clsObj, boolean skipNonStaticBases) { + return skipNonStaticBases && clsObj instanceof PythonClass && !((PythonClass) clsObj).isStaticBase(); } - protected AttributeAssumptionPair findAttrAndAssumptionInMRO(Object klass) { + AttributeAssumptionPair findAttrAndAssumptionInMRO(Object klass) { CompilerAsserts.neverPartOfCompilation(); - DynamicObjectLibrary dylib = DynamicObjectLibrary.getUncached(); // Regarding potential side effects to MRO caused by __eq__ of the keys in the dicts that we // search through: CPython seems to read the MRO once and then compute the result also // ignoring the side effects. Moreover, CPython has lookup cache, so the side effects // may or may not be visible during subsequent lookups. We want to avoid triggering the side // effects twice, so we succeed this lookup no matter what, however, we will invalidate on // the next lookup if there were some MRO side effects. - MroSequenceStorage mro = getMro(klass); + MroSequenceStorage mro = GetMroStorageNode.executeUncached(klass); Assumption attrAssumption = mro.createAttributeInMROFinalAssumption(key); Object result = PNone.NO_VALUE; for (int i = 0; i < mro.length(); i++) { PythonAbstractClass clsObj = mro.getPythonClassItemNormalized(i); if (i > 0) { assert clsObj != klass : "MRO chain is incorrect: '" + klass + "' was found at position " + i; - getMro(clsObj).addAttributeInMROFinalAssumption(key, attrAssumption); + GetMroStorageNode.executeUncached(clsObj).addAttributeInMROFinalAssumption(key, attrAssumption); } - if (skipNonStaticBase(clsObj, skipNonStaticBases, dylib)) { + if (skipNonStaticBase(clsObj, skipNonStaticBases)) { continue; } - Object value = ReadAttributeFromObjectNode.getUncachedForceType().execute(clsObj, key); + Object value = ReadAttributeFromObjectNode.getUncached().execute(clsObj, key); if (value != PNone.NO_VALUE) { result = value; break; @@ -268,13 +225,14 @@ protected AttributeAssumptionPair findAttrAndAssumptionInMRO(Object klass) { } } - @Specialization(guards = {"isSingleContext()", "isSameType(cachedKlass, klass)", "cachedAttrInMROInfo != null"}, // + @Specialization(guards = {"isSingleContext()", "isSameTypeNode.execute(inliningTarget, cachedKlass, klass)", "cachedAttrInMROInfo != null"}, // limit = "getAttributeAccessInlineCacheMaxDepth()", // assumptions = "cachedAttrInMROInfo.assumption()", // rewriteOn = InvalidateLookupException.class) - protected static Object lookupConstantMROCached(@SuppressWarnings("unused") Object klass, + static Object lookupConstantMROCached(Object klass, @Bind Node inliningTarget, - @Cached("klass") @SuppressWarnings("unused") Object cachedKlass, + @Cached("klass") Object cachedKlass, + @Cached IsSameTypeNode isSameTypeNode, @Cached InlinedBranchProfile shouldInvalidate, @Cached("findAttrAndAssumptionInMRO(cachedKlass)") AttributeAssumptionPair cachedAttrInMROInfo) { if (shouldInvalidate.wasEntered(inliningTarget)) { @@ -287,127 +245,169 @@ protected static Object lookupConstantMROCached(@SuppressWarnings("unused") Obje return cachedAttrInMROInfo.value; } - public MroShapeLookupResult lookupInMroShape(MroShape shape, Object klass) { - assert MroShape.validate(klass, PythonLanguage.get(this)); - return shape.lookup(key); - } - - // This specialization works well only for multi-context mode - // Note: MroShape creation and updates are disabled in multi-context mode, see - // PythonClass#initializeMroShape - @Specialization(guards = {"!isSingleContext()", "cachedMroShape != null", "klass.getMroShape() == cachedMroShape"}, // - limit = "getAttributeAccessInlineCacheMaxDepth()") + // The slow-path specializations are extracted in a separate node to have a single cutoff from + // the fast path @InliningCutoff - protected Object lookupConstantMROShape(PythonClass klass, - @SuppressWarnings("unused") @Cached("klass.getMroShape()") MroShape cachedMroShape, - @Cached("lookupInMroShape(cachedMroShape, klass)") MroShapeLookupResult lookupResult) { - return lookupResult.getFromMro(getMro(klass), key); + @Specialization(replaces = {"lookupPBCTCached", "lookupConstantMROCached"}) + Object lookupSlowPath(Object klass, + @Cached SlowPath slowPathNode) { + return slowPathNode.execute(klass, key, skipNonStaticBases); } - @NeverDefault - protected static ReadAttributeFromObjectNode[] create(int size) { - ReadAttributeFromObjectNode[] nodes = new ReadAttributeFromObjectNode[size]; - for (int i = 0; i < size; i++) { - nodes[i] = ReadAttributeFromObjectNode.createForceType(); + public abstract static class SlowPath extends PNodeWithContext { + + @Child private GetMroStorageNode getMroNode; + + public abstract Object execute(Object klass, TruffleString key, boolean skipNonStaticBases); + + static PythonBuiltinClassType findOwnerInMro(Python3Core core, PythonBuiltinClassType klass, TruffleString key) { + PythonBuiltinClassType current = klass; + ReadAttributeFromPythonObjectNode readNode = ReadAttributeFromPythonObjectNode.getUncached(); + while (current != null) { + if (readNode.execute(core.lookupType(current), key) != PNone.NO_VALUE) { + return current; + } + current = current.getBase(); + } + return null; } - return nodes; - } - @Specialization(guards = {"isSingleContext()", "isSameType(cachedKlass, klass)", "mroLength < 32"}, // - limit = "getAttributeAccessInlineCacheMaxDepth()", // - replaces = "lookupConstantMROShape", // - assumptions = "lookupStable") - @ExplodeLoop(kind = ExplodeLoop.LoopExplosionKind.FULL_UNROLL_UNTIL_RETURN) - @InliningCutoff - protected Object lookupConstantMRO(@SuppressWarnings("unused") Object klass, - @Cached("klass") @SuppressWarnings("unused") Object cachedKlass, - @Cached("getMro(cachedKlass)") MroSequenceStorage mro, - @Cached("mro.getLookupStableAssumption()") @SuppressWarnings("unused") Assumption lookupStable, - @Cached("mro.length()") int mroLength, - @Exclusive @CachedLibrary(limit = "1") DynamicObjectLibrary dylib, - @Cached("create(mroLength)") ReadAttributeFromObjectNode[] readAttrNodes) { - for (int i = 0; i < mroLength; i++) { - Object kls = mro.getPythonClassItemNormalized(i); - if (skipNonStaticBase(kls, skipNonStaticBases, dylib)) { - continue; + // used to be replaces = lookupPBCTCached + @Specialization(guards = "klass == cachedKlass", limit = "getAttributeAccessInlineCacheMaxDepth()") + Object lookupPBCTCachedOwner(PythonBuiltinClassType klass, TruffleString key, boolean skipNonStaticBases, + @Cached("klass") PythonBuiltinClassType cachedKlass, + @Cached("findOwnerInMro(getContext(), cachedKlass, key)") PythonBuiltinClassType ownerKlass, + @Shared @Cached ReadAttributeFromPythonObjectNode readAttrNode) { + if (ownerKlass == null) { + return PNone.NO_VALUE; + } else { + return readAttrNode.execute(PythonContext.get(this).lookupType(ownerKlass), key); } - Object value = readAttrNodes[i].execute(kls, key); - if (value != PNone.NO_VALUE) { - return value; + } + + @Specialization(replaces = "lookupPBCTCachedOwner") + Object lookupPBCTGeneric(PythonBuiltinClassType klass, TruffleString key, boolean skipNonStaticBases, + @Shared @Cached ReadAttributeFromPythonObjectNode readAttrNode) { + return findAttr(PythonContext.get(this), klass, key, readAttrNode); + } + + // This specialization works well only for multi-context mode + // Note: MroShape creation and updates are disabled in multi-context mode, see + // PythonClass#initializeMroShape + @Specialization(guards = {"!isSingleContext()", "cachedMroShape != null", "klass.getMroShape() == cachedMroShape"}, // + limit = "getAttributeAccessInlineCacheMaxDepth()") + Object lookupConstantMROShape(PythonClass klass, TruffleString key, boolean skipNonStaticBases, + @Cached("klass.getMroShape()") MroShape cachedMroShape, + @Cached("lookupInMroShape(cachedMroShape, klass, key)") MroShapeLookupResult lookupResult) { + return lookupResult.getFromMro(getMro(klass), key); + } + + @NeverDefault + static ReadAttributeFromObjectNode[] create(int size) { + ReadAttributeFromObjectNode[] nodes = new ReadAttributeFromObjectNode[size]; + for (int i = 0; i < size; i++) { + nodes[i] = ReadAttributeFromObjectNode.create(); } + return nodes; } - return PNone.NO_VALUE; - } - @Specialization(guards = {"mroLength == cachedMroLength", "cachedMroLength < 32"}, // - replaces = {"lookupConstantMROCached", "lookupConstantMRO"}, // - limit = "getAttributeAccessInlineCacheMaxDepth()") - @ExplodeLoop(kind = ExplodeLoop.LoopExplosionKind.FULL_UNROLL_UNTIL_RETURN) - @InliningCutoff - protected Object lookupCachedLen(@SuppressWarnings("unused") Object klass, - @Bind("getMro(klass)") MroSequenceStorage mro, - @Bind("mro.length()") @SuppressWarnings("unused") int mroLength, - @Cached("mro.length()") int cachedMroLength, - @Exclusive @CachedLibrary(limit = "1") DynamicObjectLibrary dylib, - @Cached("create(cachedMroLength)") ReadAttributeFromObjectNode[] readAttrNodes) { - for (int i = 0; i < cachedMroLength; i++) { - Object kls = mro.getPythonClassItemNormalized(i); - if (skipNonStaticBase(kls, skipNonStaticBases, dylib)) { - continue; + @Specialization(guards = {"isSingleContext()", "isSameTypeNode.execute(inliningTarget, cachedKlass, klass)", "mroLength < 32"}, // + limit = "getAttributeAccessInlineCacheMaxDepth()", // + replaces = "lookupConstantMROShape", // + assumptions = "lookupStable") + @ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL_UNTIL_RETURN) + static Object lookupConstantMRO(Object klass, TruffleString key, boolean skipNonStaticBases, + @Bind Node inliningTarget, + @Cached("klass") Object cachedKlass, + @Cached IsSameTypeNode isSameTypeNode, + @Cached("getMroUncached(cachedKlass)") MroSequenceStorage mro, + @Cached("mro.getLookupStableAssumption()") Assumption lookupStable, + @Cached("mro.length()") int mroLength, + @Cached("create(mroLength)") ReadAttributeFromObjectNode[] readAttrNodes) { + for (int i = 0; i < mroLength; i++) { + Object kls = mro.getPythonClassItemNormalized(i); + if (skipNonStaticBase(kls, skipNonStaticBases)) { + continue; + } + Object value = readAttrNodes[i].execute(kls, key); + if (value != PNone.NO_VALUE) { + return value; + } } - Object value = readAttrNodes[i].execute(kls, key); - if (value != PNone.NO_VALUE) { - return value; + return PNone.NO_VALUE; + } + + // used to be replaces = lookupConstantMROCached + @Specialization(guards = {"mroLength == cachedMroLength", "cachedMroLength < 32"}, // + replaces = "lookupConstantMRO", // + limit = "getAttributeAccessInlineCacheMaxDepth()") + @ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL_UNTIL_RETURN) + Object lookupCachedLen(Object klass, TruffleString key, boolean skipNonStaticBases, + @Bind("getMro(klass)") MroSequenceStorage mro, + @Bind("mro.length()") int mroLength, + @Cached("mro.length()") int cachedMroLength, + @Cached("create(cachedMroLength)") ReadAttributeFromObjectNode[] readAttrNodes) { + for (int i = 0; i < cachedMroLength; i++) { + Object kls = mro.getPythonClassItemNormalized(i); + if (skipNonStaticBase(kls, skipNonStaticBases)) { + continue; + } + Object value = readAttrNodes[i].execute(kls, key); + if (value != PNone.NO_VALUE) { + return value; + } } + return PNone.NO_VALUE; } - return PNone.NO_VALUE; - } - @Specialization(replaces = {"lookupConstantMROCached", "lookupConstantMRO", "lookupCachedLen"}) - @Megamorphic - @InliningCutoff - protected Object lookupGeneric(Object klass, - @Exclusive @CachedLibrary(limit = "1") DynamicObjectLibrary dylib, - @Cached("createForceType()") ReadAttributeFromObjectNode readAttrNode) { - return lookup(key, getMro(klass), readAttrNode, skipNonStaticBases, dylib); - } + // used to be replaces = lookupConstantMROCached + @Specialization(replaces = {"lookupConstantMRO", "lookupCachedLen"}) + @Megamorphic + @InliningCutoff + Object lookupGeneric(Object klass, TruffleString key, boolean skipNonStaticBases, + @Cached ReadAttributeFromObjectNode readAttrNode) { + return lookup(key, getMro(klass), readAttrNode, skipNonStaticBases); + } - protected GetMroStorageNode ensureGetMroNode() { - if (getMroNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getMroNode = insert(GetMroStorageNode.create()); + public MroShapeLookupResult lookupInMroShape(MroShape shape, Object klass, TruffleString key) { + assert MroShape.validate(klass, PythonLanguage.get(this)); + return shape.lookup(key); + } + + GetMroStorageNode ensureGetMroNode() { + if (getMroNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getMroNode = insert(GetMroStorageNode.create()); + } + return getMroNode; + } + + MroSequenceStorage getMro(Object clazz) { + return ensureGetMroNode().executeCached(clazz); + } + + static MroSequenceStorage getMroUncached(Object clazz) { + return GetMroStorageNode.executeUncached(clazz); } - return getMroNode; - } - protected MroSequenceStorage getMro(Object clazz) { - return ensureGetMroNode().executeCached(clazz); } @TruffleBoundary public static Object lookupSlowPath(Object klass, TruffleString key) { - return lookup(key, GetMroStorageNode.executeUncached(klass), ReadAttributeFromObjectNode.getUncachedForceType(), false, DynamicObjectLibrary.getUncached()); + return lookup(key, GetMroStorageNode.executeUncached(klass), ReadAttributeFromObjectNode.getUncached(), false); } - public static Object lookup(TruffleString key, MroSequenceStorage mro, ReadAttributeFromObjectNode readAttrNode, boolean skipNonStaticBases, DynamicObjectLibrary dylib) { + public static Object lookup(TruffleString key, MroSequenceStorage mro, ReadAttributeFromObjectNode readTypeAttrNode, boolean skipNonStaticBases) { for (int i = 0; i < mro.length(); i++) { Object kls = mro.getPythonClassItemNormalized(i); - if (skipNonStaticBase(kls, skipNonStaticBases, dylib)) { + if (skipNonStaticBase(kls, skipNonStaticBases)) { continue; } - Object value = readAttrNode.execute(kls, key); + Object value = readTypeAttrNode.execute(kls, key); if (value != PNone.NO_VALUE) { return value; } } return PNone.NO_VALUE; } - - protected boolean isSameType(Object cachedKlass, Object klass) { - if (isSameTypeNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - isSameTypeNode = insert(IsSameTypeNodeGen.create()); - } - return isSameTypeNode.executeCached(cachedKlass, klass); - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java new file mode 100644 index 0000000000..86eb9cf947 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/MergedObjectTypeModuleGetAttributeNode.java @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2017, 2025, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.attributes; + +import static com.oracle.graal.python.nodes.SpecialMethodNames.T___GETATTR__; + +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.exception.AttributeErrorBuiltins; +import com.oracle.graal.python.builtins.objects.module.ModuleBuiltins; +import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; +import com.oracle.graal.python.builtins.objects.thread.ThreadLocalBuiltins; +import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TpSlots.GetObjectSlotsNode; +import com.oracle.graal.python.builtins.objects.type.TypeBuiltins; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrGet.CallSlotDescrGet; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet; +import com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.CallSlotGetAttrNode; +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.nodes.object.GetClassNode; +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Idempotent; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; +import com.oracle.truffle.api.strings.TruffleString; + +/** + * A node merging the logic of {@link ObjectBuiltins.GetAttributeNode}, + * {@link TypeBuiltins.GetattributeNode} and {@link ModuleBuiltins.ModuleGetattributeNode} to reduce + * code size by about 3x for host inlining + */ +@GenerateUncached +@GenerateInline +@GenerateCached(false) +public abstract class MergedObjectTypeModuleGetAttributeNode extends PNodeWithContext { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object object, Object keyObj); + + @Specialization + static Object doIt(VirtualFrame frame, Node inliningTarget, Object object, Object keyObj, + @Cached CastToTruffleStringChecked1Node castToString, + @Cached GetClassNode getClassNode, + @Cached GetCachedTpSlotsNode getSlotsNode, + @Cached MergedObjectTypeModuleGetAttributeInnerNode innerNode) { + TruffleString key = castToString.cast(inliningTarget, keyObj, ErrorMessages.ATTR_NAME_MUST_BE_STRING, keyObj); + Object type = getClassNode.execute(inliningTarget, object); + TpSlots slots = getSlotsNode.execute(inliningTarget, type); + return innerNode.execute(frame, inliningTarget, object, key, type, slots); + } +} + +@GenerateUncached +@GenerateInline +@GenerateCached(false) +abstract class MergedObjectTypeModuleGetAttributeInnerNode extends PNodeWithContext { + + public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, Object type, TpSlots slots); + + /** + * Keep in sync with {@link ObjectBuiltins.GetAttributeNode} and + * {@link TypeBuiltins.GetattributeNode} and {@link ModuleBuiltins.ModuleGetattributeNode} and + * {@link ThreadLocalBuiltins.GetAttributeNode} + */ + @Specialization(guards = {"slots.tp_getattro() == cachedSlot", "isObjectTypeModuleGetAttribute(cachedSlot)"}, limit = "1") + static Object doIt(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, Object type, @SuppressWarnings("unused") TpSlots slots, + @Cached("slots.tp_getattro()") TpSlot cachedSlot, + // Common + @Cached GetObjectSlotsNode getDescrSlotsNode, + @Cached LookupAttributeInMRONode.Dynamic lookup, + @Cached InlinedBranchProfile hasDescProfile, + @Cached InlinedConditionProfile hasDescrGetProfile, + @Cached InlinedBranchProfile hasValueProfile, + @Cached PRaiseNode raiseNode, + @Cached CallSlotDescrGet.Lazy callSlotDescrGet, + // Specific to a given tp_getattro, some should probably be lazy + @Cached ReadAttributeFromObjectNode readAttributeOfObjectNode, + @Cached LookupAttributeInMRONode.Dynamic readAttributeOfClassNode, + @Cached GetObjectSlotsNode getValueSlotsNode, + @Cached InlinedBranchProfile hasNonDescriptorValueProfile, + @Cached CallSlotDescrGet.Lazy callSlotValueGet, + @Cached ModuleBuiltins.LazyHandleGetattrExceptionNode handleException) { + assert hasNoGetAttr(object); + try { + Object descr = lookup.execute(type, key); + boolean hasDescr = descr != PNone.NO_VALUE; + + TpSlot get = null; + boolean hasDescrGet = false; + if (hasDescr) { + hasDescProfile.enter(inliningTarget); + var descrSlots = getDescrSlotsNode.execute(inliningTarget, descr); + get = descrSlots.tp_descr_get(); + hasDescrGet = hasDescrGetProfile.profile(inliningTarget, get != null); + if (hasDescrGet && TpSlotDescrSet.PyDescr_IsData(descrSlots)) { + return callSlotDescrGet.get(inliningTarget).executeCached(frame, get, descr, object, type); + } + } + + // The main difference between all 3 nodes + Object value; + if (cachedSlot != TypeBuiltins.SLOTS.tp_getattro()) { + // ObjectBuiltins.SLOTS.tp_getattro() || ModuleBuiltins.SLOTS.tp_getattro() + value = readAttributeOfObjectNode.execute(object, key); + if (value != PNone.NO_VALUE) { + hasValueProfile.enter(inliningTarget); + return value; + } + } else { + // TypeBuiltins.SLOTS.tp_getattro() + value = readAttributeOfClassNode.execute(object, key); + if (value != PNone.NO_VALUE) { + hasValueProfile.enter(inliningTarget); + var valueGet = getValueSlotsNode.execute(inliningTarget, value).tp_descr_get(); + if (valueGet == null) { + hasNonDescriptorValueProfile.enter(inliningTarget); + return value; + } else { + return callSlotValueGet.get(inliningTarget).executeCached(frame, valueGet, value, PNone.NO_VALUE, object); + } + } + } + + if (hasDescr) { + hasDescProfile.enter(inliningTarget); + if (!hasDescrGet) { + return descr; + } else { + return callSlotDescrGet.get(inliningTarget).executeCached(frame, get, descr, object, type); + } + } + + throw raiseNode.raiseAttributeError(inliningTarget, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + } catch (PException e) { + // Extra behavior for module.__getattribute__ + if (cachedSlot == ModuleBuiltins.SLOTS.tp_getattro()) { + return handleException.get(inliningTarget).execute(frame, (PythonModule) object, key, e); + } else { + throw e; + } + } + } + + @InliningCutoff + @Specialization(replaces = "doIt") + static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, @SuppressWarnings("unused") Object type, TpSlots slots, + @Cached CallSlotGetAttrNode callGetAttrNode, + @Cached AttributeErrorBuiltins.SetAttributeErrorContext setContext) { + try { + return callGetAttrNode.execute(frame, inliningTarget, slots, object, key); + } catch (PException e) { + throw setContext.execute(inliningTarget, e, object, key); + } + } + + @Idempotent + static boolean isObjectTypeModuleGetAttribute(TpSlot slot) { + return slot == ObjectBuiltins.SLOTS.tp_getattro() || slot == TypeBuiltins.SLOTS.tp_getattro() || slot == ModuleBuiltins.SLOTS.tp_getattro(); + } + + static boolean hasNoGetAttr(Object obj) { + CompilerAsserts.neverPartOfCompilation("only used in asserts"); + return LookupAttributeInMRONode.Dynamic.getUncached().execute(GetClassNode.executeUncached(obj), T___GETATTR__) == PNone.NO_VALUE; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromModuleNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromModuleNode.java new file mode 100644 index 0000000000..bffff3949e --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromModuleNode.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017, 2025, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.nodes.attributes; + +import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; +import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; + +@GenerateUncached +@GenerateInline(false) +public abstract class ReadAttributeFromModuleNode extends PNodeWithContext { + + @NeverDefault + public static ReadAttributeFromModuleNode create() { + return ReadAttributeFromModuleNodeGen.create(); + } + + public static ReadAttributeFromModuleNode getUncached() { + return ReadAttributeFromModuleNodeGen.getUncached(); + } + + public abstract Object execute(PythonModule object, TruffleString key); + + // PythonModule always have a dict + @Specialization + static Object readModuleAttribute(PythonModule object, TruffleString key, + @Bind Node inliningTarget, + @Cached GetDictIfExistsNode getDict, + @Cached HashingStorageGetItem getItem) { + var dict = getDict.execute(object); + Object value = getItem.execute(inliningTarget, dict.getDictStorage(), key); + if (value == null) { + return PNone.NO_VALUE; + } else { + return value; + } + } + +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromObjectNode.java index f331799bab..b50a750fb2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromObjectNode.java @@ -40,30 +40,19 @@ */ package com.oracle.graal.python.nodes.attributes; -import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_dict; - import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; -import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; -import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem; -import com.oracle.graal.python.builtins.objects.common.PHashingCollection; import com.oracle.graal.python.builtins.objects.dict.PDict; -import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNodeGen.ReadAttributeFromObjectNotTypeNodeGen; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNodeGen.ReadAttributeFromObjectTpDictNodeGen; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; -import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Exclusive; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.ReportPolymorphism; import com.oracle.truffle.api.dsl.Specialization; @@ -71,68 +60,30 @@ import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; -@ImportStatic({PGuards.class, PythonOptions.class}) +/** + * See {@link ReadAttributeFromModuleNode} which is much simpler for modules. + */ @ReportPolymorphism +@GenerateUncached @GenerateInline(false) // footprint reduction 64 -> 47 public abstract class ReadAttributeFromObjectNode extends PNodeWithContext { - @NeverDefault - public static ReadAttributeFromObjectNode create() { - return ReadAttributeFromObjectNotTypeNodeGen.create(); - } @NeverDefault - public static ReadAttributeFromObjectNode createForceType() { - return ReadAttributeFromObjectTpDictNodeGen.create(); + public static ReadAttributeFromObjectNode create() { + return ReadAttributeFromObjectNodeGen.create(); } public static ReadAttributeFromObjectNode getUncached() { - return ReadAttributeFromObjectNotTypeNodeGen.getUncached(); - } - - public static ReadAttributeFromObjectNode getUncachedForceType() { - return ReadAttributeFromObjectTpDictNodeGen.getUncached(); + return ReadAttributeFromObjectNodeGen.getUncached(); } public abstract Object execute(Object object, TruffleString key); - public abstract Object execute(PythonModule object, TruffleString key); - - /** - * @param module Non-cached parameter to help the DSL produce a guard, not an assertion - */ - protected static HashingStorage getStorage(Object module, PHashingCollection cachedGlobals) { - return cachedGlobals.getDictStorage(); - } - - protected static PDict getDict(Object object) { - return GetDictIfExistsNode.getUncached().execute(object); - } - - // special case for the very common module read - @Specialization(guards = {"isSingleContext()", - "cachedObject == object", - // no need to check the cachedDict for equality, module.__dict__ is read-only - "getStorage(object, cachedDict) == cachedStorage" - }, limit = "1") - @SuppressWarnings("unused") - protected static Object readFromBuiltinModuleDict(PythonModule object, TruffleString key, - @Bind Node inliningTarget, - @Cached(value = "object", weak = true) PythonModule cachedObject, - @Cached(value = "getDict(object)", weak = true) PHashingCollection cachedDict, - @Cached(value = "getStorage(object, getDict(object))", weak = true) HashingStorage cachedStorage, - @Exclusive @Cached HashingStorageGetItem getItem) { - // note that we don't need to pass the state here - string keys are hashable by definition - Object value = getItem.execute(inliningTarget, cachedStorage, key); - if (value == null) { - return PNone.NO_VALUE; - } else { - return value; - } - } + public abstract Object execute(PythonAbstractNativeObject object, TruffleString key); // any python object attribute read @Specialization - protected static Object readObjectAttribute(PythonObject object, TruffleString key, + static Object readObjectAttribute(PythonObject object, TruffleString key, @Bind Node inliningTarget, @Cached InlinedConditionProfile profileHasDict, @Exclusive @Cached GetDictIfExistsNode getDict, @@ -142,9 +93,7 @@ protected static Object readObjectAttribute(PythonObject object, TruffleString k if (profileHasDict.profile(inliningTarget, dict == null)) { return readAttributeFromPythonObjectNode.execute(object, key); } else { - // Note: we should pass the frame. In theory a subclass of a string may override - // __hash__ or __eq__ and run some side effects in there. - Object value = getItem.execute(null, inliningTarget, dict.getDictStorage(), key); + Object value = getItem.execute(inliningTarget, dict.getDictStorage(), key); if (value == null) { return PNone.NO_VALUE; } else { @@ -153,52 +102,29 @@ protected static Object readObjectAttribute(PythonObject object, TruffleString k } } + @Specialization + static Object readNativeObject(PythonAbstractNativeObject object, TruffleString key, + @Bind Node inliningTarget, + @Exclusive @Cached GetDictIfExistsNode getDict, + @Exclusive @Cached HashingStorageGetItem getItem) { + PDict dict = getDict.execute(object); + if (dict != null) { + Object result = getItem.execute(null, inliningTarget, dict.getDictStorage(), key); + if (result != null) { + return result; + } + } + return PNone.NO_VALUE; + } + // foreign object or primitive @InliningCutoff @Specialization(guards = {"!isPythonObject(object)", "!isNativeObject(object)"}) - protected static Object readForeignOrPrimitive(Object object, TruffleString key) { + static Object readForeignOrPrimitive(Object object, TruffleString key) { // Foreign members are tried after the regular attribute lookup, see // ForeignObjectBuiltins.GetAttributeNode. If we looked them up here // they would get precedence over attributes in the MRO. return PNone.NO_VALUE; } - // native objects. We distinguish reading at the objects dictoffset or the tp_dict - // these are also the two nodes that generate uncached versions, because they encode - // the boolean flag forceType for the fallback in their type - - @GenerateUncached - @GenerateInline(false) // footprint reduction 64 -> 47 - protected abstract static class ReadAttributeFromObjectNotTypeNode extends ReadAttributeFromObjectNode { - @Specialization(insertBefore = "readForeignOrPrimitive") - protected static Object readNativeObject(PythonAbstractNativeObject object, TruffleString key, - @Bind Node inliningTarget, - @Exclusive @Cached GetDictIfExistsNode getDict, - @Exclusive @Cached HashingStorageGetItem getItem) { - return readNative(inliningTarget, key, getDict.execute(object), getItem); - } - } - - @GenerateUncached - @GenerateInline(false) // footprint reduction 68 -> 51 - protected abstract static class ReadAttributeFromObjectTpDictNode extends ReadAttributeFromObjectNode { - @Specialization(insertBefore = "readForeignOrPrimitive") - protected static Object readNativeClass(PythonAbstractNativeObject object, TruffleString key, - @Bind Node inliningTarget, - @Cached CStructAccess.ReadObjectNode getNativeDict, - @Exclusive @Cached HashingStorageGetItem getItem) { - return readNative(inliningTarget, key, getNativeDict.readFromObj(object, PyTypeObject__tp_dict), getItem); - } - } - - private static Object readNative(Node inliningTarget, TruffleString key, Object dict, HashingStorageGetItem getItem) { - if (dict instanceof PHashingCollection) { - Object result = getItem.execute(null, inliningTarget, ((PHashingCollection) dict).getDictStorage(), key); - if (result != null) { - return result; - } - } - return PNone.NO_VALUE; - } - } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromPythonObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromPythonObjectNode.java index b2f9dff187..3181604833 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromPythonObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromPythonObjectNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, 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 @@ -44,15 +44,12 @@ 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.PythonManagedClass; -import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Idempotent; -import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NonIdempotent; import com.oracle.truffle.api.dsl.Specialization; @@ -64,7 +61,10 @@ import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; -@ImportStatic({PGuards.class, PythonOptions.class}) +/** + * Reads attribute directly from the underlying {@link DynamicObject} regardless of whether the + * object has dict, also bypasses any other additional logic in {@link ReadAttributeFromObjectNode}. + */ @GenerateUncached @GenerateInline(false) // footprint reduction 44 -> 25 public abstract class ReadAttributeFromPythonObjectNode extends PNodeWithContext { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java index 1ffc0eea22..e225ad0792 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/WriteAttributeToObjectNode.java @@ -64,11 +64,8 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNodeGen.WriteAttributeToObjectNotTypeNodeGen; -import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNodeGen.WriteAttributeToObjectTpDictNodeGen; import com.oracle.graal.python.nodes.object.GetDictIfExistsNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -76,55 +73,29 @@ import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.DynamicObjectLibrary; import com.oracle.truffle.api.profiles.InlinedBranchProfile; +import com.oracle.truffle.api.profiles.InlinedConditionProfile; import com.oracle.truffle.api.strings.TruffleString; -@ImportStatic(PythonOptions.class) +@GenerateUncached @GenerateInline(false) // footprint reduction 120 -> 103 public abstract class WriteAttributeToObjectNode extends PNodeWithContext { public abstract boolean execute(Object primary, TruffleString key, Object value); - @NeverDefault - public static WriteAttributeToObjectNode create() { - return WriteAttributeToObjectNotTypeNodeGen.create(); - } - - @NeverDefault - public static WriteAttributeToObjectNode create(boolean forceType) { - if (forceType) { - return WriteAttributeToObjectTpDictNodeGen.create(); - } - return WriteAttributeToObjectNotTypeNodeGen.create(); - } - - @NeverDefault - public static WriteAttributeToObjectNode createForceType() { - return WriteAttributeToObjectTpDictNodeGen.create(); - } - public static WriteAttributeToObjectNode getUncached() { - return WriteAttributeToObjectNotTypeNodeGen.getUncached(); - } - - public static WriteAttributeToObjectNode getUncached(boolean forceType) { - if (forceType) { - return WriteAttributeToObjectTpDictNodeGen.getUncached(); - } - return WriteAttributeToObjectNotTypeNodeGen.getUncached(); + return WriteAttributeToObjectNodeGen.getUncached(); } - protected static boolean isAttrWritable(PythonObject self) { + static boolean isAttrWritable(PythonObject self) { return (self.getShape().getFlags() & PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG) == 0; } - protected static boolean writeToDynamicStorageNoTypeGuard(Object obj, GetDictIfExistsNode getDict) { + static boolean writeToDynamicStorageNoTypeGuard(Object obj, GetDictIfExistsNode getDict) { return getDict.execute(obj) == null && !PythonManagedClass.isInstance(obj); } @@ -296,7 +267,73 @@ static boolean doPBCT(PythonBuiltinClassType object, TruffleString key, Object v return recursive.execute(PythonContext.get(recursive).lookupType(object), key, value); } - protected static boolean isErrorCase(GetDictIfExistsNode getDict, Object object) { + private static void checkNativeImmutable(Node inliningTarget, PythonAbstractNativeObject object, TruffleString key, + CStructAccess.ReadI64Node getNativeFlags, + PRaiseNode raiseNode) { + long flags = getNativeFlags.readFromObj(object, CFields.PyTypeObject__tp_flags); + if ((flags & TypeFlags.IMMUTABLETYPE) != 0) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, object); + } + } + + @Specialization + static boolean writeNativeObjectOrClass(PythonAbstractNativeObject object, TruffleString key, Object value, + @Bind Node inliningTarget, + @Cached InlinedConditionProfile isTypeProfile, + @Shared("getDict") @Cached GetDictIfExistsNode getDict, + @Cached CStructAccess.ReadI64Node getNativeFlags, + @Cached CStructAccess.ReadObjectNode getNativeDict, + @Exclusive @Cached HashingStorageSetItem setHashingStorageItem, + @Exclusive @Cached InlinedBranchProfile updateStorage, + @Exclusive @Cached InlinedBranchProfile canBeSpecialSlot, + @Cached IsTypeNode isTypeNode, + @Exclusive @Cached PRaiseNode raiseNode, + @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, + @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { + boolean isType = isTypeProfile.profile(inliningTarget, isTypeNode.execute(inliningTarget, object)); + try { + Object dict; + if (isType) { + checkNativeImmutable(inliningTarget, object, key, getNativeFlags, raiseNode); + /* + * For native types, the type attributes are stored in a dict that is located in + * 'typePtr->tp_dict'. So, this is different to a native object (that is not a type) + * and we need to load the dict differently. We must not use + * 'PythonObjectLibrary.getDict' here but read member 'tp_dict'. + */ + dict = getNativeDict.readFromObj(object, PyTypeObject__tp_dict); + } else { + /* + * The dict of native objects that stores the object attributes is located at + * 'objectPtr + Py_TYPE(objectPtr)->tp_dictoffset'. 'PythonObjectLibrary.getDict' + * will exactly load the dict from there. + */ + dict = getDict.execute(object); + } + if (dict instanceof PDict) { + return writeToDict((PDict) dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); + } + throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + } finally { + if (isType && TpSlots.canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode)) { + canBeSpecialSlot.enter(inliningTarget); + // In theory, we should do this only in type's default tp_setattr(o) slots, + // one could probably bypass that by using different metaclass and + // overriding tp_setattr and delegate to object's tp_setattr that does not + // have this hook + TpSlots.updateSlot(object, key); + } + } + } + + @Specialization(guards = "isErrorCase(getDict, object)") + static boolean doError(Object object, TruffleString key, Object value, + @Shared("getDict") @Cached GetDictIfExistsNode getDict, + @Bind Node inliningTarget) { + throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); + } + + static boolean isErrorCase(GetDictIfExistsNode getDict, Object object) { if (object instanceof PythonObject self) { if (isAttrWritable(self) && (getDict.execute(self) == null)) { return false; @@ -314,122 +351,4 @@ protected static boolean isErrorCase(GetDictIfExistsNode getDict, Object object) return true; } - @GenerateUncached - @GenerateInline(false) // footprint reduction 124 -> 107 - protected abstract static class WriteAttributeToObjectNotTypeNode extends WriteAttributeToObjectNode { - @Specialization - static boolean writeNativeObject(PythonAbstractNativeObject object, TruffleString key, Object value, - @Bind Node inliningTarget, - @Shared("getDict") @Cached GetDictIfExistsNode getDict, - @Shared("setHashingStorageItem") @Cached HashingStorageSetItem setHashingStorageItem, - @Shared("updateStorage") @Cached InlinedBranchProfile updateStorage, - @Cached PRaiseNode raiseNode) { - /* - * The dict of native objects that stores the object attributes is located at 'objectPtr - * + Py_TYPE(objectPtr)->tp_dictoffset'. 'PythonObjectLibrary.getDict' will exactly load - * the dict from there. - */ - PDict dict = getDict.execute(object); - if (dict != null) { - return writeToDict(dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); - } - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); - } - - @Specialization(guards = "isErrorCase(getDict, object)") - static boolean doError(Object object, TruffleString key, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, - @Bind Node inliningTarget) { - throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); - } - } - - @GenerateUncached - @GenerateInline(false) // footprint reduction 132 -> 115 - @ImportStatic(TpSlots.class) - protected abstract static class WriteAttributeToObjectTpDictNode extends WriteAttributeToObjectNode { - - private static void checkNativeImmutable(Node inliningTarget, PythonAbstractNativeObject object, TruffleString key, - CStructAccess.ReadI64Node getNativeFlags, - PRaiseNode raiseNode) { - long flags = getNativeFlags.readFromObj(object, CFields.PyTypeObject__tp_flags); - if ((flags & TypeFlags.IMMUTABLETYPE) != 0) { - throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N, key, object); - } - } - - /* - * Simplest case: the key object is a String (so it cannot be a hidden key) and it's not a - * special method slot. - */ - @Specialization(guards = "!canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode)") - static boolean writeNativeClassSimple(PythonAbstractNativeObject object, TruffleString key, Object value, - @Bind Node inliningTarget, - @Shared @Cached CStructAccess.ReadI64Node getNativeFlags, - @Shared @Cached CStructAccess.ReadObjectNode getNativeDict, - @Shared("setHashingStorageItem") @Cached HashingStorageSetItem setHashingStorageItem, - @Shared("updateStorage") @Cached InlinedBranchProfile updateStorage, - @Exclusive @Cached PRaiseNode raiseNode, - @SuppressWarnings("unused") @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @SuppressWarnings("unused") @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { - checkNativeImmutable(inliningTarget, object, key, getNativeFlags, raiseNode); - /* - * For native types, the type attributes are stored in a dict that is located in - * 'typePtr->tp_dict'. So, this is different to a native object (that is not a type) and - * we need to load the dict differently. We must not use 'PythonObjectLibrary.getDict' - * here but read member 'tp_dict'. - */ - Object dict = getNativeDict.readFromObj(object, PyTypeObject__tp_dict); - if (dict instanceof PDict) { - return writeToDict((PDict) dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); - } - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); - } - - @Specialization(replaces = "writeNativeClassSimple") - static boolean writeNativeClassGeneric(PythonAbstractNativeObject object, TruffleString key, Object value, - @Bind Node inliningTarget, - @Shared @Cached CStructAccess.ReadI64Node getNativeFlags, - @Shared @Cached CStructAccess.ReadObjectNode getNativeDict, - @Exclusive @Cached HashingStorageSetItem setHashingStorageItem, - @Exclusive @Cached InlinedBranchProfile updateStorage, - @Exclusive @Cached InlinedBranchProfile canBeSpecialSlot, - @Cached IsTypeNode isTypeNode, - @Exclusive @Cached PRaiseNode raiseNode, - @Shared("cpLen") @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @Shared("cpAtIndex") @Cached TruffleString.CodePointAtIndexNode codePointAtIndexNode) { - try { - checkNativeImmutable(inliningTarget, object, key, getNativeFlags, raiseNode); - /* - * For native types, the type attributes are stored in a dict that is located in - * 'typePtr->tp_dict'. So, this is different to a native object (that is not a type) - * and we need to load the dict differently. We must not use - * 'PythonObjectLibrary.getDict' here but read member 'tp_dict'. - */ - Object dict = getNativeDict.readFromObj(object, PyTypeObject__tp_dict); - if (dict instanceof PDict) { - return writeToDict((PDict) dict, key, value, inliningTarget, updateStorage, setHashingStorageItem); - } - throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); - } finally { - if (TpSlots.canBeSpecialMethod(key, codePointLengthNode, codePointAtIndexNode)) { - canBeSpecialSlot.enter(inliningTarget); - // In theory, we should do this only in type's default tp_setattr(o) slots, - // one could probably bypass that by using different metaclass and - // overriding tp_setattr and delegate to object's tp_setattr that does not - // have this hook - if (isTypeNode.execute(inliningTarget, object)) { - TpSlots.updateSlot(object, key); - } - } - } - } - - @Specialization(guards = "isErrorCase(getDict, object)") - static boolean doError(Object object, TruffleString key, @SuppressWarnings("unused") Object value, - @SuppressWarnings("unused") @Shared("getDict") @Cached GetDictIfExistsNode getDict, - @Bind Node inliningTarget) { - throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, object, key); - } - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java index 9c51eed2d9..c802e3c7c8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/SetupAnnotationsNode.java @@ -54,7 +54,7 @@ import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectSetItem; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; @@ -103,7 +103,7 @@ public abstract static class SetupAnnotationsFromDictOrModuleNode extends PNodeW @Specialization static void doModule(Node inliningTarget, PythonModule locals, - @Cached(inline = false) ReadAttributeFromObjectNode read, + @Cached ReadAttributeFromModuleNode read, @Cached(inline = false) WriteAttributeToObjectNode write, @Cached @Exclusive InlinedBranchProfile create) { Object annotations = read.execute(locals, T___ANNOTATIONS__); 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 5f6e2969c0..f7bc5413a6 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 @@ -168,7 +168,7 @@ import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.argument.keywords.NonMappingException; import com.oracle.graal.python.nodes.argument.keywords.SameDictKeyException; -import com.oracle.graal.python.nodes.attributes.GetAttributeNode.GetFixedAttributeNode; +import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode; import com.oracle.graal.python.nodes.builtins.ListNodes; import com.oracle.graal.python.nodes.bytecode.CopyDictWithoutKeysNode; import com.oracle.graal.python.nodes.bytecode.GetSendValueNode; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java index 327471de58..70f48acd3e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadBuiltinNode.java @@ -48,7 +48,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerAsserts; @@ -77,7 +77,7 @@ Object returnBuiltinFromConstantModule(TruffleString attributeId, @Bind Node inliningTarget, @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached InlinedConditionProfile isBuiltinProfile, - @Shared @Cached ReadAttributeFromObjectNode readFromBuiltinsNode, + @Shared @Cached ReadAttributeFromModuleNode readFromBuiltinsNode, @Cached(value = "getBuiltins()", allowUncached = true) PythonModule builtins) { return readBuiltinFromModule(attributeId, raiseNode, inliningTarget, isBuiltinProfile, builtins, readFromBuiltinsNode); } @@ -93,7 +93,7 @@ Object returnBuiltin(TruffleString attributeId, @Bind Node inliningTarget, @Exclusive @Cached PRaiseNode raiseNode, @Exclusive @Cached InlinedConditionProfile isBuiltinProfile, - @Shared @Cached ReadAttributeFromObjectNode readFromBuiltinsNode, + @Shared @Cached ReadAttributeFromModuleNode readFromBuiltinsNode, @Exclusive @Cached InlinedConditionProfile ctxInitializedProfile) { PythonModule builtins = getBuiltins(inliningTarget, ctxInitializedProfile); return returnBuiltinFromConstantModule(attributeId, inliningTarget, raiseNode, isBuiltinProfile, readFromBuiltinsNode, builtins); @@ -101,7 +101,7 @@ Object returnBuiltin(TruffleString attributeId, private static Object readBuiltinFromModule(TruffleString attributeId, PRaiseNode raiseNode, Node inliningTarget, InlinedConditionProfile isBuiltinProfile, PythonModule builtins, - ReadAttributeFromObjectNode readFromBuiltinsNode) { + ReadAttributeFromModuleNode readFromBuiltinsNode) { Object builtin = readFromBuiltinsNode.execute(builtins, attributeId); if (isBuiltinProfile.profile(inliningTarget, builtin != PNone.NO_VALUE)) { return builtin; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java index 4bb08e8307..87d0564e58 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadGlobalOrBuiltinNode.java @@ -38,7 +38,7 @@ import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerAsserts; @@ -88,7 +88,7 @@ protected static Object readGlobalCached(@SuppressWarnings("unused") PythonModul @Bind Node inliningTarget, @Shared("readFromBuiltinsNode") @Cached ReadBuiltinNode readFromBuiltinsNode, @Exclusive @Cached InlinedBranchProfile wasReadFromModule, - @Shared("readFromModule") @Cached ReadAttributeFromObjectNode readFromModuleNode, + @Shared("readFromModule") @Cached ReadAttributeFromModuleNode readFromModuleNode, @Cached(value = "globals", weak = true) PythonModule cachedGlobals) { Object result = readFromModuleNode.execute(cachedGlobals, attributeId); return returnGlobalOrBuiltin(result, attributeId, readFromBuiltinsNode, inliningTarget, wasReadFromModule); @@ -100,7 +100,7 @@ protected static Object readGlobal(PythonModule globals, TruffleString attribute @Bind Node inliningTarget, @Shared("readFromBuiltinsNode") @Cached ReadBuiltinNode readFromBuiltinsNode, @Exclusive @Cached InlinedBranchProfile wasReadFromModule, - @Shared("readFromModule") @Cached ReadAttributeFromObjectNode readFromModuleNode) { + @Shared("readFromModule") @Cached ReadAttributeFromModuleNode readFromModuleNode) { Object result = readFromModuleNode.execute(globals, attributeId); return returnGlobalOrBuiltin(result, attributeId, readFromBuiltinsNode, inliningTarget, wasReadFromModule); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java index 92939aaae0..4806ec3693 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetClassNode.java @@ -49,19 +49,15 @@ import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; -import com.oracle.graal.python.builtins.objects.function.PFunction; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass; -import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; -import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.Idempotent; +import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; @@ -91,16 +87,6 @@ public static Object executeUncached(Object object) { return GetClassNodeGen.getUncached().execute(null, object); } - @SuppressWarnings("static-method") - public final Object execute(@SuppressWarnings("unused") int i) { - return PythonBuiltinClassType.PInt; - } - - @SuppressWarnings("static-method") - public final Object execute(@SuppressWarnings("unused") double d) { - return PythonBuiltinClassType.PFloat; - } - @Specialization static Object getBoolean(@SuppressWarnings("unused") Boolean object) { return PythonBuiltinClassType.Boolean; @@ -131,28 +117,10 @@ static Object getNone(@SuppressWarnings("unused") PNone object) { return PythonBuiltinClassType.PNone; } - @Specialization - static Object getBuiltinClass(PythonBuiltinClass object) { - return object.getInitialPythonClass(); - } - - @Specialization - static Object getFunction(@SuppressWarnings("unused") PFunction object) { - return object.getInitialPythonClass(); - } - - @Specialization - static Object getBuiltinFunction(@SuppressWarnings("unused") PBuiltinFunction object) { - return object.getInitialPythonClass(); - } - - // GetPythonObjectClassNode needs 3 references, so we do not inline it here, to save footprint - // if only the fast-path specializations are activated - @Specialization(guards = "isPythonObject(object) || isNativeObject(object)") - static Object getPythonObjectOrNative(PythonAbstractObject object, - @Cached(inline = false) GetPythonObjectClassNode getClassNode) { - return getClassNode.executeCached(object); + static Object getPythonObjectOrNative(Node inliningTarget, PythonAbstractObject object, + @Cached GetPythonObjectClassNode getPythonObjectClassNode) { + return getPythonObjectClassNode.executeImpl(inliningTarget, object); } /* @@ -161,57 +129,46 @@ static Object getPythonObjectOrNative(PythonAbstractObject object, * when not necessary. */ @GenerateUncached - @GenerateInline(inlineByDefault = true) + @GenerateInline + @GenerateCached(false) + @ImportStatic(PythonObject.class) public abstract static class GetPythonObjectClassNode extends PNodeWithContext { public static Object executeUncached(PythonObject object) { return GetClassNodeGen.getUncached().execute(null, object); } - // Intended only for internal usage in this node. The caller must make sure that the object - // is of one of the expected Java types. - final Object executeCached(PythonAbstractObject object) { - assert object instanceof PythonObject || object instanceof PythonAbstractNativeObject; - return executeImpl(this, object); - } - + /* + * Intended only for internal usage in the outer node. The caller must make sure that the + * object is either a PythonObject or PythonAbstractNativeObject. + */ abstract Object executeImpl(Node inliningTarget, PythonAbstractObject object); public abstract Object execute(Node inliningTarget, PythonObject object); public abstract Object execute(Node inliningTarget, PythonAbstractNativeObject object); - @Specialization(guards = {"isSingleContext()", "klass != null", "object.getShape() == cachedShape", "hasInitialClass(cachedShape)"}, limit = "1") - static Object getPythonObjectConstantClass(@SuppressWarnings("unused") PythonObject object, - @SuppressWarnings("unused") @Cached(value = "object.getShape()") Shape cachedShape, - @Cached(value = "object.getInitialPythonClass()", weak = true) Object klass) { - return klass; + @Idempotent + static Object getDynamicType(Shape shape) { + return shape.getDynamicType(); } - @Specialization(guards = "hasInitialClass(object.getShape())") - static Object getPythonObject(@SuppressWarnings("unused") PythonObject object, - @Bind("object.getInitialPythonClass()") Object klass) { - assert klass != null; - return klass; + @Specialization(guards = {"object.getShape() == cachedShape", "isPythonClass(getDynamicType(cachedShape))"}, limit = "1") + static Object doConstantClass(@SuppressWarnings("unused") PythonObject object, + @Cached(value = "object.getShape()") Shape cachedShape) { + return cachedShape.getDynamicType(); } - @InliningCutoff - @Specialization(guards = "!hasInitialClass(object.getShape())", replaces = "getPythonObjectConstantClass") - static Object getPythonObject(Node inliningTarget, PythonObject object, - @Cached HiddenAttr.ReadNode readHiddenAttrNode) { - return readHiddenAttrNode.execute(inliningTarget, object, HiddenAttr.CLASS, object.getInitialPythonClass()); + @Specialization(replaces = "doConstantClass") + static Object doReadClassField(PythonObject object) { + return object.getPythonClass(); } @InliningCutoff @Specialization - static Object getNativeObject(Node inliningTarget, PythonAbstractNativeObject object, + static Object doNativeObject(Node inliningTarget, PythonAbstractNativeObject object, @Cached CExtNodes.GetNativeClassNode getNativeClassNode) { return getNativeClassNode.execute(inliningTarget, object); } - - @Idempotent - protected static boolean hasInitialClass(Shape shape) { - return (shape.getFlags() & PythonObject.CLASS_CHANGED_FLAG) == 0; - } } @Specialization @@ -240,7 +197,7 @@ static Object getNativeVoidPtr(@SuppressWarnings("unused") PythonNativeVoidPtr o } @InliningCutoff - @Fallback + @Specialization(guards = "isForeignObject(object)") static Object getForeign(Object object, @Cached(inline = false) GetRegisteredClassNode getRegisteredClassNode) { return getRegisteredClassNode.execute(object); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java index 713aac4584..8350f0b75a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java @@ -42,6 +42,7 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError; import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_PY_OBJECT_GET_DICT_PTR; +import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_dict; import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.PNone; @@ -53,6 +54,7 @@ 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.PythonManagedClass; +import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.HiddenAttr; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -125,12 +127,25 @@ static PDict doPythonObject(PythonObject object, @InliningCutoff static PDict doNativeObject(PythonAbstractNativeObject object, @Bind Node inliningTarget, + @Cached IsTypeNode isTypeNode, + @Cached CStructAccess.ReadObjectNode getNativeDict, @CachedLibrary(limit = "1") InteropLibrary lib, @Cached PythonToNativeNode toNative, @Cached CStructAccess.ReadObjectNode readObjectNode, @Cached CStructAccess.WriteObjectNewRefNode writeObjectNode, @Cached InlinedBranchProfile createDict, @Cached CExtNodes.PCallCapiFunction callGetDictPtr) { + if (isTypeNode.execute(inliningTarget, object)) { + // Optimization for native types: read at the known offset instead of calling + // _PyObject_GetDictPtr() + Object dict = getNativeDict.readFromObj(object, PyTypeObject__tp_dict); + if (dict instanceof PDict pdict) { + return pdict; + } else { + return null; + } + } + Object dictPtr = callGetDictPtr.call(FUN_PY_OBJECT_GET_DICT_PTR, toNative.execute(object)); if (lib.isNull(dictPtr)) { return null; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java index 8dfe622eb8..3ba977af77 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsForeignObjectNode.java @@ -62,8 +62,17 @@ public abstract class IsForeignObjectNode extends PNodeWithContext { public abstract boolean execute(Node inliningTarget, Object object); + // This is useful as a guard and much better than the inlined node in terms of host inlining + // code size. + // The generated uncached node doesn't work as a guard because of @TruffleBoundary. public static boolean executeUncached(Object object) { - return IsForeignObjectNodeGen.getUncached().execute(null, object); + return !(object instanceof Boolean || + object instanceof Integer || + object instanceof Long || + object instanceof Double || + object instanceof TruffleString || + object instanceof PythonAbstractObject || + object instanceof PythonBuiltinClassType); } @Specialization diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToTruffleStringNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToTruffleStringNode.java index 0598fa2c93..5ddb860d30 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToTruffleStringNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/CastToTruffleStringNode.java @@ -50,6 +50,8 @@ import com.oracle.graal.python.builtins.objects.cext.structs.CFields; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; import com.oracle.graal.python.builtins.objects.str.PString; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; +import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.str.StringNodes.StringMaterializeNode; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -75,6 +77,10 @@ /** * Casts a Python string to a TruffleString without coercion. ATTENTION: If the cast fails, * because the object is not a Python string, the node will throw a {@link CannotCastException}. + *
+ * Prefer {@link CastToTruffleStringChecked0Node}, {@link CastToTruffleStringChecked1Node}, etc when + * possible as they are much better for host inlining with only 1 @InliningCutoff vs + * 3 @InliningCutoff in this node. */ @GenerateUncached @GenerateInline(inlineByDefault = true) 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 f6133f4463..216b1f8187 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 @@ -97,6 +97,7 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; +import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode; import org.graalvm.options.OptionKey; import com.oracle.graal.python.PythonLanguage; @@ -2690,7 +2691,7 @@ public void ensureNFILanguage(Node nodeForRaise, String optionName, String optio public TruffleString getSoAbi() { if (soABI == null) { PythonModule sysModule = this.lookupBuiltinModule(T_SYS); - Object implementationObj = ReadAttributeFromObjectNode.getUncached().execute(sysModule, T_IMPLEMENTATION); + Object implementationObj = ReadAttributeFromModuleNode.getUncached().execute(sysModule, T_IMPLEMENTATION); // sys.implementation.cache_tag TruffleString cacheTag = (TruffleString) PyObjectGetAttr.executeUncached(implementationObj, T_CACHE_TAG); // sys.implementation._multiarch 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 f98d33f97b..4fc9f3dbad 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 @@ -579,7 +579,7 @@ public static PBuiltinMethod createNewWrapper(PythonLanguage language, Object ty } public static PBuiltinFunction createBuiltinFunction(PythonLanguage language, PBuiltinFunction function, Object klass) { - PythonBuiltinClassType type = (PythonBuiltinClassType) function.getInitialPythonClass(); + PythonBuiltinClassType type = (PythonBuiltinClassType) function.getPythonClass(); return trace(language, new PBuiltinFunction(type, type.getInstanceShape(language), function.getName(), klass, function.getDefaults(), function.getKwDefaults(), function.getFlags(), function.getCallTarget(), function.getSlot(), function.getSlotWrapper())); 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 30ac35de92..21d0b9c14d 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 @@ -719,7 +719,7 @@ public static PBuiltinFunction createMethod(Object klass, Builtin builtin, RootC TruffleString name = toTruffleStringUncached(builtin.name()); PBuiltinFunction function = PFactory.createBuiltinFunction(PythonLanguage.get(null), name, type, numDefaults, flags, callTarget); if (klass != null) { - WriteAttributeToObjectNode.getUncached(true).execute(klass, name, function); + WriteAttributeToObjectNode.getUncached().execute(klass, name, function); } return function; } diff --git a/mx.graalpython/native-ce-host-inlining b/mx.graalpython/native-ce-host-inlining new file mode 100644 index 0000000000..3c20b6d582 --- /dev/null +++ b/mx.graalpython/native-ce-host-inlining @@ -0,0 +1,6 @@ +DYNAMIC_IMPORTS=/tools,/compiler,/substratevm +BUILD_TARGETS=GRAALPY_NATIVE_STANDALONE +COMPONENTS=SubstrateVM,Truffle SVM Macro +NATIVE_IMAGES=lib:pythonvm +EXTRA_IMAGE_BUILDER_ARGUMENTS=pythonvm:-H:+UnlockExperimentalVMOptions pythonvm:-H:Log=HostInliningPhase,~CanonicalizerPhase,~GraphBuilderPhase pythonvm:-H:+TruffleHostInliningPrintExplored pythonvm:-H:MethodFilter=com.oracle.graal.python.*.* pythonvm:-H:-UnlockExperimentalVMOptions pythonvm:-Dgraal.LogFile=host-inlining.txt +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/native-ee-host-inlining b/mx.graalpython/native-ee-host-inlining new file mode 100644 index 0000000000..6b69aacb64 --- /dev/null +++ b/mx.graalpython/native-ee-host-inlining @@ -0,0 +1,6 @@ +DYNAMIC_IMPORTS=/tools,/graal-enterprise,/truffle-enterprise,/vm-enterprise,/substratevm-enterprise,substratevm-enterprise-gcs +BUILD_TARGETS=GRAALPY_NATIVE_STANDALONE +COMPONENTS=SubstrateVM Enterprise,Truffle SVM Macro Enterprise,suite:substratevm-enterprise-gcs +NATIVE_IMAGES=lib:pythonvm +EXTRA_IMAGE_BUILDER_ARGUMENTS=pythonvm:-H:+UnlockExperimentalVMOptions pythonvm:-H:Log=HostInliningPhase,~CanonicalizerPhase,~GraphBuilderPhase pythonvm:-H:+TruffleHostInliningPrintExplored pythonvm:-H:MethodFilter=com.oracle.graal.python.*.* pythonvm:-H:-UnlockExperimentalVMOptions pythonvm:-Dgraal.LogFile=host-inlining.txt +GRAALVM_SKIP_ARCHIVE=true diff --git a/mx.graalpython/suite.py b/mx.graalpython/suite.py index 8df7a7f58d..a3b956e8cd 100644 --- a/mx.graalpython/suite.py +++ b/mx.graalpython/suite.py @@ -53,7 +53,7 @@ }, { "name": "tools", - "version": "c18c686390ee4a15c3c3769a553d378f0c23ea1c", + "version": "8bfc1ec4c051d3d201e92d70c6f8bcc99903405c", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"}, @@ -61,7 +61,7 @@ }, { "name": "regex", - "version": "c18c686390ee4a15c3c3769a553d378f0c23ea1c", + "version": "8bfc1ec4c051d3d201e92d70c6f8bcc99903405c", "subdir": True, "urls": [ {"url": "https://github.com/oracle/graal", "kind": "git"},