Skip to content

Commit e2d4a19

Browse files
committed
Add a shape flag to signify an object has no dict
1 parent f27db84 commit e2d4a19

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/object/PythonObject.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3434
import com.oracle.graal.python.builtins.objects.PNone;
3535
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
36+
import com.oracle.graal.python.builtins.objects.dict.PDict;
3637
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
3738
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
3839
import com.oracle.graal.python.nodes.HiddenAttributes;
@@ -47,13 +48,20 @@
4748

4849
public class PythonObject extends PythonAbstractObject {
4950
public static final HiddenKey DICT = HiddenAttributes.DICT;
50-
public static final byte CLASS_CHANGED_FLAG = 1;
51-
public static final byte HAS_SLOTS_BUT_NO_DICT_FLAG = 2;
51+
public static final byte CLASS_CHANGED_FLAG = 0b1;
52+
/**
53+
* Indicates that the object doesn't allow {@code __dict__}, but may have slots
54+
*/
55+
public static final byte HAS_SLOTS_BUT_NO_DICT_FLAG = 0b10;
5256
/**
5357
* Indicates that the shape has some properties that may contain {@link PNone#NO_VALUE} and
5458
* therefore the shape itself is not enough to resolve any lookups.
5559
*/
56-
public static final byte HAS_NO_VALUE_PROPERTIES = 4;
60+
public static final byte HAS_NO_VALUE_PROPERTIES = 0b100;
61+
/**
62+
* Indicates that the object has a dict in the form of an actual dictionary
63+
*/
64+
public static final byte HAS_MATERIALIZED_DICT = 0b1000;
5765

5866
private final Object initialPythonClass;
5967

@@ -85,6 +93,11 @@ public void setPythonClass(Object cls, DynamicObjectLibrary dylib) {
8593
dylib.put(this, CLASS, cls);
8694
}
8795

96+
public void setDict(DynamicObjectLibrary dylib, PDict dict) {
97+
dylib.setShapeFlags(this, dylib.getShapeFlags(this) | HAS_MATERIALIZED_DICT);
98+
dylib.put(this, DICT, dict);
99+
}
100+
88101
public Object getInitialPythonClass() {
89102
return initialPythonClass;
90103
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ public void setMRO(PythonAbstractClass[] mro, PythonLanguage language) {
230230
}
231231

232232
public void setDictHiddenProp(DynamicObjectLibrary dylib, BranchProfile hasMroShapeProfile, Object value) {
233+
dylib.setShapeFlags(this, dylib.getShapeFlags(this) | HAS_MATERIALIZED_DICT);
233234
dylib.put(this, DICT, value);
234235
if (mroShapeSubTypes != null) {
235236
hasMroShapeProfile.enter();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/GetDictIfExistsNode.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,29 @@
6060
import com.oracle.truffle.api.dsl.Specialization;
6161
import com.oracle.truffle.api.library.CachedLibrary;
6262
import com.oracle.truffle.api.object.DynamicObjectLibrary;
63+
import com.oracle.truffle.api.object.Shape;
6364

6465
@GenerateUncached
6566
public abstract class GetDictIfExistsNode extends PNodeWithContext {
6667
public abstract PDict execute(Object object);
6768

6869
public abstract PDict execute(PythonObject object);
6970

71+
@Specialization(guards = {"object.getShape() == cachedShape", "hasNoDict(cachedShape)"}, limit = "1")
72+
static PDict getNoDictCachedShape(@SuppressWarnings("unused") PythonObject object,
73+
@SuppressWarnings("unused") @Cached("object.getShape()") Shape cachedShape) {
74+
return null;
75+
}
76+
77+
@Specialization(guards = "hasNoDict(object.getShape())", replaces = "getNoDictCachedShape")
78+
static PDict getNoDict(@SuppressWarnings("unused") PythonObject object) {
79+
return null;
80+
}
81+
82+
protected static boolean hasNoDict(Shape shape) {
83+
return (shape.getFlags() & PythonObject.HAS_MATERIALIZED_DICT) == 0;
84+
}
85+
7086
@Specialization(guards = {"object == cached", "dictIsConstant(cached)", "dict != null"}, assumptions = "singleContextAssumption()", limit = "1")
7187
static PDict getConstant(@SuppressWarnings("unused") PythonObject object,
7288
@SuppressWarnings("unused") @Cached(value = "object", weak = true) PythonObject cached,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/SetDictNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static void doPythonClass(PythonClass object, PDict dict,
6767
@Fallback
6868
static void doPythonObjectNotClass(PythonObject object, PDict dict,
6969
@Shared("dylib") @CachedLibrary(limit = "4") DynamicObjectLibrary dylib) {
70-
dylib.put(object, PythonObject.DICT, dict);
70+
object.setDict(dylib, dict);
7171
}
7272

7373
public static SetDictNode create() {

0 commit comments

Comments
 (0)