Visitar URL original
Add per-size tuple freelist (20 buckets × 2000 each) by youknowone · Pull Request #7361 · RustPython/RustPython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
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
Next Next commit
Move exact type check from freelist_push to call-site in default_dealloc
Remove typ parameter from freelist_push trait signature. The exact type
check is now done once at the call-site alongside the heaptype check,
simplifying all freelist_push implementations.
  • Loading branch information
youknowone committed Mar 9, 2026
commit aad6d6d34f78e0895a7e7acd340146e5f32f54b8
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/complex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl PyPayload for PyComplex {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
COMPLEX_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/dict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl PyPayload for PyDict {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
DICT_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl PyPayload for PyFloat {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
FLOAT_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl PyPayload for PyInt {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
INT_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl PyPayload for PyList {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
LIST_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl PyPayload for PyRange {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
RANGE_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/builtins/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl PyPayload for PySlice {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(obj: *mut PyObject, _hint: usize) -> bool {
SLICE_FREELIST
.try_with(|fl| {
let mut list = fl.take();
Expand Down
6 changes: 1 addition & 5 deletions crates/vm/src/builtins/tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,7 @@ impl PyPayload for PyTuple {
}

#[inline]
unsafe fn freelist_push(obj: *mut PyObject, hint: usize, typ: &Py<PyType>) -> bool {
// Py_IS_TYPE(op, &PyTuple_Type): reject structseq and other subtypes
if !core::ptr::eq(typ, Self::class(crate::vm::Context::genesis())) {
return false;
}
unsafe fn freelist_push(obj: *mut PyObject, hint: usize) -> bool {
let len = hint;
if len == 0 || len > TupleFreeList::MAX_SAVE_SIZE {
return false;
Expand Down
11 changes: 6 additions & 5 deletions crates/vm/src/object/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,13 @@ pub(super) unsafe fn default_dealloc<T: PyPayload>(obj: *mut PyObject) {
}

// Try to store in freelist for reuse; otherwise deallocate.
// Only exact types (not heaptype subclasses) go into the freelist.
// The runtime type is passed to freelist_push for Py_IS_TYPE-style
// exact type checking (e.g. reject structseq subtypes of PyTuple).
// Only exact base types (not heaptype or structseq subtypes) go into the freelist.
let typ = obj_ref.class();
let pushed = if T::HAS_FREELIST && typ.heaptype_ext.is_none() {
unsafe { T::freelist_push(obj, freelist_hint, typ) }
let pushed = if T::HAS_FREELIST
&& typ.heaptype_ext.is_none()
&& core::ptr::eq(typ, T::class(crate::vm::Context::genesis()))
{
unsafe { T::freelist_push(obj, freelist_hint) }
} else {
false
};
Expand Down
3 changes: 1 addition & 2 deletions crates/vm/src/object/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,12 @@ pub trait PyPayload: MaybeTraverse + PyThreadingConstraint + Sized + 'static {
/// Try to push a dead object onto this type's freelist for reuse.
/// Returns true if the object was stored (caller must NOT free the memory).
/// `hint` is the value returned by `freelist_hint` before tp_clear.
/// `typ` is the runtime type of the object, for exact-type filtering.
///
/// # Safety
/// `obj` must be a valid pointer to a `PyInner<Self>` with refcount 0,
/// after `drop_slow_inner` and `tp_clear` have already run.
#[inline]
unsafe fn freelist_push(_obj: *mut PyObject, _hint: usize, _typ: &Py<PyType>) -> bool {
unsafe fn freelist_push(_obj: *mut PyObject, _hint: usize) -> bool {
false
}

Expand Down