Skip to content

Commit ea81156

Browse files
committed
Store call targets for method descriptors separately
1 parent 12a867a commit ea81156

File tree

8 files changed

+49
-41
lines changed

8 files changed

+49
-41
lines changed

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

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
4444
import com.oracle.graal.python.builtins.objects.dict.PDict;
4545
import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis;
46+
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
4647
import com.oracle.graal.python.builtins.objects.function.PArguments;
4748
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4849
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
@@ -54,7 +55,6 @@
5455
import com.oracle.graal.python.nodes.call.InvokeNode;
5556
import com.oracle.graal.python.nodes.control.TopLevelExceptionHandler;
5657
import com.oracle.graal.python.nodes.expression.ExpressionNode;
57-
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5858
import com.oracle.graal.python.nodes.util.BadOPCodeNode;
5959
import com.oracle.graal.python.parser.PythonParserImpl;
6060
import com.oracle.graal.python.runtime.GilNode;
@@ -171,6 +171,14 @@ public final class PythonLanguage extends TruffleLanguage<PythonContext> {
171171
*/
172172
private final ConcurrentHashMap<Object, RootCallTarget> cachedCallTargets = new ConcurrentHashMap<>();
173173

174+
/**
175+
* A map to retrieve call targets of special slot methods for a given BuiltinMethodDescriptor.
176+
* Used to perform uncached calls to slots. The call targets are not directly part of
177+
* descriptors because that would make them specific to a language instance. We want to have
178+
* them global in order to be able to efficiently compare them in guards.
179+
*/
180+
private final ConcurrentHashMap<BuiltinMethodDescriptor, RootCallTarget> descriptorCallTargets = new ConcurrentHashMap<>();
181+
174182
private final Shape emptyShape = Shape.newBuilder().allowImplicitCastIntToDouble(false).allowImplicitCastIntToLong(true).shapeFlags(0).propertyAssumptions(true).build();
175183
@CompilationFinal(dimensions = 1) private final Shape[] builtinTypeInstanceShapes = new Shape[PythonBuiltinClassType.VALUES.length];
176184

@@ -859,17 +867,14 @@ public RootCallTarget createCachedCallTarget(Function<PythonLanguage, RootNode>
859867
return createCachedCallTarget(rootNodeFunction, Arrays.asList(cacheKeys));
860868
}
861869

862-
public RootCallTarget createBuiltinCachedCallTarget(Function<PythonLanguage, RootNode> rootNodeFunction, Class<? extends PythonBuiltinBaseNode> nodeClass, String name) {
863-
return createCachedCallTarget(rootNodeFunction, Arrays.asList(nodeClass, name));
864-
}
865-
866-
@TruffleBoundary
867-
public RootCallTarget getCachedBuiltinCallTarget(Class<? extends PythonBuiltinBaseNode> nodeClass, String name) {
868-
return cachedCallTargets.get(Arrays.asList(nodeClass, name));
870+
public void registerBuiltinDescriptorCallTarget(BuiltinMethodDescriptor descriptor, RootCallTarget callTarget) {
871+
descriptorCallTargets.put(descriptor, callTarget);
869872
}
870873

871874
@TruffleBoundary
872-
public RootCallTarget getCachedBuiltinCallTarget(com.oracle.truffle.api.dsl.NodeFactory<? extends PythonBuiltinBaseNode> factory, String name) {
873-
return getCachedBuiltinCallTarget(factory.getNodeClass(), name);
875+
public RootCallTarget getDescriptorCallTarget(BuiltinMethodDescriptor descriptor) {
876+
RootCallTarget callTarget = descriptorCallTargets.get(descriptor);
877+
assert callTarget != null : "Missing call target for builtin slot descriptor";
878+
return callTarget;
874879
}
875880
}

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535
import java.util.Map.Entry;
3636

3737
import com.oracle.graal.python.builtins.objects.PNone;
38+
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
3839
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
3940
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
41+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
4042
import com.oracle.graal.python.nodes.function.BuiltinFunctionRootNode;
4143
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4244
import com.oracle.graal.python.util.BiConsumer;
@@ -73,14 +75,26 @@ public void initialize(Python3Core core) {
7375
} else {
7476
declaresExplicitSelf = true;
7577
}
76-
RootCallTarget callTarget = core.getLanguage().createBuiltinCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(),
78+
RootCallTarget callTarget = core.getLanguage().createCachedCallTarget(l -> new BuiltinFunctionRootNode(l, builtin, factory, declaresExplicitSelf), factory.getNodeClass(),
7779
builtin.name());
80+
if (SpecialMethodSlot.findSpecialSlot(builtin.name()) != null) {
81+
for (PythonBuiltinClassType type : annotation.extendClasses()) {
82+
BuiltinMethodDescriptor descriptor = BuiltinMethodDescriptor.get(factory, type);
83+
if (descriptor != null) {
84+
core.getLanguage().registerBuiltinDescriptorCallTarget(descriptor, callTarget);
85+
}
86+
}
87+
}
7888
Object builtinDoc = builtin.doc().isEmpty() ? PNone.NONE : builtin.doc();
7989
if (constructsClass != PythonBuiltinClassType.nil) {
8090
assert !builtin.isGetter() && !builtin.isSetter() && !builtin.isClassmethod() && !builtin.isStaticmethod();
8191
// we explicitly do not make these "staticmethods" here, since CPython also doesn't
8292
// for builtin types
8393
PBuiltinFunction newFunc = core.factory().createBuiltinFunction(__NEW__, constructsClass, numDefaults(builtin), callTarget);
94+
BuiltinMethodDescriptor descriptor = BuiltinMethodDescriptor.get(newFunc);
95+
if (descriptor != null) {
96+
core.getLanguage().registerBuiltinDescriptorCallTarget(descriptor, callTarget);
97+
}
8498
PythonBuiltinClass builtinClass = core.lookupType(constructsClass);
8599
builtinClass.setAttributeUnsafe(__NEW__, newFunc);
86100
builtinClass.setAttribute(__DOC__, builtinDoc);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/BuiltinMethodDescriptor.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,19 +91,19 @@ public static BuiltinMethodDescriptor get(PBuiltinFunction function) {
9191
assert enclosing == null;
9292
}
9393

94-
return get(factory, type, function.getName());
94+
return get(factory, type);
9595
}
9696

97-
public static BuiltinMethodDescriptor get(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type, String name) {
97+
public static BuiltinMethodDescriptor get(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type) {
9898
CompilerAsserts.neverPartOfCompilation();
9999
Class<? extends PythonBuiltinBaseNode> nodeClass = factory.getNodeClass();
100100
BuiltinMethodDescriptor result = null;
101101
if (PythonUnaryBuiltinNode.class.isAssignableFrom(nodeClass)) {
102-
result = new UnaryBuiltinInfo(factory, type, name);
102+
result = new UnaryBuiltinInfo(factory, type);
103103
} else if (PythonBinaryBuiltinNode.class.isAssignableFrom(nodeClass)) {
104-
result = new BinaryBuiltinInfo(factory, type, name);
104+
result = new BinaryBuiltinInfo(factory, type);
105105
} else if (PythonTernaryBuiltinNode.class.isAssignableFrom(nodeClass)) {
106-
result = new TernaryBuiltinInfo(factory, type, name);
106+
result = new TernaryBuiltinInfo(factory, type);
107107
}
108108
if (result != null) {
109109
return CACHE.computeIfAbsent(result, x -> x);
@@ -122,22 +122,16 @@ private static boolean needsFrame(NodeFactory<? extends PythonBuiltinBaseNode> f
122122

123123
private final NodeFactory<? extends PythonBuiltinBaseNode> factory;
124124
private final PythonBuiltinClassType type;
125-
private final String name;
126125

127-
public BuiltinMethodDescriptor(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type, String name) {
126+
private BuiltinMethodDescriptor(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type) {
128127
this.factory = factory;
129128
this.type = type;
130-
this.name = name;
131129
}
132130

133131
public final NodeFactory<? extends PythonBuiltinBaseNode> getFactory() {
134132
return factory;
135133
}
136134

137-
public String getName() {
138-
return name;
139-
}
140-
141135
@Override
142136
public boolean equals(Object o) {
143137
if (this == o) {
@@ -159,8 +153,8 @@ public int hashCode() {
159153
// generic class that would parametrize the 'factory' field
160154

161155
public static final class UnaryBuiltinInfo extends BuiltinMethodDescriptor {
162-
public UnaryBuiltinInfo(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type, String name) {
163-
super(factory, type, name);
156+
public UnaryBuiltinInfo(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type) {
157+
super(factory, type);
164158
}
165159

166160
public PythonUnaryBuiltinNode createNode() {
@@ -169,8 +163,8 @@ public PythonUnaryBuiltinNode createNode() {
169163
}
170164

171165
public static final class BinaryBuiltinInfo extends BuiltinMethodDescriptor {
172-
public BinaryBuiltinInfo(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type, String name) {
173-
super(factory, type, name);
166+
public BinaryBuiltinInfo(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type) {
167+
super(factory, type);
174168
}
175169

176170
public PythonBinaryBuiltinNode createNode() {
@@ -179,8 +173,8 @@ public PythonBinaryBuiltinNode createNode() {
179173
}
180174

181175
public static final class TernaryBuiltinInfo extends BuiltinMethodDescriptor {
182-
public TernaryBuiltinInfo(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type, String name) {
183-
super(factory, type, name);
176+
public TernaryBuiltinInfo(NodeFactory<? extends PythonBuiltinBaseNode> factory, PythonBuiltinClassType type) {
177+
super(factory, type);
184178
}
185179

186180
public PythonTernaryBuiltinNode createNode() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetMethod.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@
4040
*/
4141
package com.oracle.graal.python.lib;
4242

43-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
44-
4543
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4644
import com.oracle.graal.python.builtins.objects.PNone;
4745
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
@@ -77,8 +75,7 @@
7775
@GenerateUncached
7876
@ImportStatic(SpecialMethodSlot.class)
7977
public abstract class PyObjectGetMethod extends Node {
80-
private static final BuiltinMethodDescriptor OBJ_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(ObjectBuiltinsFactory.GetAttributeNodeFactory.getInstance(), PythonBuiltinClassType.PythonObject,
81-
__GETATTRIBUTE__);
78+
private static final BuiltinMethodDescriptor OBJ_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(ObjectBuiltinsFactory.GetAttributeNodeFactory.getInstance(), PythonBuiltinClassType.PythonObject);
8279

8380
public abstract Object execute(Frame frame, Object receiver, String name);
8481

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/GetAttributeNode.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,10 @@ static Assumption singleContextAssumption() {
185185
}
186186

187187
public abstract static class GetFixedAttributeNode extends GetAttributeBaseNode {
188-
private static final BuiltinMethodDescriptor OBJ_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(ObjectBuiltinsFactory.GetAttributeNodeFactory.getInstance(), PythonBuiltinClassType.PythonObject,
189-
__GETATTRIBUTE__);
188+
private static final BuiltinMethodDescriptor OBJ_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(ObjectBuiltinsFactory.GetAttributeNodeFactory.getInstance(), PythonBuiltinClassType.PythonObject);
190189
private static final BuiltinMethodDescriptor MODULE_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(ModuleBuiltinsFactory.ModuleGetattritbuteNodeFactory.getInstance(),
191-
PythonBuiltinClassType.PythonModule, __GETATTRIBUTE__);
192-
private static final BuiltinMethodDescriptor TYPE_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(TypeBuiltinsFactory.GetattributeNodeFactory.getInstance(), PythonBuiltinClassType.PythonClass,
193-
__GETATTRIBUTE__);
190+
PythonBuiltinClassType.PythonModule);
191+
private static final BuiltinMethodDescriptor TYPE_GET_ATTRIBUTE = BuiltinMethodDescriptor.get(TypeBuiltinsFactory.GetattributeNodeFactory.getInstance(), PythonBuiltinClassType.PythonClass);
194192

195193
private final String key;
196194

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallBinaryMethodNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Object callSpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unuse
9797
Object callSpecialMethodSlotCallTarget(VirtualFrame frame, BinaryBuiltinInfo info, Object arg1, Object arg2,
9898
@CachedLanguage PythonLanguage language,
9999
@Cached GenericInvokeNode invokeNode) {
100-
RootCallTarget callTarget = language.getCachedBuiltinCallTarget(info.getFactory(), info.getName());
100+
RootCallTarget callTarget = language.getDescriptorCallTarget(info);
101101
Object[] arguments = PArguments.create(2);
102102
PArguments.setArgument(arguments, 0, arg1);
103103
PArguments.setArgument(arguments, 1, arg2);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallTernaryMethodNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static Object callSpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings
8686
static Object callSpecialMethodSlotCallTarget(VirtualFrame frame, TernaryBuiltinInfo info, Object arg1, Object arg2, Object arg3,
8787
@CachedLanguage PythonLanguage language,
8888
@Cached GenericInvokeNode invokeNode) {
89-
RootCallTarget callTarget = language.getCachedBuiltinCallTarget(info.getFactory(), info.getName());
89+
RootCallTarget callTarget = language.getDescriptorCallTarget(info);
9090
Object[] arguments = PArguments.create(3);
9191
PArguments.setArgument(arguments, 0, arg1);
9292
PArguments.setArgument(arguments, 1, arg2);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/CallUnaryMethodNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Object callSpecialMethodSlotInlined(VirtualFrame frame, @SuppressWarnings("unuse
114114
Object callSpecialMethodSlotCallTarget(VirtualFrame frame, UnaryBuiltinInfo info, Object receiver,
115115
@CachedLanguage PythonLanguage language,
116116
@Cached GenericInvokeNode invokeNode) {
117-
RootCallTarget callTarget = language.getCachedBuiltinCallTarget(info.getFactory(), info.getName());
117+
RootCallTarget callTarget = language.getDescriptorCallTarget(info);
118118
Object[] arguments = PArguments.create(1);
119119
PArguments.setArgument(arguments, 0, receiver);
120120
return invokeNode.execute(frame, callTarget, arguments);

0 commit comments

Comments
 (0)