8000 py/runtime: Use the Python stack when building *arg and **kwarg state. · lvgl/lv_micropython@30fd848 · GitHub
[go: up one dir, main page]

Skip to content

Commit 30fd848

Browse files
committed
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).
1 parent 971699a commit 30fd848

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

py/runtime.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_
669669

670670
// allocate memory for the new array of args
671671
args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len);
672-
args2 = m_new(mp_obj_t, args2_alloc);
672+
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
673673

674674
// copy the self
675675
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_
690690

691691
// allocate memory for the new array of args
692692
args2_alloc = 1 + n_args + len + 2 * (n_kw + kw_dict_len);
693-
args2 = m_new(mp_obj_t, args2_alloc);
693+
args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t));
694694

695695
// copy the self
696696
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_
706706

707707
// allocate memory for the new array of args
708708
args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len) + 3;
709-
args2 = m_new(mp_obj_t, args2_alloc);
709+
args2 = mp_nonlocal_alloc(ar 10000 gs2_alloc * sizeof(mp_obj_t));
710710

711711
// copy the self
712712
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_
723723
mp_obj_t item;
724724
while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
725725
if (args2_len >= args2_alloc) {
726-
args2 = m_renew(mp_obj_t, args2, args2_alloc, args2_alloc * 2);
726+
args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), args2_alloc * 2 * sizeof(mp_obj_t));
727727
args2_alloc *= 2;
728728
}
729729
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_
774774
if (new_alloc < 4) {
775775
new_alloc = 4;
776776
}
777-
args2 = m_renew(mp_obj_t, args2, args2_alloc, new_alloc);
777+
args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), new_alloc * sizeof(mp_obj_t));
778778
args2_alloc = new_alloc;
779779
}
780780

@@ -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
806806
mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args);
807807

808808
mp_obj_t res = mp_call_function_n_kw(out_args.fun, out_args.n_args, out_args.n_kw, out_args.args);
809-
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
809+
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
810810

811811
return res;
812812
}

py/vm.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,11 @@ unwind_jump:;
966966

967967
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
968968
out_args.n_args, out_args.n_kw, out_args.args);
969-
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
969+
#if !MICROPY_ENABLE_PYSTACK
970+
// Freeing args at this point does not follow a LIFO order so only do it if
971+
// pystack is not enabled. For pystack, they are freed when code_state is.
972+
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
973+
#endif
970974
if (new_state) {
971975
new_state->prev = code_state;
972976
code_state = new_state;
@@ -1043,7 +1047,11 @@ unwind_jump:;
10431047

10441048
mp_code_state_t *new_state = mp_obj_fun_bc_prepare_codestate(out_args.fun,
10451049
out_args.n_args, out_args.n_kw, out_args.args);
1046-
m_del(mp_obj_t, out_args.args, out_args.n_alloc);
1050+
#if !MICROPY_ENABLE_PYSTACK
1051+
// Freeing args at this point does not follow a LIFO order so only do it if
1052+
// pystack is not enabled. For pystack, they are freed when code_state is.
1053+
mp_nonlocal_free(out_args.args, out_args.n_alloc * sizeof(mp_obj_t));
1054+
#endif
10471055
if (new_state) {
10481056
new_state->prev = code_state;
10491057
code_state = new_state;
@@ -1110,6 +1118,8 @@ unwind_jump:;
11101118
mp_globals_set(code_state->old_globals);
11111119
mp_code_state_t *new_code_state = code_state->prev;
11121120
#if MICROPY_ENABLE_PYSTACK
1121+
// Free code_state, and args allocated by mp_call_prepare_args_n_kw_var
1122+
// (The latter is implicitly freed when using pystack due to its LIFO nature.)
11131123
// The sizeof in the following statement does not include the size of the variable
11141124
// part of the struct. This arg is anyway not used if pystack is enabled.
11151125
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
@@ -1458,6 +1468,8 @@ unwind_jump:;
14581468
mp_globals_set(code_state->old_globals);
14591469
mp_code_state_t *new_code_state = code_state->prev;
14601470
#if MICROPY_ENABLE_PYSTACK
1471+
// Free code_state, and args allocated by mp_call_prepare_args_n_kw_var
1472+
// (The latter is implicitly freed when using pystack due to its LIFO nature.)
14611473
// The sizeof in the following statement does not include the size of the variable
14621474
// part of the struct. This arg is anyway not used if pystack is enabled.
14631475
mp_nonlocal_free(code_state, sizeof(mp_code_state_t));

0 commit comments

Comments
 (0)
0