diff options
author | Adrian Thurston <thurston@complang.org> | 2012-08-29 11:15:47 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@complang.org> | 2012-08-29 11:15:47 -0400 |
commit | 10978e1598a33811085cf3e51684948087d3c4db (patch) | |
tree | e569daa33a777fd53bb88348944cfcb909b647bd /colm | |
parent | fecd7e2f73b8e13d830b2c3acebc306e50e54a5b (diff) | |
download | colm-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.
Diffstat (limited to 'colm')
-rw-r--r-- | colm/program.c | 40 | ||||
-rw-r--r-- | colm/program.h | 1 |
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; |