49
49
// the top-level call into C.
50
50
static size_t external_call_depth = 0 ;
51
51
52
+ #if MICROPY_GC_SPLIT_HEAP_AUTO
53
+ static void gc_collect_top_level (void );
54
+ #endif
55
+
52
56
void external_call_depth_inc (void ) {
53
57
++ external_call_depth ;
58
+ #if MICROPY_GC_SPLIT_HEAP_AUTO
59
+ if (external_call_depth == 1 ) {
60
+ gc_collect_top_level ();
61
+ }
62
+ #endif
54
63
}
55
64
56
65
void external_call_depth_dec (void ) {
@@ -63,6 +72,14 @@ void mp_js_init(int heap_size) {
63
72
gc_init (heap , heap + heap_size );
64
73
#endif
65
74
75
+ #if MICROPY_GC_SPLIT_HEAP_AUTO
76
+ // When MICROPY_GC_SPLIT_HEAP_AUTO is enabled, set the GC threshold to a low
77
+ // value so that a collection is triggered before the heap fills up. The actual
78
+ // garbage collection will happen later when control returns to the top-level,
79
+ // via the `gc_collect_pending` flag and `gc_collect_top_level()`.
80
+ MP_STATE_MEM (gc_alloc_threshold ) = 16 * 1024 / MICROPY_BYTES_PER_GC_BLOCK ;
81
+ #endif
82
+
66
83
#if MICROPY_ENABLE_PYSTACK
67
84
static mp_obj_t pystack [1024 ];
68
85
mp_pystack_init (pystack , & pystack [MP_ARRAY_SIZE (pystack )]);
@@ -121,10 +138,6 @@ void mp_js_do_import(const char *name, uint32_t *out) {
121
138
}
122
139
123
140
void mp_js_do_exec (const char * src , size_t len , uint32_t * out ) {
124
- // Collect at the top-level, where there are no root pointers from stack/registers.
125
- gc_collect_start ();
126
- gc_collect_end ();
127
-
128
141
external_call_depth_inc ();
129
142
mp_parse_input_kind_t input_kind = MP_PARSE_FILE_INPUT ;
130
143
nlr_buf_t nlr ;
@@ -163,13 +176,25 @@ int mp_js_repl_process_char(int c) {
163
176
164
177
#if MICROPY_GC_SPLIT_HEAP_AUTO
165
178
179
+ static bool gc_collect_pending = false;
180
+
166
181
// The largest new region that is available to become Python heap.
167
182
size_t gc_get_max_new_split (void ) {
168
183
return 128 * 1024 * 1024 ;
169
184
}
170
185
171
186
// Don't collect anything. Instead require the heap to grow.
172
187
void gc_collect (void ) {
188
+ gc_collect_pending = true;
189
+ }
190
+
191
+ // Collect at the top-level, where there are no root pointers from stack/registers.
192
+ static void gc_collect_top_level (void ) {
193
+ if (gc_collect_pending ) {
194
+ gc_collect_pending = false;
195
+ gc_collect_start ();
196
+ gc_collect_end ();
197
+ }
173
198
}
174
199
175
200
#else
0 commit comments