From 89e5037f01776223d02fb02a28abedb5b1e5fd50 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 30 Jun 2017 17:47:04 -0700 Subject: [PATCH] Manually tail-call-optimize stack_node_release function --- src/runtime/stack.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/runtime/stack.c b/src/runtime/stack.c index 71d3e32a..10e9b7ee 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -81,22 +81,31 @@ static void stack_node_retain(StackNode *self) { } static void stack_node_release(StackNode *self, StackNodeArray *pool) { - if (!self) return; +recur: assert(self->ref_count != 0); self->ref_count--; - if (self->ref_count == 0) { - for (int i = 0; i < self->link_count; i++) { - if (self->links[i].tree) { - ts_tree_release(self->links[i].tree); - } + if (self->ref_count > 0) return; + + StackNode *last_predecessor = NULL; + if (self->link_count > 0) { + unsigned i = 0; + for (; i < self->link_count - 1; i++) { + if (self->links[i].tree) ts_tree_release(self->links[i].tree); stack_node_release(self->links[i].node, pool); } + if (self->links[i].tree) ts_tree_release(self->links[i].tree); + last_predecessor = self->links[i].node; + } - if (pool->size < MAX_NODE_POOL_SIZE) { - array_push(pool, self); - } else { - ts_free(self); - } + if (pool->size < MAX_NODE_POOL_SIZE) { + array_push(pool, self); + } else { + ts_free(self); + } + + if (last_predecessor) { + self = last_predecessor; + goto recur; } }