8000 py/gc.c: Reduce image sizes when GC multi-heap disabled. · micropython/micropython@f2198b4 · GitHub
[go: up one dir, main page]

Skip to content

Commit f2198b4

Browse files
committed
py/gc.c: Reduce image sizes when GC multi-heap disabled.
Use C macros to reduce size of firmware images when GC multiple heap feature is disabled. Image size diffs versus current master (9d7c168): unix x64: -16 -0.003% esp32: +12 +0.001% GENERIC[incl +8(data)] minimal x86: +0 +0.000% bare-arm: +0 +0.000% stm32: +136 +0.035% PYBV10[incl +128(bss)] Image size diffs versus previous commit (f1d9156): unix x64: -176 -0.034% esp32: -88 -0.006% GENERIC[incl +8(data)] minimal x86: +8 +0.005% bare-arm: +0 +0.000% stm32: -64 -0.016% PYBV10
1 parent f1d9156 commit f2198b4

File tree

1 file changed

+67
-16
lines changed

1 file changed

+67
-16
lines changed

py/gc.c

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ bool gc_is_locked(void) {
230230
return MP_STATE_THREAD(gc_lock_depth) != 0;
231231
}
232232

233+
#if MICROPY_GC_MULTIHEAP
233234
// Returns the area to which this pointer belongs, or NULL if it isn't
234235
// allocated on the GC-managed heap.
235236
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) {
244245
}
245246
return NULL;
246247
}
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+
)
247256

248257
#ifndef TRACE_MARK
249258
#if DEBUG_PRINT
@@ -283,11 +292,19 @@ STATIC void gc_mark_subtree(mp_gc_stack_item_t item) {
283292
void *ptr = *ptrs;
284293
// If this is a heap pointer that hasn't been marked, mark it and push
285294
// 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);
287298
if (!ptr_area) {
288299
// Not a heap-allocated pointer (might even be random data).
289300
continue;
290301
}
302+
#else
303+
if (!VERIFY_PTR(ptr)) {
304+
continue;
305+
}
306+
ptr_area = &MP_STATE_MEM(area);
307+
#endif
291308
size_t ptr_block = BLOCK_FROM_PTR(ptr_area, ptr);
292309
if (ATB_GET_KIND(ptr_area, ptr_block) != AT_HEAD) {
293310
// This block is already marked.
@@ -435,23 +452,33 @@ static void *gc_get_ptr(void **ptrs, int i) {
435452
}
436453

437454
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
438458
for (size_t i = 0; i < len; i++) {
439459
MICROPY_GC_HOOK_LOOP
440460
// void *ptr = ptrs[i];
441461
void *ptr = gc_get_ptr(ptrs, i);
462+
#if MICROPY_GC_MULTIHEAP
442463
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);
455482
}
456483
}
457484
}
@@ -717,8 +744,15 @@ void gc_free(void *ptr) {
717744
}
718745

719746
// 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);
721750
assert(area);
751+
#else
752+
assert(VERIFY_PTR(ptr));
753+
area = &MP_STATE_MEM(area);
754+
#endif
755+
722756
size_t block = BLOCK_FROM_PTR(area, ptr);
723757
assert(ATB_GET_KIND(area, block) == AT_HEAD);
724758

@@ -761,7 +795,18 @@ void gc_free(void *ptr) {
761795

762796
size_t gc_nbytes(const void *ptr) {
763797
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+
765810
if (area) {
766811
size_t block = BLOCK_FROM_PTR(area, ptr);
767812
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) {
830875
GC_ENTER();
831876

832877
// 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);
834881
assert(area);
882+
#else
883+
assert(VERIFY_PTR(ptr));
884+
area = &MP_STATE_MEM(area);
885+
#endif
835886
size_t block = BLOCK_FROM_PTR(area, ptr);
836887
assert(ATB_GET_KIND(area, block) == AT_HEAD);
837888

0 commit comments

Comments
 (0)
0