diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/mpconfig.h | 12 | ||||
-rw-r--r-- | py/mpstate.h | 5 | ||||
-rw-r--r-- | py/persistentcode.c | 14 | ||||
-rw-r--r-- | py/runtime.c | 4 |
4 files changed, 34 insertions, 1 deletions
diff --git a/py/mpconfig.h b/py/mpconfig.h index 287b15aae..3d9ce8bb5 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -351,6 +351,18 @@ // Convenience definition for whether any native or inline assembler emitter is enabled #define MICROPY_EMIT_MACHINE_CODE (MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM) +// Whether native relocatable code loaded from .mpy files is explicitly tracked +// so that the GC cannot reclaim it. Needed on architectures that allocate +// executable memory on the MicroPython heap and don't explicitly track this +// data some other way. +#ifndef MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE +#if !MICROPY_EMIT_MACHINE_CODE || defined(MP_PLAT_ALLOC_EXEC) || defined(MP_PLAT_COMMIT_EXEC) +#define MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE (0) +#else +#define MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE (1) +#endif +#endif + /*****************************************************************************/ /* Compiler configuration */ diff --git a/py/mpstate.h b/py/mpstate.h index 5f6cf5593..2519c77e2 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -167,6 +167,11 @@ typedef struct _mp_state_vm_t { mp_obj_dict_t *mp_module_builtins_override_dict; #endif + #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_obj_t track_reloc_code_list; + #endif + // include any root pointers defined by a port MICROPY_PORT_ROOT_POINTERS 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 diff --git a/py/runtime.c b/py/runtime.c index 78da38691..38da2f453 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -106,6 +106,10 @@ void mp_init(void) { MP_STATE_VM(mp_module_builtins_override_dict) = NULL; #endif + #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE + MP_STATE_VM(track_reloc_code_list) = MP_OBJ_NULL; + #endif + #if MICROPY_PY_OS_DUPTERM for (size_t i = 0; i < MICROPY_PY_OS_DUPTERM; ++i) { MP_STATE_VM(dupterm_objs[i]) = MP_OBJ_NULL; |