py/vm: When VM raises exception put exc obj at beginning of func state.

Instead of at end of state, n_state - 1.  It was originally (way back in
v1.0) put at the end of the state because the VM didn't have a pointer to
the start.  But now that the VM takes a mp_code_state_t pointer it does
have a pointer to the start of the state so can put the exception object
there.

This commit saves about 30 bytes of code on all architectures, and, more
importantly, reduces C-stack usage by a couple of words (8 bytes on Thumb2
and 16 bytes on x86-64) for every (non-generator) call of a bytecode
function because fun_bc_call no longer needs to remember the n_state
variable.
pull/4199/head
Damien George 2018-09-29 23:25:08 +10:00
rodzic dd288904db
commit d95947b48a
3 zmienionych plików z 3 dodań i 4 usunięć

Wyświetl plik

@ -318,7 +318,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
// must be an exception because normal functions can't yield
assert(vm_return_kind == MP_VM_RETURN_EXCEPTION);
// return value is in fastn[0]==state[n_state - 1]
result = code_state->state[n_state - 1];
result = code_state->state[0];
}
#if MICROPY_ENABLE_PYSTACK

Wyświetl plik

@ -140,9 +140,8 @@ 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: {
size_t n_state = mp_decode_uint_value(self->code_state.fun_bc->bytecode);
self->code_state.ip = 0;
*ret_val = self->code_state.state[n_state - 1];
*ret_val = self->code_state.state[0];
// PEP479: if StopIteration is raised inside a generator it is replaced with RuntimeError
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(*ret_val)), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
*ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator raised StopIteration");

Wyświetl plik

@ -1468,7 +1468,7 @@ unwind_loop:
} else {
// propagate exception to higher level
// Note: ip and sp don't have usable values at this point
fastn[0] = MP_OBJ_FROM_PTR(nlr.ret_val); // must put exception here because sp is invalid
code_state->state[0] = MP_OBJ_FROM_PTR(nlr.ret_val); // put exception here because sp is invalid
return MP_VM_RETURN_EXCEPTION;
}
}