@@ -1057,34 +1057,40 @@ public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode>
1057
1057
// be appropriate keys for the cache
1058
1058
assert RootNode .class .isAssignableFrom (key ) || key .getConstructors ().length <= 1 ;
1059
1059
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 );
1061
1061
}
1062
1062
1063
1063
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Enum <?> key ) {
1064
- return createCachedCallTargetUnsafe (rootNodeFunction , key );
1064
+ return createCachedCallTargetUnsafe (rootNodeFunction , key , true );
1065
1065
}
1066
1066
1067
1067
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Class <? extends Node > nodeClass , String key ) {
1068
1068
// for builtins: name is needed to distinguish builtins that share the same underlying node
1069
1069
// in general: a String may be parameter of the node wrapped in the root node or the root
1070
1070
// node itself, there must be finite number of strings that can appear here (i.e., must not
1071
1071
// 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 );
1073
1079
}
1074
1080
1075
1081
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Class <? extends Node > nodeClass , TruffleString key ) {
1076
1082
// See the String overload
1077
- return createCachedCallTargetUnsafe (rootNodeFunction , nodeClass , key );
1083
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , nodeClass , key );
1078
1084
}
1079
1085
1080
1086
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 );
1082
1088
}
1083
1089
1084
1090
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Class <? extends Node > nodeClass1 , Class <?> nodeClass2 , String name ) {
1085
1091
// for slot wrappers: the root node may be wrapping a helper wrapper node implementing the
1086
1092
// wrapper logic and the bare slot node itself
1087
- return createCachedCallTargetUnsafe (rootNodeFunction , nodeClass1 , nodeClass2 , name );
1093
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , nodeClass1 , nodeClass2 , name );
1088
1094
}
1089
1095
1090
1096
/**
@@ -1096,26 +1102,26 @@ public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode>
1096
1102
*/
1097
1103
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Class <? extends RootNode > klass , Enum <?> signature , TruffleString name ,
1098
1104
boolean doArgumentAndResultConversion ) {
1099
- return createCachedCallTargetUnsafe (rootNodeFunction , klass , signature , name , doArgumentAndResultConversion );
1105
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , klass , signature , name , doArgumentAndResultConversion );
1100
1106
}
1101
1107
1102
1108
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Enum <?> signature , TruffleString name ,
1103
1109
boolean doArgumentAndResultConversion ) {
1104
- return createCachedCallTargetUnsafe (rootNodeFunction , signature , name , doArgumentAndResultConversion );
1110
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , signature , name , doArgumentAndResultConversion );
1105
1111
}
1106
1112
1107
1113
public RootCallTarget createCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Enum <?> signature , TruffleString name ) {
1108
- return createCachedCallTargetUnsafe (rootNodeFunction , signature , name );
1114
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , signature , name );
1109
1115
}
1110
1116
1111
1117
public RootCallTarget createStructSeqIndexedMemberAccessCachedCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , int memberIndex ) {
1112
- return createCachedCallTargetUnsafe (rootNodeFunction , StructSequence .class , memberIndex );
1118
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , StructSequence .class , memberIndex );
1113
1119
}
1114
1120
1115
1121
public RootCallTarget createCachedPropAccessCallTarget (Function <PythonLanguage , RootNode > rootNodeFunction , Class <?> nodeClass , String name , int type , int offset ) {
1116
1122
// For the time being, we assume finite/limited number of cext/hpy types members, their
1117
1123
// types and offsets
1118
- return createCachedCallTargetUnsafe (rootNodeFunction , nodeClass , name , type , offset );
1124
+ return createCachedCallTargetUnsafe (rootNodeFunction , true , nodeClass , name , type , offset );
1119
1125
}
1120
1126
1121
1127
/**
@@ -1128,17 +1134,17 @@ public RootCallTarget createCachedPropAccessCallTarget(Function<PythonLanguage,
1128
1134
* instances. Public methods for adding to the cache must take concrete key type(s) so that all
1129
1135
* possible cache keys are explicit and documented.
1130
1136
*/
1131
- private RootCallTarget createCachedCallTargetUnsafe (Function <PythonLanguage , RootNode > rootNodeFunction , Object key ) {
1137
+ private RootCallTarget createCachedCallTargetUnsafe (Function <PythonLanguage , RootNode > rootNodeFunction , Object key , boolean cacheInSingleContext ) {
1132
1138
CompilerAsserts .neverPartOfCompilation ();
1133
- if (!singleContext ) {
1139
+ if (cacheInSingleContext || !singleContext ) {
1134
1140
return cachedCallTargets .computeIfAbsent (key , k -> PythonUtils .getOrCreateCallTarget (rootNodeFunction .apply (this )));
1135
1141
} else {
1136
1142
return PythonUtils .getOrCreateCallTarget (rootNodeFunction .apply (this ));
1137
1143
}
1138
1144
}
1139
1145
1140
- private RootCallTarget createCachedCallTargetUnsafe (Function <PythonLanguage , RootNode > rootNodeFunction , Object ... cacheKeys ) {
1141
- return createCachedCallTargetUnsafe (rootNodeFunction , Arrays .asList (cacheKeys ));
1146
+ private RootCallTarget createCachedCallTargetUnsafe (Function <PythonLanguage , RootNode > rootNodeFunction , boolean cacheInSingleContext , Object ... cacheKeys ) {
1147
+ return createCachedCallTargetUnsafe (rootNodeFunction , Arrays .asList (cacheKeys ), cacheInSingleContext );
1142
1148
}
1143
1149
1144
1150
public void registerBuiltinDescriptorCallTarget (BuiltinMethodDescriptor descriptor , RootCallTarget callTarget ) {
0 commit comments