Visitar URL original
Add freelists for PyComplex, PyInt, PyRange by youknowone 路 Pull Request #7345 路 RustPython/RustPython 路 GitHub
Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Remove PyBoundMethod freelist to fix refcount/weakref test failures
Non-Option PyObjectRef fields retain references in freelist, causing
weakref and refcount assertions to fail in test_unittest, test_multiprocessing,
and test_socket.
  • Loading branch information
youknowone committed Mar 4, 2026
commit 01b5319e46129fd68dcf291fc9e641cb2f71cf56
42 changes: 1 addition & 41 deletions crates/vm/src/builtins/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ use crate::{
Callable, Comparable, Constructor, GetAttr, GetDescriptor, PyComparisonOp, Representable,
},
};
use core::cell::Cell;
use core::ptr::NonNull;
use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
use itertools::Itertools;
#[cfg(feature = "jit")]
Expand Down Expand Up @@ -1084,7 +1082,7 @@ impl Constructor for PyFunction {
}
}

#[pyclass(module = false, name = "method", traverse, clear = false)]
#[pyclass(module = false, name = "method", traverse)]
#[derive(Debug)]
pub struct PyBoundMethod {
object: PyObjectRef,
Expand Down Expand Up @@ -1207,49 +1205,11 @@ impl PyBoundMethod {
}
}

// spell-checker:ignore MAXFREELIST
thread_local! {
static BOUND_METHOD_FREELIST: Cell<crate::object::FreeList<PyBoundMethod>> = const { Cell::new(crate::object::FreeList::new()) };
}

impl PyPayload for PyBoundMethod {
const MAX_FREELIST: usize = 20;
const HAS_FREELIST: bool = true;

#[inline]
fn class(ctx: &Context) -> &'static Py<PyType> {
ctx.types.bound_method_type
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject) -> bool {
BOUND_METHOD_FREELIST
.try_with(|fl| {
let mut list = fl.take();
let stored = if list.len() < Self::MAX_FREELIST {
list.push(obj);
true
} else {
false
};
fl.set(list);
stored
})
.unwrap_or(false)
}

#[inline]
unsafe fn freelist_pop() -> Option<NonNull<PyObject>> {
BOUND_METHOD_FREELIST
.try_with(|fl| {
let mut list = fl.take();
let result = list.pop().map(|p| unsafe { NonNull::new_unchecked(p) });
fl.set(list);
result
})
.ok()
.flatten()
}
}

impl Representable for PyBoundMethod {
Expand Down