|
42 | 42 |
|
43 | 43 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
|
44 | 44 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
|
| 45 | +import static com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TYPE_FLAGS; |
45 | 46 | import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BASETYPE;
|
46 | 47 | import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BASE_EXC_SUBCLASS;
|
47 | 48 | import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BYTES_SUBCLASS;
|
|
76 | 77 | import com.oracle.graal.python.builtins.objects.cext.CExtNodes.GetTypeMemberNode;
|
77 | 78 | import com.oracle.graal.python.builtins.objects.cext.CExtNodes.PCallCapiFunction;
|
78 | 79 | import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToSulongNode;
|
| 80 | +import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory; |
79 | 81 | import com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols;
|
80 | 82 | import com.oracle.graal.python.builtins.objects.cext.NativeMember;
|
81 | 83 | import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
|
|
110 | 112 | import com.oracle.graal.python.nodes.SpecialMethodNames;
|
111 | 113 | import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
|
112 | 114 | import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
|
| 115 | +import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; |
113 | 116 | import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
|
114 | 117 | import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
|
115 | 118 | import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
|
|
127 | 130 | import com.oracle.truffle.api.CompilerDirectives;
|
128 | 131 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
129 | 132 | import com.oracle.truffle.api.dsl.Cached;
|
130 |
| -import com.oracle.truffle.api.dsl.Cached.Shared; |
131 | 133 | import com.oracle.truffle.api.dsl.CachedContext;
|
132 | 134 | import com.oracle.truffle.api.dsl.Fallback;
|
133 | 135 | import com.oracle.truffle.api.dsl.GenerateUncached;
|
@@ -227,37 +229,52 @@ static long doBuiltinClass(PythonBuiltinClass clazz) {
|
227 | 229 |
|
228 | 230 | @Specialization
|
229 | 231 | static long doPythonClass(PythonClass clazz,
|
230 |
| - @Cached GetMroStorageNode getMroStorageNode, |
231 |
| - @Cached SequenceStorageNodes.LenNode lenNode, |
232 |
| - @Cached SequenceStorageNodes.GetItemDynamicNode getItemNode, |
233 |
| - @Shared("getTpFlagsNode") @Cached CExtNodes.GetTypeMemberNode getTpFlagsNode) { |
| 232 | + @Cached ReadAttributeFromObjectNode readHiddenFlagsNode, |
| 233 | + @Cached WriteAttributeToObjectNode writeHiddenFlagsNode, |
| 234 | + @Cached("createCountingProfile()") ConditionProfile profile) { |
| 235 | + |
| 236 | + Object flagsObject = readHiddenFlagsNode.execute(clazz, TYPE_FLAGS); |
| 237 | + if (profile.profile(flagsObject != PNone.NO_VALUE)) { |
| 238 | + // we have it under control; it must be a long |
| 239 | + return (long) flagsObject; |
| 240 | + } |
| 241 | + long flags = computeFlags(clazz); |
| 242 | + writeHiddenFlagsNode.execute(clazz, TYPE_FLAGS, flags); |
| 243 | + return flags; |
| 244 | + } |
| 245 | + |
| 246 | + @Specialization |
| 247 | + static long doNative(PythonNativeClass clazz, |
| 248 | + @Cached CExtNodes.GetTypeMemberNode getTpFlagsNode) { |
| 249 | + return (long) getTpFlagsNode.execute(clazz, NativeMember.TP_FLAGS); |
| 250 | + } |
| 251 | + |
| 252 | + @TruffleBoundary |
| 253 | + private static long computeFlags(PythonClass clazz) { |
234 | 254 |
|
235 | 255 | // according to 'type_new' in 'typeobject.c', all have DEFAULT, HEAPTYPE, and BASETYPE.
|
236 | 256 | // The HAVE_GC is inherited. But we do not mimic this behavior in every detail, so it
|
237 | 257 | // should be fine to just set it.
|
238 | 258 | long result = DEFAULT | HEAPTYPE | BASETYPE | HAVE_GC;
|
239 | 259 |
|
240 | 260 | // flags are inherited
|
241 |
| - MroSequenceStorage mroStorage = getMroStorageNode.execute(clazz); |
242 |
| - int n = lenNode.execute(mroStorage); |
| 261 | + MroSequenceStorage mroStorage = GetMroStorageNodeGen.getUncached().execute(clazz); |
| 262 | + int n = SequenceStorageNodes.LenNode.getUncached().execute(mroStorage); |
243 | 263 | for (int i = 0; i < n; i++) {
|
244 |
| - Object mroEntry = getItemNode.execute(mroStorage, i); |
| 264 | + Object mroEntry = SequenceStorageNodes.GetItemDynamicNode.getUncached().execute(mroStorage, i); |
245 | 265 | if (mroEntry instanceof PythonBuiltinClass) {
|
246 | 266 | result |= doBuiltinClass((PythonBuiltinClass) mroEntry);
|
247 | 267 | } else if (mroEntry instanceof PythonBuiltinClassType) {
|
248 | 268 | result |= doBuiltinClassType((PythonBuiltinClassType) mroEntry);
|
249 | 269 | } else if (mroEntry instanceof PythonAbstractNativeObject) {
|
250 |
| - result |= doNative((PythonAbstractNativeObject) mroEntry, getTpFlagsNode); |
| 270 | + result |= doNative((PythonAbstractNativeObject) mroEntry, CExtNodesFactory.GetTypeMemberNodeGen.getUncached()); |
251 | 271 | }
|
| 272 | + // 'PythonClass' is intentionally ignored because they do not actually add any |
| 273 | + // interesting flags except that we already specify before the loop |
252 | 274 | }
|
253 | 275 | return result;
|
254 | 276 | }
|
255 | 277 |
|
256 |
| - @Specialization |
257 |
| - static long doNative(PythonNativeClass clazz, |
258 |
| - @Shared("getTpFlagsNode") @Cached CExtNodes.GetTypeMemberNode getTpFlagsNode) { |
259 |
| - return (long) getTpFlagsNode.execute(clazz, NativeMember.TP_FLAGS); |
260 |
| - } |
261 | 278 | }
|
262 | 279 |
|
263 | 280 | @GenerateUncached
|
|
0 commit comments