From e35b1e9865a54ad2a245d7fda0e670ebeb060dc1 Mon Sep 17 00:00:00 2001 From: eightycc Date: Wed, 30 Apr 2025 18:52:05 -0700 Subject: [PATCH 1/3] Workaround Risc-V code gen problem causing Python interpreter crash. --- shared/runtime/pyexec.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index 14e5e51a49aa5..8d09a9257a6b0 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -90,8 +90,9 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input nlr_buf_t nlr; nlr.ret_val = NULL; + // CIRCUITPY-CHANGE + mp_obj_t module_fun = mp_const_none; if (nlr_push(&nlr) == 0) { - mp_obj_t module_fun = mp_const_none; // CIRCUITPY-CHANGE #if CIRCUITPY_ATEXIT if (!(exec_flags & EXEC_FLAG_SOURCE_IS_ATEXIT)) @@ -157,6 +158,7 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input mp_call_function_n_kw(callback->func, callback->n_pos, callback->n_kw, callback->args); } else #endif + // CIRCUITPY-CHANGE if (module_fun != mp_const_none) { mp_call_function_0(module_fun); } From fba4e681e1a4a0f5b352d356b97d7fc50564c287 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 2 May 2025 22:49:12 -0700 Subject: [PATCH 2/3] Fix finaliser in malloc helper --- py/malloc.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/py/malloc.c b/py/malloc.c index c83dd4bd6c7d1..fcf930ecfaa83 100644 --- a/py/malloc.c +++ b/py/malloc.c @@ -55,18 +55,8 @@ // example. On the other hand, some (e.g. bare-metal) ports may use GC // heap as system heap, so, to avoid warnings, we do undef's first. // CIRCUITPY-CHANGE: Add selective collect support to malloc to optimize GC for large buffers -#undef malloc #undef free #undef realloc -#if MICROPY_ENABLE_SELECTIVE_COLLECT -#define malloc(b) gc_alloc((b), GC_ALLOC_FLAG_DO_NOT_COLLECT) -#define malloc_with_collect(b) gc_alloc((b), 0) -#define malloc_without_collect(b) gc_alloc((b), GC_ALLOC_FLAG_DO_NOT_COLLECT) -#else -#define malloc(b) gc_alloc((b), 0) -#define malloc_with_collect(b) gc_alloc((b), 0) -#endif -#define malloc_with_finaliser(b) gc_alloc((b), GC_ALLOC_FLAG_HAS_FINALISER) #define free gc_free #define realloc(ptr, n) gc_realloc(ptr, n, true) #define realloc_ext(ptr, n, mv) gc_realloc(ptr, n, mv) @@ -99,15 +89,18 @@ static void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { void *m_malloc_helper(size_t num_bytes, uint8_t flags) { void *ptr; #if MICROPY_ENABLE_GC + uint8_t gc_flags = 0; #if MICROPY_ENABLE_SELECTIVE_COLLECT if ((flags & M_MALLOC_COLLECT) == 0) { - ptr = malloc_without_collect(num_bytes); - } else { - ptr = malloc_with_collect(num_bytes); + gc_flags |= GC_ALLOC_FLAG_DO_NOT_COLLECT; + } + #endif + #if MICROPY_ENABLE_FINALISER + if ((flags & M_MALLOC_WITH_FINALISER) != 0) { + gc_flags |= GC_ALLOC_FLAG_HAS_FINALISER; } - #else - ptr = malloc_with_collect(num_bytes); #endif + ptr = gc_alloc(num_bytes, gc_flags); #else ptr = malloc(num_bytes); #endif From 1f5ce9613980d2c7ba57b128644869de80cbfaad Mon Sep 17 00:00:00 2001 From: eightycc Date: Fri, 2 May 2025 22:58:32 -0700 Subject: [PATCH 3/3] Durable fix for RISC-V interpreter crash. --- shared/runtime/pyexec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index 8d09a9257a6b0..df2b60e207c94 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -90,9 +90,10 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input nlr_buf_t nlr; nlr.ret_val = NULL; - // CIRCUITPY-CHANGE - mp_obj_t module_fun = mp_const_none; if (nlr_push(&nlr) == 0) { + // CIRCUITPY-CHANGE: Made volatile to prevent gcc from re-ordering store of function pointer into stack frame + // after call to gc_collect. For RISC-V this was causing free of the compiled function before execution. + volatile mp_obj_t module_fun = mp_const_none; // CIRCUITPY-CHANGE #if CIRCUITPY_ATEXIT if (!(exec_flags & EXEC_FLAG_SOURCE_IS_ATEXIT))