diff options
| author | Damien George <damien@micropython.org> | 2023-08-15 14:34:25 +1000 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2023-08-15 16:12:54 +1000 |
| commit | fa1ea21f75601a93827d143bb9074b1f7474a953 (patch) | |
| tree | 48407859e4da7aa7f84747f512f42cf9ad12193e | |
| parent | 05dcb8be9957d0ed6c9694629be186a40c1a3fd9 (diff) | |
esp32/gccollect: Make level arg volatile to force recursive function.
Otherwise the compiler may inline the gc_collect_inner() function and/or
remove the recursion, which is necessary to spill all the windowed
registers to the C stack.
Signed-off-by: Damien George <damien@micropython.org>
| -rw-r--r-- | ports/esp32/gccollect.c | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/ports/esp32/gccollect.c b/ports/esp32/gccollect.c index e16e8028a..4b6dd8ab6 100644 --- a/ports/esp32/gccollect.c +++ b/ports/esp32/gccollect.c @@ -39,30 +39,25 @@ #include "xtensa/hal.h" -static void gc_collect_inner(int level) { +// The level argument must be volatile to force the compiler to emit code that +// will call this function recursively, to nest the C stack. +static void gc_collect_inner(volatile unsigned int level) { if (level < XCHAL_NUM_AREGS / 8) { + // Go deeper on the stack to spill more registers from the register window. gc_collect_inner(level + 1); - if (level != 0) { - return; - } - } - - if (level == XCHAL_NUM_AREGS / 8) { - // get the sp + } else { + // Deep enough so that all registers are on the C stack, now trace the stack. volatile uint32_t sp = (uint32_t)esp_cpu_get_sp(); gc_collect_root((void **)sp, ((mp_uint_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t)); - return; } - - // trace root pointers from any threads - #if MICROPY_PY_THREAD - mp_thread_gc_others(); - #endif } void gc_collect(void) { gc_collect_start(); gc_collect_inner(0); + #if MICROPY_PY_THREAD + mp_thread_gc_others(); + #endif gc_collect_end(); } |
