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
This commit is contained in:
Scott Shawcroft 2017-05-05 12:04:20 -07:00
parent 5ad426124b
commit c6d539ace3
2 changed files with 4 additions and 9 deletions

View File

@ -115,7 +115,6 @@ void init_flash_fs(void) {
f_chdrive("/flash"); f_chdrive("/flash");
} }
static char *stack_top;
static char heap[16384]; static char heap[16384];
void reset_mp(void) { void reset_mp(void) {
@ -519,12 +518,6 @@ int main(void) {
// initialise the cpu and peripherals // initialise the cpu and peripherals
samd21_init(); 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 // Stack limit should be less than real stack size, so we have a chance
// to recover from limit hit. (Limit is measured in bytes.) // to recover from limit hit. (Limit is measured in bytes.)
mp_stack_ctrl_init(); mp_stack_ctrl_init();
@ -581,7 +574,7 @@ void gc_collect(void) {
gc_collect_start(); gc_collect_start();
// This naively collects all object references from an approximate stack // This naively collects all object references from an approximate stack
// range. // 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(); gc_collect_end();
} }

View File

@ -104,11 +104,13 @@
#ifdef LOG_HEAP_ACTIVITY #ifdef LOG_HEAP_ACTIVITY
volatile uint32_t change_me; 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) { void __attribute__ ((noinline)) gc_log_change(uint32_t start_block, uint32_t length) {
change_me += start_block; change_me += start_block;
change_me += length; // Break on this line. change_me += length; // Break on this line.
} }
#pragma GCC pop_options
#endif #endif
// TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool // TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool