X-Git-Url: https://git.llucax.com/software/dgc/cdgc.git/blobdiff_plain/5578146600d4ace17878e3b010aa09efdb202fb4..27b5b707bcd280cd2cc4e2a2a5cc17eb4e06347a:/rt/gc/cdgc/gc.d?ds=inline diff --git a/rt/gc/cdgc/gc.d b/rt/gc/cdgc/gc.d index c008177..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; } @@ -619,18 +621,7 @@ void mark(void *pbot, void *ptop, size_t* pm_bitmask) //printf("marking range: %p -> %p\n", pbot, ptop); for (; p1 + type_size <= p2; p1 += type_size) { - size_t n = 0; - if (has_type_info) { - while (n < type_size && pm_bits[n / BITS_PER_WORD] == 0) - n += BITS_PER_WORD; - if (n < type_size && (pm_bits[n / BITS_PER_WORD] & - ((1 << (BITS_PER_WORD / 2)) - 1)) == 0) - n += BITS_PER_WORD / 2; - else if (n < type_size && (pm_bits[n / BITS_PER_WORD] & - ((1 << (BITS_PER_WORD / 4)) - 1)) == 0) - n += BITS_PER_WORD / 4; - } - for (; n < type_size; n++) { + for (size_t n = 0; n < type_size; n++) { // scan bit set for this word if (has_type_info && !(pm_bits[n / BITS_PER_WORD] & (1 << (n % BITS_PER_WORD)))) @@ -937,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)) @@ -1840,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) { @@ -1996,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; }