summaryrefslogtreecommitdiffstatshomepage
path: root/py/persistentcode.c
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2024-09-25 14:06:00 +1000
committerDamien George <damien@micropython.org>2024-09-26 22:15:28 +1000
commit5b22bde044b27aaf82cde8d7609ba37015b37b4c (patch)
tree6b88129a7aa71af7074d74a433f4f728e055ed11 /py/persistentcode.c
parentf4ab9d924790581989f2398fe30bbac5d680577f (diff)
downloadmicropython-5b22bde044b27aaf82cde8d7609ba37015b37b4c.tar.gz
micropython-5b22bde044b27aaf82cde8d7609ba37015b37b4c.zip
py/persistentcode: Explicitly track native BSS/rodata when needed.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/persistentcode.c')
-rw-r--r--py/persistentcode.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/py/persistentcode.c b/py/persistentcode.c
index 5088c05f03..be93eaa5b4 100644
--- a/py/persistentcode.c
+++ b/py/persistentcode.c
@@ -72,6 +72,20 @@ typedef struct _bytecode_prelude_t {
static int read_byte(mp_reader_t *reader);
static size_t read_uint(mp_reader_t *reader);
+#if MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA || MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA
+
+// An mp_obj_list_t that tracks native text/BSS/rodata to prevent the GC from reclaiming them.
+MP_REGISTER_ROOT_POINTER(mp_obj_t persistent_code_root_pointers);
+
+static void track_root_pointer(void *ptr) {
+ if (MP_STATE_PORT(persistent_code_root_pointers) == MP_OBJ_NULL) {
+ MP_STATE_PORT(persistent_code_root_pointers) = mp_obj_new_list(0, NULL);
+ }
+ mp_obj_list_append(MP_STATE_PORT(persistent_code_root_pointers), MP_OBJ_FROM_PTR(ptr));
+}
+
+#endif
+
#if MICROPY_EMIT_MACHINE_CODE
typedef struct _reloc_info_t {
@@ -299,11 +313,10 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
read_bytes(reader, rodata, rodata_size);
}
- // Viper code with BSS/rodata should not have any children.
- // Reuse the children pointer to reference the BSS/rodata
- // memory so that it is not reclaimed by the GC.
- assert(!has_children);
- children = (void *)data;
+ #if MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA
+ // Track the BSS/rodata memory so it's not reclaimed by the GC.
+ track_root_pointer(data);
+ #endif
}
}
#endif
@@ -351,16 +364,9 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co
fun_data = MP_PLAT_COMMIT_EXEC(fun_data, fun_data_len, opt_ri);
#else
if (native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC) {
- #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE
- // If native code needs relocations then it's not guaranteed that a pointer to
- // the head of `buf` (containing the machine code) will be retained for the GC
- // to trace. This is because native functions can start inside `buf` and so
- // it's possible that the only GC-reachable pointers are pointers inside `buf`.
- // So put this `buf` on a list of reachable root pointers.
- if (MP_STATE_PORT(track_reloc_code_list) == MP_OBJ_NULL) {
- MP_STATE_PORT(track_reloc_code_list) = mp_obj_new_list(0, NULL);
- }
- mp_obj_list_append(MP_STATE_PORT(track_reloc_code_list), MP_OBJ_FROM_PTR(fun_data));
+ #if MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA
+ // Track the function data memory so it's not reclaimed by the GC.
+ track_root_pointer(fun_data);
#endif
// Do the relocations.
mp_native_relocate(&ri, fun_data, (uintptr_t)fun_data);
@@ -662,8 +668,3 @@ void mp_raw_code_save_file(mp_compiled_module_t *cm, qstr filename) {
#endif // MICROPY_PERSISTENT_CODE_SAVE_FILE
#endif // MICROPY_PERSISTENT_CODE_SAVE
-
-#if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE
-// An mp_obj_list_t that tracks relocated native code to prevent the GC from reclaiming them.
-MP_REGISTER_ROOT_POINTER(mp_obj_t track_reloc_code_list);
-#endif