call_slot_del is cold

This commit is contained in:
Jeong Yunwon
2022-05-12 04:35:50 +09:00
parent 39e3f8faff
commit e76d79e725

View File

@@ -734,26 +734,37 @@ impl PyObject {
#[inline(always)] // the outer function is never inlined
fn drop_slow_inner(&self) -> Result<(), ()> {
// CPython-compatible drop implementation
if let Some(slot_del) = self.class().mro_find_map(|cls| cls.slots.del.load()) {
let ret = crate::vm::thread::with_vm(self, |vm| {
self.0.ref_count.inc();
if let Err(e) = slot_del(self, vm) {
let del_method = self.get_class_attr("__del__").unwrap();
// __del__ is mostly not implemented
#[inline(never)]
#[cold]
fn call_slot_del(
zelf: &PyObject,
slot_del: fn(&PyObject, &VirtualMachine) -> PyResult<()>,
) -> Result<(), ()> {
let ret = crate::vm::thread::with_vm(zelf, |vm| {
zelf.0.ref_count.inc();
if let Err(e) = slot_del(zelf, vm) {
let del_method = zelf.get_class_attr("__del__").unwrap();
vm.run_unraisable(e, None, del_method);
}
self.0.ref_count.dec()
zelf.0.ref_count.dec()
});
match ret {
// the decref right above set ref_count back to 0
Some(true) => {}
Some(true) => Ok(()),
// we've been resurrected by __del__
Some(false) => return Err(()),
Some(false) => Err(()),
None => {
warn!("couldn't run __del__ method for object")
warn!("couldn't run __del__ method for object");
Ok(())
}
}
}
// CPython-compatible drop implementation
if let Some(slot_del) = self.class().mro_find_map(|cls| cls.slots.del.load()) {
call_slot_del(self, slot_del)?;
}
if let Some(wrl) = self.weak_ref_list() {
wrl.clear();
}
@@ -763,7 +774,6 @@ impl PyObject {
/// Can only be called when ref_count has dropped to zero. `ptr` must be valid
#[inline(never)]
#[cold]
unsafe fn drop_slow(ptr: NonNull<PyObject>) {
if let Err(()) = ptr.as_ref().drop_slow_inner() {
// abort drop for whatever reason