summaryrefslogtreecommitdiff
path: root/py/emitnative.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-03-17 14:54:53 +1100
committerDamien George <damien.p.george@gmail.com>2017-03-17 16:39:13 +1100
commit71a3d6ec3bd02c5bd13334537e1bd146bb643bad (patch)
tree34880f7950ba32866608fafd0bca6d0e11099533 /py/emitnative.c
parenteeff0c352845649a3ae7b2e325361744d2db114b (diff)
py: Reduce size of mp_code_state_t structure.
Instead of caching data that is constant (code_info, const_table and n_state), store just a pointer to the underlying function object from which this data can be derived. This helps reduce stack usage for the case when the mp_code_state_t structure is stored on the stack, as well as heap usage when it's stored on the heap. The downside is that the VM becomes a little more complex because it now needs to derive the data from the underlying function object. But this doesn't impact the performance by much (if at all) because most of the decoding of data is done outside the main opcode loop. Measurements using pystone show that little to no performance is lost. This patch also fixes a nasty bug whereby the bytecode can be reclaimed by the GC during execution. With this patch there is always a pointer to the function object held by the VM during execution, since it's stored in the mp_code_state_t structure.
Diffstat (limited to 'py/emitnative.c')
-rw-r--r--py/emitnative.c35
1 files changed, 12 insertions, 23 deletions
diff --git a/py/emitnative.c b/py/emitnative.c
index 55eb6cadf..4af68102b 100644
--- a/py/emitnative.c
+++ b/py/emitnative.c
@@ -407,43 +407,29 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
#endif
// prepare incoming arguments for call to mp_setup_code_state
+
#if N_X86
- asm_x86_mov_arg_to_r32(emit->as, 0, REG_ARG_2);
- asm_x86_mov_arg_to_r32(emit->as, 1, REG_ARG_3);
- asm_x86_mov_arg_to_r32(emit->as, 2, REG_ARG_4);
- asm_x86_mov_arg_to_r32(emit->as, 3, REG_ARG_5);
- #else
- #if N_THUMB
- ASM_MOV_REG_REG(emit->as, ASM_THUMB_REG_R4, REG_ARG_4);
- #elif N_ARM
- ASM_MOV_REG_REG(emit->as, ASM_ARM_REG_R4, REG_ARG_4);
- #else
- ASM_MOV_REG_REG(emit->as, REG_ARG_5, REG_ARG_4);
- #endif
- ASM_MOV_REG_REG(emit->as, REG_ARG_4, REG_ARG_3);
- ASM_MOV_REG_REG(emit->as, REG_ARG_3, REG_ARG_2);
- ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_ARG_1);
+ asm_x86_mov_arg_to_r32(emit->as, 0, REG_ARG_1);
+ asm_x86_mov_arg_to_r32(emit->as, 1, REG_ARG_2);
+ asm_x86_mov_arg_to_r32(emit->as, 2, REG_ARG_3);
+ asm_x86_mov_arg_to_r32(emit->as, 3, REG_ARG_4);
#endif
+ // set code_state.fun_bc
+ ASM_MOV_REG_TO_LOCAL(emit->as, REG_ARG_1, offsetof(mp_code_state_t, fun_bc) / sizeof(uintptr_t));
+
// set code_state.ip (offset from start of this function to prelude info)
// XXX this encoding may change size
- ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->prelude_offset, offsetof(mp_code_state_t, ip) / sizeof(mp_uint_t), REG_ARG_1);
-
- // set code_state.n_state
- ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->n_state, offsetof(mp_code_state_t, n_state) / sizeof(mp_uint_t), REG_ARG_1);
+ ASM_MOV_IMM_TO_LOCAL_USING(emit->as, emit->prelude_offset, offsetof(mp_code_state_t, ip) / sizeof(uintptr_t), REG_ARG_1);
// put address of code_state into first arg
ASM_MOV_LOCAL_ADDR_TO_REG(emit->as, 0, REG_ARG_1);
// call mp_setup_code_state to prepare code_state structure
#if N_THUMB
- asm_thumb_op16(emit->as, 0xb400 | (1 << ASM_THUMB_REG_R4)); // push 5th arg
asm_thumb_bl_ind(emit->as, mp_fun_table[MP_F_SETUP_CODE_STATE], MP_F_SETUP_CODE_STATE, ASM_THUMB_REG_R4);
- asm_thumb_op16(emit->as, 0xbc00 | (1 << REG_RET)); // pop dummy (was 5th arg)
#elif N_ARM
- asm_arm_push(emit->as, 1 << ASM_ARM_REG_R4); // push 5th arg
asm_arm_bl_ind(emit->as, mp_fun_table[MP_F_SETUP_CODE_STATE], MP_F_SETUP_CODE_STATE, ASM_ARM_REG_R4);
- asm_arm_pop(emit->as, 1 << REG_RET); // pop dummy (was 5th arg)
#else
ASM_CALL_IND(emit->as, mp_fun_table[MP_F_SETUP_CODE_STATE], MP_F_SETUP_CODE_STATE);
#endif
@@ -477,6 +463,9 @@ STATIC void emit_native_end_pass(emit_t *emit) {
if (!emit->do_viper_types) {
emit->prelude_offset = mp_asm_base_get_code_pos(&emit->as->base);
+ mp_asm_base_data(&emit->as->base, 1, 0x80 | ((emit->n_state >> 7) & 0x7f));
+ mp_asm_base_data(&emit->as->base, 1, emit->n_state & 0x7f);
+ mp_asm_base_data(&emit->as->base, 1, 0); // n_exc_stack
mp_asm_base_data(&emit->as->base, 1, emit->scope->scope_flags);
mp_asm_base_data(&emit->as->base, 1, emit->scope->num_pos_args);
mp_asm_base_data(&emit->as->base, 1, emit->scope->num_kwonly_args);