summaryrefslogtreecommitdiffstatshomepage
path: root/py/objgenerator.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/objgenerator.c
parenteeff0c352845649a3ae7b2e325361744d2db114b (diff)
downloadmicropython-71a3d6ec3bd02c5bd13334537e1bd146bb643bad.tar.gz
micropython-71a3d6ec3bd02c5bd13334537e1bd146bb643bad.zip
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/objgenerator.c')
-rw-r--r--py/objgenerator.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 654b186703..2baead2315 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -67,9 +67,9 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
o->base.type = &mp_type_gen_instance;
o->globals = self_fun->globals;
- o->code_state.n_state = n_state;
- o->code_state.ip = (byte*)(ip - self_fun->bytecode); // offset to prelude
- mp_setup_code_state(&o->code_state, self_fun, n_args, n_kw, args);
+ o->code_state.fun_bc = self_fun;
+ o->code_state.ip = 0;
+ mp_setup_code_state(&o->code_state, n_args, n_kw, args);
return MP_OBJ_FROM_PTR(o);
}
@@ -92,7 +92,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
STATIC void gen_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in);
- mp_printf(print, "<generator object '%q' at %p>", mp_obj_code_get_name(self->code_state.code_info), self);
+ mp_printf(print, "<generator object '%q' at %p>", mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self);
}
mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
@@ -134,10 +134,13 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
}
break;
- case MP_VM_RETURN_EXCEPTION:
+ case MP_VM_RETURN_EXCEPTION: {
+ const byte *bc = self->code_state.fun_bc->bytecode;
+ size_t n_state = mp_decode_uint(&bc);
self->code_state.ip = 0;
- *ret_val = self->code_state.state[self->code_state.n_state - 1];
+ *ret_val = self->code_state.state[n_state - 1];
break;
+ }
}
return ret_kind;