6060import com .oracle .graal .python .builtins .objects .type .TpSlots ;
6161import com .oracle .graal .python .builtins .objects .type .TypeFlags ;
6262import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsTypeNode ;
63- import com .oracle .graal .python .lib .PyObjectReprAsTruffleStringNode ;
6463import com .oracle .graal .python .nodes .ErrorMessages ;
6564import com .oracle .graal .python .nodes .PNodeWithContext ;
6665import com .oracle .graal .python .nodes .PRaiseNode ;
6766import com .oracle .graal .python .nodes .object .GetDictIfExistsNode ;
6867import com .oracle .graal .python .runtime .PythonContext ;
6968import com .oracle .truffle .api .CompilerAsserts ;
69+ import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
7070import com .oracle .truffle .api .dsl .Bind ;
7171import com .oracle .truffle .api .dsl .Cached ;
7272import com .oracle .truffle .api .dsl .Cached .Exclusive ;
@@ -95,7 +95,7 @@ static boolean isAttrWritable(PythonObject self) {
9595 return (self .getShape ().getFlags () & PythonObject .HAS_SLOTS_BUT_NO_DICT_FLAG ) == 0 ;
9696 }
9797
98- static boolean writeToDynamicStorageNoTypeGuard (Object obj , GetDictIfExistsNode getDict ) {
98+ static boolean writeToDynamicStorageNoTypeGuard (PythonObject obj , GetDictIfExistsNode getDict ) {
9999 return getDict .execute (obj ) == null && !PythonManagedClass .isInstance (obj );
100100 }
101101
@@ -112,49 +112,48 @@ static boolean writeToDynamicStorageNoType(PythonObject object, TruffleString ke
112112 return true ;
113113 }
114114
115- // Specializations for no dict & PythonManagedClass -> requires calling onAttributeUpdate
116- @ Specialization (guards = {"isAttrWritable(klass)" , "getDict.execute(klass) == null" })
117- boolean writeToDynamicStorageBuiltinType (PythonBuiltinClass klass , TruffleString key , Object value ,
118- @ Bind Node inliningTarget ,
119- @ SuppressWarnings ("unused" ) @ Shared ("getDict" ) @ Cached GetDictIfExistsNode getDict ,
120- @ Shared ("callAttrUpdate" ) @ Cached InlinedBranchProfile callAttrUpdate ,
121- @ Shared ("dylib" ) @ CachedLibrary (limit = "getAttributeAccessInlineCacheMaxDepth()" ) DynamicObjectLibrary dylib ,
122- @ Shared ("cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
123- @ Shared ("cpAtIndex" ) @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
124- if (PythonContext .get (this ).isInitialized ()) {
115+ @ Specialization (guards = "isPythonBuiltinClass(klassOrType) || isPythonBuiltinClassType(klassOrType)" )
116+ @ TruffleBoundary
117+ boolean writeToDynamicStorageBuiltinType (Object klassOrType , TruffleString key , Object value ) {
118+ PythonContext context = PythonContext .get (this );
119+ PythonBuiltinClass klass ;
120+ if (klassOrType instanceof PythonBuiltinClass pbc ) {
121+ klass = pbc ;
122+ } else {
123+ klass = context .lookupType ((PythonBuiltinClassType ) klassOrType );
124+ }
125+ if (context .isInitialized () || value == PNone .NO_VALUE ) {
125126 throw PRaiseNode .raiseStatic (this , TypeError , ErrorMessages .CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N , key , klass );
126127 } else {
127- return writeToDynamicStorageManagedClass (klass , key , value , inliningTarget , callAttrUpdate , dylib , codePointLengthNode , codePointAtIndexNode );
128+ PDict dict = GetDictIfExistsNode .getUncached ().execute (klass );
129+ if (dict == null ) {
130+ return writeToDynamicStorageManagedClass (klass , key , value , DynamicObjectLibrary .getUncached ());
131+ } else {
132+ return writeToDictManagedClass (klass , dict , key , value , null , InlinedBranchProfile .getUncached (), HashingStorageSetItem .getUncached ());
133+ }
128134 }
129135 }
130136
131137 @ Specialization (guards = {"isAttrWritable(klass)" , "getDict.execute(klass) == null" })
132138 static boolean writeToDynamicStoragePythonClass (PythonClass klass , TruffleString key , Object value ,
133139 @ Bind Node inliningTarget ,
134140 @ SuppressWarnings ("unused" ) @ Shared ("getDict" ) @ Cached GetDictIfExistsNode getDict ,
135- @ Exclusive @ Cached InlinedBranchProfile callAttrUpdate ,
136141 @ Exclusive @ Cached InlinedBranchProfile updateFlags ,
137- @ Shared ("dylib" ) @ CachedLibrary (limit = "getAttributeAccessInlineCacheMaxDepth()" ) DynamicObjectLibrary dylib ,
138- @ Shared ("cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
139- @ Shared ("cpAtIndex" ) @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
142+ @ CachedLibrary (limit = "getAttributeAccessInlineCacheMaxDepth()" ) DynamicObjectLibrary dylib ) {
140143 if (value == PNone .NO_VALUE ) {
141144 updateFlags .enter (inliningTarget );
142145 dylib .setShapeFlags (klass , dylib .getShapeFlags (klass ) | HAS_NO_VALUE_PROPERTIES );
143146 }
144- return writeToDynamicStorageManagedClass (klass , key , value , inliningTarget , callAttrUpdate , dylib , codePointLengthNode , codePointAtIndexNode );
147+ return writeToDynamicStorageManagedClass (klass , key , value , dylib );
145148 }
146149
147- private static boolean writeToDynamicStorageManagedClass (PythonManagedClass klass , TruffleString key , Object value , Node inliningTarget ,
148- InlinedBranchProfile callAttrUpdate , DynamicObjectLibrary dylib , TruffleString .CodePointLengthNode codePointLengthNode , TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
150+ private static boolean writeToDynamicStorageManagedClass (PythonManagedClass klass , TruffleString key , Object value , DynamicObjectLibrary dylib ) {
149151 CompilerAsserts .partialEvaluationConstant (klass .getClass ());
150152 try {
151153 dylib .put (klass , key , value );
152154 return true ;
153155 } finally {
154- if (!klass .canSkipOnAttributeUpdate (key , value , codePointLengthNode , codePointAtIndexNode )) {
155- callAttrUpdate .enter (inliningTarget );
156- klass .onAttributeUpdate (key , value );
157- }
156+ klass .onAttributeUpdate (key , value );
158157 }
159158 }
160159
@@ -169,35 +168,14 @@ static boolean writeToDictNoType(@SuppressWarnings("unused") PythonObject object
169168 return writeToDict (dict , key , value , inliningTarget , updateStorage , setHashingStorageItem );
170169 }
171170
172- // write to the dict & PythonManagedClass -> requires calling onAttributeUpdate
173- @ Specialization (guards = {"dict != null" , "!isNoValue(value)" })
174- boolean writeToDictBuiltinType (PythonBuiltinClass klass , TruffleString key , Object value ,
175- @ Bind Node inliningTarget ,
176- @ SuppressWarnings ("unused" ) @ Shared ("getDict" ) @ Cached GetDictIfExistsNode getDict ,
177- @ Bind ("getDict.execute(klass)" ) PDict dict ,
178- @ Shared ("callAttrUpdate" ) @ Cached InlinedBranchProfile callAttrUpdate ,
179- @ Shared ("updateStorage" ) @ Cached InlinedBranchProfile updateStorage ,
180- @ Shared ("setHashingStorageItem" ) @ Cached HashingStorageSetItem setHashingStorageItem ,
181- @ Shared ("cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
182- @ Shared ("cpAtIndex" ) @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
183- if (PythonContext .get (this ).isInitialized ()) {
184- throw PRaiseNode .raiseStatic (this , TypeError , ErrorMessages .CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N , PyObjectReprAsTruffleStringNode .executeUncached (key ), klass );
185- } else {
186- return writeToDictManagedClass (klass , dict , key , value , inliningTarget , callAttrUpdate , updateStorage , setHashingStorageItem , codePointLengthNode , codePointAtIndexNode );
187- }
188- }
189-
190171 @ Specialization (guards = {"dict != null" , "!isNoValue(value)" })
191172 static boolean writeToDictClass (PythonClass klass , TruffleString key , Object value ,
192173 @ Bind Node inliningTarget ,
193174 @ SuppressWarnings ("unused" ) @ Shared ("getDict" ) @ Cached GetDictIfExistsNode getDict ,
194175 @ Bind ("getDict.execute(klass)" ) PDict dict ,
195- @ Shared ("callAttrUpdate" ) @ Cached InlinedBranchProfile callAttrUpdate ,
196176 @ Shared ("updateStorage" ) @ Cached InlinedBranchProfile updateStorage ,
197- @ Shared ("setHashingStorageItem" ) @ Cached HashingStorageSetItem setHashingStorageItem ,
198- @ Shared ("cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
199- @ Shared ("cpAtIndex" ) @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
200- return writeToDictManagedClass (klass , dict , key , value , inliningTarget , callAttrUpdate , updateStorage , setHashingStorageItem , codePointLengthNode , codePointAtIndexNode );
177+ @ Shared ("setHashingStorageItem" ) @ Cached HashingStorageSetItem setHashingStorageItem ) {
178+ return writeToDictManagedClass (klass , dict , key , value , inliningTarget , updateStorage , setHashingStorageItem );
201179 }
202180
203181 // @Exclusive for truffle-interpreted-performance
@@ -206,42 +184,24 @@ static boolean deleteFromPythonObject(PythonObject obj, TruffleString key, Objec
206184 @ Bind Node inliningTarget ,
207185 @ SuppressWarnings ("unused" ) @ Shared ("getDict" ) @ Cached GetDictIfExistsNode getDict ,
208186 @ Bind ("getDict.execute(obj)" ) PDict dict ,
209- @ Exclusive @ Cached InlinedBranchProfile callAttrUpdate ,
210- @ Cached HashingStorageNodes .HashingStorageDelItem hashingStorageDelItem ,
211- @ Shared ("cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
212- @ Shared ("cpAtIndex" ) @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
187+ @ Cached HashingStorageNodes .HashingStorageDelItem hashingStorageDelItem ) {
213188 try {
214189 HashingStorage dictStorage = dict .getDictStorage ();
215190 return hashingStorageDelItem .execute (inliningTarget , dictStorage , key , dict );
216191 } finally {
217192 if (obj instanceof PythonManagedClass klass ) {
218- if (!klass .canSkipOnAttributeUpdate (key , value , codePointLengthNode , codePointAtIndexNode )) {
219- callAttrUpdate .enter (inliningTarget );
220- klass .onAttributeUpdate (key , value );
221- }
193+ klass .onAttributeUpdate (key , value );
222194 }
223195 }
224196 }
225197
226- @ Specialization (guards = {"dict != null" , "isNoValue(value)" })
227- static boolean deleteFromPythonBuiltinClass (PythonBuiltinClass klass , TruffleString key , Object value ,
228- @ Bind Node inliningTarget ,
229- @ SuppressWarnings ("unused" ) @ Shared ("getDict" ) @ Cached GetDictIfExistsNode getDict ,
230- @ Bind ("getDict.execute(klass)" ) PDict dict ) {
231- throw PRaiseNode .raiseStatic (inliningTarget , TypeError , ErrorMessages .CANT_SET_ATTRIBUTE_R_OF_IMMUTABLE_TYPE_N , key , klass );
232- }
233-
234198 private static boolean writeToDictManagedClass (PythonManagedClass klass , PDict dict , TruffleString key , Object value , Node inliningTarget ,
235- InlinedBranchProfile callAttrUpdate , InlinedBranchProfile updateStorage , HashingStorageSetItem setHashingStorageItem , TruffleString .CodePointLengthNode codePointLengthNode ,
236- TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
199+ InlinedBranchProfile updateStorage , HashingStorageSetItem setHashingStorageItem ) {
237200 CompilerAsserts .partialEvaluationConstant (klass .getClass ());
238201 try {
239202 return writeToDict (dict , key , value , inliningTarget , updateStorage , setHashingStorageItem );
240203 } finally {
241- if (!klass .canSkipOnAttributeUpdate (key , value , codePointLengthNode , codePointAtIndexNode )) {
242- callAttrUpdate .enter (inliningTarget );
243- klass .onAttributeUpdate (key , value );
244- }
204+ klass .onAttributeUpdate (key , value );
245205 }
246206 }
247207
@@ -261,12 +221,6 @@ static boolean writeToDict(PDict dict, TruffleString key, Object value,
261221 return true ;
262222 }
263223
264- @ Specialization
265- static boolean doPBCT (PythonBuiltinClassType object , TruffleString key , Object value ,
266- @ Cached WriteAttributeToObjectNode recursive ) {
267- return recursive .execute (PythonContext .get (recursive ).lookupType (object ), key , value );
268- }
269-
270224 private static void checkNativeImmutable (Node inliningTarget , PythonAbstractNativeObject object , TruffleString key ,
271225 CStructAccess .ReadI64Node getNativeFlags ,
272226 PRaiseNode raiseNode ) {
@@ -288,8 +242,8 @@ static boolean writeNativeObjectOrClass(PythonAbstractNativeObject object, Truff
288242 @ Exclusive @ Cached InlinedBranchProfile canBeSpecialSlot ,
289243 @ Cached IsTypeNode isTypeNode ,
290244 @ Exclusive @ Cached PRaiseNode raiseNode ,
291- @ Shared ( "cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
292- @ Shared ( "cpAtIndex" ) @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
245+ @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
246+ @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) {
293247 boolean isType = isTypeProfile .profile (inliningTarget , isTypeNode .execute (inliningTarget , object ));
294248 try {
295249 Object dict ;
0 commit comments