10000 py: Remove unique_codes from emitglue.c. Replace with pointers. · micropython/micropython@df8127a · GitHub
[go: up one dir, main page]

Skip to content

Commit df8127a

Browse files
committed
py: Remove unique_codes from emitglue.c. Replace with pointers.
Attempt to address issue #386. unique_code_id's have been removed and replaced with a pointer to the "raw code" information. This pointer is stored in the actual byte code (aligned, so the GC can trace it), so that raw code (ie byte code, native code and inline assembler) is kept only for as long as it is needed. In memory it's now like a tree: the outer module's byte code points directly to its children's raw code. So when the outer code gets freed, if there are no remaining functions that need the raw code, then the children's code gets freed as well. This is pretty much like CPython does it, except that CPython stores indexes in the byte code rather than machine pointers. These indices index the per-function constant table in order to find the relevant code.
1 parent 68e7c51 commit df8127a

File tree

15 files changed

+149
-171
lines changed

15 files changed

+149
-171
lines changed

py/compile.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
#include "qstr.h"
1111
#include "lexer.h"
1212
#include "parse.h"
13-
#include "scope.h"
1413
#include "runtime0.h"
15-
#include "emit.h"
16-
#include "emitglue.h"
1714
#include "obj.h"
15+
#include "emitglue.h"
16+
#include "scope.h"
17+
#include "emit.h"
1818
#include "compile.h"
1919
#include "runtime.h"
2020
#include "builtin.h"
@@ -283,7 +283,7 @@ STATIC void compile_decrease_except_level(compiler_t *comp) {
283283
}
284284

285285
STATIC scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) {
286-
scope_t *scope = scope_new(kind, pn, comp->source_file, mp_emit_glue_get_unique_code_id(), emit_options);
286+
scope_t *scope = scope_new(kind, pn, comp->source_file, emit_options);
287287
scope->parent = comp->scope_cur;
288288
scope->next = NULL;
289289
if (comp->scope_head == NULL) {
@@ -3454,7 +3454,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
34543454
#endif // !MICROPY_EMIT_CPYTHON
34553455

34563456
// free the scopes
3457-
uint unique_code_id = module_scope->unique_code_id;
3457+
mp_raw_code_t *outer_raw_code = module_scope->raw_code;
34583458
for (scope_t *s = module_scope; s;) {
34593459
scope_t *next = s->next;
34603460
scope_free(s);
@@ -3471,12 +3471,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
34713471
} else {
34723472
#if MICROPY_EMIT_CPYTHON
34733473
// can't create code, so just return true
3474-
(void)unique_code_id; // to suppress warning that unique_code_id is unused
3474+
(void)outer_raw_code; // to suppress warning that outer_raw_code is unused
34753475
return mp_const_true;
34763476
#else
34773477
// return function that executes the outer module
3478-
// we can free the unique_code slot because no-one has reference to this unique_code_id anymore
3479-
return mp_make_function_from_id_and_free(unique_code_id, MP_OBJ_NULL, MP_OBJ_NULL);
3478+
return mp_make_function_from_raw_code(outer_raw_code, MP_OBJ_NULL, MP_OBJ_NULL);
34803479
#endif
34813480
}
34823481
}

py/emitbc.c

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
#include "qstr.h"
1010
#include "lexer.h"
1111
#include "parse.h"
12+
#include "obj.h"
13+
#include "emitglue.h"
1214
#include "scope.h"
1315
#include "runtime0.h"
1416
#include "emit.h"
15-
#include "emitglue.h"
1617
#include "bc0.h"
1718

1819
struct _emit_t {
@@ -65,6 +66,10 @@ STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_writ
6566
}
6667
}
6768

69+
STATIC void emit_align_code_info_to_machine_word(emit_t* emit) {
70+
emit->code_info_offset = (emit->code_info_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1));
71+
}
72+
6873
STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
6974
byte* c = emit_get_cur_to_write_code_info(emit, 4);
7075
// TODO variable length encoding for qstr
@@ -98,6 +103,10 @@ STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_writ
98103
}
99104
}
100105

106+
STATIC void emit_align_byte_code_to_machine_word(emit_t* emit) {
107+
emit->byte_code_offset = (emit->byte_code_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1));
108+
}
109+
101110
STATIC void emit_write_byte_code_byte(emit_t* emit, byte b1) {
102111
byte* c = emit_get_cur_to_write_byte_code(emit, 1);
103112
c[0] = b1;
@@ -158,6 +167,14 @@ STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
158167
emit_write_byte_code_uint(emit, num);
159168
}
160169

170+
// aligns the pointer so it is friendly to GC
171+
STATIC void emit_write_byte_code_byte_ptr(emit_t* emit, byte b, void *ptr) {
172+
emit_write_byte_code_byte(emit, b);
173+
emit_align_byte_code_to_machine_word(emit);
174+
machine_uint_t *c = (machine_uint_t*)emit_get_cur_to_write_byte_code(emit, sizeof(machine_uint_t));
175+
*c = (machine_uint_t)ptr;
176+
}
177+
161178
/* currently unused
162179
STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
163180
emit_write_byte_code_byte(emit, b);
@@ -178,7 +195,7 @@ STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint
178195
} else {
179196
byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3;
180197
}
181-
byte* c = emit_get_cur_to_write_byte_code(emit, 3);
198+
byte *c = emit_get_cur_to_write_byte_code(emit, 3);
182199
c[0] = b1;
183200
c[1] = byte_code_offset;
184201
c[2] = byte_code_offset >> 8;
@@ -269,19 +286,20 @@ STATIC void emit_bc_end_pass(emit_t *emit) {
269286
}
270287

271288
emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info
289+
emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned
272290

273291
if (emit->pass == PASS_2) {
274292
// calculate size of code in bytes
275293
emit->code_info_size = emit->code_info_offset;
276294
emit->byte_code_size = emit->byte_code_offset;
277-
emit->code_base = m_new(byte, emit->code_info_size + emit->byte_code_size);
295+
emit->code_base = m_new0(byte, emit->code_info_size + emit->byte_code_size);
278296

279297
} else if (emit->pass == PASS_3) {
280298
qstr *arg_names = m_new(qstr, emit->scope->num_params);
281299
for (int i = 0; i < emit->scope->num_params; i++) {
282300
arg_names[i] = emit->scope->id_info[i].qstr;
283301
}
284-
mp_emit_glue_assign_byte_code(emit->scope->unique_code_id, emit->code_base,
302+
mp_emit_glue_assign_byte_code(emit->scope->raw_code, emit->code_base,
285303
emit->code_info_size + emit->byte_code_size,
286304
emit->scope->num_params, emit->scope->num_locals,
287305
emit->scope->scope_flags, arg_names);
@@ -733,7 +751,7 @@ STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) {
733751
STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
734752
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
735753
emit_bc_pre(emit, 1);
736-
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
754+
emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION, scope->raw_code);
737755
} else {
738756
if (n_pos_defaults == 0) {
739757
// load dummy entry for non-existent positional default tuple
@@ -744,14 +762,14 @@ STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defau
744762
emit_bc_load_null(emit);
745763
}
746764
emit_bc_pre(emit, -1);
747-
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
765+
emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
748766
}
749767
}
750768

751769
STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
752770
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
753771
emit_bc_pre(emit, 0);
754-
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
772+
emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE, scope->raw_code);
755773
} else {
756774
if (n_pos_defaults == 0) {
757775
// load dummy entry for non-existent positional default tuple
@@ -763,7 +781,7 @@ STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaul
763781
emit_bc_rot_two(emit);
764782
}
765783
emit_bc_pre(emit, -2);
766-
emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id);
784+
emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
767785
}
768786
}
769787

py/emitcommon.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#include "qstr.h"
88
#include "lexer.h"
99
#include "parse.h"
10-
#include "scope.h"
1110
#include "runtime0.h"
11+
#include "obj.h"
12+
#include "emitglue.h"
13+
#include "scope.h"
1214
#include "emit.h"
1315

1416
#define EMIT(fun, ...) (emit_method_table->fun(emit, __VA_ARGS__))

py/emitcpy.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "qstr.h"
1010
#include "lexer.h"
1111
#include "parse.h"
12+
#include "obj.h"
13+
#include "emitglue.h"
1214
#include "scope.h"
1315
#include "runtime0.h"
1416
#include "emit.h"

0 commit comments

Comments
 (0)
0