Skip to content

Commit e1d5236

Browse files
committed
Lazily compute and cache flags for user classes.
1 parent 44c358d commit e1d5236

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeBuiltins.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ public class TypeBuiltins extends PythonBuiltins {
152152
public static final HiddenPythonKey TYPE_ALLOC = new HiddenPythonKey(__ALLOC__);
153153
public static final HiddenPythonKey TYPE_DEALLOC = new HiddenPythonKey("__dealloc__");
154154
public static final HiddenPythonKey TYPE_FREE = new HiddenPythonKey("__free__");
155+
public static final HiddenPythonKey TYPE_FLAGS = new HiddenPythonKey(__FLAGS__);
155156

156157
@Override
157158
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
4444
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
45+
import static com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TYPE_FLAGS;
4546
import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BASETYPE;
4647
import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BASE_EXC_SUBCLASS;
4748
import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BYTES_SUBCLASS;
@@ -76,6 +77,7 @@
7677
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.GetTypeMemberNode;
7778
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.PCallCapiFunction;
7879
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToSulongNode;
80+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory;
7981
import com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols;
8082
import com.oracle.graal.python.builtins.objects.cext.NativeMember;
8183
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
@@ -110,6 +112,7 @@
110112
import com.oracle.graal.python.nodes.SpecialMethodNames;
111113
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
112114
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
115+
import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode;
113116
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
114117
import com.oracle.graal.python.nodes.call.special.CallUnaryMethodNode;
115118
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
@@ -127,7 +130,6 @@
127130
import com.oracle.truffle.api.CompilerDirectives;
128131
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
129132
import com.oracle.truffle.api.dsl.Cached;
130-
import com.oracle.truffle.api.dsl.Cached.Shared;
131133
import com.oracle.truffle.api.dsl.CachedContext;
132134
import com.oracle.truffle.api.dsl.Fallback;
133135
import com.oracle.truffle.api.dsl.GenerateUncached;
@@ -227,37 +229,52 @@ static long doBuiltinClass(PythonBuiltinClass clazz) {
227229

228230
@Specialization
229231
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) {
234254

235255
// according to 'type_new' in 'typeobject.c', all have DEFAULT, HEAPTYPE, and BASETYPE.
236256
// The HAVE_GC is inherited. But we do not mimic this behavior in every detail, so it
237257
// should be fine to just set it.
238258
long result = DEFAULT | HEAPTYPE | BASETYPE | HAVE_GC;
239259

240260
// 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);
243263
for (int i = 0; i < n; i++) {
244-
Object mroEntry = getItemNode.execute(mroStorage, i);
264+
Object mroEntry = SequenceStorageNodes.GetItemDynamicNode.getUncached().execute(mroStorage, i);
245265
if (mroEntry instanceof PythonBuiltinClass) {
246266
result |= doBuiltinClass((PythonBuiltinClass) mroEntry);
247267
} else if (mroEntry instanceof PythonBuiltinClassType) {
248268
result |= doBuiltinClassType((PythonBuiltinClassType) mroEntry);
249269
} else if (mroEntry instanceof PythonAbstractNativeObject) {
250-
result |= doNative((PythonAbstractNativeObject) mroEntry, getTpFlagsNode);
270+
result |= doNative((PythonAbstractNativeObject) mroEntry, CExtNodesFactory.GetTypeMemberNodeGen.getUncached());
251271
}
272+
// 'PythonClass' is intentionally ignored because they do not actually add any
273+
// interesting flags except that we already specify before the loop
252274
}
253275
return result;
254276
}
255277

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-
}
261278
}
262279

263280
@GenerateUncached

0 commit comments

Comments
 (0)