Skip to content

Commit

Permalink
webassembly: Set GC threshold and do top-level GC collect when possible.
Browse files Browse the repository at this point in the history
Signed-off-by: Damien George <[email protected]>
  • Loading branch information
dpgeorge committed May 22, 2024
1 parent cdaf2de commit c0ca4bb
Showing 1 changed file with 29 additions and 4 deletions.
33 changes: 29 additions & 4 deletions ports/webassembly/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,17 @@
// the top-level call into C.
static size_t external_call_depth = 0;

#if MICROPY_GC_SPLIT_HEAP_AUTO
static void gc_collect_top_level(void);
#endif

void external_call_depth_inc(void) {
++external_call_depth;
#if MICROPY_GC_SPLIT_HEAP_AUTO
if (external_call_depth == 1) {
gc_collect_top_level();
}
#endif
}

void external_call_depth_dec(void) {
Expand All @@ -63,6 +72,14 @@ void mp_js_init(int heap_size) {
gc_init(heap, heap + heap_size);
#endif

#if MICROPY_GC_SPLIT_HEAP_AUTO
// When MICROPY_GC_SPLIT_HEAP_AUTO is enabled, set the GC threshold to a low
// value so that a collection is triggered before the heap fills up. The actual
// garbage collection will happen later when control returns to the top-level,
// via the `gc_collect_pending` flag and `gc_collect_top_level()`.
MP_STATE_MEM(gc_alloc_threshold) = 16 * 1024 / MICROPY_BYTES_PER_GC_BLOCK;
#endif

#if MICROPY_ENABLE_PYSTACK
static mp_obj_t pystack[1024];
mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]);
Expand Down Expand Up @@ -121,10 +138,6 @@ void mp_js_do_import(const char *name, uint32_t *out) {
}

void mp_js_do_exec(const char *src, size_t len, uint32_t *out) {
// Collect at the top-level, where there are no root pointers from stack/registers.
gc_collect_start();
gc_collect_end();

external_call_depth_inc();
mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT;
nlr_buf_t nlr;
Expand Down Expand Up @@ -163,13 +176,25 @@ int mp_js_repl_process_char(int c) {

#if MICROPY_GC_SPLIT_HEAP_AUTO

static bool gc_collect_pending = false;

// The largest new region that is available to become Python heap.
size_t gc_get_max_new_split(void) {
return 128 * 1024 * 1024;
}

// Don't collect anything. Instead require the heap to grow.
void gc_collect(void) {
gc_collect_pending = true;
}

// Collect at the top-level, where there are no root pointers from stack/registers.
static void gc_collect_top_level(void) {
if (gc_collect_pending) {
gc_collect_pending = false;
gc_collect_start();
gc_collect_end();
}
}

#else
Expand Down

0 comments on commit c0ca4bb

Please sign in to comment.