diff --git a/compile_flags.txt b/compile_flags.txt index 2c6d9758..bbb94fbc 100644 --- a/compile_flags.txt +++ b/compile_flags.txt @@ -4,5 +4,5 @@ -std=c11 -Iinclude/ -I3rd/lz4/ --I3rd/cute_headers/include/ +-I3rd/cute_png/include/ -I3rd/msgpack/include/ diff --git a/include/typings/gc.pyi b/include/typings/gc.pyi index 449a48e6..b74b595e 100644 --- a/include/typings/gc.pyi +++ b/include/typings/gc.pyi @@ -1,4 +1,4 @@ -from typing import Callable +from typing import Callable, Literal def isenabled() -> bool: """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. """ -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.""" diff --git a/src/interpreter/heap.c b/src/interpreter/heap.c index ca4d2366..cd24cc34 100644 --- a/src/interpreter/heap.c +++ b/src/interpreter/heap.c @@ -6,7 +6,6 @@ #include "pocketpy/pocketpy.h" #include - void ManagedHeap__ctor(ManagedHeap* self) { MultiPool__ctor(&self->small_objects); c11_vector__ctor(&self->large_objects, sizeof(PyObject*)); @@ -34,7 +33,20 @@ void ManagedHeap__dtor(ManagedHeap* self) { 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); c11_sbuf buf; @@ -65,11 +77,11 @@ static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpet int l_freed = out_info->large_types[i]; if(s_freed == 0 && l_freed == 0) continue; snprintf(line_buf, - sizeof(line_buf), - "[%-24s] small: %6d large: %6d\n", - type_name, - s_freed, - l_freed); + sizeof(line_buf), + "[%-24s] small: %6d large: %6d\n", + type_name, + s_freed, + l_freed); c11_sbuf__write_cstr(&buf, line_buf); } 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_pushnil(); + py_newstr(py_pushtmp(), "stop"); py_StackRef arg = py_pushtmp(); c11_sbuf__py_submit(&buf, arg); - bool ok = py_vectorcall(1, 0); + bool ok = py_vectorcall(2, 0); if(!ok) { char* msg = py_formatexc(); c11__abort("gc_debug_callback error!!\n%s", msg); @@ -99,8 +112,11 @@ void ManagedHeap__collect_hint(ManagedHeap* self) { self->gc_counter = 0; 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); if(out_info) out_info->mark_end_ns = time_ns(); int freed = ManagedHeap__sweep(self, out_info); @@ -126,7 +142,7 @@ void ManagedHeap__collect_hint(ManagedHeap* self) { self->gc_threshold = c11__min(c11__max(new_threshold, lower), upper); 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); } } @@ -135,8 +151,11 @@ int ManagedHeap__collect(ManagedHeap* self) { self->gc_counter = 0; 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); if(out_info) out_info->mark_end_ns = time_ns(); int freed = ManagedHeap__sweep(self, out_info); @@ -148,7 +167,7 @@ int ManagedHeap__collect(ManagedHeap* self) { } 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); } return freed;