summaryrefslogtreecommitdiff
path: root/py/persistentcode.c
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2020-07-27 23:52:38 +1000
committerDamien George <damien@micropython.org>2020-08-02 22:34:09 +1000
commit9883d8e818feba112935676eb5aa4ce211d7779c (patch)
treeae254d6a502b92012dc1f962ede53f05f05153de /py/persistentcode.c
parent8da40baa47ee9fe7aac228af2c0addd1f4ce3646 (diff)
py/persistentcode: Maintain root ptr list of imported native .mpy code.
On ports where normal heap memory can contain executable code (eg ARM-based ports such as stm32), native code loaded from an .mpy file may be reclaimed by the GC because there's no reference to the very start of the native machine code block that is reachable from root pointers (only pointers to internal parts of the machine code block are reachable, but that doesn't help the GC find the memory). This commit fixes this issue by maintaining an explicit list of root pointers pointing to native code that is loaded from an .mpy file. This is not needed for all ports so is selectable by the new configuration option MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE. It's enabled by default if a port does not specify any special functions to allocate or commit executable memory. A test is included to test that native code loaded from an .mpy file does not get reclaimed by the GC. Fixes #6045. Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/persistentcode.c')
-rw-r--r--py/persistentcode.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/py/persistentcode.c b/py/persistentcode.c
index 386ea4947..da3234a5f 100644
--- a/py/persistentcode.c
+++ b/py/persistentcode.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013-2016 Damien P. George
+ * Copyright (c) 2013-2020 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -516,6 +516,18 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) {
fun_data = MP_PLAT_COMMIT_EXEC(fun_data, fun_data_len, opt_ri);
#else
if (prelude.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));
+ #endif
+ // Do the relocations.
mp_native_relocate(&ri, fun_data, (uintptr_t)fun_data);
}
#endif