@@ -235,6 +235,7 @@ unsafe impl crate::object::Traverse for PyType {
235235 . count ( ) ;
236236 if let Some ( ext) = self . heaptype_ext . as_ref ( ) {
237237 ext. specialization_init . read ( ) . traverse ( tracer_fn) ;
238+ ext. specialization_getitem . read ( ) . traverse ( tracer_fn) ;
238239 }
239240 }
240241
@@ -263,11 +264,19 @@ unsafe impl crate::object::Traverse for PyType {
263264 out. push ( val) ;
264265 }
265266 }
266- if let Some ( ext) = self . heaptype_ext . as_ref ( )
267- && let Some ( mut guard) = ext. specialization_init . try_write ( )
268- && let Some ( init) = guard. take ( )
269- {
270- out. push ( init. into ( ) ) ;
267+ if let Some ( ext) = self . heaptype_ext . as_ref ( ) {
268+ if let Some ( mut guard) = ext. specialization_init . try_write ( )
269+ && let Some ( init) = guard. take ( )
270+ {
271+ out. push ( init. into ( ) ) ;
272+ }
273+ if let Some ( mut guard) = ext. specialization_getitem . try_write ( )
274+ && let Some ( getitem) = guard. take ( )
275+ {
276+ out. push ( getitem. into ( ) ) ;
277+ ext. specialization_getitem_version
278+ . store ( 0 , Ordering :: Release ) ;
279+ }
271280 }
272281 }
273282}
@@ -860,14 +869,18 @@ impl PyType {
860869 let Some ( ext) = self . heaptype_ext . as_ref ( ) else {
861870 return false ;
862871 } ;
863- if tp_version == 0 || self . tp_version_tag . load ( Ordering :: Acquire ) != tp_version {
872+ if tp_version == 0 {
864873 return false ;
865874 }
866875 let func_version = getitem. get_version_for_current_state ( ) ;
867876 if func_version == 0 {
868877 return false ;
869878 }
870- * ext. specialization_getitem . write ( ) = Some ( getitem) ;
879+ let mut guard = ext. specialization_getitem . write ( ) ;
880+ if self . tp_version_tag . load ( Ordering :: Acquire ) != tp_version {
881+ return false ;
882+ }
883+ * guard = Some ( getitem) ;
871884 ext. specialization_getitem_version
872885 . store ( func_version, Ordering :: Release ) ;
873886 true
@@ -876,15 +889,15 @@ impl PyType {
876889 /// Read cached __getitem__ for BINARY_OP_SUBSCR_GETITEM specialization.
877890 pub ( crate ) fn get_cached_getitem_for_specialization ( & self ) -> Option < ( PyRef < PyFunction > , u32 ) > {
878891 let ext = self . heaptype_ext . as_ref ( ) ?;
879- if self . tp_version_tag . load ( Ordering :: Acquire ) == 0 {
880- return None ;
881- }
882892 let cached_version = ext. specialization_getitem_version . load ( Ordering :: Acquire ) ;
883893 if cached_version == 0 {
884894 return None ;
885895 }
886- ext. specialization_getitem
887- . read ( )
896+ let guard = ext. specialization_getitem . read ( ) ;
897+ if self . tp_version_tag . load ( Ordering :: Acquire ) == 0 {
898+ return None ;
899+ }
900+ guard
888901 . as_ref ( )
889902 . map ( |getitem| ( getitem. to_owned ( ) , cached_version) )
890903 }
0 commit comments