Skip to content

Commit 3af263c

Browse files
committed
Do not lazily initialize type flags for built-in types.
1 parent a55dac3 commit 3af263c

File tree

11 files changed

+227
-160
lines changed

11 files changed

+227
-160
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: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
7878
PDictValueIterator(BuiltinNames.DICT_VALUEITERATOR),
7979
PDictReverseValueIterator(BuiltinNames.DICT_REVERSE_VALUEITERATOR),
8080
PDictValuesView(BuiltinNames.DICT_VALUES),
81-
PEllipsis("ellipsis"),
81+
PEllipsis("ellipsis", false),
8282
PEnumerate("enumerate", BuiltinNames.BUILTINS),
8383
PMap("map", BuiltinNames.BUILTINS),
8484
PFloat("float", BuiltinNames.BUILTINS),
@@ -92,8 +92,8 @@ public enum PythonBuiltinClassType implements TruffleObject {
9292
PMemoryView("memoryview", BuiltinNames.BUILTINS),
9393
PMethod("method"),
9494
PMMap("mmap", "mmap"),
95-
PNone("NoneType"),
96-
PNotImplemented("NotImplementedType"),
95+
PNone("NoneType", false),
96+
PNotImplemented("NotImplementedType", false),
9797
PRandom("Random", "_random"),
9898
PRange("range", BuiltinNames.BUILTINS, false),
9999
PReferenceType("ReferenceType", "_weakref"),
@@ -109,7 +109,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
109109
PythonModule("module"),
110110
PythonObject("object", BuiltinNames.BUILTINS),
111111
Super("super", BuiltinNames.BUILTINS),
112-
PCode("code"),
112+
PCode("code", false),
113113
PZip("zip", BuiltinNames.BUILTINS),
114114
PZipImporter("zipimporter", "zipimport"),
115115
PBuffer("buffer", BuiltinNames.BUILTINS),
@@ -240,6 +240,10 @@ public enum PythonBuiltinClassType implements TruffleObject {
240240
this(name, publicInModule, true);
241241
}
242242

243+
PythonBuiltinClassType(String name, boolean basetype) {
244+
this(name, null, basetype);
245+
}
246+
243247
PythonBuiltinClassType(String name) {
244248
this(name, null, true);
245249
}

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

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,36 +1505,19 @@ int tbHere(PFrame frame,
15051505
@GenerateNodeFactory
15061506
abstract static class PyTruffle_GetTpFlags extends NativeBuiltin {
15071507

1508-
@Child private GetTypeFlagsNode getTypeFlagsNode;
1509-
@Child private GetClassNode getClassNode;
1510-
15111508
@Specialization(limit = "1")
1512-
long doPythonObject(PythonNativeWrapper nativeWrapper,
1509+
static long doPythonObject(PythonNativeWrapper nativeWrapper,
1510+
@Shared("getTypeFlagsNode") @Cached GetTypeFlagsNode getTypeFlagsNode,
1511+
@Shared("objectLib") @CachedLibrary(limit = "3") PythonObjectLibrary objectLib,
15131512
@CachedLibrary("nativeWrapper") PythonNativeWrapperLibrary lib) {
1514-
Object pclass = getGetClassNode().execute(lib.getDelegate(nativeWrapper));
1515-
return getGetTypeFlagsNode().execute(pclass);
1513+
return getTypeFlagsNode.execute(objectLib.getLazyPythonClass(lib.getDelegate(nativeWrapper)));
15161514
}
15171515

15181516
@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;
1517+
static long doPythonObject(PythonAbstractObject object,
1518+
@Shared("getTypeFlagsNode") @Cached GetTypeFlagsNode getTypeFlagsNode,
1519+
@Shared("objectLib") @CachedLibrary(limit = "3") PythonObjectLibrary objectLib) {
1520+
return getTypeFlagsNode.execute(objectLib.getLazyPythonClass(object));
15381521
}
15391522
}
15401523

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: 17 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

@@ -1143,19 +1145,17 @@ Object setNative(@SuppressWarnings("unused") PythonAbstractNativeObject cls, @Su
11431145
}
11441146
}
11451147

1146-
@Builtin(name = "__flags__", minNumOfPositionalArgs = 1, isGetter = true)
1148+
@Builtin(name = __FLAGS__, minNumOfPositionalArgs = 1, isGetter = true)
11471149
@GenerateNodeFactory
11481150
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));
1151+
@Specialization(limit = "3")
1152+
static Object doGeneric(Object self,
1153+
@CachedLibrary("self") InteropLibrary lib,
1154+
@Cached GetTypeFlagsNode getTypeFlagsNode) {
1155+
if (PGuards.isClass(self, lib)) {
1156+
return getTypeFlagsNode.execute(self);
1157+
}
1158+
return PNone.NO_VALUE;
11591159
}
11601160
}
11611161
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.objects.type;
42+
43+
/**
44+
* This class defines the type flags as specified in CPython's {@code Include/object.h}. The values
45+
* should be kept in sync with this header.
46+
*/
47+
public abstract class TypeFlags {
48+
49+
public static final long HEAPTYPE = (1L << 9);
50+
public static final long BASETYPE = (1L << 10);
51+
public static final long HAVE_VECTORCALL = (1L << 11);
52+
public static final long READY = (1L << 12);
53+
public static final long READYING = (1L << 13);
54+
public static final long HAVE_GC = (1L << 14);
55+
public static final long HAVE_STACKLESS_EXTENSION = 0;
56+
public static final long METHOD_DESCRIPTOR = (1L << 17);
57+
public static final long HAVE_VERSION_TAG = (1L << 18);
58+
public static final long VALID_VERSION_TAG = (1L << 19);
59+
public static final long IS_ABSTRACT = (1L << 20);
60+
public static final long LONG_SUBCLASS = (1L << 24);
61+
public static final long LIST_SUBCLASS = (1L << 25);
62+
public static final long TUPLE_SUBCLASS = (1L << 26);
63+
public static final long BYTES_SUBCLASS = (1L << 27);
64+
public static final long UNICODE_SUBCLASS = (1L << 28);
65+
public static final long DICT_SUBCLASS = (1L << 29);
66+
public static final long BASE_EXC_SUBCLASS = (1L << 30);
67+
public static final long TYPE_SUBCLASS = (1L << 31);
68+
public static final long DEFAULT = HAVE_STACKLESS_EXTENSION | HAVE_VERSION_TAG;
69+
public static final long HAVE_FINALIZE = 1L;
70+
}

0 commit comments

Comments
 (0)