summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@complang.org>2012-08-29 11:15:47 -0400
committerAdrian Thurston <thurston@complang.org>2012-08-29 11:15:47 -0400
commit10978e1598a33811085cf3e51684948087d3c4db (patch)
treee569daa33a777fd53bb88348944cfcb909b647bd
parentfecd7e2f73b8e13d830b2c3acebc306e50e54a5b (diff)
downloadcolm-10978e1598a33811085cf3e51684948087d3c4db.tar.gz
keep a reserve stack block around for balanced push/pop following contiguous call
There may be some balanced push/pop calls after a call to contiguous, but we still need the contiguous space there. The pop can cause the contiguous stack block to be freed. One way to prevent this is to keep the last popped block around as a reserve and use it if it's big enough. Not sure if this is good enough, but so far seems to work ok.
-rw-r--r--colm/program.c40
-rw-r--r--colm/program.h1
2 files changed, 29 insertions, 12 deletions
diff --git a/colm/program.c b/colm/program.c
index 9960027b..a96b931e 100644
--- a/colm/program.c
+++ b/colm/program.c
@@ -84,19 +84,29 @@ Tree **vm_grow( Program *prg, Tree **sp, int n )
prg->sb_total += prg->stackBlock->len - prg->stackBlock->offset;
}
- StackBlock *b = malloc( sizeof(StackBlock) );
- int size = VM_STACK_SIZE;
- if ( n > size )
- size = n;
- b->next = prg->stackBlock;
- b->data = malloc( sizeof(Tree*) * size );
- b->len = size;
- b->offset = 0;
+ if ( prg->reserve != 0 && prg->reserve->len >= n) {
+ StackBlock *b = prg->reserve;
+ b->next = prg->stackBlock;
+ b->offset = 0;
- prg->stackBlock = b;
+ prg->stackBlock = b;
+ prg->reserve = 0;
+ }
+ else {
+ StackBlock *b = malloc( sizeof(StackBlock) );
+ int size = VM_STACK_SIZE;
+ if ( n > size )
+ size = n;
+ b->next = prg->stackBlock;
+ b->data = malloc( sizeof(Tree*) * size );
+ b->len = size;
+ b->offset = 0;
+
+ prg->stackBlock = b;
+ }
prg->sb_beg = prg->stackBlock->data;
- prg->sb_end = prg->stackBlock->data + size;
+ prg->sb_end = prg->stackBlock->data + prg->stackBlock->len;
return prg->sb_end;
}
@@ -109,12 +119,18 @@ Tree **vm_shrink( Program *prg )
return prg->sb_end;
}
else {
+ if ( prg->reserve != 0 ) {
+ free( prg->reserve->data );
+ free( prg->reserve );
+ }
+
StackBlock *b = prg->stackBlock;
prg->stackBlock = prg->stackBlock->next;
- free( b->data );
- free( b );
+ prg->reserve = b;
+ /* FIXME: need to use offset here? Maybe we can grant more space in
+ * case any push that follows has fewer requirements. */
prg->sb_beg = prg->stackBlock->data + prg->stackBlock->offset;
prg->sb_end = prg->stackBlock->data + prg->stackBlock->len;
diff --git a/colm/program.h b/colm/program.h
index 7925a991..aec024ae 100644
--- a/colm/program.h
+++ b/colm/program.h
@@ -125,6 +125,7 @@ typedef struct ColmProgram
Tree **sb_beg;
Tree **sb_end;
long sb_total;
+ StackBlock *reserve;
StackBlock *stackBlock;
Tree **stackRoot;