Skip to content

Commit cfe2ab3

Browse files
committed
[GR-25643] Do not lazily initialize type flags for built-in types.
PullRequest: graalpython/1208
2 parents 15da5f6 + e1d5236 commit cfe2ab3

File tree

11 files changed

+266
-169
lines changed

11 files changed

+266
-169
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
#include "capi.h"
77

8-
PyTypeObject PyComplex_Type = PY_TRUFFLE_TYPE("complex", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyComplexObject));
8+
PyTypeObject PyComplex_Type = PY_TRUFFLE_TYPE("complex", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, sizeof(PyComplexObject));
99

1010
static Py_complex c_error = {-1., 0.};
1111

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -46,10 +46,10 @@ typedef struct {
4646
PyObject *mapping;
4747
} mappingproxyobject;
4848

49-
PyTypeObject PyGetSetDescr_Type = PY_TRUFFLE_TYPE("getset_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyGetSetDescrObject));;
50-
PyTypeObject PyWrapperDescr_Type = PY_TRUFFLE_TYPE("wrapper_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyWrapperDescrObject));;
51-
PyTypeObject PyMemberDescr_Type = PY_TRUFFLE_TYPE("member_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyMemberDescrObject));;
52-
PyTypeObject PyMethodDescr_Type = PY_TRUFFLE_TYPE("method_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyMethodDescrObject));;
49+
PyTypeObject PyGetSetDescr_Type = PY_TRUFFLE_TYPE("getset_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyGetSetDescrObject));
50+
PyTypeObject PyWrapperDescr_Type = PY_TRUFFLE_TYPE("wrapper_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_METHOD_DESCRIPTOR, sizeof(PyWrapperDescrObject));
51+
PyTypeObject PyMemberDescr_Type = PY_TRUFFLE_TYPE("member_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(PyMemberDescrObject));
52+
PyTypeObject PyMethodDescr_Type = PY_TRUFFLE_TYPE("method_descriptor", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_METHOD_DESCRIPTOR, sizeof(PyMethodDescrObject));
5353
PyTypeObject PyDictProxy_Type = PY_TRUFFLE_TYPE("mappingproxy", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, sizeof(mappingproxyobject));
5454

5555
POLYGLOT_DECLARE_TYPE(mappingproxyobject);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.oracle.truffle.api.library.CachedLibrary;
5151
import com.oracle.truffle.api.library.ExportLibrary;
5252
import com.oracle.truffle.api.library.ExportMessage;
53+
import com.oracle.truffle.api.nodes.ExplodeLoop;
5354
import com.oracle.truffle.api.object.Shape;
5455

5556
@ExportLibrary(InteropLibrary.class)
@@ -78,7 +79,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
7879
PDictValueIterator(BuiltinNames.DICT_VALUEITERATOR),
7980
PDictReverseValueIterator(BuiltinNames.DICT_REVERSE_VALUEITERATOR),
8081
PDictValuesView(BuiltinNames.DICT_VALUES),
81-
PEllipsis("ellipsis"),
82+
PEllipsis("ellipsis", false),
8283
PEnumerate("enumerate", BuiltinNames.BUILTINS),
8384
PMap("map", BuiltinNames.BUILTINS),
8485
PFloat("float", BuiltinNames.BUILTINS),
@@ -92,8 +93,8 @@ public enum PythonBuiltinClassType implements TruffleObject {
9293
PMemoryView("memoryview", BuiltinNames.BUILTINS),
9394
PMethod("method"),
9495
PMMap("mmap", "mmap"),
95-
PNone("NoneType"),
96-
PNotImplemented("NotImplementedType"),
96+
PNone("NoneType", false),
97+
PNotImplemented("NotImplementedType", false),
9798
PRandom("Random", "_random"),
9899
PRange("range", BuiltinNames.BUILTINS, false),
99100
PReferenceType("ReferenceType", "_weakref"),
@@ -109,7 +110,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
109110
PythonModule("module"),
110111
PythonObject("object", BuiltinNames.BUILTINS),
111112
Super("super", BuiltinNames.BUILTINS),
112-
PCode("code"),
113+
PCode("code", false),
113114
PZip("zip", BuiltinNames.BUILTINS),
114115
PZipImporter("zipimporter", "zipimport"),
115116
PBuffer("buffer", BuiltinNames.BUILTINS),
@@ -240,6 +241,10 @@ public enum PythonBuiltinClassType implements TruffleObject {
240241
this(name, publicInModule, true);
241242
}
242243

244+
PythonBuiltinClassType(String name, boolean basetype) {
245+
this(name, null, basetype);
246+
}
247+
243248
PythonBuiltinClassType(String name) {
244249
this(name, null, true);
245250
}
@@ -274,8 +279,8 @@ public final Shape getInstanceShape() {
274279
return instanceShape;
275280
}
276281

277-
public static final PythonBuiltinClassType[] VALUES = Arrays.copyOf(values(), values().length - 1);
278-
public static final PythonBuiltinClassType[] EXCEPTIONS;
282+
@CompilationFinal(dimensions = 1) public static final PythonBuiltinClassType[] VALUES = Arrays.copyOf(values(), values().length - 1);
283+
@CompilationFinal(dimensions = 1) public static final PythonBuiltinClassType[] EXCEPTIONS;
279284

280285
static {
281286
// fill the EXCEPTIONS array
@@ -573,4 +578,14 @@ static String getMetaSimpleName(PythonBuiltinClassType self) {
573578
static String getMetaQualifiedName(PythonBuiltinClassType self) {
574579
return self.getQualifiedName();
575580
}
581+
582+
@ExplodeLoop
583+
public static boolean isExceptionType(PythonBuiltinClassType type) {
584+
for (int i = 0; i < EXCEPTIONS.length; i++) {
585+
if (EXCEPTIONS[i] == type) {
586+
return true;
587+
}
588+
}
589+
return false;
590+
}
576591
}

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

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@
201201
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
202202
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
203203
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroStorageNode;
204-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetTypeFlagsNode;
205204
import com.oracle.graal.python.nodes.ErrorMessages;
206205
import com.oracle.graal.python.nodes.PGuards;
207206
import com.oracle.graal.python.nodes.PNodeWithContext;
@@ -1501,43 +1500,6 @@ int tbHere(PFrame frame,
15011500
}
15021501
}
15031502

1504-
@Builtin(name = "PyTruffle_GetTpFlags", minNumOfPositionalArgs = 1)
1505-
@GenerateNodeFactory
1506-
abstract static class PyTruffle_GetTpFlags extends NativeBuiltin {
1507-
1508-
@Child private GetTypeFlagsNode getTypeFlagsNode;
1509-
@Child private GetClassNode getClassNode;
1510-
1511-
@Specialization(limit = "1")
1512-
long doPythonObject(PythonNativeWrapper nativeWrapper,
1513-
@CachedLibrary("nativeWrapper") PythonNativeWrapperLibrary lib) {
1514-
Object pclass = getGetClassNode().execute(lib.getDelegate(nativeWrapper));
1515-
return getGetTypeFlagsNode().execute(pclass);
1516-
}
1517-
1518-
@Specialization
1519-
long doPythonObject(PythonAbstractObject object) {
1520-
Object pclass = getGetClassNode().execute(object);
1521-
return getGetTypeFlagsNode().execute(pclass);
1522-
}
1523-
1524-
private GetClassNode getGetClassNode() {
1525-
if (getClassNode == null) {
1526-
CompilerDirectives.transferToInterpreterAndInvalidate();
1527-
getClassNode = insert(GetClassNode.create());
1528-
}
1529-
return getClassNode;
1530-
}
1531-
1532-
private GetTypeFlagsNode getGetTypeFlagsNode() {
1533-
if (getTypeFlagsNode == null) {
1534-
CompilerDirectives.transferToInterpreterAndInvalidate();
1535-
getTypeFlagsNode = insert(GetTypeFlagsNode.create());
1536-
}
1537-
return getTypeFlagsNode;
1538-
}
1539-
}
1540-
15411503
@Builtin(name = "PyTruffle_Set_SulongType", minNumOfPositionalArgs = 2)
15421504
@GenerateNodeFactory
15431505
abstract static class PyTruffle_Set_SulongType extends NativeBuiltin {

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,11 +1007,25 @@ static long doObRefcnt(@SuppressWarnings("unused") Object o, PythonNativeWrapper
10071007
}
10081008

10091009
@Specialization(guards = "eq(TP_FLAGS, key)")
1010-
static long doTpFlags(PythonManagedClass object, @SuppressWarnings("unused") PythonNativeWrapper nativeWrapper, @SuppressWarnings("unused") String key, long flags) {
1011-
object.setFlags(flags);
1010+
static long doTpFlags(PythonManagedClass object, @SuppressWarnings("unused") PythonNativeWrapper nativeWrapper, @SuppressWarnings("unused") String key, long flags,
1011+
@Cached GetTypeFlagsNode getTypeFlagsNode,
1012+
@Cached WriteAttributeToObjectNode writeAttributeToObjectNode) {
1013+
if (object instanceof PythonBuiltinClass) {
1014+
// just assert that we try to set the same flags; if there is a difference, this
1015+
// means we did not properly maintain our flag definition in
1016+
// TypeNodes.GetTypeFlagsNode.
1017+
assert getTypeFlagsNode.execute(object) == flags : flagsErrorMessage(object);
1018+
} else {
1019+
writeAttributeToObjectNode.execute(object, SpecialAttributeNames.__FLAGS__, flags);
1020+
}
10121021
return flags;
10131022
}
10141023

1024+
@TruffleBoundary
1025+
private static String flagsErrorMessage(PythonManagedClass object) {
1026+
return "type flags of " + object.getName() + " definitions are out of sync";
1027+
}
1028+
10151029
@Specialization(guards = {"isPythonClass(object)", "eq(TP_BASICSIZE, key)"})
10161030

10171031
static long doTpBasicsize(Object object, @SuppressWarnings("unused") PythonNativeWrapper nativeWrapper, @SuppressWarnings("unused") String key, long basicsize,

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

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
2929
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DOC__;
3030

31+
import java.util.ArrayList;
3132
import java.util.Collections;
3233
import java.util.Set;
3334
import java.util.WeakHashMap;
@@ -49,13 +50,12 @@
4950
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5051
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5152
import com.oracle.truffle.api.dsl.Cached;
52-
import com.oracle.truffle.api.dsl.Specialization;
5353
import com.oracle.truffle.api.dsl.Cached.Shared;
54+
import com.oracle.truffle.api.dsl.Specialization;
5455
import com.oracle.truffle.api.library.CachedLibrary;
5556
import com.oracle.truffle.api.library.ExportMessage;
5657
import com.oracle.truffle.api.object.DynamicObjectLibrary;
5758
import com.oracle.truffle.api.object.Shape;
58-
import java.util.ArrayList;
5959

6060
public abstract class PythonManagedClass extends PythonObject implements PythonAbstractClass {
6161

@@ -65,7 +65,6 @@ public abstract class PythonManagedClass extends PythonObject implements PythonA
6565

6666
private final Set<PythonAbstractClass> subClasses = Collections.newSetFromMap(new WeakHashMap<PythonAbstractClass, Boolean>());
6767
private final Shape instanceShape;
68-
private final FlagsContainer flags;
6968
private String name;
7069
private String qualName;
7170

@@ -87,8 +86,6 @@ protected PythonManagedClass(Object typeClass, Shape classShape, Shape instanceS
8786
unsafeSetSuperClass(baseClasses);
8887
}
8988

90-
this.flags = new FlagsContainer(getSuperClass());
91-
9289
// Compute MRO
9390
this.methodResolutionOrder.setInternalArrayObject(ComputeMroNode.doSlowPath(this));
9491
this.methodResolutionOrder.setInitialized();
@@ -288,34 +285,6 @@ public PythonAbstractClass[] getBaseClasses() {
288285
return baseClasses;
289286
}
290287

291-
public void setFlags(long flags) {
292-
this.flags.setValue(flags);
293-
}
294-
295-
FlagsContainer getFlagsContainer() {
296-
return flags;
297-
}
298-
299-
/**
300-
* Flags are copied from the initial dominant base class. However, classes may already be
301-
* created before the C API was initialized, i.e., flags were not set.
302-
*/
303-
static final class FlagsContainer {
304-
PythonAbstractClass initialDominantBase;
305-
long flags;
306-
307-
public FlagsContainer(PythonAbstractClass superClass) {
308-
this.initialDominantBase = superClass;
309-
}
310-
311-
private void setValue(long flags) {
312-
if (initialDominantBase != null) {
313-
initialDominantBase = null;
314-
}
315-
this.flags = flags;
316-
}
317-
}
318-
319288
public PythonClassNativeWrapper getClassNativeWrapper() {
320289
return (PythonClassNativeWrapper) super.getNativeWrapper();
321290
}

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

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@
3333
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__CLASS__;
3434
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICTOFFSET__;
3535
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DICT__;
36+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FLAGS__;
3637
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__ITEMSIZE__;
3738
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MODULE__;
3839
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MRO__;
3940
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
4041
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__QUALNAME__;
42+
import static com.oracle.graal.python.nodes.SpecialMethodNames.MRO;
4143
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ALLOC__;
4244
import static com.oracle.graal.python.nodes.SpecialMethodNames.__CALL__;
4345
import static com.oracle.graal.python.nodes.SpecialMethodNames.__DELETE__;
@@ -76,15 +78,21 @@
7678
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
7779
import com.oracle.graal.python.builtins.objects.function.PFunction;
7880
import com.oracle.graal.python.builtins.objects.function.PKeyword;
81+
import com.oracle.graal.python.builtins.objects.getsetdescriptor.HiddenPythonKey;
7982
import com.oracle.graal.python.builtins.objects.list.PList;
8083
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
8184
import com.oracle.graal.python.builtins.objects.object.PythonObject;
8285
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
8386
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
8487
import com.oracle.graal.python.builtins.objects.type.TypeBuiltinsFactory.CallNodeFactory;
88+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode;
89+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
90+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBestBaseClassNode;
8591
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetMroNode;
8692
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
8793
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesNode;
94+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetTypeFlagsNode;
95+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
8896
import com.oracle.graal.python.builtins.objects.type.TypeNodesFactory.IsSameTypeNodeGen;
8997
import com.oracle.graal.python.nodes.BuiltinNames;
9098
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -132,12 +140,6 @@
132140
import com.oracle.truffle.api.interop.InteropLibrary;
133141
import com.oracle.truffle.api.interop.UnsupportedMessageException;
134142
import com.oracle.truffle.api.library.CachedLibrary;
135-
import com.oracle.graal.python.builtins.objects.getsetdescriptor.HiddenPythonKey;
136-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.CheckCompatibleForAssigmentNode;
137-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBaseClassNode;
138-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetBestBaseClassNode;
139-
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
140-
import static com.oracle.graal.python.nodes.SpecialMethodNames.MRO;
141143
import com.oracle.truffle.api.profiles.BranchProfile;
142144
import com.oracle.truffle.api.profiles.ConditionProfile;
143145

@@ -150,6 +152,7 @@ public class TypeBuiltins extends PythonBuiltins {
150152
public static final HiddenPythonKey TYPE_ALLOC = new HiddenPythonKey(__ALLOC__);
151153
public static final HiddenPythonKey TYPE_DEALLOC = new HiddenPythonKey("__dealloc__");
152154
public static final HiddenPythonKey TYPE_FREE = new HiddenPythonKey("__free__");
155+
public static final HiddenPythonKey TYPE_FLAGS = new HiddenPythonKey(__FLAGS__);
153156

154157
@Override
155158
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
@@ -1143,19 +1146,17 @@ Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @Su
11431146
}
11441147
}
11451148

1146-
@Builtin(name = "__flags__", minNumOfPositionalArgs = 1, isGetter = true)
1149+
@Builtin(name = __FLAGS__, minNumOfPositionalArgs = 1, isGetter = true)
11471150
@GenerateNodeFactory
11481151
abstract static class FlagsNode extends PythonUnaryBuiltinNode {
1149-
@Child TypeNodes.GetTypeFlagsNode getFlagsNode = TypeNodes.GetTypeFlagsNode.create();
1150-
1151-
@Specialization
1152-
Object flags(PythonAbstractClass self) {
1153-
return getFlagsNode.execute(self);
1154-
}
1155-
1156-
@Specialization
1157-
Object flags(PythonBuiltinClassType self) {
1158-
return getFlagsNode.execute(getCore().lookupType(self));
1152+
@Specialization(limit = "3")
1153+
Object doGeneric(Object self,
1154+
@CachedLibrary("self") InteropLibrary lib,
1155+
@Cached GetTypeFlagsNode getTypeFlagsNode) {
1156+
if (PGuards.isClass(self, lib)) {
1157+
return getTypeFlagsNode.execute(self);
1158+
}
1159+
throw raise(PythonErrorType.TypeError, "descriptor '__flags__' for 'type' objects doesn't apply to '%p' object", self);
11591160
}
11601161
}
11611162
}

0 commit comments

Comments
 (0)