@@ -65,24 +65,70 @@ public static ReadAttributeFromObjectNode create() {
65
65
66
66
public abstract Object execute (Object object , Object key );
67
67
68
- protected Location getLocationOrNull (Property prop ) {
68
+ protected static Location getLocationOrNull (Property prop ) {
69
69
return prop == null ? null : prop .getLocation ();
70
70
}
71
71
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
+
72
118
@ SuppressWarnings ("unused" )
73
119
@ Specialization (limit = "getIntOption(getContext(), AttributeAccessInlineCacheMaxDepth)" , //
74
120
guards = {
75
121
"object.getStorage().getShape() == cachedShape" ,
76
- "key == cachedKey"
122
+ "key == cachedKey" ,
123
+ "isNull(loc) || !loc.isAssumedFinal()"
77
124
}, //
78
125
assumptions = "layoutAssumption" )
79
126
protected Object readDirect (PythonObject object , Object key ,
80
127
@ Cached ("key" ) Object cachedKey ,
81
128
@ Cached ("object.getStorage().getShape()" ) Shape cachedShape ,
82
129
@ 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 ) {
86
132
return PNone .NO_VALUE ;
87
133
} else {
88
134
return loc .get (object .getStorage ());
0 commit comments