diff options
author | Damien George <damien.p.george@gmail.com> | 2017-04-19 09:45:59 +1000 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2017-04-22 23:39:20 +1000 |
commit | dd11af209d226b7d18d5148b239662e30ed60bad (patch) | |
tree | 8343a2ce54172f2f3304ca5dba49f352f37b5c17 /py/emitnative.c | |
parent | 5335942b599d85263d3c18eb99ff5ebd04a8bc98 (diff) |
py: Add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls.
This patch allows the following code to run without allocating on the heap:
super().foo(...)
Before this patch such a call would allocate a super object on the heap and
then load the foo method and call it right away. The super object is only
needed to perform the lookup of the method and not needed after that. This
patch makes an optimisation to allocate the super object on the C stack and
discard it right after use.
Changes in code size due to this patch are:
bare-arm: +128
minimal: +232
unix x64: +416
unix nanbox: +364
stmhal: +184
esp8266: +340
cc3200: +128
Diffstat (limited to 'py/emitnative.c')
-rw-r--r-- | py/emitnative.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/py/emitnative.c b/py/emitnative.c index 3ab001f8d..99adc809c 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -85,6 +85,7 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { [MP_F_LOAD_BUILD_CLASS] = 0, [MP_F_LOAD_ATTR] = 2, [MP_F_LOAD_METHOD] = 3, + [MP_F_LOAD_SUPER_METHOD] = 2, [MP_F_STORE_NAME] = 2, [MP_F_STORE_GLOBAL] = 2, [MP_F_STORE_ATTR] = 3, @@ -1065,12 +1066,18 @@ STATIC void emit_native_load_attr(emit_t *emit, qstr qst) { emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } -STATIC void emit_native_load_method(emit_t *emit, qstr qst) { - vtype_kind_t vtype_base; - emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base - assert(vtype_base == VTYPE_PYOBJ); - emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr - emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name +STATIC void emit_native_load_method(emit_t *emit, qstr qst, bool is_super) { + if (is_super) { + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, 3); // arg2 = dest ptr + emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_2, 2); // arg2 = dest ptr + emit_call_with_imm_arg(emit, MP_F_LOAD_SUPER_METHOD, qst, REG_ARG_1); // arg1 = method name + } else { + vtype_kind_t vtype_base; + emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = base + assert(vtype_base == VTYPE_PYOBJ); + emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, 2); // arg3 = dest ptr + emit_call_with_imm_arg(emit, MP_F_LOAD_METHOD, qst, REG_ARG_2); // arg2 = method name + } } STATIC void emit_native_load_build_class(emit_t *emit) { |