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.
This commit is contained in:
Damien George
2017-03-17 14:54:53 +11:00
parent eeff0c3528
commit 71a3d6ec3b
6 changed files with 62 additions and 59 deletions

View File

@@ -220,9 +220,9 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
return NULL;
}
code_state->ip = (byte*)(ip - self->bytecode); // offset to after n_state/n_exc_stack
code_state->n_state = n_state;
mp_setup_code_state(code_state, self, n_args, n_kw, args);
code_state->fun_bc = self;
code_state->ip = 0;
mp_setup_code_state(code_state, n_args, n_kw, args);
// execute the byte code with the correct globals context
code_state->old_globals = mp_globals_get();
@@ -265,9 +265,9 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
state_size = 0; // indicate that we allocated using alloca
}
code_state->ip = (byte*)(ip - self->bytecode); // offset to after n_state/n_exc_stack
code_state->n_state = n_state;
mp_setup_code_state(code_state, self, n_args, n_kw, args);
code_state->fun_bc = self;
code_state->ip = 0;
mp_setup_code_state(code_state, n_args, n_kw, args);
// execute the byte code with the correct globals context
code_state->old_globals = mp_globals_get();