Skip to content
Snippets Groups Projects
Commit ea7cf2b7 authored by Ayke van Laethem's avatar Ayke van Laethem Committed by Damien George
Browse files

py/gc: Reduce code size by specialising VERIFY_MARK_AND_PUSH macro.

This macro is written out explicitly in the two locations that it is used
and then the code is optimised, opening possibilities for further
optimisations and reducing code size:

unix:            -48
minimal CROSS=1: -32
stm32:           -32
parent a3e01d36
No related branches found
No related tags found
No related merge requests found
......@@ -203,24 +203,6 @@ bool gc_is_locked(void) {
#endif
#endif
// ptr should be of type void*
#define VERIFY_MARK_AND_PUSH(ptr) \
do { \
if (VERIFY_PTR(ptr)) { \
size_t _block = BLOCK_FROM_PTR(ptr); \
if (ATB_GET_KIND(_block) == AT_HEAD) { \
/* an unmarked head, mark it, and push it on gc stack */ \
TRACE_MARK(_block, ptr); \
ATB_HEAD_TO_MARK(_block); \
if (MP_STATE_MEM(gc_sp) < &MP_STATE_MEM(gc_stack)[MICROPY_ALLOC_GC_STACK_SIZE]) { \
*MP_STATE_MEM(gc_sp)++ = _block; \
} else { \
MP_STATE_MEM(gc_stack_overflow) = 1; \
} \
} \
} \
} while (0)
STATIC void gc_drain_stack(void) {
while (MP_STATE_MEM(gc_sp) > MP_STATE_MEM(gc_stack)) {
// pop the next block off the stack
......@@ -236,7 +218,20 @@ STATIC void gc_drain_stack(void) {
void **ptrs = (void**)PTR_FROM_BLOCK(block);
for (size_t i = n_blocks * BYTES_PER_BLOCK / sizeof(void*); i > 0; i--, ptrs++) {
void *ptr = *ptrs;
VERIFY_MARK_AND_PUSH(ptr);
if (VERIFY_PTR(ptr)) {
// Mark and push this pointer
size_t childblock = BLOCK_FROM_PTR(ptr);
if (ATB_GET_KIND(childblock) == AT_HEAD) {
// an unmarked head, mark it, and push it on gc stack
TRACE_MARK(childblock, ptr);
ATB_HEAD_TO_MARK(childblock);
if (MP_STATE_MEM(gc_sp) < &MP_STATE_MEM(gc_stack)[MICROPY_ALLOC_GC_STACK_SIZE]) {
*MP_STATE_MEM(gc_sp)++ = childblock;
} else {
MP_STATE_MEM(gc_stack_overflow) = 1;
}
}
}
}
}
}
......@@ -337,8 +332,17 @@ void gc_collect_start(void) {
void gc_collect_root(void **ptrs, size_t len) {
for (size_t i = 0; i < len; i++) {
void *ptr = ptrs[i];
VERIFY_MARK_AND_PUSH(ptr);
gc_drain_stack();
if (VERIFY_PTR(ptr)) {
// Mark and push this pointer
size_t block = BLOCK_FROM_PTR(ptr);
if (ATB_GET_KIND(block) == AT_HEAD) {
// an unmarked head, mark it, and push it on gc stack
TRACE_MARK(block, ptr);
ATB_HEAD_TO_MARK(block);
*MP_STATE_MEM(gc_sp)++ = block;
gc_drain_stack();
}
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment