summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2024-05-21 11:36:41 +1000
committerDamien George <damien@micropython.org>2024-05-22 16:32:47 +1000
commitc0ca4bb85f4f1307cbd34fe499035b16bcd22637 (patch)
tree95ba82489933fac6f8f32c2b6f48b1708c5b5f8e
parentcdaf2de80cd875da4644455673e81af261f1f3ee (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.c33
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