Skip to content

Commit 70787f4

Browse files
committed
[GR-67626] Optimize host inlining of attribute lookup in GraalPy
PullRequest: graalpython/3889
2 parents 571499d + cfd056f commit 70787f4

File tree

95 files changed

+1483
-1409
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1483
-1409
lines changed

ci/graal/common.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@
5353
"labsjdk-ee-25Debug": {"name": "labsjdk", "version": "ee-25+30-jvmci-b01-debug", "platformspecific": true },
5454
"labsjdk-ee-25-llvm": {"name": "labsjdk", "version": "ee-25+30-jvmci-b01-sulong", "platformspecific": true },
5555

56-
"oraclejdk-latest": {"name": "jpg-jdk", "version": "26", "build_id": "jdk-26+7", "platformspecific": true, "extrabundles": ["static-libs"]},
57-
"labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-26+7-jvmci-b01", "platformspecific": true },
58-
"labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-26+7-jvmci-b01-debug", "platformspecific": true },
59-
"labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-26+7-jvmci-b01-sulong", "platformspecific": true },
60-
"labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-26+7-jvmci-b01", "platformspecific": true },
61-
"labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-26+7-jvmci-b01-debug", "platformspecific": true },
62-
"labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-26+7-jvmci-b01-sulong", "platformspecific": true }
56+
"oraclejdk-latest": {"name": "jpg-jdk", "version": "26", "build_id": "jdk-26+8", "platformspecific": true, "extrabundles": ["static-libs"]},
57+
"labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-26+8-jvmci-b01", "platformspecific": true },
58+
"labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-26+8-jvmci-b01-debug", "platformspecific": true },
59+
"labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-26+8-jvmci-b01-sulong", "platformspecific": true },
60+
"labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-26+8-jvmci-b01", "platformspecific": true },
61+
"labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-26+8-jvmci-b01-debug", "platformspecific": true },
62+
"labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-26+8-jvmci-b01-sulong", "platformspecific": true }
6363
},
6464

6565
"eclipse": {

docs/contributor/CONTRIBUTING.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ If the IDE was initialized properly by using the command mentioned above, the ex
127127
128128
Both of these commands also work when you have a `graalpy` executable, e.g. inside a `venv`.
129129
130-
For debugging the C API and native extensions, first make sure you rebuild (`mx clean` first!) graalpything with the environment variable `CFLAGS=-g` set.
130+
For debugging the C API and native extensions, first make sure you rebuild (`mx clean` first!) graalpython with the environment variable `CFLAGS=-g` set.
131131
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.
132132
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.
133-
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`.
133+
Make sure you find and keep the `libpythonvm.so.debug` file around next to your GraalPy build, you can find it under `mxbuild/*/libpythonvm`.
134134
135135
## Advanced Commands to Develop and Debug
136136
@@ -149,6 +149,7 @@ mx python-gate --tags python-unittest
149149
150150
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.
151151
Note that you can insert `-d` to debug on the Java level or use `--inspect` to debug in the Chrome debugger.
152+
Use `com.oracle.graal.python.runtime.exception.ExceptionUtils.printPythonLikeStackTrace()` in the Java debugger to print the current Python traceback on `stderr`.
152153
153154
```bash
154155
mx [-d] graalpytest [--inspect] TEST-SELECTOR

graalpython/com.oracle.graal.python.cext/src/capi.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -616,10 +616,6 @@ PyAPI_FUNC(void*) GraalPyPrivate_PointerAddOffset(void* x, Py_ssize_t y) {
616616
return (char *)x + y;
617617
}
618618

619-
PyAPI_FUNC(int) GraalPyPrivate_SubclassCheck(PyObject* type) {
620-
return PyType_FastSubclass(Py_TYPE(type), Py_TPFLAGS_TYPE_SUBCLASS);
621-
}
622-
623619
// Implements the basesisze check in typeobject.c:_PyObject_GetState
624620
PyAPI_FUNC(int) GraalPyPrivate_CheckBasicsizeForGetstate(PyTypeObject* type, int slot_num) {
625621
Py_ssize_t basicsize = PyBaseObject_Type.tp_basicsize;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
import com.oracle.graal.python.compiler.ParserCallbacksImpl;
8383
import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler;
8484
import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler.BytecodeDSLCompilerResult;
85-
import com.oracle.graal.python.nodes.HiddenAttr;
8685
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
8786
import com.oracle.graal.python.nodes.bytecode_dsl.BytecodeDSLCodeUnit;
8887
import com.oracle.graal.python.nodes.call.CallDispatchers;
@@ -1043,7 +1042,7 @@ public Shape getEmptyShape() {
10431042

10441043
public Shape getShapeForClass(PythonAbstractClass klass) {
10451044
if (isSingleContext()) {
1046-
return Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttr.getClassHiddenKey(), klass, 0).build();
1045+
return Shape.newBuilder(getEmptyShape()).dynamicType(klass).build();
10471046
} else {
10481047
return getEmptyShape();
10491048
}
@@ -1065,7 +1064,7 @@ public Shape getBuiltinTypeInstanceShape(PythonBuiltinClassType type) {
10651064

10661065
private Shape createBuiltinShape(PythonBuiltinClassType type, int ordinal) {
10671066
Shape shape;
1068-
Shape.DerivedBuilder shapeBuilder = Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttr.getClassHiddenKey(), type, 0);
1067+
Shape.DerivedBuilder shapeBuilder = Shape.newBuilder(getEmptyShape()).dynamicType(type);
10691068
if (!type.isBuiltinWithDict()) {
10701069
shapeBuilder.shapeFlags(PythonObject.HAS_SLOTS_BUT_NO_DICT_FLAG);
10711070
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
import com.oracle.graal.python.nodes.ErrorMessages;
7373
import com.oracle.graal.python.nodes.PGuards;
7474
import com.oracle.graal.python.nodes.PRaiseNode;
75-
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
75+
import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode;
7676
import com.oracle.graal.python.nodes.call.CallNode;
7777
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
7878
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
@@ -178,8 +178,8 @@ static Object getCurrentLoop(VirtualFrame frame, Object ignored,
178178
@Cached CallNode callGetPolicy,
179179
@Cached CallNode callGetLoop,
180180
@Cached AbstractImportNode.ImportName importName,
181-
@Cached(parameters = "T_GET_EVENT_LOOP") GetAttributeNode.GetFixedAttributeNode getGetLoop,
182-
@Cached(parameters = "T_GET_EVENT_LOOP_POLICY") GetAttributeNode.GetFixedAttributeNode getGetLoopPolicy) {
181+
@Cached(parameters = "T_GET_EVENT_LOOP") GetFixedAttributeNode getGetLoop,
182+
@Cached(parameters = "T_GET_EVENT_LOOP_POLICY") GetFixedAttributeNode getGetLoopPolicy) {
183183
Object eventLoop = context.getThreadState(context.getLanguage(inliningTarget)).getRunningEventLoop();
184184
if (eventLoop == null) {
185185
Object asyncio = importName.execute(frame, context, context.getBuiltins(), T_ASYNCIO_EVENTS, PNone.NONE, PythonUtils.EMPTY_TRUFFLESTRING_ARRAY, 0);

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,8 @@
208208
import com.oracle.graal.python.nodes.SpecialMethodNames;
209209
import com.oracle.graal.python.nodes.StringLiterals;
210210
import com.oracle.graal.python.nodes.argument.ReadArgumentNode;
211-
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
211+
import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode;
212+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode;
212213
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
213214
import com.oracle.graal.python.nodes.builtins.ListNodes;
214215
import com.oracle.graal.python.nodes.builtins.ListNodes.ConstructListNode;
@@ -1730,7 +1731,7 @@ static Object ord(@SuppressWarnings("unused") Object obj,
17301731
"flush: whether to forcibly flush the stream.")
17311732
@GenerateNodeFactory
17321733
public abstract static class PrintNode extends PythonBuiltinNode {
1733-
@Child private ReadAttributeFromObjectNode readStdout;
1734+
@Child private ReadAttributeFromModuleNode readStdout;
17341735
@CompilationFinal private PythonModule cachedSys;
17351736

17361737
@Specialization
@@ -1836,7 +1837,7 @@ private Object getStdout() {
18361837
}
18371838
if (readStdout == null) {
18381839
CompilerDirectives.transferToInterpreterAndInvalidate();
1839-
readStdout = insert(ReadAttributeFromObjectNode.create());
1840+
readStdout = insert(ReadAttributeFromModuleNode.create());
18401841
}
18411842
Object stdout = readStdout.execute(sys, T_STDOUT);
18421843
if (stdout == NO_VALUE) {
@@ -2435,7 +2436,7 @@ protected Object doItNonFunction(VirtualFrame frame, Object function, Object[] a
24352436
@Cached CastToTruffleStringNode castToTruffleStringNode,
24362437
@Cached("createFor($node)") IndirectCallData indirectCallData,
24372438
@Cached CalculateMetaclassNode calculateMetaClass,
2438-
@Cached("create(T___PREPARE__)") GetAttributeNode getPrepare,
2439+
@Cached("create(T___PREPARE__)") GetFixedAttributeNode getPrepare,
24392440
@Cached PyMappingCheckNode pyMappingCheckNode,
24402441
@Cached CallNode callPrep,
24412442
@Cached CallNode callType,
@@ -2527,7 +2528,7 @@ class InitializeBuildClass {
25272528

25282529
Object ns;
25292530
try {
2530-
Object prep = getPrepare.executeObject(frame, init.meta);
2531+
Object prep = getPrepare.execute(frame, init.meta);
25312532
ns = callPrep.execute(frame, prep, new Object[]{name, init.bases}, init.mkw);
25322533
} catch (PException p) {
25332534
p.expectAttributeError(inliningTarget, noAttributeProfile);

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
import com.oracle.graal.python.nodes.HiddenAttr;
103103
import com.oracle.graal.python.nodes.PRaiseNode;
104104
import com.oracle.graal.python.nodes.SpecialAttributeNames;
105-
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
105+
import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode;
106106
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
107107
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
108108
import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode;
@@ -352,10 +352,10 @@ Object exportSymbol(PBuiltinFunction fun, @SuppressWarnings("unused") PNone name
352352
@Specialization(guards = "isModuleMethod(fun)")
353353
static Object exportSymbol(VirtualFrame frame, Object fun, @SuppressWarnings("unused") PNone name,
354354
@Bind Node inliningTarget,
355-
@Cached("create(T___NAME__)") GetAttributeNode.GetFixedAttributeNode getNameAttributeNode,
355+
@Cached("create(T___NAME__)") GetFixedAttributeNode getNameAttributeNode,
356356
@Cached CastToJavaStringNode castToStringNode,
357357
@Cached PRaiseNode raiseNode) {
358-
Object attrNameValue = getNameAttributeNode.executeObject(frame, fun);
358+
Object attrNameValue = getNameAttributeNode.execute(frame, fun);
359359
String methodName;
360360
try {
361361
methodName = castToStringNode.execute(attrNameValue);

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

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import java.util.List;
5050
import java.util.Objects;
5151

52+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromModuleNode;
5253
import org.graalvm.collections.EconomicMap;
5354

5455
import com.oracle.graal.python.builtins.Builtin;
@@ -79,8 +80,7 @@
7980
import com.oracle.graal.python.nodes.HiddenAttr;
8081
import com.oracle.graal.python.nodes.PNodeWithContext;
8182
import com.oracle.graal.python.nodes.PRaiseNode;
82-
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
83-
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
83+
import com.oracle.graal.python.nodes.attributes.GetFixedAttributeNode;
8484
import com.oracle.graal.python.nodes.call.CallNode;
8585
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
8686
import com.oracle.graal.python.nodes.function.builtins.PythonSenaryBuiltinNode;
@@ -622,7 +622,7 @@ static Object doSingleContext(
622622
@Specialization(replaces = "doSingleContext")
623623
static Object doRead(
624624
@Bind PythonContext context,
625-
@Cached ReadAttributeFromObjectNode read) {
625+
@Cached ReadAttributeFromModuleNode read) {
626626
PythonModule module = context.lookupBuiltinModule(BuiltinNames.T__SRE);
627627
return read.execute(module, T_MATCH_CONSTRUCTOR);
628628
}
@@ -643,7 +643,7 @@ abstract static class TRegexSearch extends PythonSenaryBuiltinNode {
643643
protected static final TruffleString T__PATTERN__FALLBACK_COMPILE = tsLiteral("_Pattern__fallback_compile");
644644

645645
@Child private HiddenAttr.ReadNode readCacheNode = HiddenAttr.ReadNode.create();
646-
@Child private GetAttributeNode getFallbackCompileNode;
646+
@Child private GetFixedAttributeNode getFallbackCompileNode;
647647
@Child private CallNode callFallbackCompileNode;
648648
@Child private CallNode callFallbackMethodNode;
649649
@Child private SliceNodes.CreateSliceNode createSliceNode;
@@ -666,7 +666,7 @@ protected Object doCached(VirtualFrame frame, PythonObject pattern, Object input
666666
@Cached @Shared PyNumberAsSizeNode asSizeNode,
667667
@Cached @Shared PyObjectSizeNode lengthNode,
668668
@CachedLibrary(limit = "1") @Shared InteropLibrary libCompiledRegex,
669-
@Cached("create(method.getMethodName())") GetAttributeNode getFallbackMethodNode,
669+
@Cached("create(method.getMethodName())") GetFixedAttributeNode getFallbackMethodNode,
670670
@Cached @Shared TRegexCallExec tRegexCallExec,
671671
@Cached @Shared CreateMatchFromTRegexResultNode createMatchFromTRegexResultNode) {
672672
int pos = asSizeNode.executeExact(frame, inliningTarget, indexNode.execute(frame, inliningTarget, posArg));
@@ -686,8 +686,9 @@ protected Object doCached(VirtualFrame frame, PythonObject pattern, Object input
686686
reCheckInputTypeNode.execute(frame, input, tRegexCache.isBinary());
687687

688688
if (fallbackProfile.profile(inliningTarget, libCompiledRegex.isNull(compiledRegex))) {
689-
Object fallbackRegex = getCallFallbackCompileNode().executeWithoutFrame(getGetFallbackCompileNode().executeObject(frame, pattern));
690-
return getCallFallbackMethodNode().executeWithoutFrame(getFallbackMethodNode.executeObject(frame, fallbackRegex), input, pos, endPos);
689+
GetFixedAttributeNode getFixedAttributeNode = getGetFallbackCompileNode();
690+
Object fallbackRegex = getCallFallbackCompileNode().executeWithoutFrame(getFixedAttributeNode.execute(frame, pattern));
691+
return getCallFallbackMethodNode().executeWithoutFrame(getFallbackMethodNode.execute(frame, fallbackRegex), input, pos, endPos);
691692
}
692693

693694
Object truncatedInput = input;
@@ -716,7 +717,7 @@ protected Object doCachedRegex(VirtualFrame frame, PythonObject pattern, Object
716717
@Cached @Shared PyNumberAsSizeNode asSizeNode,
717718
@Cached @Shared PyObjectSizeNode lengthNode,
718719
@CachedLibrary(limit = "1") @Shared InteropLibrary libCompiledRegex,
719-
@Cached("create(method.getMethodName())") GetAttributeNode getFallbackMethodNode,
720+
@Cached("create(method.getMethodName())") GetFixedAttributeNode getFallbackMethodNode,
720721
@Cached @Shared TRegexCallExec tRegexCallExec,
721722
@Cached @Shared CreateMatchFromTRegexResultNode createMatchFromTRegexResultNode) {
722723
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
738739
@Cached @Shared InlinedConditionProfile fallbackProfile,
739740
@Cached @Shared InlinedConditionProfile truncatingInputProfile,
740741
@CachedLibrary(limit = "1") @Shared InteropLibrary libCompiledRegex,
741-
@Cached("create(method.getMethodName())") GetAttributeNode getFallbackMethodNode,
742+
@Cached("create(method.getMethodName())") GetFixedAttributeNode getFallbackMethodNode,
742743
@Cached @Shared TRegexCallExec tRegexCallExec,
743744
@Cached @Shared CreateMatchFromTRegexResultNode createMatchFromTRegexResultNode) {
744745
TRegexCache tRegexCache = getTRegexCache(pattern);
@@ -752,10 +753,10 @@ protected TRegexCache getTRegexCache(PythonObject pattern) {
752753
return (TRegexCache) readCacheNode.executeCached(pattern, HiddenAttr.TREGEX_CACHE, null);
753754
}
754755

755-
private GetAttributeNode getGetFallbackCompileNode() {
756+
private GetFixedAttributeNode getGetFallbackCompileNode() {
756757
if (getFallbackCompileNode == null) {
757758
CompilerDirectives.transferToInterpreterAndInvalidate();
758-
getFallbackCompileNode = insert(GetAttributeNode.create(T__PATTERN__FALLBACK_COMPILE));
759+
getFallbackCompileNode = insert(GetFixedAttributeNode.create(T__PATTERN__FALLBACK_COMPILE));
759760
}
760761
return getFallbackCompileNode;
761762
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,7 @@ Object doWarn(VirtualFrame frame, PythonModule mod, Object message, Object categ
10011001
@Bind Node inliningTarget,
10021002
@Cached("createFor($node)") IndirectCallData indirectCallData,
10031003
@Cached SequenceStorageNodes.GetItemScalarNode getItemScalarNode,
1004-
@Cached StringNodes.CastToTruffleStringCheckedNode castToStringChecked,
1004+
@Cached StringNodes.CastToTruffleStringChecked1Node castToStringChecked,
10051005
@Cached PRaiseNode raiseNode,
10061006
@Cached WarningsModuleNode moduleFunctionsNode) {
10071007
// warnings_warn_impl

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextBuiltins.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,19 +1014,19 @@ abstract static class PyObjectSetAttrNode extends PNodeWithContext {
10141014

10151015
@Specialization
10161016
static void doBuiltinClass(PythonBuiltinClass object, TruffleString key, Object value,
1017-
@Exclusive @Cached(value = "createForceType()", inline = false) WriteAttributeToObjectNode writeAttrNode) {
1017+
@Exclusive @Cached WriteAttributeToObjectNode writeAttrNode) {
10181018
writeAttrNode.execute(object, key, value);
10191019
}
10201020

10211021
@Specialization
10221022
static void doNativeClass(PythonNativeClass object, TruffleString key, Object value,
1023-
@Exclusive @Cached(value = "createForceType()", inline = false) WriteAttributeToObjectNode writeAttrNode) {
1023+
@Exclusive @Cached WriteAttributeToObjectNode writeAttrNode) {
10241024
writeAttrNode.execute(object, key, value);
10251025
}
10261026

10271027
@Specialization(guards = {"!isPythonBuiltinClass(object)"})
10281028
static void doObject(PythonObject object, TruffleString key, Object value,
1029-
@Exclusive @Cached(inline = false) WriteAttributeToPythonObjectNode writeAttrToPythonObjectNode) {
1029+
@Exclusive @Cached WriteAttributeToPythonObjectNode writeAttrToPythonObjectNode) {
10301030
writeAttrToPythonObjectNode.execute(object, key, value);
10311031
}
10321032
}

0 commit comments

Comments
 (0)