X-Git-Url: https://git.llucax.com/software/dgc/cdgc.git/blobdiff_plain/62b4073393f1d66e88322376627c8bef7b27f81d..53daba87c2208fcced6c7704dd31932a8a56467b:/rt/gc/cdgc/gc.d?ds=sidebyside diff --git a/rt/gc/cdgc/gc.d b/rt/gc/cdgc/gc.d index 151d28b..59d9f55 100644 --- a/rt/gc/cdgc/gc.d +++ b/rt/gc/cdgc/gc.d @@ -307,6 +307,8 @@ BlkInfo getInfo(void* p) return BlkInfo.init; BlkInfo info; info.base = pool.findBase(p); + if (info.base is null) + return BlkInfo.init; info.size = pool.findSize(info.base); info.attr = getAttr(pool, cast(size_t)(info.base - pool.baseAddr) / 16u); if (has_pointermap(info.attr)) { @@ -398,7 +400,7 @@ void minimize() { size_t n; size_t pn; - Pool* pool; + Pool* pool; for (n = 0; n < gc.pools.length; n++) { @@ -615,7 +617,7 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask) void **p1 = cast(void **)pbot; void **p2 = cast(void **)ptop; size_t pcache = 0; - uint changes = 0; + bool changes = false; size_t type_size = pm_bitmask[0]; size_t* pm_bits = pm_bitmask + 1; @@ -641,13 +643,17 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask) if (pool) { size_t offset = cast(size_t)(p - pool.baseAddr); - size_t bit_i; + size_t bit_i = void; size_t pn = offset / PAGESIZE; Bins bin = cast(Bins)pool.pagetable[pn]; + // Cache B_PAGE, B_PAGEPLUS and B_FREE lookups + if (bin >= B_PAGE) + pcache = cast(size_t)p & ~(PAGESIZE-1); + // Adjust bit to be at start of allocated memory block if (bin <= B_PAGE) - bit_i = (offset & notbinsize[bin]) >> 4; + bit_i = (offset & notbinsize[bin]) / 16; else if (bin == B_PAGEPLUS) { do @@ -657,14 +663,8 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask) while (cast(Bins)pool.pagetable[pn] == B_PAGEPLUS); bit_i = pn * (PAGESIZE / 16); } - else - { - // Don't mark bits in B_FREE pages + else // Don't mark bits in B_FREE pages continue; - } - - if (bin >= B_PAGE) // Cache B_PAGE and B_PAGEPLUS lookups - pcache = cast(size_t)p & ~(PAGESIZE-1); if (!pool.mark.test(bit_i)) { @@ -672,7 +672,7 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask) if (!pool.noscan.test(bit_i)) { pool.scan.set(bit_i); - changes = 1; + changes = true; } } } @@ -824,9 +824,6 @@ void mark(void *stackTop) { debug(COLLECT_PRINTF) printf("\tmark()\n"); - gc.p_cache = null; - gc.size_cache = 0; - gc.any_changes = false; for (size_t n = 0; n < gc.pools.length; n++) { @@ -972,6 +969,8 @@ size_t sweep() { // Free up everything not marked debug(COLLECT_PRINTF) printf("\tsweep\n"); + gc.p_cache = null; + gc.size_cache = 0; size_t freedpages = 0; size_t freed = 0; for (size_t n = 0; n < gc.pools.length; n++) @@ -1003,14 +1002,12 @@ version(none) // BUG: doesn't work because freebits() must also be cleared { if (pool.finals.nbits && pool.finals.testClear(bit_i)) { if (opts.options.sentinel) - rt_finalize(cast(List *)sentinel_add(p), false/*gc.no_stack > 0*/); + rt_finalize(sentinel_add(p), false/*gc.no_stack > 0*/); else - rt_finalize(cast(List *)p, false/*gc.no_stack > 0*/); + rt_finalize(p, false/*gc.no_stack > 0*/); } clrAttr(pool, bit_i, BlkAttr.ALL_BITS); - List *list = cast(List *)p; - if (opts.options.mem_stomp) memset(p, 0xF3, size); } @@ -1029,14 +1026,12 @@ version(none) // BUG: doesn't work because freebits() must also be cleared pool.freebits.set(bit_i); if (pool.finals.nbits && pool.finals.testClear(bit_i)) { if (opts.options.sentinel) - rt_finalize(cast(List *)sentinel_add(p), false/*gc.no_stack > 0*/); + rt_finalize(sentinel_add(p), false/*gc.no_stack > 0*/); else - rt_finalize(cast(List *)p, false/*gc.no_stack > 0*/); + rt_finalize(p, false/*gc.no_stack > 0*/); } clrAttr(pool, bit_i, BlkAttr.ALL_BITS); - List *list = cast(List *)p; - if (opts.options.mem_stomp) memset(p, 0xF3, size); @@ -1294,6 +1289,7 @@ private void *malloc(size_t size, uint attrs, size_t* pm_bitmask) if (!gc.free_list[bin] && !allocPage(bin)) { newPool(1); // allocate new pool to find a new page + // TODO: hint allocPage() to use the pool we just created int result = allocPage(bin); if (!result) onOutOfMemoryError(); @@ -1437,10 +1433,13 @@ private void *realloc(void *p, size_t size, uint attrs, memset(p + size - pm_bitmask_size, 0xF2, blk_size - size - pm_bitmask_size); pool.freePages(pagenum + newsz, psz - newsz); + auto new_blk_size = (PAGESIZE * newsz); + // update the size cache, assuming that is very likely the + // size of this block will be queried in the near future + pool.update_cache(p, new_blk_size); if (has_pm) { - auto end_of_blk = cast(size_t**)( - blk_base_addr + (PAGESIZE * newsz) - - pm_bitmask_size); + auto end_of_blk = cast(size_t**)(blk_base_addr + + new_blk_size - pm_bitmask_size); *end_of_blk = pm_bitmask; } return p; @@ -1458,10 +1457,14 @@ private void *realloc(void *p, size_t size, uint attrs, - pm_bitmask_size); memset(pool.pagetable + pagenum + psz, B_PAGEPLUS, newsz - psz); + auto new_blk_size = (PAGESIZE * newsz); + // update the size cache, assuming that is very + // likely the size of this block will be queried in + // the near future + pool.update_cache(p, new_blk_size); if (has_pm) { auto end_of_blk = cast(size_t**)( - blk_base_addr + - (PAGESIZE * newsz) - + blk_base_addr + new_blk_size - pm_bitmask_size); *end_of_blk = pm_bitmask; } @@ -1570,6 +1573,9 @@ body memset(pool.pagetable + pagenum + psz, B_PAGEPLUS, sz); gc.p_cache = null; gc.size_cache = 0; + // update the size cache, assuming that is very likely the size of this + // block will be queried in the near future + pool.update_cache(p, new_size); if (has_pm) { new_size -= size_t.sizeof; @@ -1615,11 +1621,13 @@ private void free(void *p) if (opts.options.mem_stomp) memset(p, 0xF2, npages * PAGESIZE); pool.freePages(pagenum, npages); + // just in case we were caching this pointer + pool.clear_cache(p); } else { // Add to free list - List *list = cast(List*)p; + List* list = cast(List*) p; if (opts.options.mem_stomp) memset(p, 0xF2, binsize[bin]); @@ -1716,9 +1724,7 @@ private void checkNoSync(void *p) if (bin < B_PAGE) { // Check that p is not on a free list - List *list; - - for (list = gc.free_list[bin]; list; list = list.next) + for (List* list = gc.free_list[bin]; list; list = list.next) { assert(cast(void*)list != p); } @@ -1784,7 +1790,7 @@ private GCStats getStats() for (n = 0; n < B_PAGE; n++) { - for (List *list = gc.free_list[n]; list; list = list.next) + for (List* list = gc.free_list[n]; list; list = list.next) flsize += binsize[n]; } @@ -1895,10 +1901,18 @@ struct Pool size_t cached_size; void* cached_ptr; - void clear_cache() + void clear_cache(void* ptr = null) + { + if (ptr is null || ptr is this.cached_ptr) { + this.cached_ptr = null; + this.cached_size = 0; + } + } + + void update_cache(void* ptr, size_t size) { - this.cached_ptr = null; - this.cached_size = 0; + this.cached_ptr = ptr; + this.cached_size = size; } void initialize(size_t npages) @@ -1915,7 +1929,6 @@ struct Pool npages = 0; poolsize = 0; } - //assert(baseAddr); topAddr = baseAddr + poolsize; size_t nbits = cast(size_t)poolsize / 16;