Skip to content

Commit 2210630

Browse files
committed
Fix: provide unique instance shape per native class in single context
1 parent 09ce92e commit 2210630

File tree

6 files changed

+44
-6
lines changed

6 files changed

+44
-6
lines changed

graalpython/com.oracle.graal.python.cext/src/typeobject.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,7 @@ static void add_method_or_slot(PyTypeObject* cls, PyObject* type_dict, char* nam
408408

409409
UPCALL_ID(PyTruffle_Get_Inherited_Native_Slots);
410410
UPCALL_ID(PyTruffle_Compute_Mro);
411+
UPCALL_ID(PyTruffle_NewTypeDict);
411412
int PyType_Ready(PyTypeObject* cls) {
412413
#define RETURN_ERROR(__type__) \
413414
do { \
@@ -492,7 +493,7 @@ int PyType_Ready(PyTypeObject* cls) {
492493
/* Initialize tp_dict */
493494
PyObject* dict = cls->tp_dict;
494495
if (dict == NULL) {
495-
dict = PyDict_New();
496+
dict = UPCALL_CEXT_O(_jls_PyTruffle_NewTypeDict, native_type_to_java(cls));
496497
if (dict == NULL) {
497498
RETURN_ERROR(cls);
498499
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.concurrent.Semaphore;
3333
import java.util.logging.Level;
3434

35+
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
3536
import org.graalvm.options.OptionDescriptors;
3637
import org.graalvm.options.OptionKey;
3738
import org.graalvm.options.OptionValues;
@@ -811,7 +812,7 @@ public Shape getEmptyShape() {
811812
return emptyShape;
812813
}
813814

814-
public Shape getShapeForClass(PythonManagedClass klass) {
815+
public Shape getShapeForClass(PythonAbstractClass klass) {
815816
if (singleContextAssumption.isValid()) {
816817
return Shape.newBuilder(getEmptyShape()).addConstantProperty(HiddenAttributes.CLASS, klass, 0).build();
817818
} else {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,11 @@
148148
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodes.UnicodeFromWcharNode;
149149
import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.ConvertPIntToPrimitiveNodeGen;
150150
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext;
151+
import com.oracle.graal.python.builtins.objects.cext.common.CExtContext.Store;
151152
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode;
152153
import com.oracle.graal.python.builtins.objects.cext.common.CExtParseArgumentsNode.SplitFormatStringNode;
153154
import com.oracle.graal.python.builtins.objects.code.PCode;
155+
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
154156
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
155157
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
156158
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
@@ -290,6 +292,7 @@
290292
import com.oracle.truffle.api.nodes.ControlFlowException;
291293
import com.oracle.truffle.api.nodes.Node;
292294
import com.oracle.truffle.api.nodes.UnexpectedResultException;
295+
import com.oracle.truffle.api.object.DynamicObjectLibrary;
293296
import com.oracle.truffle.api.object.HiddenKey;
294297
import com.oracle.truffle.api.profiles.BranchProfile;
295298
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -2324,6 +2327,21 @@ Object doIt(Object self, String className) {
23242327
}
23252328
}
23262329

2330+
@Builtin(name = "PyTruffle_NewTypeDict")
2331+
@GenerateNodeFactory
2332+
@TypeSystemReference(PythonTypes.class)
2333+
public abstract static class PyTruffleNewTypeDict extends PythonUnaryBuiltinNode {
2334+
2335+
@Specialization
2336+
@TruffleBoundary
2337+
static PDict doGeneric(PythonNativeClass nativeClass) {
2338+
PythonLanguage language = PythonLanguage.getCurrent();
2339+
Store nativeTypeStore = new Store(language.getEmptyShape());
2340+
DynamicObjectLibrary.getUncached().put(nativeTypeStore, PythonNativeClass.INSTANCESHAPE, language.getShapeForClass(nativeClass));
2341+
return PythonObjectFactory.getUncached().createDict(new DynamicObjectStorage(nativeTypeStore));
2342+
}
2343+
}
2344+
23272345
@Builtin(name = "PyTruffle_Type_Modified", minNumOfPositionalArgs = 3)
23282346
@GenerateNodeFactory
23292347
@TypeSystemReference(PythonTypes.class)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonNativeClass.java

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

4343
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
4444
import com.oracle.truffle.api.interop.TruffleObject;
45+
import com.oracle.truffle.api.object.HiddenKey;
4546

4647
/**
4748
* A simple wrapper around types objects created through the Python C API that can be cast to
@@ -51,6 +52,8 @@
5152
*/
5253
public interface PythonNativeClass extends PythonAbstractClass {
5354

55+
public static final HiddenKey INSTANCESHAPE = new HiddenKey("instanceshape");
56+
5457
TruffleObject getPtr();
5558

5659
default String getName() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public static boolean isMethFastcallWithKeywords(int flags) {
150150
return (flags & METH_FASTCALL) != 0 && (flags & METH_KEYWORDS) != 0;
151151
}
152152

153-
protected static final class Store extends DynamicObject {
153+
public static final class Store extends DynamicObject {
154154
public Store(Shape shape) {
155155
super(shape);
156156
}

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol;
9191
import com.oracle.graal.python.builtins.objects.cext.capi.NativeMember;
9292
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef;
93+
import com.oracle.graal.python.builtins.objects.common.DynamicObjectStorage;
9394
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
9495
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
9596
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary.HashingStorageIterator;
@@ -156,6 +157,7 @@
156157
import com.oracle.truffle.api.library.CachedLibrary;
157158
import com.oracle.truffle.api.nodes.ControlFlowException;
158159
import com.oracle.truffle.api.nodes.Node;
160+
import com.oracle.truffle.api.object.DynamicObjectLibrary;
159161
import com.oracle.truffle.api.object.Shape;
160162
import com.oracle.truffle.api.profiles.BranchProfile;
161163
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -1511,9 +1513,22 @@ static Shape doManagedClass(PythonManagedClass clazz) {
15111513
}
15121514

15131515
@Specialization
1514-
static Shape doNativeClass(@SuppressWarnings("unused") PythonAbstractNativeObject clazz,
1515-
@Shared("lang") @CachedLanguage PythonLanguage lang) {
1516-
return lang.getEmptyShape();
1516+
static Shape doNativeClass(PythonAbstractNativeObject clazz,
1517+
@Cached GetTypeMemberNode getTpDictNode,
1518+
@CachedLibrary(limit = "1") DynamicObjectLibrary lib) {
1519+
Object tpDictObj = getTpDictNode.execute(clazz, NativeMember.TP_DICT);
1520+
if (tpDictObj instanceof PDict) {
1521+
HashingStorage dictStorage = ((PDict) tpDictObj).getDictStorage();
1522+
if (dictStorage instanceof DynamicObjectStorage) {
1523+
Object instanceShapeObj = lib.getOrDefault(((DynamicObjectStorage) dictStorage).getStore(), PythonNativeClass.INSTANCESHAPE, PNone.NO_VALUE);
1524+
if (instanceShapeObj != PNone.NO_VALUE) {
1525+
return (Shape) instanceShapeObj;
1526+
}
1527+
throw CompilerDirectives.shouldNotReachHere("instanceshape object is not a shape");
1528+
}
1529+
}
1530+
// TODO(fa): track unique shape per native class in language?
1531+
throw CompilerDirectives.shouldNotReachHere("custom dicts for native classes are unsupported");
15171532
}
15181533

15191534
@Specialization(guards = {"!isManagedClass(clazz)", "!isPythonBuiltinClassType(clazz)"})

0 commit comments

Comments
 (0)