8000 feat: add `gc()` into stdlib · RustPython/RustPython@985b9a4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 985b9a4

Browse files
c 10000 ommitted
feat: add gc() into stdlib
1 parent 05dbae1 commit 985b9a4

File tree

2 files changed

+26
-7
lines changed

2 files changed

+26
-7
lines changed

vm/src/object/gc/collector_sync.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,19 @@ unsafe fn free(ptr: ObjPtr) {
7575
dealloc(ptr.cast().as_ptr(), Layout::for_value(ptr.as_ref()));
7676
}
7777
impl CcSync {
78-
/// _suggest_(may or may not) collector to collect garbage.
78+
/// _suggest_(may or may not) collector to collect garbage. return number of cyclic garbage being collected
7979
#[inline]
80-
pub fn gc(&self) {
80+
pub fn gc(&self)->usize {
8181
if self.should_gc() {
82-
self.collect_cycles();
82+
self.force_gc()
83+
}else {
84+
0
8385
}
8486
}
87+
#[inline]
88+
pub fn force_gc(&self)->usize{
89+
self.collect_cycles()
90+
}
8591
fn roots_len(&self) -> usize {
8692
self.roots.lock().unwrap().len()
8793
}
@@ -153,9 +159,9 @@ impl CcSync {
153159
}
154160
}
155161

156-
fn collect_cycles(&self) {
162+
fn collect_cycles(&self) ->usize{
157163
if IS_GC_THREAD.with(|v| v.get()) {
158-
return;
164+
return 0;
159165
// already call collect_cycle() once
160166
}
161167
// order of acquire lock and check IS_GC_THREAD here is important
@@ -169,7 +175,7 @@ impl CcSync {
169175
// to not stop the world
170176
// what's left for collection should already be in garbage cycle,
171177
// no mutator will operate on them
172-
self.collect_roots(lock);
178+
self.collect_roots(lock)
173179
}
174180

175181
fn mark_roots(&self) {
@@ -212,7 +218,7 @@ impl CcSync {
212218
})
213219
.count();
214220
}
215-
fn collect_roots(&self, lock: MutexGuard<()>) {
221+
fn collect_roots(&self, lock: MutexGuard<()>) ->usize {
216222
// Collecting the nodes into this Vec is difference from the original
217223
// Bacon-Rajan paper. We need this because we have destructors(RAII) and
218224
// running them during traversal will cause cycles to be broken which
@@ -231,6 +237,7 @@ impl CcSync {
231237
self.collect_white(obj, &mut white);
232238
})
233239
.count();
240+
let len_white = white.len();
234241
if !white.is_empty() {
235242
warn!("Collect cyclic garbage in white.len()={}", white.len());
236243
}
@@ -259,6 +266,7 @@ impl CcSync {
259266
for i in &white {
260267
unsafe { free(*i) }
261268
}
269+
len_white
262270
}
263271
fn collect_white(&self, obj: ObjRef, white: &mut Vec<NonNull<dyn GcObjPtr>>) {
264272
if obj.header().color() == Color::White && !obj.header().buffered() {

vm/src/stdlib/builtins.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ mod builtins {
3838
const CODEGEN_NOT_SUPPORTED: &str =
3939
"can't compile() to bytecode when the `codegen` feature of rustpython is disabled";
4040

41+
#[pyfunction]
42+
fn gc() -> PyResult<usize> {
43+
#[cfg(feature = "gc")]
44+
{
45+
use crate::object::gc::GLOBAL_COLLECTOR;
46+
Ok(GLOBAL_COLLECTOR.force_gc())
47+
}
48+
#[cfg(not(feature = "gc"))]
49+
Ok(0)
50+
}
51+
4152
#[pyfunction]
4253
fn abs(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
4354
vm._abs(&x)

0 commit comments

Comments
 (0)
0