diff options
Diffstat (limited to 'py/gc.c')
-rw-r--r-- | py/gc.c | 140 |
1 files changed, 70 insertions, 70 deletions
@@ -51,17 +51,17 @@ #define STACK_SIZE (64) // tunable; minimum is 1 STATIC byte *gc_alloc_table_start; -STATIC machine_uint_t gc_alloc_table_byte_len; +STATIC mp_uint_t gc_alloc_table_byte_len; #if MICROPY_ENABLE_FINALISER STATIC byte *gc_finaliser_table_start; #endif -STATIC machine_uint_t *gc_pool_start; -STATIC machine_uint_t *gc_pool_end; +STATIC mp_uint_t *gc_pool_start; +STATIC mp_uint_t *gc_pool_end; STATIC int gc_stack_overflow; -STATIC machine_uint_t gc_stack[STACK_SIZE]; -STATIC machine_uint_t *gc_sp; -STATIC machine_uint_t gc_lock_depth; +STATIC mp_uint_t gc_stack[STACK_SIZE]; +STATIC mp_uint_t *gc_sp; +STATIC mp_uint_t gc_lock_depth; // ATB = allocation table byte // 0b00 = FREE -- free block @@ -93,8 +93,8 @@ STATIC machine_uint_t gc_lock_depth; #define ATB_HEAD_TO_MARK(block) do { gc_alloc_table_start[(block) / BLOCKS_PER_ATB] |= (AT_MARK << BLOCK_SHIFT(block)); } while (0) #define ATB_MARK_TO_HEAD(block) do { gc_alloc_table_start[(block) / BLOCKS_PER_ATB] &= (~(AT_TAIL << BLOCK_SHIFT(block))); } while (0) -#define BLOCK_FROM_PTR(ptr) (((ptr) - (machine_uint_t)gc_pool_start) / BYTES_PER_BLOCK) -#define PTR_FROM_BLOCK(block) (((block) * BYTES_PER_BLOCK + (machine_uint_t)gc_pool_start)) +#define BLOCK_FROM_PTR(ptr) (((ptr) - (mp_uint_t)gc_pool_start) / BYTES_PER_BLOCK) +#define PTR_FROM_BLOCK(block) (((block) * BYTES_PER_BLOCK + (mp_uint_t)gc_pool_start)) #define ATB_FROM_BLOCK(bl) ((bl) / BLOCKS_PER_ATB) #if MICROPY_ENABLE_FINALISER @@ -111,7 +111,7 @@ STATIC machine_uint_t gc_lock_depth; // 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))); + end = (void*)((mp_uint_t)end & (~(BYTES_PER_BLOCK - 1))); DEBUG_printf("Initializing GC heap: %p..%p = " UINT_FMT " bytes\n", start, end, (byte*)end - (byte*)start); // calculate parameters for GC (T=total, A=alloc table, F=finaliser table, P=pool; all in bytes): @@ -119,7 +119,7 @@ void gc_init(void *start, void *end) { // F = A * BLOCKS_PER_ATB / BLOCKS_PER_FTB // P = A * BLOCKS_PER_ATB * BYTES_PER_BLOCK // => T = A * (1 + BLOCKS_PER_ATB / BLOCKS_PER_FTB + BLOCKS_PER_ATB * BYTES_PER_BLOCK) - machine_uint_t total_byte_len = (byte*)end - (byte*)start; + mp_uint_t total_byte_len = (byte*)end - (byte*)start; #if MICROPY_ENABLE_FINALISER gc_alloc_table_byte_len = total_byte_len * BITS_PER_BYTE / (BITS_PER_BYTE + BITS_PER_BYTE * BLOCKS_PER_ATB / BLOCKS_PER_FTB + BITS_PER_BYTE * BLOCKS_PER_ATB * BYTES_PER_BLOCK); #else @@ -130,13 +130,13 @@ void gc_init(void *start, void *end) { gc_alloc_table_start = (byte*)start; #if MICROPY_ENABLE_FINALISER - machine_uint_t gc_finaliser_table_byte_len = (gc_alloc_table_byte_len * BLOCKS_PER_ATB) / BLOCKS_PER_FTB; + mp_uint_t gc_finaliser_table_byte_len = (gc_alloc_table_byte_len * BLOCKS_PER_ATB) / BLOCKS_PER_FTB; gc_finaliser_table_start = gc_alloc_table_start + gc_alloc_table_byte_len; #endif - machine_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BLOCKS_PER_ATB; - gc_pool_start = (machine_uint_t*)((byte*)end - gc_pool_block_len * BYTES_PER_BLOCK); - gc_pool_end = (machine_uint_t*)end; + mp_uint_t gc_pool_block_len = gc_alloc_table_byte_len * BLOCKS_PER_ATB; + gc_pool_start = (mp_uint_t*)((byte*)end - gc_pool_block_len * BYTES_PER_BLOCK); + gc_pool_end = (mp_uint_t*)end; // clear ATBs memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len); @@ -178,14 +178,14 @@ bool gc_is_locked(void) { #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 */ \ - && ptr < (machine_uint_t)gc_pool_end /* must be below end of pool */ \ + && ptr >= (mp_uint_t)gc_pool_start /* must be above start of pool */ \ + && ptr < (mp_uint_t)gc_pool_end /* must be below end of pool */ \ ) #define VERIFY_MARK_AND_PUSH(ptr) \ do { \ if (VERIFY_PTR(ptr)) { \ - machine_uint_t _block = BLOCK_FROM_PTR(ptr); \ + mp_uint_t _block = BLOCK_FROM_PTR(ptr); \ if (ATB_GET_KIND(_block) == AT_HEAD) { \ /* an unmarked head, mark it, and push it on gc stack */ \ ATB_HEAD_TO_MARK(_block); \ @@ -201,18 +201,18 @@ bool gc_is_locked(void) { STATIC void gc_drain_stack(void) { while (gc_sp > gc_stack) { // pop the next block off the stack - machine_uint_t block = *--gc_sp; + mp_uint_t block = *--gc_sp; // work out number of consecutive blocks in the chain starting with this one - machine_uint_t n_blocks = 0; + mp_uint_t n_blocks = 0; do { n_blocks += 1; } while (ATB_GET_KIND(block + n_blocks) == AT_TAIL); // check this block's children - machine_uint_t *scan = (machine_uint_t*)PTR_FROM_BLOCK(block); - for (machine_uint_t i = n_blocks * WORDS_PER_BLOCK; i > 0; i--, scan++) { - machine_uint_t ptr2 = *scan; + mp_uint_t *scan = (mp_uint_t*)PTR_FROM_BLOCK(block); + for (mp_uint_t i = n_blocks * WORDS_PER_BLOCK; i > 0; i--, scan++) { + mp_uint_t ptr2 = *scan; VERIFY_MARK_AND_PUSH(ptr2); } } @@ -224,7 +224,7 @@ STATIC void gc_deal_with_stack_overflow(void) { gc_sp = gc_stack; // scan entire memory looking for blocks which have been marked but not their children - for (machine_uint_t block = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) { + for (mp_uint_t block = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) { // trace (again) if mark bit set if (ATB_GET_KIND(block) == AT_MARK) { *gc_sp++ = block; @@ -244,7 +244,7 @@ STATIC void gc_sweep(void) { #endif // free unmarked heads and their tails int free_tail = 0; - for (machine_uint_t block = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) { + for (mp_uint_t block = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) { switch (ATB_GET_KIND(block)) { case AT_HEAD: #if MICROPY_ENABLE_FINALISER @@ -290,9 +290,9 @@ void gc_collect_start(void) { gc_sp = gc_stack; } -void gc_collect_root(void **ptrs, machine_uint_t len) { - for (machine_uint_t i = 0; i < len; i++) { - machine_uint_t ptr = (machine_uint_t)ptrs[i]; +void gc_collect_root(void **ptrs, mp_uint_t len) { + for (mp_uint_t i = 0; i < len; i++) { + mp_uint_t ptr = (mp_uint_t)ptrs[i]; VERIFY_MARK_AND_PUSH(ptr); gc_drain_stack(); } @@ -305,14 +305,14 @@ void gc_collect_end(void) { } void gc_info(gc_info_t *info) { - info->total = (gc_pool_end - gc_pool_start) * sizeof(machine_uint_t); + info->total = (gc_pool_end - gc_pool_start) * sizeof(mp_uint_t); info->used = 0; info->free = 0; info->num_1block = 0; info->num_2block = 0; info->max_block = 0; - for (machine_uint_t block = 0, len = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) { - machine_uint_t kind = ATB_GET_KIND(block); + for (mp_uint_t block = 0, len = 0; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB; block++) { + mp_uint_t kind = ATB_GET_KIND(block); if (kind == AT_FREE || kind == AT_HEAD) { if (len == 1) { info->num_1block += 1; @@ -349,8 +349,8 @@ void gc_info(gc_info_t *info) { info->free *= BYTES_PER_BLOCK; } -void *gc_alloc(machine_uint_t n_bytes, bool has_finaliser) { - machine_uint_t n_blocks = ((n_bytes + BYTES_PER_BLOCK - 1) & (~(BYTES_PER_BLOCK - 1))) / BYTES_PER_BLOCK; +void *gc_alloc(mp_uint_t n_bytes, bool has_finaliser) { + mp_uint_t n_blocks = ((n_bytes + BYTES_PER_BLOCK - 1) & (~(BYTES_PER_BLOCK - 1))) / BYTES_PER_BLOCK; DEBUG_printf("gc_alloc(" UINT_FMT " bytes -> " UINT_FMT " blocks)\n", n_bytes, n_blocks); // check if GC is locked @@ -363,10 +363,10 @@ void *gc_alloc(machine_uint_t n_bytes, bool has_finaliser) { return NULL; } - machine_uint_t i; - machine_uint_t end_block; - machine_uint_t start_block; - machine_uint_t n_free = 0; + mp_uint_t i; + mp_uint_t end_block; + mp_uint_t start_block; + mp_uint_t n_free = 0; int collected = 0; for (;;) { @@ -399,7 +399,7 @@ found: // mark rest of blocks as used tail // TODO for a run of many blocks can make this more efficient - for (machine_uint_t bl = start_block + 1; bl <= end_block; bl++) { + for (mp_uint_t bl = start_block + 1; bl <= end_block; bl++) { ATB_FREE_TO_TAIL(bl); } @@ -427,11 +427,11 @@ found: } /* -void *gc_alloc(machine_uint_t n_bytes) { +void *gc_alloc(mp_uint_t n_bytes) { return _gc_alloc(n_bytes, false); } -void *gc_alloc_with_finaliser(machine_uint_t n_bytes) { +void *gc_alloc_with_finaliser(mp_uint_t n_bytes) { return _gc_alloc(n_bytes, true); } */ @@ -443,11 +443,11 @@ void gc_free(void *ptr_in) { return; } - machine_uint_t ptr = (machine_uint_t)ptr_in; + mp_uint_t ptr = (mp_uint_t)ptr_in; DEBUG_printf("gc_free(%p)\n", ptr); if (VERIFY_PTR(ptr)) { - machine_uint_t block = BLOCK_FROM_PTR(ptr); + mp_uint_t block = BLOCK_FROM_PTR(ptr); if (ATB_GET_KIND(block) == AT_HEAD) { // free head and all of its tail blocks do { @@ -458,14 +458,14 @@ void gc_free(void *ptr_in) { } } -machine_uint_t gc_nbytes(void *ptr_in) { - machine_uint_t ptr = (machine_uint_t)ptr_in; +mp_uint_t gc_nbytes(void *ptr_in) { + mp_uint_t ptr = (mp_uint_t)ptr_in; if (VERIFY_PTR(ptr)) { - machine_uint_t block = BLOCK_FROM_PTR(ptr); + mp_uint_t block = BLOCK_FROM_PTR(ptr); if (ATB_GET_KIND(block) == AT_HEAD) { // work out number of consecutive blocks in the chain starting with this on - machine_uint_t n_blocks = 0; + mp_uint_t n_blocks = 0; do { n_blocks += 1; } while (ATB_GET_KIND(block + n_blocks) == AT_TAIL); @@ -479,8 +479,8 @@ machine_uint_t gc_nbytes(void *ptr_in) { #if 0 // old, simple realloc that didn't expand memory in place -void *gc_realloc(void *ptr, machine_uint_t n_bytes) { - machine_uint_t n_existing = gc_nbytes(ptr); +void *gc_realloc(void *ptr, mp_uint_t n_bytes) { + mp_uint_t n_existing = gc_nbytes(ptr); if (n_bytes <= n_existing) { return ptr; } else { @@ -489,7 +489,7 @@ void *gc_realloc(void *ptr, machine_uint_t n_bytes) { has_finaliser = false; } else { #if MICROPY_ENABLE_FINALISER - has_finaliser = FTB_GET(BLOCK_FROM_PTR((machine_uint_t)ptr)); + has_finaliser = FTB_GET(BLOCK_FROM_PTR((mp_uint_t)ptr)); #else has_finaliser = false; #endif @@ -506,7 +506,7 @@ void *gc_realloc(void *ptr, machine_uint_t n_bytes) { #else // Alternative gc_realloc impl -void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { +void *gc_realloc(void *ptr_in, mp_uint_t n_bytes) { if (gc_lock_depth > 0) { return NULL; } @@ -516,7 +516,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { return gc_alloc(n_bytes, false); } - machine_uint_t ptr = (machine_uint_t)ptr_in; + mp_uint_t ptr = (mp_uint_t)ptr_in; // sanity check the ptr if (!VERIFY_PTR(ptr)) { @@ -524,7 +524,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { } // get first block - machine_uint_t block = BLOCK_FROM_PTR(ptr); + mp_uint_t block = BLOCK_FROM_PTR(ptr); // sanity check the ptr is pointing to the head of a block if (ATB_GET_KIND(block) != AT_HEAD) { @@ -532,14 +532,14 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { } // compute number of new blocks that are requested - machine_uint_t new_blocks = (n_bytes + BYTES_PER_BLOCK - 1) / BYTES_PER_BLOCK; + mp_uint_t new_blocks = (n_bytes + BYTES_PER_BLOCK - 1) / BYTES_PER_BLOCK; // get the number of consecutive tail blocks and // the number of free blocks after last tail block // stop if we reach (or are at) end of heap - machine_uint_t n_free = 0; - machine_uint_t n_blocks = 1; // counting HEAD block - machine_uint_t max_block = gc_alloc_table_byte_len * BLOCKS_PER_ATB; + mp_uint_t n_free = 0; + mp_uint_t n_blocks = 1; // counting HEAD block + mp_uint_t max_block = gc_alloc_table_byte_len * BLOCKS_PER_ATB; while (block + n_blocks + n_free < max_block) { if (n_blocks + n_free >= new_blocks) { // stop as soon as we find enough blocks for n_bytes @@ -562,7 +562,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { // check if we can shrink the allocated area if (new_blocks < n_blocks) { // free unneeded tail blocks - for (machine_uint_t bl = block + new_blocks; ATB_GET_KIND(bl) == AT_TAIL; bl++) { + for (mp_uint_t bl = block + new_blocks; ATB_GET_KIND(bl) == AT_TAIL; bl++) { ATB_ANY_TO_FREE(bl); } return ptr_in; @@ -571,7 +571,7 @@ void *gc_realloc(void *ptr_in, machine_uint_t n_bytes) { // check if we can expand in place if (new_blocks <= n_blocks + n_free) { // mark few more blocks as used tail - for (machine_uint_t bl = block + n_blocks; bl < block + new_blocks; bl++) { + for (mp_uint_t bl = block + n_blocks; bl < block + new_blocks; bl++) { assert(ATB_GET_KIND(bl) == AT_FREE); ATB_FREE_TO_TAIL(bl); } @@ -613,7 +613,7 @@ void gc_dump_info() { void gc_dump_alloc_table(void) { printf("GC memory layout; from %p:", gc_pool_start); - for (machine_uint_t bl = 0; bl < gc_alloc_table_byte_len * BLOCKS_PER_ATB; bl++) { + for (mp_uint_t bl = 0; bl < gc_alloc_table_byte_len * BLOCKS_PER_ATB; bl++) { if (bl % 64 == 0) { printf("\n%04x: ", (uint)bl); } @@ -623,12 +623,12 @@ void gc_dump_alloc_table(void) { case AT_HEAD: c = 'h'; break; /* this prints the uPy object type of the head block case AT_HEAD: { - machine_uint_t *ptr = gc_pool_start + bl * WORDS_PER_BLOCK; - if (*ptr == (machine_uint_t)&mp_type_tuple) { c = 'T'; } - else if (*ptr == (machine_uint_t)&mp_type_list) { c = 'L'; } - else if (*ptr == (machine_uint_t)&mp_type_dict) { c = 'D'; } - else if (*ptr == (machine_uint_t)&mp_type_float) { c = 'F'; } - else if (*ptr == (machine_uint_t)&mp_type_fun_bc) { c = 'B'; } + mp_uint_t *ptr = gc_pool_start + bl * WORDS_PER_BLOCK; + if (*ptr == (mp_uint_t)&mp_type_tuple) { c = 'T'; } + else if (*ptr == (mp_uint_t)&mp_type_list) { c = 'L'; } + else if (*ptr == (mp_uint_t)&mp_type_dict) { c = 'D'; } + else if (*ptr == (mp_uint_t)&mp_type_float) { c = 'F'; } + else if (*ptr == (mp_uint_t)&mp_type_fun_bc) { c = 'B'; } else { c = 'h'; } break; } @@ -643,23 +643,23 @@ void gc_dump_alloc_table(void) { #if DEBUG_PRINT void gc_test(void) { - machine_uint_t len = 500; - machine_uint_t *heap = malloc(len); - gc_init(heap, heap + len / sizeof(machine_uint_t)); + mp_uint_t len = 500; + mp_uint_t *heap = malloc(len); + gc_init(heap, heap + len / sizeof(mp_uint_t)); void *ptrs[100]; { - machine_uint_t **p = gc_alloc(16, false); + mp_uint_t **p = gc_alloc(16, false); p[0] = gc_alloc(64, false); p[1] = gc_alloc(1, false); p[2] = gc_alloc(1, false); p[3] = gc_alloc(1, false); - machine_uint_t ***p2 = gc_alloc(16, false); + mp_uint_t ***p2 = gc_alloc(16, false); p2[0] = p; p2[1] = p; ptrs[0] = p2; } for (int i = 0; i < 25; i+=2) { - machine_uint_t *p = gc_alloc(i, false); + mp_uint_t *p = gc_alloc(i, false); printf("p=%p\n", p); if (i & 3) { //ptrs[i] = p; |