From bb5316b9056720a67c25934aebb5a68e4772a7da Mon Sep 17 00:00:00 2001 From: Damien Date: Tue, 22 Oct 2013 21:12:29 +0100 Subject: [PATCH] gc: reserve first block; lexer: free vstr. --- py/gc.c | 57 +++++++++++++++++++++++++++++------------------------- py/lexer.c | 1 + 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/py/gc.c b/py/gc.c index 0c9c560860..4a3d1dabee 100644 --- a/py/gc.c +++ b/py/gc.c @@ -20,7 +20,6 @@ typedef unsigned char byte; #define STACK_SIZE (64) // tunable; minimum is 1 static byte *gc_alloc_table_start; -static byte *gc_alloc_table_end; static machine_uint_t gc_alloc_table_byte_len; static machine_uint_t *gc_pool_start; static machine_uint_t *gc_pool_end; @@ -29,31 +28,6 @@ static int gc_stack_overflow; static machine_uint_t gc_stack[STACK_SIZE]; static machine_uint_t *gc_sp; -// TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool -void gc_init(void *start, void *end) { - // align end pointer on block boundary - end = (void*)((machine_uint_t)end & (~(BYTES_PER_BLOCK - 1))); - - // calculate parameters for GC - machine_uint_t total_word_len = (machine_uint_t*)end - (machine_uint_t*)start; - gc_alloc_table_byte_len = total_word_len * BYTES_PER_WORD / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK); - gc_alloc_table_start = (byte*)start; - gc_alloc_table_end = gc_alloc_table_start + gc_alloc_table_byte_len; - machine_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BITS_PER_BYTE / 2; - machine_uint_t gc_pool_word_len = gc_pool_block_len * WORDS_PER_BLOCK; - gc_pool_start = (machine_uint_t*)end - gc_pool_word_len; - gc_pool_end = end; - - // clear ATBs - memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len); - - /* - printf("GC layout:\n"); - printf(" alloc table at %p, length %u bytes\n", gc_alloc_table_start, gc_alloc_table_byte_len); - printf(" pool at %p, length %u blocks = %u words = %u bytes\n", gc_pool_start, gc_pool_block_len, gc_pool_word_len, gc_pool_word_len * BYTES_PER_WORD); - */ -} - // ATB = allocation table byte // 0b00 = FREE -- free block // 0b01 = HEAD -- head of a chain of blocks @@ -88,6 +62,37 @@ void gc_init(void *start, void *end) { #define PTR_FROM_BLOCK(block) (((block) * BYTES_PER_BLOCK + (machine_uint_t)gc_pool_start)) #define ATB_FROM_BLOCK(bl) ((bl) / BLOCKS_PER_ATB) +// TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool +void gc_init(void *start, void *end) { + // align end pointer on block boundary + end = (void*)((machine_uint_t)end & (~(BYTES_PER_BLOCK - 1))); + + // calculate parameters for GC + machine_uint_t total_word_len = (machine_uint_t*)end - (machine_uint_t*)start; + gc_alloc_table_byte_len = total_word_len * BYTES_PER_WORD / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK); + gc_alloc_table_start = (byte*)start; + machine_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BITS_PER_BYTE / 2; + machine_uint_t gc_pool_word_len = gc_pool_block_len * WORDS_PER_BLOCK; + gc_pool_start = (machine_uint_t*)end - gc_pool_word_len; + gc_pool_end = end; + + // clear ATBs + memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len); + + // allocate first block because gc_pool_start points there and it will never + // be freed, so allocating 1 block with null pointers will minimise memory loss + ATB_FREE_TO_HEAD(0); + for (int i = 0; i < WORDS_PER_BLOCK; i++) { + gc_pool_start[i] = 0; + } + + /* + printf("GC layout:\n"); + printf(" alloc table at %p, length %u bytes\n", gc_alloc_table_start, gc_alloc_table_byte_len); + printf(" pool at %p, length %u blocks = %u words = %u bytes\n", gc_pool_start, gc_pool_block_len, gc_pool_word_len, gc_pool_word_len * BYTES_PER_WORD); + */ +} + #define VERIFY_PTR(ptr) ( \ (ptr & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \ && ptr >= (machine_uint_t)gc_pool_start /* must be above start of pool */ \ diff --git a/py/lexer.c b/py/lexer.c index 9ab0641967..88bc0a1aae 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -635,6 +635,7 @@ void py_lexer_free(py_lexer_t *lex) { if (lex->stream_close) { lex->stream_close(lex->stream_data); } + vstr_clear(&lex->vstr); m_free(lex); } }