py/runtime: Use the Python stack when building *arg and **kwarg state.
With MICROPY_ENABLE_PYSTACK enabled the following language constructs no longer allocate on the heap: f(*arg), f(**kwarg).
This commit is contained in:
parent
971699abe7
commit
30fd8484eb
12
py/runtime.c
12
py/runtime.c
|
@ -669,7 +669,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
|||
|
||||
// allocate memory for the new array of args
|
||||
args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len);
|
||||
args2 = m_new(mp_obj_t, args2_alloc);
|
||||
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
|
||||
|
||||
// copy the self
|
||||
if (self != MP_OBJ_NULL) {
|
||||
|
@ -690,7 +690,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
|||
|
||||
// allocate memory for the new array of args
|
||||
args2_alloc = 1 + n_args + len + 2 * (n_kw + kw_dict_len);
|
||||
args2 = m_new(mp_obj_t, args2_alloc);
|
||||
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
|
||||
|
||||
// copy the self
|
||||
if (self != MP_OBJ_NULL) {
|
||||
|
@ -706,7 +706,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
|||
|
||||
// allocate memory for the new array of args
|
||||
args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len) + 3;
|
||||
args2 = m_new(mp_obj_t, args2_alloc);
|
||||
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
|
||||
|
||||
// copy the self
|
||||
if (self != MP_OBJ_NULL) {
|
||||
|
@ -723,7 +723,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
|||
mp_obj_t item;
|
||||
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
if (args2_len >= args2_alloc) {
|
||||
args2 = m_renew(mp_obj_t, args2, args2_alloc, args2_alloc * 2);
|
||||
args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), args2_alloc * 2 * sizeof(mp_obj_t));
|
||||
args2_alloc *= 2;
|
||||
}
|
||||
args2[args2_len++] = item;
|
||||
|
@ -774,7 +774,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
|
|||
if (new_alloc < 4) {
|
||||
new_alloc = 4;
|
||||
}
|
||||
args2 = m_renew(mp_obj_t, args2, args2_alloc, new_alloc);
|
||||
args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), new_alloc * sizeof(mp_obj_t));
|
||||
args2_alloc = new_alloc;
|
||||
}
|
||||
|
||||
|
@ -806,7 +806,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob
|
|||
mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args);
|
||||
|
||||
mp_obj_t res = mp_call_function_n_kw(out_args.fun, out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
16
py/vm.c
16
py/vm.c
|
@ -966,7 +966,11 @@ unwind_jump:;
|
|||
|
||||
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
#if !MICROPY_ENABLE_PYSTACK
|
||||
// Freeing args at this point does not follow a LIFO order so only do it if
|
||||
// pystack is not enabled. For pystack, they are freed when code_state is.
|
||||
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
|
||||
#endif
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
|
@ -1043,7 +1047,11 @@ unwind_jump:;
|
|||
|
||||
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
|
||||
out_args.n_args, out_args.n_kw, out_args.args);
|
||||
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
|
||||
#if !MICROPY_ENABLE_PYSTACK
|
||||
// Freeing args at this point does not follow a LIFO order so only do it if
|
||||
// pystack is not enabled. For pystack, they are freed when code_state is.
|
||||
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
|
||||
#endif
|
||||
if (new_state) {
|
||||
new_state->prev = code_state;
|
||||
code_state = new_state;
|
||||
|
@ -1110,6 +1118,8 @@ unwind_return:
|
|||
mp_globals_set(code_state->old_globals);
|
||||
mp_code_state_t *new_code_state = code_state->prev;
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
// Free code_state, and args allocated by mp_call_prepare_args_n_kw_var
|
||||
// (The latter is implicitly freed when using pystack due to its LIFO nature.)
|
||||
// The sizeof in the following statement does not include the size of the variable
|
||||
// part of the struct. This arg is anyway not used if pystack is enabled.
|
||||
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
|
||||
|
@ -1458,6 +1468,8 @@ unwind_loop:
|
|||
mp_globals_set(code_state->old_globals);
|
||||
mp_code_state_t *new_code_state = code_state->prev;
|
||||
#if MICROPY_ENABLE_PYSTACK
|
||||
// Free code_state, and args allocated by mp_call_prepare_args_n_kw_var
|
||||
// (The latter is implicitly freed when using pystack due to its LIFO nature.)
|
||||
// The sizeof in the following statement does not include the size of the variable
|
||||
// part of the struct. This arg is anyway not used if pystack is enabled.
|
||||
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
|
||||
|
|
Loading…
Reference in New Issue