|
51 | 51 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.PyTypeObject;
|
52 | 52 | import static com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor.Py_ssize_t;
|
53 | 53 | import static com.oracle.graal.python.builtins.objects.cext.common.CExtContext.METH_CLASS;
|
| 54 | +import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_name; |
54 | 55 | import static com.oracle.graal.python.nodes.HiddenAttr.METHOD_DEF_PTR;
|
55 | 56 | import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DOC__;
|
56 | 57 | import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___NAME__;
|
57 | 58 | import static com.oracle.graal.python.util.PythonUtils.EMPTY_OBJECT_ARRAY;
|
58 |
| -import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; |
59 | 59 |
|
60 | 60 | import com.oracle.graal.python.PythonLanguage;
|
61 | 61 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi7BuiltinNode;
|
62 | 62 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApi8BuiltinNode;
|
63 | 63 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBinaryBuiltinNode;
|
64 | 64 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiBuiltin;
|
65 | 65 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiCallPath;
|
66 |
| -import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiTernaryBuiltinNode; |
67 | 66 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.CApiUnaryBuiltinNode;
|
68 | 67 | import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltins.PyObjectSetAttrNode;
|
69 | 68 | import com.oracle.graal.python.builtins.objects.PNone;
|
|
78 | 77 | import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.GetterRoot;
|
79 | 78 | import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.PExternalFunctionWrapper;
|
80 | 79 | import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodes.SetterRoot;
|
| 80 | +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.ArgDescriptor; |
81 | 81 | import com.oracle.graal.python.builtins.objects.cext.common.CArrayWrappers.CArrayWrapper;
|
82 | 82 | import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.EnsureExecutableNode;
|
83 | 83 | import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
|
|
89 | 89 | import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
|
90 | 90 | import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor;
|
91 | 91 | import com.oracle.graal.python.builtins.objects.object.PythonObject;
|
92 |
| -import com.oracle.graal.python.builtins.objects.tuple.PTuple; |
93 | 92 | import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
|
94 | 93 | import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
|
95 | 94 | import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
|
|
103 | 102 | import com.oracle.graal.python.nodes.attributes.WriteAttributeToPythonObjectNode;
|
104 | 103 | import com.oracle.graal.python.nodes.object.GetDictIfExistsNode;
|
105 | 104 | import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
|
| 105 | +import com.oracle.graal.python.runtime.PythonContext; |
106 | 106 | import com.oracle.graal.python.runtime.object.PythonObjectFactory;
|
107 | 107 | import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage;
|
108 |
| -import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; |
109 | 108 | import com.oracle.graal.python.util.Function;
|
110 | 109 | import com.oracle.graal.python.util.PythonUtils;
|
111 | 110 | import com.oracle.truffle.api.CompilerDirectives;
|
|
120 | 119 | import com.oracle.truffle.api.dsl.ImportStatic;
|
121 | 120 | import com.oracle.truffle.api.dsl.Specialization;
|
122 | 121 | import com.oracle.truffle.api.interop.InteropLibrary;
|
123 |
| -import com.oracle.truffle.api.interop.UnsupportedMessageException; |
124 | 122 | import com.oracle.truffle.api.library.CachedLibrary;
|
125 | 123 | import com.oracle.truffle.api.nodes.Node;
|
126 | 124 | import com.oracle.truffle.api.nodes.RootNode;
|
127 | 125 | import com.oracle.truffle.api.object.DynamicObject;
|
128 | 126 | import com.oracle.truffle.api.object.DynamicObjectLibrary;
|
129 | 127 | import com.oracle.truffle.api.object.Shape;
|
130 |
| -import com.oracle.truffle.api.profiles.InlinedExactClassProfile; |
131 | 128 | import com.oracle.truffle.api.strings.TruffleString;
|
132 | 129 | import com.oracle.truffle.api.utilities.CyclicAssumption;
|
133 | 130 |
|
@@ -217,73 +214,48 @@ static PDict doGeneric(PythonNativeClass nativeClass) {
|
217 | 214 | }
|
218 | 215 | }
|
219 | 216 |
|
220 |
| - @CApiBuiltin(ret = Int, args = {PyTypeObject, ConstCharPtrAsTruffleString, PyObject}, call = Ignored) |
221 |
| - abstract static class PyTruffle_Type_Modified extends CApiTernaryBuiltinNode { |
| 217 | + @CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject}, call = Ignored) |
| 218 | + abstract static class PyTruffle_InitializeOldStyleSlots extends CApiUnaryBuiltinNode { |
222 | 219 |
|
223 | 220 | @TruffleBoundary
|
224 |
| - @Specialization(guards = "isNoValue(mroTuple)") |
225 |
| - int doIt(PythonNativeClass clazz, TruffleString name, @SuppressWarnings("unused") PNone mroTuple) { |
226 |
| - CyclicAssumption nativeClassStableAssumption = getContext().getNativeClassStableAssumption(clazz, false); |
227 |
| - if (nativeClassStableAssumption != null) { |
228 |
| - nativeClassStableAssumption.invalidate("PyType_Modified(\"" + name.toJavaStringUncached() + "\") (without MRO) called"); |
229 |
| - } |
230 |
| - SpecialMethodSlot.reinitializeSpecialMethodSlots(PythonNativeClass.cast(clazz), getLanguage()); |
231 |
| - // TODO: this is called from two places: at the end of PyType_Ready, and theoretically |
232 |
| - // could be called from: |
233 |
| - // |
234 |
| - // void PyType_Modified(PyTypeObject* type) -> GraalPyTruffle_Type_Modified(type, |
235 |
| - // type->tp_name, type->tp_mro); |
236 |
| - // |
237 |
| - // in unlikely (impossible?) case that type->tp_mro was NULL. Should we distinguish |
238 |
| - // the two cases? As a cleanup if it is impossible situation (separate two different |
239 |
| - // upcalls), or because at the end of PyType_Ready, we do not want to call |
240 |
| - // TpSlots.updateAllSlots(clazz), but from PyType_Modified we do. |
241 |
| - return 0; |
| 221 | + @Specialization |
| 222 | + static Object doIt(PythonAbstractNativeObject clazz, |
| 223 | + @Bind("this") Node inliningTarget) { |
| 224 | + SpecialMethodSlot.reinitializeSpecialMethodSlots(clazz, PythonLanguage.get(inliningTarget)); |
| 225 | + return PNone.NO_VALUE; |
242 | 226 | }
|
| 227 | + } |
| 228 | + |
| 229 | + @CApiBuiltin(ret = ArgDescriptor.Void, args = {PyTypeObject}, call = Direct) |
| 230 | + abstract static class PyType_Modified extends CApiUnaryBuiltinNode { |
243 | 231 |
|
244 | 232 | @TruffleBoundary
|
245 | 233 | @Specialization
|
246 |
| - int doIt(PythonNativeClass clazz, TruffleString name, PTuple mroTuple, |
247 |
| - @Bind("this") Node inliningTarget, |
248 |
| - @Cached InlinedExactClassProfile profile) { |
249 |
| - CyclicAssumption nativeClassStableAssumption = getContext().getNativeClassStableAssumption(clazz, false); |
| 234 | + static Object doIt(PythonAbstractNativeObject clazz, |
| 235 | + @Bind("this") Node inliningTarget) { |
| 236 | + PythonContext context = PythonContext.get(inliningTarget); |
| 237 | + CyclicAssumption nativeClassStableAssumption = context.getNativeClassStableAssumption(clazz, false); |
250 | 238 | if (nativeClassStableAssumption != null) {
|
251 |
| - nativeClassStableAssumption.invalidate("PyType_Modified(\"" + name.toJavaStringUncached() + "\") called"); |
| 239 | + nativeClassStableAssumption.invalidate("PyType_Modified(\"" + TypeNodes.GetNameNode.executeUncached(clazz).toJavaStringUncached() + "\") called"); |
252 | 240 | }
|
253 |
| - SequenceStorage sequenceStorage = profile.profile(inliningTarget, mroTuple.getSequenceStorage()); |
254 |
| - if (sequenceStorage instanceof MroSequenceStorage) { |
255 |
| - ((MroSequenceStorage) sequenceStorage).lookupChanged(); |
256 |
| - } else { |
257 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
258 |
| - throw new IllegalStateException("invalid MRO object for native type \"" + name.toJavaStringUncached() + "\""); |
259 |
| - } |
260 |
| - SpecialMethodSlot.reinitializeSpecialMethodSlots(PythonNativeClass.cast(clazz), getLanguage()); |
261 |
| - TpSlots.updateAllSlots(clazz); |
262 |
| - return 0; |
| 241 | + MroSequenceStorage mroStorage = TypeNodes.GetMroStorageNode.executeUncached(clazz); |
| 242 | + mroStorage.lookupChanged(); |
| 243 | + // Reload slots from native, which also invalidates cached slot lookups |
| 244 | + clazz.setTpSlots(TpSlots.fromNative(clazz, context)); |
| 245 | + return PNone.NO_VALUE; |
263 | 246 | }
|
264 | 247 | }
|
265 | 248 |
|
266 |
| - @CApiBuiltin(ret = Int, args = {Pointer, Pointer}, call = Ignored) |
267 |
| - abstract static class PyTruffle_Trace_Type extends CApiBinaryBuiltinNode { |
| 249 | + @CApiBuiltin(ret = Int, args = {Pointer}, call = Ignored) |
| 250 | + abstract static class PyTruffle_Trace_Type extends CApiUnaryBuiltinNode { |
268 | 251 | private static final TruffleLogger LOGGER = CApiContext.getLogger(PyTruffle_Trace_Type.class);
|
269 | 252 |
|
270 |
| - @Specialization(limit = "3") |
271 |
| - int trace(Object ptr, Object classNameObj, |
272 |
| - @CachedLibrary("ptr") InteropLibrary ptrLib, |
273 |
| - @CachedLibrary("classNameObj") InteropLibrary nameLib, |
274 |
| - @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { |
275 |
| - final TruffleString className; |
276 |
| - if (nameLib.isString(classNameObj)) { |
277 |
| - try { |
278 |
| - className = switchEncodingNode.execute(nameLib.asTruffleString(classNameObj), TS_ENCODING); |
279 |
| - } catch (UnsupportedMessageException e) { |
280 |
| - throw CompilerDirectives.shouldNotReachHere(e); |
281 |
| - } |
282 |
| - } else { |
283 |
| - className = null; |
284 |
| - } |
285 |
| - Object primitivePtr = CApiContext.asPointer(ptr, ptrLib); |
286 |
| - LOGGER.fine(() -> PythonUtils.formatJString("Initializing native type %s (ptr = %s)", className, CApiContext.asHex(primitivePtr))); |
| 253 | + @Specialization |
| 254 | + @TruffleBoundary |
| 255 | + int trace(Object ptr) { |
| 256 | + LOGGER.fine(() -> PythonUtils.formatJString("Initializing native type %s (ptr = %s)", |
| 257 | + CStructAccess.ReadCharPtrNode.getUncached().read(ptr, PyTypeObject__tp_name), |
| 258 | + CApiContext.asHex(CApiContext.asPointer(ptr, InteropLibrary.getUncached())))); |
287 | 259 | return 0;
|
288 | 260 | }
|
289 | 261 | }
|
|
0 commit comments