Skip to content

Commit b2881fc

Browse files
committed
handle final locations in ReadAttributeFromObjectNode
1 parent 1632b5d commit b2881fc

File tree

1 file changed

+51
-5
lines changed

1 file changed

+51
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/ReadAttributeFromObjectNode.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,70 @@ public static ReadAttributeFromObjectNode create() {
6565

6666
public abstract Object execute(Object object, Object key);
6767

68-
protected Location getLocationOrNull(Property prop) {
68+
protected static Location getLocationOrNull(Property prop) {
6969
return prop == null ? null : prop.getLocation();
7070
}
7171

72+
protected static boolean isNull(Object value) {
73+
return value == null;
74+
}
75+
76+
protected static Object readFinalValue(PythonObject object, Location location) {
77+
Object value = location.get(object.getStorage());
78+
return value == null ? PNone.NO_VALUE : value;
79+
}
80+
81+
/*
82+
* Includes "object" as a parameter so that Truffle DSL sees this as a dynamic check.
83+
*/
84+
protected static boolean checkShape(@SuppressWarnings("unused") PythonObject object, PythonObject cachedObject, Shape cachedShape) {
85+
return cachedObject.getStorage().getShape() == cachedShape;
86+
}
87+
88+
@SuppressWarnings("unused")
89+
@Specialization(limit = "1", //
90+
guards = {
91+
"object == cachedObject",
92+
"checkShape(object, cachedObject, cachedShape)",
93+
"key == cachedKey",
94+
"!isNull(loc)",
95+
"loc.isAssumedFinal()"
96+
}, //
97+
assumptions = {
98+
"layoutAssumption",
99+
"finalAssumption"
100+
})
101+
protected Object readDirectFinal(PythonObject object, Object key,
102+
@Cached("object") PythonObject cachedObject,
103+
@Cached("key") Object cachedKey,
104+
@Cached("object.getStorage().getShape()") Shape cachedShape,
105+
@Cached("cachedShape.getValidAssumption()") Assumption layoutAssumption,
106+
@Cached("getLocationOrNull(cachedShape.getProperty(key))") Location loc,
107+
@Cached("loc.getFinalAssumption()") Assumption finalAssumption,
108+
@Cached("readFinalValue(object, loc)") Object cachedValue) {
109+
assert assertFinal(object, key, cachedValue);
110+
return cachedValue;
111+
}
112+
113+
private static boolean assertFinal(PythonObject object, Object key, Object cachedValue) {
114+
Object other = object.getStorage().get(key) == null ? PNone.NO_VALUE : object.getStorage().get(key);
115+
return cachedValue == other || cachedValue instanceof Number && other instanceof Number && ((Number) cachedValue).doubleValue() == ((Number) other).doubleValue();
116+
}
117+
72118
@SuppressWarnings("unused")
73119
@Specialization(limit = "getIntOption(getContext(), AttributeAccessInlineCacheMaxDepth)", //
74120
guards = {
75121
"object.getStorage().getShape() == cachedShape",
76-
"key == cachedKey"
122+
"key == cachedKey",
123+
"isNull(loc) || !loc.isAssumedFinal()"
77124
}, //
78125
assumptions = "layoutAssumption")
79126
protected Object readDirect(PythonObject object, Object key,
80127
@Cached("key") Object cachedKey,
81128
@Cached("object.getStorage().getShape()") Shape cachedShape,
82129
@Cached("cachedShape.getValidAssumption()") Assumption layoutAssumption,
83-
@Cached("cachedShape.getProperty(key)") Property prop,
84-
@Cached("getLocationOrNull(prop)") Location loc) {
85-
if (prop == null) {
130+
@Cached("getLocationOrNull(cachedShape.getProperty(key))") Location loc) {
131+
if (loc == null) {
86132
return PNone.NO_VALUE;
87133
} else {
88134
return loc.get(object.getStorage());

0 commit comments

Comments
 (0)