diff options
author | Damien George <damien@micropython.org> | 2022-05-10 13:56:24 +1000 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2022-05-17 16:44:49 +1000 |
commit | 1fb01bd6c5dc350f3c617ca8edae8dea9e5516ae (patch) | |
tree | d6d936d44bebbcf1e965e88d4ceffd27aad90800 /py/objgenerator.c | |
parent | 8725a32f41de6c4ea720945f2c81edd08d349895 (diff) |
py/emitnative: Put a pointer to the native prelude in child_table array.
Some architectures (like esp32 xtensa) cannot read byte-wise from
executable memory. This means the prelude for native functions -- which is
usually located after the machine code for the native function -- must be
placed in separate memory that can be read byte-wise. Prior to this commit
this was achieved by enabling N_PRELUDE_AS_BYTES_OBJ for the emitter and
MICROPY_EMIT_NATIVE_PRELUDE_AS_BYTES_OBJ for the runtime. The prelude was
then placed in a bytes object, pointed to by the module's constant table.
This behaviour is changed by this commit so that a pointer to the prelude
is stored either in mp_obj_fun_bc_t.child_table, or in
mp_obj_fun_bc_t.child_table[num_children] if num_children > 0. The reasons
for doing this are:
1. It decouples the native emitter from runtime requirements, the emitted
code no longer needs to know if the system it runs on can/can't read
byte-wise from executable memory.
2. It makes all ports have the same emitter behaviour, there is no longer
the N_PRELUDE_AS_BYTES_OBJ option.
3. The module's constant table is now used only for actual constants in the
Python code. This allows further optimisations to be done with the
constants (eg constant deduplication).
Code size change for those ports that enable the native emitter:
unix x64: +80 +0.015%
stm32: +24 +0.004% PYBV10
esp8266: +88 +0.013% GENERIC
esp32: -20 -0.002% GENERIC[incl -112(data)]
rp2: +32 +0.005% PICO
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/objgenerator.c')
-rw-r--r-- | py/objgenerator.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/py/objgenerator.c b/py/objgenerator.c index 12fd81a8b..802fd45bb 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -98,14 +98,13 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k mp_obj_fun_bc_t *self_fun = MP_OBJ_TO_PTR(self_in); // Determine start of prelude. - uintptr_t prelude_offset = ((uintptr_t *)self_fun->bytecode)[0]; - #if MICROPY_EMIT_NATIVE_PRELUDE_AS_BYTES_OBJ - // Prelude is in bytes object in const_table, at index prelude_offset - mp_obj_str_t *prelude_bytes = MP_OBJ_TO_PTR(self_fun->context->constants.obj_table[prelude_offset]); - const uint8_t *prelude_ptr = prelude_bytes->data; - #else - const uint8_t *prelude_ptr = self_fun->bytecode + prelude_offset; - #endif + uintptr_t prelude_ptr_index = ((uintptr_t *)self_fun->bytecode)[0]; + const uint8_t *prelude_ptr; + if (prelude_ptr_index == 0) { + prelude_ptr = (void *)self_fun->child_table; + } else { + prelude_ptr = (void *)self_fun->child_table[prelude_ptr_index]; + } // Extract n_state from the prelude. const uint8_t *ip = prelude_ptr; |