From e0252c77517e504d060db3465dfec48c845fe553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 22 Aug 2017 15:50:24 +0200 Subject: [PATCH] [python] Fix garbage collector Change-Id: I529ff93e7f8841574ff24cb1b6461aa48039ab61 --- apps/code/executor_controller.cpp | 3 ++ python/port/port.c | 63 +++++++++++-------------------- python/port/port.h | 6 +++ 3 files changed, 32 insertions(+), 40 deletions(-) create mode 100644 python/port/port.h diff --git a/apps/code/executor_controller.cpp b/apps/code/executor_controller.cpp index e99753941..5f380cefb 100644 --- a/apps/code/executor_controller.cpp +++ b/apps/code/executor_controller.cpp @@ -2,6 +2,7 @@ extern "C" { #include +#include "port.h" #include "py/compile.h" #include "py/runtime.h" #include "py/gc.h" @@ -72,6 +73,8 @@ void ExecutorController::ContentView::runPython() const { // Initialized stack limit mp_stack_set_limit(40000); + mp_port_init_stack_top(); + char * pythonHeap = (char *)malloc(16384); gc_init(pythonHeap, pythonHeap + 16384); diff --git a/python/port/port.c b/python/port/port.c index 6f1aaf0c0..10ec4847c 100644 --- a/python/port/port.c +++ b/python/port/port.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "py/nlr.h" #include "py/compile.h" @@ -9,51 +10,33 @@ #include "py/gc.h" #include "py/mperrno.h" -mp_uint_t gc_helper_get_regs_and_sp(mp_uint_t *regs); +typedef jmp_buf regs_t; + +STATIC void gc_helper_get_regs(regs_t arr) { + setjmp(arr); +} + +static char * python_stack_top = NULL; + +void mp_port_init_stack_top() { + char dummy; + python_stack_top = &dummy; +} void gc_collect(void) { -#if 0 - gc_collect_start(); + assert(python_stack_top != NULL); + gc_collect_start(); - // get the registers and the sp - mp_uint_t regs[10]; - mp_uint_t sp = gc_helper_get_regs_and_sp(regs); + /* get the registers. + * regs is the also the last object on the stack so the stack is bound by + * ®s and python_stack_top. */ + regs_t regs; + gc_helper_get_regs(regs); + void **regs_ptr = (void**)(void*)®s; + gc_collect_root(regs_ptr, ((uintptr_t)python_stack_top - (uintptr_t)®s) / sizeof(uintptr_t)); - - /* Next we want to iterate through the whole stack - * Without threads, the stmhal version just refers to the top of the stack as _ram_end, because that's where the - * stack actually starts. - * This is going to need some help from Ion. - */ - - - // trace the stack, including the registers (since they live on the stack in this function) - #if MICROPY_PY_THREAD - gc_collect_root((void**)sp, ((uint32_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t)); - #else - gc_collect_root((void**)sp, ((uint32_t)&_ram_end - sp) / sizeof(uint32_t)); - #endif - - // trace root pointers from any threads - #if MICROPY_PY_THREAD - mp_thread_gc_others(); - #endif - - // end the GC - gc_collect_end(); - - // Let's just do nothing for now -#else - // WARNING: This gc_collect implementation doesn't try to get root - // pointers from CPU registers, and thus may function incorrectly. - void *dummy; - gc_collect_start(); - // FIXME - //gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t)); - gc_collect_end(); - //gc_dump_info(); -#endif + gc_collect_end(); } mp_lexer_t *mp_lexer_new_from_file(const char *filename) { diff --git a/python/port/port.h b/python/port/port.h new file mode 100644 index 000000000..7cc204f86 --- /dev/null +++ b/python/port/port.h @@ -0,0 +1,6 @@ +#ifndef PYTHON_PORT_H +#define PYTHON_PORT_H + +void mp_port_init_stack_top(); + +#endif