@@ -230,6 +230,7 @@ bool gc_is_locked(void) {
230
230
return MP_STATE_THREAD (gc_lock_depth ) != 0 ;
231
231
}
232
232
233
+ #if MICROPY_GC_MULTIHEAP
233
234
// Returns the area to which this pointer belongs, or NULL if it isn't
234
235
// allocated on the GC-managed heap.
235
236
STATIC inline mp_state_mem_area_t * gc_get_ptr_area (const void * ptr ) {
@@ -244,6 +245,14 @@ STATIC inline mp_state_mem_area_t *gc_get_ptr_area(const void *ptr) {
244
245
}
245
246
return NULL ;
246
247
}
248
+ #endif
249
+
250
+ // ptr should be of type void*
251
+ #define VERIFY_PTR (ptr ) ( \
252
+ ((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
253
+ && ptr >= (void *)MP_STATE_MEM(area).gc_pool_start /* must be above start of pool */ \
254
+ && ptr < (void *)MP_STATE_MEM(area).gc_pool_end /* must be below end of pool */ \
255
+ )
247
256
248
257
#ifndef TRACE_MARK
249
258
#if DEBUG_PRINT
@@ -283,11 +292,19 @@ STATIC void gc_mark_subtree(mp_gc_stack_item_t item) {
283
292
void * ptr = * ptrs ;
284
293
// If this is a heap pointer that hasn't been marked, mark it and push
285
294
// it's children to the stack.
286
- mp_state_mem_area_t * ptr_area = gc_get_ptr_area (ptr );
295
+ mp_state_mem_area_t * ptr_area ;
296
+ #if MICROPY_GC_MULTIHEAP
297
+ ptr_area = gc_get_ptr_area (ptr );
287
298
if (!ptr_area ) {
288
299
// Not a heap-allocated pointer (might even be random data).
289
300
continue ;
290
301
}
302
+ #else
303
+ if (!VERIFY_PTR (ptr )) {
304
+ continue ;
305
+ }
306
+ ptr_area = & MP_STATE_MEM (area );
307
+ #endif
291
308
size_t ptr_block = BLOCK_FROM_PTR (ptr_area , ptr );
292
309
if (ATB_GET_KIND (ptr_area , ptr_block ) != AT_HEAD ) {
293
310
// This block is already marked.
@@ -435,23 +452,33 @@ static void *gc_get_ptr(void **ptrs, int i) {
435
452
}
436
453
437
454
void gc_collect_root (void * * ptrs , size_t len ) {
455
+ #if !MICROPY_GC_MULTIHEAP
456
+ mp_state_mem_area_t * area = & MP_STATE_MEM (area );
457
+ #endif
438
458
for (size_t i = 0 ; i < len ; i ++ ) {
439
459
MICROPY_GC_HOOK_LOOP
440
460
// void *ptr = ptrs[i];
441
461
void * ptr = gc_get_ptr (ptrs , i );
462
+ #if MICROPY_GC_MULTIHEAP
442
463
mp_state_mem_area_t * area = gc_get_ptr_area (ptr );
443
- if (area ) {
444
- size_t block = BLOCK_FROM_PTR (area , ptr );
445
- if (ATB_GET_KIND (area , block ) == AT_HEAD ) {
446
- // An unmarked head: mark it, and mark all its children
447
- ATB_HEAD_TO_MARK (area , block );
448
- #if MICROPY_GC_MULTIHEAP
449
- mp_gc_stack_item_t item = {area , block };
450
- #else
451
- mp_gc_stack_item_t item = {block };
452
- #endif
453
- gc_mark_subtree (item );
454
- }
464
+ if (!area ) {
465
+ continue ;
466
+ }
467
+ #else
468
+ if (!VERIFY_PTR (ptr )) {
469
+ continue ;
470
+ }
471
+ #endif
472
+ size_t block = BLOCK_FROM_PTR (area , ptr );
473
+ if (ATB_GET_KIND (area , block ) == AT_HEAD ) {
474
+ // An unmarked head: mark it, and mark all its children
475
+ ATB_HEAD_TO_MA
ED4F
RK (area , block );
476
+ #if MICROPY_GC_MULTIHEAP
477
+ mp_gc_stack_item_t item = {area , block };
478
+ #else
479
+ mp_gc_stack_item_t item = {block };
480
+ #endif
481
+ gc_mark_subtree (item );
455
482
}
456
483
}
457
484
}
@@ -717,8 +744,15 @@ void gc_free(void *ptr) {
717
744
}
718
745
719
746
// get the GC block number corresponding to this pointer
720
- mp_state_mem_area_t * area = gc_get_ptr_area (ptr );
747
+ mp_state_mem_area_t * area ;
748
+ #if MICROPY_GC_MULTIHEAP
749
+ area = gc_get_ptr_area (ptr );
721
750
assert (area );
751
+ #else
752
+ assert (VERIFY_PTR (ptr ));
753
+ area = & MP_STATE_MEM (area );
754
+ #endif
755
+
722
756
size_t block = BLOCK_FROM_PTR (area , ptr );
723
757
assert (ATB_GET_KIND (area , block ) == AT_HEAD );
724
758
@@ -761,7 +795,18 @@ void gc_free(void *ptr) {
761
795
762
796
size_t gc_nbytes (const void * ptr ) {
763
797
GC_ENTER ();
764
- mp_state_mem_area_t * area = gc_get_ptr_area (ptr );
798
+
799
+ mp_state_mem_area_t * area ;
800
+ #if MICROPY_GC_MULTIHEAP
801
+ area = gc_get_ptr_area (ptr );
802
+ #else
803
+ if (VERIFY_PTR (ptr )) {
804
+ area = & MP_STATE_MEM (area );
805
+ } else {
806
+ area = NULL ;
807
+ }
808
+ #endif
809
+
765
810
if (area ) {
766
811
size_t block = BLOCK_FROM_PTR (area , ptr );
767
812
if (ATB_GET_KIND (area , block ) == AT_HEAD ) {
@@ -830,8 +875,14 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
830
875
GC_ENTER ();
831
876
832
877
// get the GC block number corresponding to this pointer
833
- mp_state_mem_area_t * area = gc_get_ptr_area (ptr );
878
+ mp_state_mem_area_t * area ;
879
+ #if MICROPY_GC_MULTIHEAP
880
+ area = gc_get_ptr_area (ptr );
834
881
assert (area );
882
+ #else
883
+ assert (VERIFY_PTR (ptr ));
884
+ area = & MP_STATE_MEM (area );
885
+ #endif
835
886
size_t block = BLOCK_FROM_PTR (area , ptr );
836
887
assert (ATB_GET_KIND (area , block ) == AT_HEAD );
837
888
0 commit comments