From 0d32f1aeb3e3792f2bd04c499a6d5a22c2efdf0c Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Tue, 20 Dec 2016 11:20:01 +1100
Subject: [PATCH] esp8266: When doing GC be sure to trace the memory holding
 native code.

Native code can hold pointers to objects on the heap, eg constant objects
like big integers.
---
 esp8266/gccollect.c |  5 +++++
 esp8266/gccollect.h |  1 +
 esp8266/modesp.c    | 12 ++++++++++++
 3 files changed, 18 insertions(+)

diff --git a/esp8266/gccollect.c b/esp8266/gccollect.c
index 3a5032bc9..1b9349f57 100644
--- a/esp8266/gccollect.c
+++ b/esp8266/gccollect.c
@@ -46,6 +46,11 @@ void gc_collect(void) {
     // trace the stack, including the registers (since they live on the stack in this function)
     gc_collect_root((void**)sp, (STACK_END - sp) / sizeof(uint32_t));
 
+    #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
+    // trace any native code because it can contain pointers to the heap
+    esp_native_code_gc_collect();
+    #endif
+
     // end the GC
     gc_collect_end();
 }
diff --git a/esp8266/gccollect.h b/esp8266/gccollect.h
index e360ef2f2..d81cba12c 100644
--- a/esp8266/gccollect.h
+++ b/esp8266/gccollect.h
@@ -38,3 +38,4 @@ extern uint32_t _heap_start;
 extern uint32_t _heap_end;
 
 void gc_collect(void);
+void esp_native_code_gc_collect(void);
diff --git a/esp8266/modesp.c b/esp8266/modesp.c
index a20769abc..4403dfde4 100644
--- a/esp8266/modesp.c
+++ b/esp8266/modesp.c
@@ -711,6 +711,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_esf_free_bufs_obj, esp_esf_free_bufs);
 // esp.set_native_code_location() function; see below.  If flash is selected
 // then it is erased as needed.
 
+#include "gccollect.h"
+
 #define IRAM1_END (0x40108000)
 #define FLASH_START (0x40200000)
 #define FLASH_END (0x40300000)
@@ -734,6 +736,16 @@ void esp_native_code_init(void) {
     esp_native_code_erased = 0;
 }
 
+void esp_native_code_gc_collect(void) {
+    void *src;
+    if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1) {
+        src = (void*)esp_native_code_start;
+    } else {
+        src = (void*)(FLASH_START + esp_native_code_start);
+    }
+    gc_collect_root(src, (esp_native_code_end - esp_native_code_start) / sizeof(uint32_t));
+}
+
 void *esp_native_code_commit(void *buf, size_t len) {
     //printf("COMMIT(buf=%p, len=%u, start=%08x, cur=%08x, end=%08x, erased=%08x)\n", buf, len, esp_native_code_start, esp_native_code_cur, esp_native_code_end, esp_native_code_erased);
 
-- 
GitLab