summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitbc.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-04-13 11:04:33 +0100
committerDamien George <damien.p.george@gmail.com>2014-04-13 11:04:33 +0100
commitdf8127a17eeb3057e820180e318ec3d915111b6a (patch)
tree55fa023ce2de910492c9c713bfa15f6e6df475c2 /py/emitbc.c
parent68e7c5146ce24a593889df67d50d8f9c0cfa528e (diff)
downloadmicropython-df8127a17eeb3057e820180e318ec3d915111b6a.tar.gz
micropython-df8127a17eeb3057e820180e318ec3d915111b6a.zip
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.
Diffstat (limited to 'py/emitbc.c')
-rw-r--r--py/emitbc.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/py/emitbc.c b/py/emitbc.c
index d1d59ef4a5..2d71d86855 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -9,10 +9,11 @@
#include "qstr.h"
#include "lexer.h"
#include "parse.h"
+#include "obj.h"
+#include "emitglue.h"
#include "scope.h"
#include "runtime0.h"
#include "emit.h"
-#include "emitglue.h"
#include "bc0.h"
struct _emit_t {
@@ -65,6 +66,10 @@ STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_writ
}
}
+STATIC void emit_align_code_info_to_machine_word(emit_t* emit) {
+ emit->code_info_offset = (emit->code_info_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1));
+}
+
STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
byte* c = emit_get_cur_to_write_code_info(emit, 4);
// 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
}
}
+STATIC void emit_align_byte_code_to_machine_word(emit_t* emit) {
+ emit->byte_code_offset = (emit->byte_code_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1));
+}
+
STATIC void emit_write_byte_code_byte(emit_t* emit, byte b1) {
byte* c = emit_get_cur_to_write_byte_code(emit, 1);
c[0] = b1;
@@ -158,6 +167,14 @@ STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) {
emit_write_byte_code_uint(emit, num);
}
+// aligns the pointer so it is friendly to GC
+STATIC void emit_write_byte_code_byte_ptr(emit_t* emit, byte b, void *ptr) {
+ emit_write_byte_code_byte(emit, b);
+ emit_align_byte_code_to_machine_word(emit);
+ machine_uint_t *c = (machine_uint_t*)emit_get_cur_to_write_byte_code(emit, sizeof(machine_uint_t));
+ *c = (machine_uint_t)ptr;
+}
+
/* currently unused
STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) {
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
} else {
byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3;
}
- byte* c = emit_get_cur_to_write_byte_code(emit, 3);
+ byte *c = emit_get_cur_to_write_byte_code(emit, 3);
c[0] = b1;
c[1] = byte_code_offset;
c[2] = byte_code_offset >> 8;
@@ -269,19 +286,20 @@ STATIC void emit_bc_end_pass(emit_t *emit) {
}
emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info
+ emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned
if (emit->pass == PASS_2) {
// calculate size of code in bytes
emit->code_info_size = emit->code_info_offset;
emit->byte_code_size = emit->byte_code_offset;
- emit->code_base = m_new(byte, emit->code_info_size + emit->byte_code_size);
+ emit->code_base = m_new0(byte, emit->code_info_size + emit->byte_code_size);
} else if (emit->pass == PASS_3) {
qstr *arg_names = m_new(qstr, emit->scope->num_params);
for (int i = 0; i < emit->scope->num_params; i++) {
arg_names[i] = emit->scope->id_info[i].qstr;
}
- mp_emit_glue_assign_byte_code(emit->scope->unique_code_id, emit->code_base,
+ mp_emit_glue_assign_byte_code(emit->scope->raw_code, emit->code_base,
emit->code_info_size + emit->byte_code_size,
emit->scope->num_params, emit->scope->num_locals,
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) {
STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
emit_bc_pre(emit, 1);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION, scope->raw_code);
} else {
if (n_pos_defaults == 0) {
// 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
emit_bc_load_null(emit);
}
emit_bc_pre(emit, -1);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
}
}
STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) {
if (n_pos_defaults == 0 && n_kw_defaults == 0) {
emit_bc_pre(emit, 0);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE, scope->raw_code);
} else {
if (n_pos_defaults == 0) {
// 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
emit_bc_rot_two(emit);
}
emit_bc_pre(emit, -2);
- emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id);
+ emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
}
}