From 41d02b654e5c844f85fbb79283eaebf35af60fbb Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 24 Jan 2014 22:42:28 +0000 Subject: [PATCH] py: Improve freeing of emitters in mp_compile. There can be multiple emitters allocated during compile (eg byte code and native). --- py/compile.c | 31 ++++++++++++++++++++++++++----- py/emit.h | 10 +++++++--- py/emitbc.c | 4 +--- py/emitcpy.c | 2 -- py/emitinlinethumb.c | 10 ++++++++-- py/emitnative.c | 4 +--- py/emitpass1.c | 2 -- 7 files changed, 43 insertions(+), 20 deletions(-) diff --git a/py/compile.c b/py/compile.c index e8a5197841..e1b62a11bf 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3154,11 +3154,28 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) { } } - bool had_error = comp->had_error; - if (comp->emit_method_table->free != NULL) { - comp->emit_method_table->free(comp->emit); + // free the emitters +#if !MICROPY_EMIT_CPYTHON + if (emit_bc != NULL) { + emit_bc_free(emit_bc); } - m_del_obj(compiler_t, comp); +#if MICROPY_EMIT_NATIVE + if (emit_native != NULL) { +#if MICROPY_EMIT_X64 + emit_native_x64_free(emit_native); +#elif MICROPY_EMIT_THUMB + emit_native_thumb_free(emit_native); +#endif + } +#endif +#if MICROPY_EMIT_INLINE_THUMB + if (emit_inline_thumb != NULL) { + emit_inline_thumb_free(emit_inline_thumb); + } +#endif +#endif // !MICROPY_EMIT_CPYTHON + + // free the scopes uint unique_code_id = module_scope->unique_code_id; for (scope_t *s = module_scope; s;) { scope_t *next = s->next; @@ -3166,13 +3183,17 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) { s = next; } + // free the compiler + bool had_error = comp->had_error; + m_del_obj(compiler_t, comp); + if (had_error) { // TODO return a proper error message return mp_const_none; } else { #if MICROPY_EMIT_CPYTHON // can't create code, so just return true - (void)unique_code_id; // to suppress warning that module_scope is unused + (void)unique_code_id; // to suppress warning that unique_code_id is unused return mp_const_true; #else // return function that executes the outer module diff --git a/py/emit.h b/py/emit.h index c4d38530cd..fc5538f586 100644 --- a/py/emit.h +++ b/py/emit.h @@ -17,8 +17,6 @@ typedef enum { typedef struct _emit_t emit_t; typedef struct _emit_method_table_t { - void (*free)(emit_t *emit); - void (*set_native_types)(emit_t *emit, bool do_native_types); void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope); void (*end_pass)(emit_t *emit); @@ -120,12 +118,16 @@ extern const emit_method_table_t emit_native_x64_method_table; extern const emit_method_table_t emit_native_thumb_method_table; emit_t *emit_pass1_new(qstr qstr___class__); -void emit_pass1_free(emit_t *emit); emit_t *emit_cpython_new(uint max_num_labels); emit_t *emit_bc_new(uint max_num_labels); emit_t *emit_native_x64_new(uint max_num_labels); emit_t *emit_native_thumb_new(uint max_num_labels); +void emit_pass1_free(emit_t *emit); +void emit_bc_free(emit_t *emit); +void emit_native_x64_free(emit_t *emit); +void emit_native_thumb_free(emit_t *emit); + typedef struct _emit_inline_asm_t emit_inline_asm_t; typedef struct _emit_inline_asm_method_table_t { @@ -139,3 +141,5 @@ typedef struct _emit_inline_asm_method_table_t { extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table; emit_inline_asm_t *emit_inline_thumb_new(uint max_num_labels); +void emit_inline_thumb_free(emit_inline_asm_t *emit); + diff --git a/py/emitbc.c b/py/emitbc.c index d66202eb2a..10a95fbcfa 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -43,7 +43,7 @@ emit_t *emit_bc_new(uint max_num_labels) { return emit; } -static void emit_bc_free(emit_t *emit) { +void emit_bc_free(emit_t *emit) { m_del(uint, emit->label_offsets, emit->max_num_labels); m_del_obj(emit_t, emit); } @@ -756,8 +756,6 @@ static void emit_bc_yield_from(emit_t *emit) { } const emit_method_table_t emit_bc_method_table = { - emit_bc_free, - emit_bc_set_native_types, emit_bc_start_pass, emit_bc_end_pass, diff --git a/py/emitcpy.c b/py/emitcpy.c index 6984ebf4bd..de2a5784db 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -796,8 +796,6 @@ static void emit_cpy_yield_from(emit_t *emit) { } const emit_method_table_t emit_cpython_method_table = { - NULL, - emit_cpy_set_native_types, emit_cpy_start_pass, emit_cpy_end_pass, diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 9d5a4206a0..c35192210c 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -20,13 +20,13 @@ struct _emit_inline_asm_t { int pass; scope_t *scope; - int max_num_labels; + uint max_num_labels; qstr *label_lookup; asm_thumb_t *as; }; emit_inline_asm_t *emit_inline_thumb_new(uint max_num_labels) { - emit_inline_asm_t *emit = m_new(emit_inline_asm_t, 1); + emit_inline_asm_t *emit = m_new_obj(emit_inline_asm_t); emit->max_num_labels = max_num_labels; emit->label_lookup = m_new(qstr, max_num_labels); memset(emit->label_lookup, 0, emit->max_num_labels * sizeof(qstr)); @@ -34,6 +34,12 @@ emit_inline_asm_t *emit_inline_thumb_new(uint max_num_labels) { return emit; } +void emit_inline_thumb_free(emit_inline_asm_t *emit) { + m_del(qstr, emit->label_lookup, emit->max_num_labels); + asm_thumb_free(emit->as, false); + m_del_obj(emit_inline_asm_t, emit); +} + static void emit_inline_thumb_start_pass(emit_inline_asm_t *emit, pass_kind_t pass, scope_t *scope) { emit->pass = pass; emit->scope = scope; diff --git a/py/emitnative.c b/py/emitnative.c index ddda90659e..258aa9fce5 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -146,7 +146,7 @@ emit_t *EXPORT_FUN(new)(uint max_num_labels) { return emit; } -static void emit_native_free(emit_t *emit) { +void EXPORT_FUN(free)(emit_t *emit) { #if N_X64 asm_x64_free(emit->as, false); #elif N_THUMB @@ -1235,8 +1235,6 @@ static void emit_native_yield_from(emit_t *emit) { } const emit_method_table_t EXPORT_FUN(method_table) = { - emit_native_free, - emit_native_set_viper_types, emit_native_start_pass, emit_native_end_pass, diff --git a/py/emitpass1.c b/py/emitpass1.c index 6a26cd155b..38115a51c1 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -97,8 +97,6 @@ static void emit_pass1_delete_id(emit_t *emit, qstr qstr) { } const emit_method_table_t emit_pass1_method_table = { - emit_pass1_free, - (void*)emit_pass1_dummy, emit_pass1_start_pass, emit_pass1_end_pass,