summaryrefslogtreecommitdiff
path: root/py/gc.c
diff options
context:
space:
mode:
authorAyke van Laethem <aykevanlaethem@gmail.com>2018-02-15 17:10:13 +0100
committerDamien George <damien.p.george@gmail.com>2018-02-19 16:00:59 +1100
commit5c9e5618e088ddc233cd3bd1b1f48572ab403983 (patch)
treebebb2f1626bc91856eacca50c3ecd5333a125fc7 /py/gc.c
parentea7cf2b738c3b103b472547500fb0107b956fc0c (diff)
py/gc: Rename gc_drain_stack to gc_mark_subtree and pass it first block.
This saves a bit in code size: minimal CROSS=1: -44 unix: -96
Diffstat (limited to 'py/gc.c')
-rw-r--r--py/gc.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/py/gc.c b/py/gc.c
index 9089a26be..616ff783f 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -203,11 +203,13 @@ bool gc_is_locked(void) {
#endif
#endif
-STATIC void gc_drain_stack(void) {
- while (MP_STATE_MEM(gc_sp) > MP_STATE_MEM(gc_stack)) {
- // pop the next block off the stack
- size_t block = *--MP_STATE_MEM(gc_sp);
-
+// Take the given block as the topmost block on the stack. Check all it's
+// children: mark the unmarked child blocks and put those newly marked
+// blocks on the stack. When all children have been checked, pop off the
+// topmost block on the stack and repeat with that one.
+STATIC void gc_mark_subtree(size_t block) {
+ // Start with the block passed in the argument.
+ for (;;) {
// work out number of consecutive blocks in the chain starting with this one
size_t n_blocks = 0;
do {
@@ -233,6 +235,14 @@ STATIC void gc_drain_stack(void) {
}
}
}
+
+ // Are there any blocks on the stack?
+ if (MP_STATE_MEM(gc_sp) <= MP_STATE_MEM(gc_stack)) {
+ break; // No, stack is empty, we're done.
+ }
+
+ // pop the next block off the stack
+ block = *--MP_STATE_MEM(gc_sp);
}
}
@@ -245,8 +255,7 @@ STATIC void gc_deal_with_stack_overflow(void) {
for (size_t block = 0; block < MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB; block++) {
// trace (again) if mark bit set
if (ATB_GET_KIND(block) == AT_MARK) {
- *MP_STATE_MEM(gc_sp)++ = block;
- gc_drain_stack();
+ gc_mark_subtree(block);
}
}
}
@@ -339,8 +348,7 @@ void gc_collect_root(void **ptrs, size_t len) {
// 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();
+ gc_mark_subtree(block);
}
}
}