Skip to content

Commit e97dab9

Browse files
committed
vm: add GC traverse/clear for specialization_getitem and revalidate version under lock
1 parent 7a6da75 commit e97dab9

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

crates/vm/src/builtins/type.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)