X-Git-Url: https://git.llucax.com/software/dgc/cdgc.git/blobdiff_plain/b802e8fe709f22ad56f8a43bc9675c114c2fc21f..27b5b707bcd280cd2cc4e2a2a5cc17eb4e06347a:/rt/gc/cdgc/gc.d?ds=sidebyside diff --git a/rt/gc/cdgc/gc.d b/rt/gc/cdgc/gc.d index b8008f1..3a925fc 100644 --- a/rt/gc/cdgc/gc.d +++ b/rt/gc/cdgc/gc.d @@ -264,26 +264,28 @@ bool Invariant() * Return null if not in a Pool. * Assume pools is sorted. */ -Pool *findPool(void *p) +Pool* findPool(void* p) { - if (p >= gc.min_addr && p < gc.max_addr) - { - if (gc.pools.length == 1) - { - return gc.pools[0]; - } - - for (size_t i = 0; i < gc.pools.length; i++) - { - Pool* pool = gc.pools[i]; - if (p < pool.topAddr) - { - if (pool.baseAddr <= p) - return pool; - break; - } - } + if (p < gc.min_addr || p >= gc.max_addr) + return null; + if (gc.pools.length == 0) + return null; + if (gc.pools.length == 1) + return gc.pools[0]; + /// The pooltable[] is sorted by address, so do a binary search + size_t low = 0; + size_t high = gc.pools.length - 1; + while (low <= high) { + size_t mid = (low + high) / 2; + auto pool = gc.pools[mid]; + if (p < pool.baseAddr) + high = mid - 1; + else if (p >= pool.topAddr) + low = mid + 1; + else + return pool; } + // Not found return null; } @@ -295,65 +297,26 @@ Pool *findPool(void *p) BlkInfo getInfo(void* p) { assert (p !is null); - - Pool* pool; + Pool* pool = findPool(p); + if (pool is null) + return BlkInfo.init; BlkInfo info; - - pool = findPool(p); - if (pool) - { - size_t offset = cast(size_t)(p - pool.baseAddr); - size_t pn = offset / PAGESIZE; - Bins bin = cast(Bins)pool.pagetable[pn]; - - //////////////////////////////////////////////////////////////////// - // findAddr - //////////////////////////////////////////////////////////////////// - - if (bin <= B_PAGE) - { - info.base = pool.baseAddr + (offset & notbinsize[bin]); - } - else if (bin == B_PAGEPLUS) - { - do - { - --pn, offset -= PAGESIZE; - } - while (cast(Bins)pool.pagetable[pn] == B_PAGEPLUS); - - info.base = pool.baseAddr + (offset & (offset.max ^ (PAGESIZE-1))); - - // fix bin for use by size calc below - bin = cast(Bins)pool.pagetable[pn]; + info.base = pool.findBase(p); + info.size = pool.findSize(info.base); + info.attr = getAttr(pool, cast(size_t)(info.base - pool.baseAddr) / 16u); + if (has_pointermap(info.attr)) { + info.size -= size_t.sizeof; // PointerMap bitmask + // Points to the PointerMap bitmask pointer, not user data + if (p >= (info.base + info.size)) { + return BlkInfo.init; } - - //////////////////////////////////////////////////////////////////// - // findSize - //////////////////////////////////////////////////////////////////// - - info.size = binsize[bin]; - if (bin == B_PAGE) - { - ubyte* pt; - size_t i; - - pt = &pool.pagetable[0]; - for (i = pn + 1; i < pool.npages; i++) - { - if (pt[i] != B_PAGEPLUS) - break; - } - info.size = (i - pn) * PAGESIZE; - } - - //////////////////////////////////////////////////////////////////// - // getAttr - //////////////////////////////////////////////////////////////////// - - info.attr = getAttr(pool, cast(size_t)(offset / 16)); - if (!(info.attr & BlkAttr.NO_SCAN)) - info.size -= (size_t*).sizeof; // bitmask + } + if (opts.options.sentinel) { + info.base = sentinel_add(info.base); + // points to sentinel data, not user data + if (p < info.base || p >= sentinel_post(info.base)) + return BlkInfo.init; + info.size -= SENTINEL_EXTRA; } return info; } @@ -654,12 +617,14 @@ void mark(void *pbot, void *ptop, size_t* pm_bitmask) size_t type_size = pm_bitmask[0]; size_t* pm_bits = pm_bitmask + 1; + bool has_type_info = type_size != 1 || pm_bits[0] != 1 || pm_bits[1] != 0; //printf("marking range: %p -> %p\n", pbot, ptop); for (; p1 + type_size <= p2; p1 += type_size) { for (size_t n = 0; n < type_size; n++) { // scan bit set for this word - if (!(pm_bits[n / BITS_PER_WORD] & (1 << (n % BITS_PER_WORD)))) + if (has_type_info && + !(pm_bits[n / BITS_PER_WORD] & (1 << (n % BITS_PER_WORD)))) continue; void* p = *(p1 + n); @@ -963,6 +928,7 @@ size_t fullcollect(void *stackTop) for (n = 0; n < gc.pools.length; n++) { pool = gc.pools[n]; + pool.clear_cache(); uint* bbase = pool.mark.base(); size_t pn; for (pn = 0; pn < pool.npages; pn++, bbase += PAGESIZE / (32 * 16)) @@ -1866,6 +1832,15 @@ struct Pool size_t npages; ubyte* pagetable; + /// Cache for findSize() + size_t cached_size; + void* cached_ptr; + + void clear_cache() + { + this.cached_ptr = null; + this.cached_size = 0; + } void initialize(size_t npages) { @@ -2022,10 +1997,15 @@ struct Pool Bins bin = cast(Bins)this.pagetable[pagenum]; if (bin != B_PAGE) return binsize[bin]; - for (size_t i = pagenum + 1; i < this.npages; i++) + if (this.cached_ptr == p) + return this.cached_size; + size_t i = pagenum + 1; + for (; i < this.npages; i++) if (this.pagetable[i] != B_PAGEPLUS) - return (i - pagenum) * PAGESIZE; - return (this.npages - pagenum) * PAGESIZE; + break; + this.cached_ptr = p; + this.cached_size = (i - pagenum) * PAGESIZE; + return this.cached_size; }