forked from Rust-related/RustPython
call_slot_del is cold
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user