Skip to content

Commit fa1ea21

Browse files
committed
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>
1 parent 05dcb8b commit fa1ea21

File tree

1 file changed

+9
-14
lines changed

1 file changed

+9
-14
lines changed

ports/esp32/gccollect.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,25 @@
3939

4040
#include "xtensa/hal.h"
4141

42-
static void gc_collect_inner(int level) {
42+
// The level argument must be volatile to force the compiler to emit code that
43+
// will call this function recursively, to nest the C stack.
44+
static void gc_collect_inner(volatile unsigned int level) {
4345
if (level < XCHAL_NUM_AREGS / 8) {
46+
// Go deeper on the stack to spill more registers from the register window.
4447
gc_collect_inner(level + 1);
45-
if (level != 0) {
46-
return;
47-
}
48-
}
49-
50-
if (level == XCHAL_NUM_AREGS / 8) {
51-
// get the sp
48+
} else {
49+
// Deep enough so that all registers are on the C stack, now trace the stack.
5250
volatile uint32_t sp = (uint32_t)esp_cpu_get_sp();
5351
gc_collect_root((void **)sp, ((mp_uint_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t));
54-
return;
5552
}
56-
57-
// trace root pointers from any threads
58-
#if MICROPY_PY_THREAD
59-
mp_thread_gc_others();
60-
#endif
6153
}
6254

6355
void gc_collect(void) {
6456
gc_collect_start();
6557
gc_collect_inner(0);
58+
#if MICROPY_PY_THREAD
59+
mp_thread_gc_others();
60+
#endif
6661
gc_collect_end();
6762
}
6863

0 commit comments

Comments
 (0)