Skip to content

Commit 9ed5137

Browse files
committed
fix: check buf in drop_slow
1 parent 823a80f commit 9ed5137

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

Lib/test/test_ordered_dict.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,8 +665,6 @@ class A:
665665
r = weakref.ref(A)
666666
del A
667667
gc.collect()
668-
# TODO: RUSTPYTHON, Need to fix this: somehow after del A, it takes two call to `gc.collect()`
669-
# for gc to realize a loop is there and to be collected
670668
self.assertIsNone(r())
671669

672670
# TODO: RUSTPYTHON

vm/src/object/core.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -940,24 +940,39 @@ impl PyObject {
940940
}
941941

942942
/// Can only be called when ref_count has dropped to zero. `ptr` must be valid, it run __del__ then drop&dealloc
943-
pub(in crate::object) unsafe fn drop_slow(ptr: NonNull<PyObject>) -> bool {
943+
pub(in crate::object) unsafe fn drop_slow(ptr: NonNull<PyObject>) {
944944
if let Err(()) = ptr.as_ref().drop_slow_inner() {
945945
// abort drop for whatever reason
946-
return false;
946+
return;
947947
}
948948

949949
#[cfg(feature = "gc_bacon")]
950-
if !ptr.as_ref().header().check_set_drop_dealloc() {
951-
return false;
950+
{
951+
let zelf = ptr.as_ref();
952+
// if is buffered by run `drop_slow_inner`, then drop only here and early return
953+
if zelf.header().buffered() {
954+
if zelf.header().check_set_drop_only() {
955+
Self::drop_only(ptr);
956+
} else {
957+
panic!("Should be able to drop only for {:?}", zelf.header())
958+
}
959+
return;
960+
}
961+
if !ptr.as_ref().header().check_set_drop_dealloc() {
962+
unreachable!(
963+
"Should be able to drop_dealloc for {:?}",
964+
ptr.as_ref().header()
965+
)
966+
}
952967
}
968+
953969
#[cfg(debug_assertions)]
954970
{
955971
*ptr.as_ref().0.is_drop.lock() = true;
956972
}
957973
let drop_dealloc = ptr.as_ref().0.vtable.drop_dealloc;
958974
// call drop only when there are no references in scope - stacked borrows stuff
959975
drop_dealloc(ptr.as_ptr());
960-
true
961976
}
962977

963978
/// # Safety

vm/src/object/gc/object.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,14 @@ impl PyObject {
175175

176176
Self::drop_clr_wr(ptr)
177177
}
178+
/// call `drop_only` in vtable
179+
pub(in crate::object) unsafe fn drop_only(ptr: NonNull<PyObject>) {
180+
let zelf = ptr.as_ref();
181+
// not set PyInner's is_drop because still havn't dealloc
182+
let drop_only = zelf.0.vtable.drop_only;
178183

184+
drop_only(ptr.as_ptr());
185+
}
179186
pub(in crate::object) unsafe fn dealloc_only(ptr: NonNull<PyObject>) -> bool {
180187
// can't check for if is a alive PyWeak here because already dropped payload
181188
#[cfg(feature = "gc_bacon")]

0 commit comments

Comments
 (0)