webassembly: Set GC threshold and do top-level GC collect when possible.
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -49,8 +49,17 @@
|
|||||||
// the top-level call into C.
|
// the top-level call into C.
|
||||||
static size_t external_call_depth = 0;
|
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) {
|
void external_call_depth_inc(void) {
|
||||||
++external_call_depth;
|
++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) {
|
void external_call_depth_dec(void) {
|
||||||
@@ -63,6 +72,14 @@ void mp_js_init(int heap_size) {
|
|||||||
gc_init(heap, heap + heap_size);
|
gc_init(heap, heap + heap_size);
|
||||||
#endif
|
#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
|
#if MICROPY_ENABLE_PYSTACK
|
||||||
static mp_obj_t pystack[1024];
|
static mp_obj_t pystack[1024];
|
||||||
mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]);
|
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) {
|
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();
|
external_call_depth_inc();
|
||||||
mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT;
|
mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT;
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
@@ -163,6 +176,8 @@ int mp_js_repl_process_char(int c) {
|
|||||||
|
|
||||||
#if MICROPY_GC_SPLIT_HEAP_AUTO
|
#if MICROPY_GC_SPLIT_HEAP_AUTO
|
||||||
|
|
||||||
|
static bool gc_collect_pending = false;
|
||||||
|
|
||||||
// The largest new region that is available to become Python heap.
|
// The largest new region that is available to become Python heap.
|
||||||
size_t gc_get_max_new_split(void) {
|
size_t gc_get_max_new_split(void) {
|
||||||
return 128 * 1024 * 1024;
|
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.
|
// Don't collect anything. Instead require the heap to grow.
|
||||||
void gc_collect(void) {
|
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
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user