update setup_gc_debug_callback

This commit is contained in:
blueloveTH 2025-11-26 23:47:43 +08:00
parent 673c3e2802
commit 1f782b799c
3 changed files with 36 additions and 17 deletions

View File

@ -4,5 +4,5 @@
-std=c11 -std=c11
-Iinclude/ -Iinclude/
-I3rd/lz4/ -I3rd/lz4/
-I3rd/cute_headers/include/ -I3rd/cute_png/include/
-I3rd/msgpack/include/ -I3rd/msgpack/include/

View File

@ -1,4 +1,4 @@
from typing import Callable from typing import Callable, Literal
def isenabled() -> bool: def isenabled() -> bool:
"""Check if automatic garbage collection is enabled.""" """Check if automatic garbage collection is enabled."""
@ -23,5 +23,5 @@ def collect_hint() -> None:
and `gc.collect_hint()` is called at the end of each frame. and `gc.collect_hint()` is called at the end of each frame.
""" """
def setup_debug_callback(cb: Callable[[str], None] | None) -> None: def setup_debug_callback(cb: Callable[[Literal['start', 'stop'], str], None] | None) -> None:
"""Setup a callback that will be triggered at the end of each collection.""" """Setup a callback that will be triggered at the end of each collection."""

View File

@ -6,7 +6,6 @@
#include "pocketpy/pocketpy.h" #include "pocketpy/pocketpy.h"
#include <assert.h> #include <assert.h>
void ManagedHeap__ctor(ManagedHeap* self) { void ManagedHeap__ctor(ManagedHeap* self) {
MultiPool__ctor(&self->small_objects); MultiPool__ctor(&self->small_objects);
c11_vector__ctor(&self->large_objects, sizeof(PyObject*)); c11_vector__ctor(&self->large_objects, sizeof(PyObject*));
@ -34,7 +33,20 @@ void ManagedHeap__dtor(ManagedHeap* self) {
c11_vector__dtor(&self->gc_roots); c11_vector__dtor(&self->gc_roots);
} }
static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) { static void ManagedHeap__fire_debug_callback_start(ManagedHeap* self) {
py_push(&self->debug_callback);
py_pushnil();
py_newstr(py_pushtmp(), "start");
py_newstr(py_pushtmp(), "");
bool ok = py_vectorcall(2, 0);
if(!ok) {
char* msg = py_formatexc();
c11__abort("gc_debug_callback error!!\n%s", msg);
}
}
static void ManagedHeap__fire_debug_callback_stop(ManagedHeap* self,
ManagedHeapSwpetInfo* out_info) {
assert(out_info != NULL); assert(out_info != NULL);
c11_sbuf buf; c11_sbuf buf;
@ -65,11 +77,11 @@ static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpet
int l_freed = out_info->large_types[i]; int l_freed = out_info->large_types[i];
if(s_freed == 0 && l_freed == 0) continue; if(s_freed == 0 && l_freed == 0) continue;
snprintf(line_buf, snprintf(line_buf,
sizeof(line_buf), sizeof(line_buf),
"[%-24s] small: %6d large: %6d\n", "[%-24s] small: %6d large: %6d\n",
type_name, type_name,
s_freed, s_freed,
l_freed); l_freed);
c11_sbuf__write_cstr(&buf, line_buf); c11_sbuf__write_cstr(&buf, line_buf);
} }
c11_sbuf__write_cstr(&buf, DIVIDER); c11_sbuf__write_cstr(&buf, DIVIDER);
@ -85,9 +97,10 @@ static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpet
py_push(&self->debug_callback); py_push(&self->debug_callback);
py_pushnil(); py_pushnil();
py_newstr(py_pushtmp(), "stop");
py_StackRef arg = py_pushtmp(); py_StackRef arg = py_pushtmp();
c11_sbuf__py_submit(&buf, arg); c11_sbuf__py_submit(&buf, arg);
bool ok = py_vectorcall(1, 0); bool ok = py_vectorcall(2, 0);
if(!ok) { if(!ok) {
char* msg = py_formatexc(); char* msg = py_formatexc();
c11__abort("gc_debug_callback error!!\n%s", msg); c11__abort("gc_debug_callback error!!\n%s", msg);
@ -99,7 +112,10 @@ void ManagedHeap__collect_hint(ManagedHeap* self) {
self->gc_counter = 0; self->gc_counter = 0;
ManagedHeapSwpetInfo* out_info = NULL; ManagedHeapSwpetInfo* out_info = NULL;
if(!py_isnone(&self->debug_callback)) out_info = ManagedHeapSwpetInfo__new(); if(!py_isnone(&self->debug_callback)) {
out_info = ManagedHeapSwpetInfo__new();
ManagedHeap__fire_debug_callback_start(self);
}
ManagedHeap__mark(self); ManagedHeap__mark(self);
if(out_info) out_info->mark_end_ns = time_ns(); if(out_info) out_info->mark_end_ns = time_ns();
@ -126,7 +142,7 @@ void ManagedHeap__collect_hint(ManagedHeap* self) {
self->gc_threshold = c11__min(c11__max(new_threshold, lower), upper); self->gc_threshold = c11__min(c11__max(new_threshold, lower), upper);
if(!py_isnone(&self->debug_callback)) { if(!py_isnone(&self->debug_callback)) {
ManagedHeap__fire_debug_callback(self, out_info); ManagedHeap__fire_debug_callback_stop(self, out_info);
ManagedHeapSwpetInfo__delete(out_info); ManagedHeapSwpetInfo__delete(out_info);
} }
} }
@ -135,7 +151,10 @@ int ManagedHeap__collect(ManagedHeap* self) {
self->gc_counter = 0; self->gc_counter = 0;
ManagedHeapSwpetInfo* out_info = NULL; ManagedHeapSwpetInfo* out_info = NULL;
if(!py_isnone(&self->debug_callback)) out_info = ManagedHeapSwpetInfo__new(); if(!py_isnone(&self->debug_callback)) {
out_info = ManagedHeapSwpetInfo__new();
ManagedHeap__fire_debug_callback_start(self);
}
ManagedHeap__mark(self); ManagedHeap__mark(self);
if(out_info) out_info->mark_end_ns = time_ns(); if(out_info) out_info->mark_end_ns = time_ns();
@ -148,7 +167,7 @@ int ManagedHeap__collect(ManagedHeap* self) {
} }
if(!py_isnone(&self->debug_callback)) { if(!py_isnone(&self->debug_callback)) {
ManagedHeap__fire_debug_callback(self, out_info); ManagedHeap__fire_debug_callback_stop(self, out_info);
ManagedHeapSwpetInfo__delete(out_info); ManagedHeapSwpetInfo__delete(out_info);
} }
return freed; return freed;