Skip to content

Commit 61d91d6

Browse files
Add garbage collection c-api (#8239)
1 parent 3a4b4a8 commit 61d91d6

3 files changed

Lines changed: 84 additions & 1 deletion

File tree

crates/capi/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub mod longobject;
2525
pub mod methodobject;
2626
pub mod moduleobject;
2727
pub mod object;
28+
pub mod objimpl;
2829
pub mod osmodule;
2930
pub mod pycapsule;
3031
pub mod pyerrors;

crates/capi/src/objimpl.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use crate::PyObject;
2+
use crate::pymem::{PyMem_Calloc, PyMem_Free, PyMem_Malloc, PyMem_Realloc};
3+
use crate::pystate::with_vm;
4+
use core::ffi::{c_int, c_void};
5+
use rustpython_vm::gc_state;
6+
7+
#[unsafe(no_mangle)]
8+
pub unsafe extern "C" fn PyObject_GC_Track(op: *mut PyObject) {
9+
with_vm(|_vm| {
10+
let obj = unsafe { &*op };
11+
if !obj.is_gc_tracked() {
12+
unsafe { gc_state::gc_state().track_object(obj.into()) };
13+
}
14+
})
15+
}
16+
17+
#[unsafe(no_mangle)]
18+
pub unsafe extern "C" fn PyObject_GC_UnTrack(op: *mut PyObject) {
19+
with_vm(|_vm| {
20+
let obj = unsafe { &*op };
21+
if obj.is_gc_tracked() {
22+
unsafe { gc_state::gc_state().untrack_object(obj.into()) };
23+
}
24+
})
25+
}
26+
27+
#[unsafe(no_mangle)]
28+
pub unsafe extern "C" fn PyObject_GC_IsTracked(op: *mut PyObject) -> c_int {
29+
with_vm(|_vm| unsafe { (&*op).is_gc_tracked() })
30+
}
31+
32+
#[unsafe(no_mangle)]
33+
pub unsafe extern "C" fn PyObject_GC_IsFinalized(op: *mut PyObject) -> c_int {
34+
with_vm(|_vm| unsafe { (&*op).gc_finalized() })
35+
}
36+
37+
#[unsafe(no_mangle)]
38+
pub extern "C" fn PyGC_Collect() -> isize {
39+
let result = gc_state::gc_state().collect(2);
40+
(result.collected + result.uncollectable) as isize
41+
}
42+
43+
#[unsafe(no_mangle)]
44+
pub extern "C" fn PyGC_Enable() -> c_int {
45+
let gc = gc_state::gc_state();
46+
let was_enabled = gc.is_enabled();
47+
gc.enable();
48+
was_enabled.into()
49+
}
50+
51+
#[unsafe(no_mangle)]
52+
pub extern "C" fn PyGC_Disable() -> c_int {
53+
let gc = gc_state::gc_state();
54+
let was_enabled = gc.is_enabled();
55+
gc.disable();
56+
was_enabled.into()
57+
}
58+
59+
#[unsafe(no_mangle)]
60+
pub extern "C" fn PyGC_IsEnabled() -> c_int {
61+
gc_state::gc_state().is_enabled().into()
62+
}
63+
64+
#[unsafe(no_mangle)]
65+
pub unsafe extern "C" fn PyObject_Malloc(size: usize) -> *mut c_void {
66+
unsafe { PyMem_Malloc(size) }
67+
}
68+
69+
#[unsafe(no_mangle)]
70+
pub unsafe extern "C" fn PyObject_Calloc(nelem: usize, elsize: usize) -> *mut c_void {
71+
unsafe { PyMem_Calloc(nelem, elsize) }
72+
}
73+
74+
#[unsafe(no_mangle)]
75+
pub unsafe extern "C" fn PyObject_Realloc(ptr: *mut c_void, new_size: usize) -> *mut c_void {
76+
unsafe { PyMem_Realloc(ptr, new_size) }
77+
}
78+
79+
#[unsafe(no_mangle)]
80+
pub unsafe extern "C" fn PyObject_Free(ptr: *mut c_void) {
81+
unsafe { PyMem_Free(ptr) }
82+
}

crates/vm/src/object/core.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,7 @@ impl PyObject {
16541654
/// Check if the object has been finalized (__del__ already called).
16551655
/// _PyGC_FINALIZED in Py_GIL_DISABLED mode.
16561656
#[inline]
1657-
pub(crate) fn gc_finalized(&self) -> bool {
1657+
pub fn gc_finalized(&self) -> bool {
16581658
GcBits::from_bits_retain(self.0.gc_bits.load(Ordering::Relaxed)).contains(GcBits::FINALIZED)
16591659
}
16601660

0 commit comments

Comments
 (0)