Skip to content

Commit 2e613d7

Browse files
qunaibitsteve-s
authored andcommitted
Update methods flags for subclasses during slots fixup
1 parent b6d7748 commit 2e613d7

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

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

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.type;
4242

43+
import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_dict;
4344
import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_ADD;
4445
import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_AND;
4546
import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_BOOL;
@@ -60,6 +61,7 @@
6061
import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_TRUE_DIVIDE;
6162
import static com.oracle.graal.python.builtins.objects.type.MethodsFlags.NB_XOR;
6263
import static com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot.Flags.NO_BUILTIN_DESCRIPTORS;
64+
import static com.oracle.graal.python.lib.GetMethodsFlagsNode.METHODS_FLAGS;
6365
import static com.oracle.graal.python.nodes.SpecialAttributeNames.T___DICT__;
6466
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___ADD__;
6567
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___AENTER__;
@@ -150,15 +152,18 @@
150152
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
151153
import com.oracle.graal.python.builtins.objects.PNone;
152154
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
155+
import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
153156
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
154157
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
158+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem;
155159
import com.oracle.graal.python.builtins.objects.dict.PDict;
156160
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
157161
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
158162
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
159163
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
160164
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode;
161165
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesNode;
166+
import com.oracle.graal.python.lib.GetMethodsFlagsNodeGen;
162167
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
163168
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
164169
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
@@ -175,6 +180,7 @@
175180
import com.oracle.truffle.api.object.DynamicObject;
176181
import com.oracle.truffle.api.object.DynamicObjectLibrary;
177182
import com.oracle.truffle.api.strings.TruffleString;
183+
import com.oracle.truffle.api.utilities.CyclicAssumption;
178184

179185
/**
180186
* Subset of special methods that is cached in {@link PythonManagedClass} and
@@ -601,6 +607,32 @@ private static boolean isMroSubtype(MroSequenceStorage superTypeMro, PythonManag
601607
return isMroSubtype;
602608
}
603609

610+
private static void setMethodsFlag(PythonManagedClass klass, long flag, PythonContext context) {
611+
if (flag == 0) {
612+
return;
613+
}
614+
615+
long isHeaptype = context.isCoreInitialized() ? MethodsFlags.SLOT1BINFULL : 0L;
616+
klass.setMethodsFlags(flag | isHeaptype);
617+
}
618+
619+
private static void setMethodsFlag(PythonNativeClass cls, long flag, PythonContext context) {
620+
if (flag == 0) {
621+
return;
622+
}
623+
624+
long flags = GetMethodsFlagsNodeGen.getUncached().execute(null, cls);
625+
if ((flags & flag) == 0) {
626+
// mq: We should put a wrapped function in the native slot.
627+
CyclicAssumption assumption = context.getNativeClassStableAssumption(cls, false);
628+
if (assumption != null && assumption.getAssumption().isValid()) {
629+
assumption.invalidate("methods flags have changed after class creation");
630+
}
631+
PDict dict = (PDict) CStructAccess.ReadObjectNode.getUncached().readFromObj(cls, PyTypeObject__tp_dict);
632+
dict.setDictStorage(HashingStorageSetItem.executeUncached(dict.getDictStorage(), METHODS_FLAGS, flags | flag));
633+
}
634+
}
635+
604636
private static void setMethodsFlags(Object[] slots, PythonManagedClass klass) {
605637
long methodsFlags = 0;
606638
for (SpecialMethodSlot slot : VALUES) {
@@ -613,10 +645,7 @@ private static void setMethodsFlags(Object[] slots, PythonManagedClass klass) {
613645
methodsFlags |= builtinClass.getMethodsFlags();
614646
}
615647

616-
if (methodsFlags != 0) {
617-
long isHeaptype = PythonContext.get(null).isCoreInitialized() ? MethodsFlags.SLOT1BINFULL : 0L;
618-
klass.setMethodsFlags(methodsFlags | isHeaptype);
619-
}
648+
setMethodsFlag(klass, methodsFlags, PythonContext.get(null));
620649
}
621650

622651
/**
@@ -738,9 +767,8 @@ public static void fixupSpecialMethodSlot(PythonManagedClass klass, SpecialMetho
738767

739768
PythonContext context = PythonContext.get(null);
740769
slot.setValue(klass, newValue, context);
741-
if (oldValue == PNone.NO_VALUE && slot.getMethodsFlag() != 0) {
742-
long isHeaptype = context.isCoreInitialized() ? MethodsFlags.SLOT1BINFULL : 0L;
743-
klass.setMethodsFlags(isHeaptype | slot.getMethodsFlag());
770+
if (oldValue == PNone.NO_VALUE) {
771+
setMethodsFlag(klass, slot.getMethodsFlag(), context);
744772
}
745773
fixupSpecialMethodInSubClasses(klass.getSubClasses(), slot, value, context);
746774
}
@@ -768,9 +796,11 @@ private static void fixupSpecialMethodSlotInternal(PythonManagedClass klass, Spe
768796
}
769797

770798
private static void fixupSpecialMethodSlot(Object klass, SpecialMethodSlot slot, Object newValue, PythonContext context) {
771-
if (klass instanceof PythonManagedClass) {
799+
if (klass instanceof PythonManagedClass clazz) {
800+
setMethodsFlag(clazz, slot.getMethodsFlag(), context);
772801
fixupSpecialMethodSlotInternal((PythonManagedClass) klass, slot, newValue, context);
773-
} else if (klass instanceof PythonNativeClass) {
802+
} else if (klass instanceof PythonNativeClass clazz) {
803+
setMethodsFlag(clazz, slot.getMethodsFlag(), context);
774804
fixupSpecialMethodInSubClasses(GetSubclassesNode.executeUncached(klass), slot, newValue, context);
775805
} else {
776806
throw new AssertionError(Objects.toString(klass));
@@ -780,7 +810,6 @@ private static void fixupSpecialMethodSlot(Object klass, SpecialMethodSlot slot,
780810
private static void fixupSpecialMethodInSubClasses(java.util.Set<PythonAbstractClass> subClasses, SpecialMethodSlot slot, Object newValue, PythonContext context) {
781811
for (PythonAbstractClass subClass : subClasses) {
782812
fixupSpecialMethodSlot(subClass, slot, newValue, context);
783-
// mq: TODO: we might need to update methods flags for subclasses
784813
}
785814
}
786815

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ protected static long pythonclasstype(PythonBuiltinClassType cls) {
8989
@TruffleBoundary
9090
private static long populateMethodsFlags(PythonAbstractNativeObject cls, PDict dict) {
9191
Long flags = (Long) PCallCapiFunction.getUncached().call(NativeCAPISymbol.FUN_GET_METHODS_FLAGS, cls.getPtr());
92-
HashingStorageSetItem.executeUncached(dict.getDictStorage(), METHODS_FLAGS, flags);
92+
dict.setDictStorage(HashingStorageSetItem.executeUncached(dict.getDictStorage(), METHODS_FLAGS, flags));
9393
return flags;
9494
}
9595

0 commit comments

Comments
 (0)