From c6d539ace36b9be698a3a248793ee948ba269e68 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 5 May 2017 12:04:20 -0700 Subject: [PATCH] atmel-samd: Fix sporadic "syntax errors" The GC was deleting memory that was in use because its scan of the stack missed the very top. Switching to _estack fixes this by relying on the location from the linker. Fixes #124 --- atmel-samd/main.c | 9 +-------- py/gc.c | 4 +++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 9ed1c3cd1b..6184d64ebf 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -115,7 +115,6 @@ void init_flash_fs(void) { f_chdrive("/flash"); } -static char *stack_top; static char heap[16384]; void reset_mp(void) { @@ -519,12 +518,6 @@ int main(void) { // initialise the cpu and peripherals samd21_init(); - int stack_dummy; - // Store the location of stack_dummy as an approximation for the top of the - // stack so the GC can account for objects that may be referenced by the - // stack between here and where gc_collect is called. - stack_top = (char*)&stack_dummy; - // Stack limit should be less than real stack size, so we have a chance // to recover from limit hit. (Limit is measured in bytes.) mp_stack_ctrl_init(); @@ -581,7 +574,7 @@ void gc_collect(void) { gc_collect_start(); // This naively collects all object references from an approximate stack // range. - gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t)); + gc_collect_root(&dummy, ((mp_uint_t)&_estack - (mp_uint_t)&dummy) / sizeof(mp_uint_t)); gc_collect_end(); } diff --git a/py/gc.c b/py/gc.c index 75fc823827..72eecd7efe 100644 --- a/py/gc.c +++ b/py/gc.c @@ -104,11 +104,13 @@ #ifdef LOG_HEAP_ACTIVITY volatile uint32_t change_me; - +#pragma GCC push_options +#pragma GCC optimize ("O0") void __attribute__ ((noinline)) gc_log_change(uint32_t start_block, uint32_t length) { change_me += start_block; change_me += length; // Break on this line. } +#pragma GCC pop_options #endif // TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool