8000 py/persistnative: Load qstrs separately · dpgeorge/micropython@ddbafcf · GitHub
[go: up one dir, main page]

Skip to content

Commit ddbafcf

Browse files
committed
py/persistnative: Load qstrs separately
This costs 20 bytes on a Cortex-M0 but saves 94 bytes of file size in the modx example.
1 parent ff3740d commit ddbafcf

File tree

6 files changed

+42
-15
lines changed

6 files changed

+42
-15
lines changed

examples/modx/elftompy.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,28 @@ def to_uint(n):
2424
b[-1] &= 0x7f # clear high bit: it's the last byte
2525
return bytes(b)
2626

27+
def align(n, a):
28+
return (n + a - 1) // a * a
29+
2730
def process_file(filename):
2831
with open(filename, 'rb') as f:
2932
header = f.read(6)
3033
num_qstrs = struct.unpack('H', f.read(2))[0]
31-
data = f.read()
34+
qstr_strings_len = struct.unpack('Q', f.read(8))[0]
35+
qstr_buffer_len = align(qstr_strings_len, 8)
36+
qstrbuf = f.read(qstr_buffer_len)[:qstr_strings_len]
37+
text = f.read()
38+
qstrs = qstrbuf.rstrip('\0').split(b'\0')
39+
if len(qstrs) != num_qstrs:
40+
raise ValueError('expected len(qstrs) == num_qstrs')
3241
with open(filename, 'wb') as f:
3342
f.write(header)
3443
f.write(to_uint(num_qstrs))
35-
f.write(to_uint(len(data)))
36-
f.write(data)
44+
for qstr in qstrs:
45+
f.write(to_uint(len(qstr)))
46+
f.write(qstr)
47+
f.write(to_uint(len(text)))
48+
f.write(text)
3749

3850
if __name__ == '__main__':
3951
process_file(sys.argv[1])

examples/modx/modx.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ enum {
1414
MP_LOCAL_QSTR_number_of,
1515
};
1616

17+
__attribute__((section(".qstr")))
18+
struct {
19+
#define QDEF(id, str) const char id[sizeof(str)];
20+
QSTR_DEFINES
21+
#undef QDEF
22+
} QSTR_VALUE = {
23+
#define QDEF(id, str) str,
24+
QSTR_DEFINES
25+
#undef QDEF
26+
};
27+
1728
STATIC mp_obj_t modx_add1(CONTEXT mp_obj_t x) {
1829
return RT(mp_binary_op)(MP_BINARY_OP_ADD, x, MP_OBJ_NEW_SMALL_INT(1));
1930
}
@@ -34,14 +45,6 @@ MP_PERSISTENT_NATIVE_HEADER
3445

3546
MP_PERSISTENT_NATIVE_INIT
3647
void init(CONTEXT_ALONE) {
37-
// create qstrs
38-
{
39-
qstr *q = pnd->qstr_table;
40-
#define QDEF(id, str) *q++ = RT(qstr_from_str)(str);
41-
QSTR_DEFINES
42-
#undef QDEF
43-
}
44-
4548
// constants
4649
RT(mp_store_global)(QSTR(VAL1), CONST(_true));
4750
RT(mp_store_global)(QSTR(VAL2), MP_OBJ_NEW_SMALL_INT(123));

examples/modx/persistnative.ld

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ SECTIONS
88
{
99
. = ALIGN(4);
1010
KEEP(*(.mpyheader))
11+
QUAD(_qstr_end - _qstr_start)
12+
_qstr_start = .;
13+
KEEP(*(.qstr))
14+
_qstr_end = .;
15+
. = ALIGN(8);
1116
KEEP(*(.mpytext))
1217
*(.text*)
1318
*(.rodata*)

py/emitglue.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ typedef struct _mp_persistent_native_data_t {
4747
void *data;
4848
} mp_persistent_native_data_t;
4949

50-
mp_persistent_native_data_t *mp_new_persistent_native_data(size_t num_qstrs);
50+
mp_persistent_native_data_t *mp_new_persistent_native_data(qstr *qstr_table);
5151
#endif
5252

5353
typedef struct _mp_raw_code_t {

py/nativeglue.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,10 @@ const void *const mp_fun_table[MP_F_NUMBER_OF] = {
184184
};
185185

186186
#if MICROPY_PERSISTENT_NATIVE
187-
mp_persistent_native_data_t *mp_new_persistent_native_data(size_t num_qstrs) {
187+
mp_persistent_native_data_t *mp_new_persistent_native_data(qstr *qstr_table) {
188188
mp_persistent_native_data_t *data = m_new_obj(mp_persistent_native_data_t);
189189
data->fun_table = mp_fun_table;
190-
data->qstr_table = m_new0(qstr, num_qstrs);
190+
data->qstr_table = qstr_table;
191191
data->data = NULL;
192192
return data;
193193
}

py/persistentcode.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,14 @@ mp_raw_code_t *load_raw_code_native(mp_reader_t *reader) {
217217
if (arch != MP_PERSISTENT_ARCH_CURRENT) {
< A3E2 /code>
218218
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, ".mpy has wrong arch"));
219219
}
220+
221+
// load qstrs
220222
uint num_qstrs = read_uint(reader);
223+
qstr *qstr_table = m_new0(qstr, num_qstrs);
224+
qstr *q = qstr_table;
225+
for (size_t i=0; i<num_qstrs; i++) {
226+
*q++ = load_qstr(reader);
227+
}
221228

222229
// load machine code
223230
mp_uint_t len = read_uint(reader);
@@ -226,7 +233,7 @@ mp_raw_code_t *load_raw_code_native(mp_reader_t *reader) {
226233
MP_PLAT_ALLOC_EXEC(len, &data, &alloc);
227234
read_bytes(reader, data, len);
228235

229-
mp_persistent_native_data_t *per_nat_data = mp_new_persistent_native_data(num_qstrs);
236+
mp_persistent_native_data_t *per_nat_data = mp_new_persistent_native_data(qstr_table);
230237

231238
// create raw_code and return it
232239
mp_raw_code_t *rc = mp_emit_glue_new_raw_code();

0 commit comments

Comments
 (0)
0