diff options
| author | Damien George <damien@micropython.org> | 2024-05-21 11:36:41 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2024-05-22 16:32:47 +1000 |
| commit | c0ca4bb85f4f1307cbd34fe499035b16bcd22637 (patch) | |
| tree | 95ba82489933fac6f8f32c2b6f48b1708c5b5f8e | |
| parent | cdaf2de80cd875da4644455673e81af261f1f3ee (diff) | |
webassembly: Set GC threshold and do top-level GC collect when possible.
Signed-off-by: Damien George <damien@micropython.org>
| -rw-r--r-- | ports/webassembly/main.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/ports/webassembly/main.c b/ports/webassembly/main.c index fd331f8dc..6502ed16d 100644 --- a/ports/webassembly/main.c +++ b/ports/webassembly/main.c @@ -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) { @@ -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)]); @@ -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; @@ -163,6 +176,8 @@ 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; @@ -170,6 +185,16 @@ size_t gc_get_max_new_split(void) { // 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 |
