aboutsummaryrefslogtreecommitdiff
path: root/py/nlrx86.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2017-11-26 23:28:40 +1100
committerDamien George <damien.p.george@gmail.com>2017-12-11 13:49:09 +1100
commit02d830c035aca166d70551e485ccd2d1658189c9 (patch)
tree7ef2e7b883a5f6aee8b1a321979e2688e574066c /py/nlrx86.c
parent5b8998da6dfed6c8f54b8b34228f25d93dbb9d29 (diff)
py: Introduce a Python stack for scoped allocation.
This patch introduces the MICROPY_ENABLE_PYSTACK option (disabled by default) which enables a "Python stack" that allows to allocate and free memory in a scoped, or Last-In-First-Out (LIFO) way, similar to alloca(). A new memory allocation API is introduced along with this Py-stack. It includes both "local" and "nonlocal" LIFO allocation. Local allocation is intended to be equivalent to using alloca(), whereby the same function must free the memory. Nonlocal allocation is where another function may free the memory, so long as it's still LIFO. Follow-up patches will convert all uses of alloca() and VLA to the new scoped allocation API. The old behaviour (using alloca()) will still be available, but when MICROPY_ENABLE_PYSTACK is enabled then alloca() is no longer required or used. The benefits of enabling this option are (or will be once subsequent patches are made to convert alloca()/VLA): - Toolchains without alloca() can use this feature to obtain correct and efficient scoped memory allocation (compared to using the heap instead of alloca(), which is slower). - Even if alloca() is available, enabling the Py-stack gives slightly more efficient use of stack space when calling nested Python functions, due to the way that compilers implement alloca(). - Enabling the Py-stack with the stackless mode allows for even more efficient stack usage, as well as retaining high performance (because the heap is no longer used to build and destroy stackless code states). - With Py-stack and stackless enabled, Python-calling-Python is no longer recursive in the C mp_execute_bytecode function. The micropython.pystack_use() function is included to measure usage of the Python stack.
Diffstat (limited to 'py/nlrx86.c')
-rw-r--r--py/nlrx86.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/py/nlrx86.c b/py/nlrx86.c
index 094dea3cc..3a27460eb 100644
--- a/py/nlrx86.c
+++ b/py/nlrx86.c
@@ -73,6 +73,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr) {
nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
nlr->prev = *top;
+ MP_NLR_SAVE_PYSTACK(nlr);
*top = nlr;
return 0; // normal return
}
@@ -90,6 +91,7 @@ NORETURN void nlr_jump(void *val) {
}
top->ret_val = val;
+ MP_NLR_RESTORE_PYSTACK(top);
*top_ptr = top->prev;
__asm volatile (