MCPcopy Index your code
hub / github.com/RustPython/RustPython / drop_slow_inner

Method drop_slow_inner

crates/vm/src/object/core.rs:1597–1650  ·  view source on GitHub ↗

the outer function is never inlined

(&self)

Source from the content-addressed store, hash-verified

1595
1596 #[inline(always)] // the outer function is never inlined
1597 fn drop_slow_inner(&self) -> Result<(), ()> {
1598 // __del__ is mostly not implemented
1599 #[inline(never)]
1600 #[cold]
1601 fn call_slot_del(
1602 zelf: &PyObject,
1603 slot_del: fn(&PyObject, &VirtualMachine) -> PyResult<()>,
1604 ) -> Result<(), ()> {
1605 let ret = crate::vm::thread::with_vm(zelf, |vm| {
1606 // Temporarily resurrect (0→2) so ref_count stays positive
1607 // during __del__, preventing safe_inc from seeing 0.
1608 zelf.0.ref_count.inc_by(2);
1609
1610 if let Err(e) = slot_del(zelf, vm) {
1611 let del_method = zelf.get_class_attr(identifier!(vm, __del__)).unwrap();
1612 vm.run_unraisable(e, None, del_method);
1613 }
1614
1615 // Undo the temporary resurrection. Always remove both
1616 // temporary refs; the second dec returns true only when
1617 // ref_count drops to 0 (no resurrection).
1618 let _ = zelf.0.ref_count.dec();
1619 zelf.0.ref_count.dec()
1620 });
1621 match ret {
1622 // the decref set ref_count back to 0
1623 Some(true) => Ok(()),
1624 // we've been resurrected by __del__
1625 Some(false) => Err(()),
1626 None => Ok(()),
1627 }
1628 }
1629
1630 // __del__ should only be called once (like _PyGC_FINALIZED check in GIL_DISABLED)
1631 // We call __del__ BEFORE clearing weakrefs to allow the finalizer to access
1632 // the object's weak references if needed.
1633 let del = self.class().slots.del.load();
1634 if let Some(slot_del) = del
1635 && !self.gc_finalized()
1636 {
1637 self.set_gc_finalized();
1638 call_slot_del(self, slot_del)?;
1639 }
1640
1641 // Clear weak refs AFTER __del__.
1642 // Note: This differs from GC behavior which clears weakrefs before finalizers,
1643 // but for direct deallocation (drop_slow_inner), we need to allow the finalizer
1644 // to run without triggering use-after-free from WeakRefList operations.
1645 if let Some(wrl) = self.weak_ref_list() {
1646 wrl.clear(self);
1647 }
1648
1649 Ok(())
1650 }
1651
1652 /// _Py_Dealloc: dispatch to type's dealloc
1653 #[inline(never)]

Callers 1

default_deallocFunction · 0.80

Calls 6

gc_finalizedMethod · 0.80
set_gc_finalizedMethod · 0.80
weak_ref_listMethod · 0.80
loadMethod · 0.45
classMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected