Skip to content

Commit 416465d

Browse files
committed
py/emitglue: Provide a truncated mp_raw_code_t for non-asm code.
The `asm_n_pos_args` and `asm_type_sig` members of `mp_raw_code_t` are only used for raw codes of type MP_CODE_NATIVE_ASM, which are rare, for example in frozen code. So using a truncated `mp_raw_code_t` in these cases helps to reduce frozen code size on targets that have MICROPY_EMIT_INLINE_ASM enabled. With this, change in firmware size of RPI_PICO builds is -648. Signed-off-by: Damien George <damien@micropython.org>
1 parent 39bf055 commit 416465d

3 files changed

Lines changed: 35 additions & 9 deletions

File tree

py/dynruntime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ static inline void *mp_obj_malloc_helper_dyn(size_t num_bytes, const mp_obj_type
207207

208208
#define MP_DYNRUNTIME_INIT_ENTRY \
209209
mp_obj_t old_globals = mp_fun_table.swap_globals(self->context->module.globals); \
210-
mp_raw_code_t rc; \
210+
mp_raw_code_truncated_t rc; \
211211
rc.kind = MP_CODE_NATIVE_VIPER; \
212212
rc.scope_flags = 0; \
213213
(void)rc;
@@ -217,7 +217,7 @@ static inline void *mp_obj_malloc_helper_dyn(size_t num_bytes, const mp_obj_type
217217
return mp_const_none;
218218

219219
#define MP_DYNRUNTIME_MAKE_FUNCTION(f) \
220-
(mp_make_function_from_raw_code((rc.fun_data = (f), &rc), self->context, NULL))
220+
(mp_make_function_from_raw_code((rc.fun_data = (f), (const mp_raw_code_t *)&rc), self->context, NULL))
221221

222222
#define mp_import_name(name, fromlist, level) \
223223
(mp_fun_table.import_name((name), (fromlist), (level)))

py/emitglue.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,29 @@ typedef struct _mp_raw_code_t {
8484
#endif
8585
} mp_raw_code_t;
8686

87+
// Version of mp_raw_code_t but without the asm_n_pos_args/asm_type_sig entries, which are
88+
// only needed when the kind is MP_CODE_NATIVE_ASM. So this struct can be used when the
89+
// kind is MP_CODE_BYTECODE, MP_CODE_NATIVE_PY or MP_CODE_NATIVE_VIPER, to reduce its size.
90+
typedef struct _mp_raw_code_truncated_t {
91+
uint32_t kind : 3;
92+
uint32_t scope_flags : 7;
93+
const void *fun_data;
94+
struct _mp_raw_code_t **children;
95+
#if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS
96+
uint32_t fun_data_len;
97+
#endif
98+
#if MICROPY_PERSISTENT_CODE_SAVE
99+
uint16_t n_children;
100+
#if MICROPY_EMIT_MACHINE_CODE
101+
uint16_t prelude_offset;
102+
#endif
103+
#if MICROPY_PY_SYS_SETTRACE
104+
uint32_t line_of_definition;
105+
mp_bytecode_prelude_t prelude;
106+
#endif
107+
#endif
108+
} mp_raw_code_truncated_t;
109+
87110
mp_raw_code_t *mp_emit_glue_new_raw_code(void);
88111

89112
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code,

tools/mpy-tool.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ def freeze(self, compiled_module_index):
683683
else:
684684
print(" .obj_table = NULL,")
685685
print(" },")
686-
print(" .rc = &raw_code_%s," % self.raw_code.escaped_name)
686+
print(" .rc = (const mp_raw_code_t *)&raw_code_%s," % self.raw_code.escaped_name)
687687
print("};")
688688

689689
def freeze_constant_obj(self, obj_name, obj):
@@ -898,15 +898,19 @@ def freeze_children(self, prelude_ptr=None):
898898
print()
899899
print("static const mp_raw_code_t *const children_%s[] = {" % self.escaped_name)
900900
for rc in self.children:
901-
print(" &raw_code_%s," % rc.escaped_name)
901+
print(" (const mp_raw_code_t *)&raw_code_%s," % rc.escaped_name)
902902
if prelude_ptr:
903903
print(" (void *)%s," % prelude_ptr)
904904
print("};")
905905
print()
906906

907907
def freeze_raw_code(self, prelude_ptr=None, type_sig=0):
908908
# Generate mp_raw_code_t.
909-
print("static const mp_raw_code_t raw_code_%s = {" % self.escaped_name)
909+
if self.code_kind == MP_CODE_NATIVE_ASM:
910+
raw_code_type = "mp_raw_code_t"
911+
else:
912+
raw_code_type = "mp_raw_code_truncated_t"
913+
print("static const %s raw_code_%s = {" % (raw_code_type, self.escaped_name))
910914
print(" .kind = %s," % RawCode.code_kind_str[self.code_kind])
911915
print(" .scope_flags = 0x%02x," % self.scope_flags)
912916
print(" .fun_data = fun_data_%s," % self.escaped_name)
@@ -949,10 +953,9 @@ def freeze_raw_code(self, prelude_ptr=None, type_sig=0):
949953
print(" },")
950954
print(" #endif")
951955
print(" #endif")
952-
print(" #if MICROPY_EMIT_INLINE_ASM")
953-
print(" .asm_n_pos_args = %u," % self.n_pos_args)
954-
print(" .asm_type_sig = %u," % type_sig)
955-
print(" #endif")
956+
if self.code_kind == MP_CODE_NATIVE_ASM:
957+
print(" .asm_n_pos_args = %u," % self.n_pos_args)
958+
print(" .asm_type_sig = %u," % type_sig)
956959
print("};")
957960

958961
global raw_code_count, raw_code_content

0 commit comments

Comments
 (0)