aboutsummaryrefslogtreecommitdiff
path: root/py/bc.h
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/bc.h
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/bc.h')
-rw-r--r--py/bc.h12
1 files changed, 7 insertions, 5 deletions
diff --git a/py/bc.h b/py/bc.h
index c7dffbac5..996b1a2f3 100644
--- a/py/bc.h
+++ b/py/bc.h
@@ -28,6 +28,7 @@
#include "py/runtime.h"
#include "py/obj.h"
+#include "py/objfun.h"
// bytecode layout:
//
@@ -70,9 +71,12 @@ typedef struct _mp_exc_stack_t {
} mp_exc_stack_t;
typedef struct _mp_code_state_t {
- const byte *code_info;
+ // The fun_bc entry points to the underlying function object that is being executed.
+ // It is needed to access the start of bytecode and the const_table.
+ // It is also needed to prevent the GC from reclaiming the bytecode during execution,
+ // because the ip pointer below will always point to the interior of the bytecode.
+ mp_obj_fun_bc_t *fun_bc;
const byte *ip;
- const mp_uint_t *const_table;
mp_obj_t *sp;
// bit 0 is saved currently_in_except_block value
mp_exc_stack_t *exc_sp;
@@ -80,7 +84,6 @@ typedef struct _mp_code_state_t {
#if MICROPY_STACKLESS
struct _mp_code_state_t *prev;
#endif
- size_t n_state;
// Variable-length
mp_obj_t state[0];
// Variable-length, never accessed by name, only as (void*)(state + n_state)
@@ -91,8 +94,7 @@ mp_uint_t mp_decode_uint(const byte **ptr);
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc);
mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args);
-struct _mp_obj_fun_bc_t;
-void mp_setup_code_state(mp_code_state_t *code_state, struct _mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args);
+void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args);
void mp_bytecode_print(const void *descr, const byte *code, mp_uint_t len, const mp_uint_t *const_table);
void mp_bytecode_print2(const byte *code, size_t len, const mp_uint_t *const_table);
const byte *mp_bytecode_print_str(const byte *ip);