Skip to content

Commit 818488a

Browse files
committed
[GR-58076] Cache most of the CallTargets even in single context mode.
PullRequest: graalpython/3477
2 parents ac15d87 + c95cb23 commit 818488a

File tree

4 files changed

+28
-21
lines changed

4 files changed

+28
-21
lines changed

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

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,34 +1057,40 @@ public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode>
10571057
// be appropriate keys for the cache
10581058
assert RootNode.class.isAssignableFrom(key) || key.getConstructors().length <= 1;
10591059
assert RootNode.class.isAssignableFrom(key) || key.getConstructors().length == 0 || key.getConstructors()[0].getParameterCount() == 0;
1060-
return createCachedCallTargetUnsafe(rootNodeFunction, key);
1060+
return createCachedCallTargetUnsafe(rootNodeFunction, key, true);
10611061
}
10621062

10631063
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Enum<?> key) {
1064-
return createCachedCallTargetUnsafe(rootNodeFunction, key);
1064+
return createCachedCallTargetUnsafe(rootNodeFunction, key, true);
10651065
}
10661066

10671067
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends Node> nodeClass, String key) {
10681068
// for builtins: name is needed to distinguish builtins that share the same underlying node
10691069
// in general: a String may be parameter of the node wrapped in the root node or the root
10701070
// node itself, there must be finite number of strings that can appear here (i.e., must not
10711071
// be dynamically generated unless their number is bounded).
1072-
return createCachedCallTargetUnsafe(rootNodeFunction, nodeClass, key);
1072+
return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, key);
1073+
}
1074+
1075+
// Variant that should be called at most once per context, because it does not cache the target
1076+
// in single context mode
1077+
public RootCallTarget initBuiltinCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends Node> nodeClass, String key) {
1078+
return createCachedCallTargetUnsafe(rootNodeFunction, false, nodeClass, key);
10731079
}
10741080

10751081
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends Node> nodeClass, TruffleString key) {
10761082
// See the String overload
1077-
return createCachedCallTargetUnsafe(rootNodeFunction, nodeClass, key);
1083+
return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, key);
10781084
}
10791085

10801086
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends Node> nodeClass, int key) {
1081-
return createCachedCallTargetUnsafe(rootNodeFunction, nodeClass, key);
1087+
return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, key);
10821088
}
10831089

10841090
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends Node> nodeClass1, Class<?> nodeClass2, String name) {
10851091
// for slot wrappers: the root node may be wrapping a helper wrapper node implementing the
10861092
// wrapper logic and the bare slot node itself
1087-
return createCachedCallTargetUnsafe(rootNodeFunction, nodeClass1, nodeClass2, name);
1093+
return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass1, nodeClass2, name);
10881094
}
10891095

10901096
/**
@@ -1094,28 +1100,29 @@ public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode>
10941100
* functions. This may hold onto call targets created by one extension used in a context that
10951101
* was closed in the meanwhile and no other context ever loads the extension.
10961102
*/
1097-
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends RootNode> klass, Enum<?> signature, TruffleString name,
1098-
boolean doArgumentAndResultConversion) {
1099-
return createCachedCallTargetUnsafe(rootNodeFunction, klass, signature, name, doArgumentAndResultConversion);
1103+
public RootCallTarget createCachedExternalFunWrapperCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction,
1104+
Class<? extends RootNode> klass, Enum<?> signature, TruffleString name,
1105+
boolean doArgumentAndResultConversion, boolean isStatic) {
1106+
return createCachedCallTargetUnsafe(rootNodeFunction, true, klass, signature, name, doArgumentAndResultConversion, isStatic);
11001107
}
11011108

11021109
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Enum<?> signature, TruffleString name,
11031110
boolean doArgumentAndResultConversion) {
1104-
return createCachedCallTargetUnsafe(rootNodeFunction, signature, name, doArgumentAndResultConversion);
1111+
return createCachedCallTargetUnsafe(rootNodeFunction, true, signature, name, doArgumentAndResultConversion);
11051112
}
11061113

11071114
public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Enum<?> signature, TruffleString name) {
1108-
return createCachedCallTargetUnsafe(rootNodeFunction, signature, name);
1115+
return createCachedCallTargetUnsafe(rootNodeFunction, true, signature, name);
11091116
}
11101117

11111118
public RootCallTarget createStructSeqIndexedMemberAccessCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, int memberIndex) {
1112-
return createCachedCallTargetUnsafe(rootNodeFunction, StructSequence.class, memberIndex);
1119+
return createCachedCallTargetUnsafe(rootNodeFunction, true, StructSequence.class, memberIndex);
11131120
}
11141121

11151122
public RootCallTarget createCachedPropAccessCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<?> nodeClass, String name, int type, int offset) {
11161123
// For the time being, we assume finite/limited number of cext/hpy types members, their
11171124
// types and offsets
1118-
return createCachedCallTargetUnsafe(rootNodeFunction, nodeClass, name, type, offset);
1125+
return createCachedCallTargetUnsafe(rootNodeFunction, true, nodeClass, name, type, offset);
11191126
}
11201127

11211128
/**
@@ -1128,17 +1135,17 @@ public RootCallTarget createCachedPropAccessCallTarget(Function<PythonLanguage,
11281135
* instances. Public methods for adding to the cache must take concrete key type(s) so that all
11291136
* possible cache keys are explicit and documented.
11301137
*/
1131-
private RootCallTarget createCachedCallTargetUnsafe(Function<PythonLanguage, RootNode> rootNodeFunction, Object key) {
1138+
private RootCallTarget createCachedCallTargetUnsafe(Function<PythonLanguage, RootNode> rootNodeFunction, Object key, boolean cacheInSingleContext) {
11321139
CompilerAsserts.neverPartOfCompilation();
1133-
if (!singleContext) {
1140+
if (cacheInSingleContext || !singleContext) {
11341141
return cachedCallTargets.computeIfAbsent(key, k -> PythonUtils.getOrCreateCallTarget(rootNodeFunction.apply(this)));
11351142
} else {
11361143
return PythonUtils.getOrCreateCallTarget(rootNodeFunction.apply(this));
11371144
}
11381145
}
11391146

1140-
private RootCallTarget createCachedCallTargetUnsafe(Function<PythonLanguage, RootNode> rootNodeFunction, Object... cacheKeys) {
1141-
return createCachedCallTargetUnsafe(rootNodeFunction, Arrays.asList(cacheKeys));
1147+
private RootCallTarget createCachedCallTargetUnsafe(Function<PythonLanguage, RootNode> rootNodeFunction, boolean cacheInSingleContext, Object... cacheKeys) {
1148+
return createCachedCallTargetUnsafe(rootNodeFunction, Arrays.asList(cacheKeys), cacheInSingleContext);
11421149
}
11431150

11441151
public void registerBuiltinDescriptorCallTarget(BuiltinMethodDescriptor descriptor, RootCallTarget callTarget) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ public void initialize(Python3Core core) {
173173
declaresExplicitSelf = true;
174174
}
175175
TruffleString tsName = toTruffleStringUncached(builtin.name());
176-
RootCallTarget callTarget = core.getLanguage().createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(),
176+
RootCallTarget callTarget = core.getLanguage().initBuiltinCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(),
177177
builtin.name());
178178
Object builtinDoc = builtin.doc().isEmpty() ? PNone.NONE : toTruffleStringUncached(builtin.doc());
179179
int flags = PBuiltinFunction.getFlags(builtin, callTarget);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,13 +448,13 @@ static GetSetDescriptor createGetSet(Node inliningTarget, TruffleString name, Ob
448448
@TruffleBoundary
449449
private static RootCallTarget getterCallTarget(TruffleString name, PythonLanguage lang) {
450450
Function<PythonLanguage, RootNode> rootNodeFunction = l -> new GetterRoot(l, name, PExternalFunctionWrapper.GETTER);
451-
return lang.createCachedCallTarget(rootNodeFunction, GetterRoot.class, PExternalFunctionWrapper.GETTER, name, true);
451+
return lang.createCachedExternalFunWrapperCallTarget(rootNodeFunction, GetterRoot.class, PExternalFunctionWrapper.GETTER, name, true, false);
452452
}
453453

454454
@TruffleBoundary
455455
private static RootCallTarget setterCallTarget(TruffleString name, PythonLanguage lang) {
456456
Function<PythonLanguage, RootNode> rootNodeFunction = l -> new SetterRoot(l, name, PExternalFunctionWrapper.SETTER);
457-
return lang.createCachedCallTarget(rootNodeFunction, SetterRoot.class, PExternalFunctionWrapper.SETTER, name, true);
457+
return lang.createCachedExternalFunWrapperCallTarget(rootNodeFunction, SetterRoot.class, PExternalFunctionWrapper.SETTER, name, true, false);
458458
}
459459
}
460460

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ static RootCallTarget getOrCreateCallTarget(PExternalFunctionWrapper sig, Python
620620
default:
621621
throw CompilerDirectives.shouldNotReachHere();
622622
}
623-
return language.createCachedCallTarget(rootNodeFunction, nodeKlass, sig, name, doArgAndResultConversion);
623+
return language.createCachedExternalFunWrapperCallTarget(rootNodeFunction, nodeKlass, sig, name, doArgAndResultConversion, isStatic);
624624
}
625625

626626
public static PBuiltinFunction createWrapperFunction(TruffleString name, Object callable, Object enclosingType, int flags, int sig,

0 commit comments

Comments
 (0)