Skip to content

Commit b6e766a

Browse files
committed
Store methods flags in tp_dict for native classes
1 parent 5b2ba78 commit b6e766a

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

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

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,25 @@
4242

4343
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4444
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
45+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
4546
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction;
4647
import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
48+
import com.oracle.graal.python.builtins.objects.cext.capi.NativeMember;
49+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
50+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem;
51+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodesFactory.HashingStorageGetItemNodeGen;
52+
import com.oracle.graal.python.builtins.objects.dict.PDict;
4753
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
54+
import com.oracle.graal.python.runtime.PythonContext;
55+
import com.oracle.truffle.api.Assumption;
56+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4857
import com.oracle.truffle.api.dsl.Cached;
4958
import com.oracle.truffle.api.dsl.Fallback;
5059
import com.oracle.truffle.api.dsl.GenerateInline;
5160
import com.oracle.truffle.api.dsl.GenerateUncached;
5261
import com.oracle.truffle.api.dsl.Specialization;
5362
import com.oracle.truffle.api.nodes.Node;
63+
import com.oracle.truffle.api.object.HiddenKey;
5464

5565
/**
5666
* Retrieve slots occupation of `cls->tp_as_number`, `cls->tp_as_sequence` and `cls->tp_as_mapping`
@@ -72,13 +82,44 @@ protected static long pythonclasstype(PythonBuiltinClassType cls) {
7282
return cls.getMethodsFlags();
7383
}
7484

75-
@Specialization
76-
static long doNative(PythonAbstractNativeObject cls,
77-
@Cached PCallCapiFunction callCapiFunction) {
78-
Long flags = (Long) callCapiFunction.call(NativeCAPISymbol.FUN_GET_METHODS_FLAGS, cls.getPtr());
85+
public static final HiddenKey METHODS_FLAGS = new HiddenKey("__methods_flags__");
86+
87+
@TruffleBoundary
88+
private static long populateMethodsFlags(PythonAbstractNativeObject cls, PDict dict) {
89+
Long flags = (Long) PCallCapiFunction.getUncached().call(NativeCAPISymbol.FUN_GET_METHODS_FLAGS, cls.getPtr());
90+
HashingStorageSetItem.executeUncached(dict.getDictStorage(), METHODS_FLAGS, flags);
7991
return flags;
8092
}
8193

94+
protected static long getMethodsFlags(PythonAbstractNativeObject cls) {
95+
return doNative(cls, CExtNodes.GetTypeMemberNode.getUncached(), HashingStorageGetItemNodeGen.getUncached());
96+
}
97+
98+
// The assumption should hold unless `PyType_Modified` is called.
99+
protected static Assumption nativeAssumption(PythonAbstractNativeObject cls) {
100+
return PythonContext.get(null).getNativeClassStableAssumption(cls, true).getAssumption();
101+
}
102+
103+
@Specialization(guards = "cachedCls == cls", limit = "5", assumptions = "nativeAssumption(cachedCls)")
104+
static long doNativeCached(@SuppressWarnings("unused") PythonAbstractNativeObject cls,
105+
@SuppressWarnings("unused") @Cached("cls") PythonAbstractNativeObject cachedCls,
106+
@Cached("getMethodsFlags(cls)") long flags) {
107+
return flags;
108+
}
109+
110+
@Specialization(replaces = "doNativeCached")
111+
static long doNative(PythonAbstractNativeObject cls,
112+
@Cached CExtNodes.GetTypeMemberNode getTpDictNode,
113+
@Cached HashingStorageGetItem getItem) {
114+
// classes must have tp_dict since they are set during PyType_Ready
115+
PDict dict = (PDict) getTpDictNode.execute(cls, NativeMember.TP_DICT);
116+
Object f = getItem.execute(null, dict.getDictStorage(), METHODS_FLAGS);
117+
if (f == null) {
118+
return populateMethodsFlags(cls, dict);
119+
}
120+
return (Long) f;
121+
}
122+
82123
@Fallback
83124
protected static long zero(@SuppressWarnings("unused") Object cls) {
84125
return 0;

0 commit comments

Comments
 (0)