X-Git-Url: https://git.llucax.com/software/dgc/cdgc.git/blobdiff_plain/0c03b35e455d2c8bb2c50bb2cdaf3b1538431a0a..11b7fc5cdb1df190c6c434fea14a00e700721fbc:/rt/gc/cdgc/gc.d?ds=sidebyside diff --git a/rt/gc/cdgc/gc.d b/rt/gc/cdgc/gc.d index ca30f56..e7fdbd2 100644 --- a/rt/gc/cdgc/gc.d +++ b/rt/gc/cdgc/gc.d @@ -31,7 +31,6 @@ module rt.gc.cdgc.gc; /************** Debugging ***************************/ //debug = COLLECT_PRINTF; // turn on printf's -//debug = LOGGING; // log allocations / frees //debug = MEMSTOMP; // stomp on memory //debug = SENTINEL; // add underrun/overrrun protection //debug = PTRCHECK; // more pointer checking @@ -48,8 +47,27 @@ version = STACKGROWSDOWN; // growing the stack means subtracting from the import rt.gc.cdgc.bits: GCBits; import rt.gc.cdgc.stats: GCStats; import alloc = rt.gc.cdgc.alloc; -import libc = rt.gc.cdgc.libc; +import rt.gc.cdgc.dynarray: DynArray; +import cstdlib = tango.stdc.stdlib; +import cstring = tango.stdc.string; + +/* + * This is a small optimization that proved it's usefulness. For small chunks + * or memory memset() seems to be slower (probably because of the call) that + * simply doing a simple loop to set the memory. + */ +void memset(void* dst, int c, size_t n) +{ + // This number (32) has been determined empirically + if (n > 32) { + cstring.memset(dst, c, n); + return; + } + auto p = cast(ubyte*)(dst); + while (n-- > 0) + *p++ = c; +} version (GNU) { @@ -110,106 +128,6 @@ private alias GC gc_t; -/* ======================= Leak Detector =========================== */ - - -debug (LOGGING) -{ - struct Log - { - void* p; - size_t size; - size_t line; - char* file; - void* parent; - - void print() - { - printf(" p = %x, size = %d, parent = %x ", p, size, parent); - if (file) - { - printf("%s(%u)", file, line); - } - printf("\n"); - } - } - - - struct LogArray - { - size_t dim; - size_t allocdim; - Log *data; - - void Dtor() - { - if (data) - libc.free(data); - data = null; - } - - void reserve(size_t nentries) - { - assert(dim <= allocdim); - if (allocdim - dim < nentries) - { - allocdim = (dim + nentries) * 2; - assert(dim + nentries <= allocdim); - if (!data) - { - data = cast(Log*) libc.malloc(allocdim * Log.sizeof); - if (!data && allocdim) - onOutOfMemoryError(); - } - else - { - Log *newdata = cast(Log*) libc.malloc( - allocdim * Log.sizeof); - if (!newdata && allocdim) - onOutOfMemoryError(); - libc.memcpy(newdata, data, dim * Log.sizeof); - libc.free(data); - data = newdata; - } - } - } - - - void push(Log log) - { - reserve(1); - data[dim++] = log; - } - - void remove(size_t i) - { - libc.memmove(data + i, data + i + 1, (dim - i) * Log.sizeof); - dim--; - } - - - size_t find(void *p) - { - for (size_t i = 0; i < dim; i++) - { - if (data[i].p == p) - return i; - } - return OPFAIL; // not found - } - - - void copy(LogArray *from) - { - reserve(from.dim - dim); - assert(from.dim <= allocdim); - libc.memcpy(data, from.data, from.dim * Log.sizeof); - dim = from.dim; - } - } -} - - /* ============================ GC =============================== */ @@ -234,7 +152,7 @@ class GC void initialize() { gcLock = GCLock.classinfo; - gcx = cast(Gcx*) libc.calloc(1, Gcx.sizeof); + gcx = cast(Gcx*) cstdlib.calloc(1, Gcx.sizeof); if (!gcx) onOutOfMemoryError(); gcx.initialize(); @@ -242,17 +160,6 @@ class GC } - void Dtor() - { - if (gcx) - { - gcx.Dtor(); - libc.free(gcx); - gcx = null; - } - } - - /** * */ @@ -478,8 +385,8 @@ class GC // Return next item from free list gcx.bucket[bin] = (cast(List*)p).next; if( !(bits & BlkAttr.NO_SCAN) ) - libc.memset(p + size, 0, binsize[bin] - size); - debug (MEMSTOMP) libc.memset(p, 0xF0, size); + memset(p + size, 0, binsize[bin] - size); + debug (MEMSTOMP) memset(p, 0xF0, size); } else { @@ -490,7 +397,6 @@ class GC size -= SENTINEL_EXTRA; p = sentinel_add(p); sentinel_init(p, size); - gcx.log_malloc(p, size); if (bits) { @@ -532,7 +438,7 @@ class GC assert(size != 0); void *p = mallocNoSync(size, bits); - libc.memset(p, 0, size); + memset(p, 0, size); return p; } @@ -603,7 +509,7 @@ class GC p2 = mallocNoSync(size, bits); if (psize < size) size = psize; - libc.memcpy(p2, p, size); + cstring.memcpy(p2, p, size); p = p2; } } @@ -626,7 +532,7 @@ class GC synchronized (gcLock) { debug (MEMSTOMP) - libc.memset(p + size, 0xF2, psize - size); + memset(p + size, 0xF2, psize - size); pool.freePages(pagenum + newsz, psz - newsz); } return p; @@ -641,10 +547,10 @@ class GC if (i == pagenum + newsz) { debug (MEMSTOMP) - libc.memset(p + psize, 0xF0, + memset(p + psize, 0xF0, size - psize); - libc.memset(&pool.pagetable[pagenum + psz], - B_PAGEPLUS, newsz - psz); + memset(pool.pagetable + pagenum + + psz, B_PAGEPLUS, newsz - psz); return p; } if (i == pool.npages) @@ -683,7 +589,7 @@ class GC p2 = mallocNoSync(size, bits); if (psize < size) size = psize; - libc.memcpy(p2, p, size); + cstring.memcpy(p2, p, size); p = p2; } } @@ -755,8 +661,8 @@ class GC if (sz < minsz) return 0; debug (MEMSTOMP) - libc.memset(p + psize, 0xF0, (psz + sz) * PAGESIZE - psize); - libc.memset(pool.pagetable + pagenum + psz, B_PAGEPLUS, sz); + memset(p + psize, 0xF0, (psz + sz) * PAGESIZE - psize); + memset(pool.pagetable + pagenum + psz, B_PAGEPLUS, sz); gcx.p_cache = null; gcx.size_cache = 0; return (psz + sz) * PAGESIZE; @@ -847,7 +753,7 @@ class GC size_t n = pagenum; while (++n < pool.npages && pool.pagetable[n] == B_PAGEPLUS) npages++; - debug (MEMSTOMP) libc.memset(p, 0xF2, npages * PAGESIZE); + debug (MEMSTOMP) memset(p, 0xF2, npages * PAGESIZE); pool.freePages(pagenum, npages); } else @@ -855,12 +761,11 @@ class GC // Add to free list List *list = cast(List*)p; - debug (MEMSTOMP) libc.memset(p, 0xF2, binsize[bin]); + debug (MEMSTOMP) memset(p, 0xF2, binsize[bin]); list.next = gcx.bucket[bin]; gcx.bucket[bin] = list; } - gcx.log_free(sentinel_add(p)); } @@ -1101,11 +1006,13 @@ class GC if (!thread_needLock()) { - gcx.addRoot(p); + if (roots.append(p) is null) + onOutOfMemoryError(); } else synchronized (gcLock) { - gcx.addRoot(p); + if (roots.append(p) is null) + onOutOfMemoryError(); } } @@ -1120,14 +1027,16 @@ class GC return; } + bool r; if (!thread_needLock()) { - gcx.removeRoot(p); + r = roots.remove(p); } else synchronized (gcLock) { - gcx.removeRoot(p); + r = roots.remove(p); } + assert (r); } @@ -1143,11 +1052,13 @@ class GC if (!thread_needLock()) { - gcx.addRange(p, p + sz); + if (ranges.append(Range(p, p+sz)) is null) + onOutOfMemoryError(); } else synchronized (gcLock) { - gcx.addRange(p, p + sz); + if (ranges.append(Range(p, p+sz)) is null) + onOutOfMemoryError(); } } @@ -1162,14 +1073,16 @@ class GC return; } + bool r; if (!thread_needLock()) { - gcx.removeRange(p); + r = ranges.remove(Range(p, null)); } else synchronized (gcLock) { - gcx.removeRange(p); + r = ranges.remove(Range(p, null)); } + assert (r); } @@ -1194,7 +1107,6 @@ class GC getStats(stats); } - gcx.log_collect(); } @@ -1263,11 +1175,11 @@ class GC size_t n; size_t bsize = 0; - libc.memset(&stats, 0, GCStats.sizeof); + memset(&stats, 0, GCStats.sizeof); - for (n = 0; n < gcx.npools; n++) + for (n = 0; n < pools.length; n++) { - Pool *pool = gcx.pooltable[n]; + Pool* pool = pools[n]; psize += pool.npages * PAGESIZE; for (size_t j = 0; j < pool.npages; j++) { @@ -1331,7 +1243,7 @@ class GC // 1. to hide the reference from the GC // 2. the GC doesn't scan delegates added by rt_attachDisposeEvent // for references - auto wp = cast(WeakPointer*)(libc.malloc(WeakPointer.sizeof)); + auto wp = cast(WeakPointer*)(cstdlib.malloc(WeakPointer.sizeof)); if (!wp) onOutOfMemoryError(); wp.reference = r; @@ -1356,7 +1268,7 @@ class GC if (wp.reference) rt_detachDisposeEvent(wp.reference, &wp.ondestroy); }); - libc.free(wp); + cstdlib.free(wp); } } @@ -1420,6 +1332,13 @@ struct Range { void *pbot; void *ptop; + int opCmp(in Range other) + { + if (pbot < other.pbot) + return -1; + else + return cast(int)(pbot > other.pbot); + } } @@ -1427,6 +1346,13 @@ const uint binsize[B_MAX] = [ 16,32,64,128,256,512,1024,2048,4096 ]; const uint notbinsize[B_MAX] = [ ~(16u-1),~(32u-1),~(64u-1),~(128u-1),~(256u-1), ~(512u-1),~(1024u-1),~(2048u-1),~(4096u-1) ]; +DynArray!(void*) roots; + +DynArray!(Range) ranges; + +DynArray!(Pool) pools; + + /* ============================ Gcx =============================== */ @@ -1436,14 +1362,6 @@ struct Gcx void *p_cache; size_t size_cache; - size_t nroots; - size_t rootdim; - void **roots; - - size_t nranges; - size_t rangedim; - Range *ranges; - uint noStack; // !=0 means don't scan stack uint log; // turn on logging uint anychanges; @@ -1454,9 +1372,6 @@ struct Gcx byte *minAddr; // min(baseAddr) byte *maxAddr; // max(topAddr) - size_t npools; - Pool **pooltable; - List *bucket[B_MAX]; // free list for each size @@ -1465,33 +1380,11 @@ struct Gcx int dummy; (cast(byte*)this)[0 .. Gcx.sizeof] = 0; stackBottom = cast(char*)&dummy; - log_init(); //printf("gcx = %p, self = %x\n", this, self); inited = 1; } - void Dtor() - { - inited = 0; - - for (size_t i = 0; i < npools; i++) - { - Pool *pool = pooltable[i]; - pool.Dtor(); - libc.free(pool); - } - if (pooltable) - libc.free(pooltable); - - if (roots) - libc.free(roots); - - if (ranges) - libc.free(ranges); - } - - void Invariant() { } @@ -1502,41 +1395,32 @@ struct Gcx //printf("Gcx.invariant(): this = %p\n", this); size_t i; - for (i = 0; i < npools; i++) + for (i = 0; i < pools.length; i++) { - Pool *pool = pooltable[i]; + Pool* pool = pools[i]; pool.Invariant(); if (i == 0) { assert(minAddr == pool.baseAddr); } - if (i + 1 < npools) + if (i + 1 < pools.length) { - assert(pool.opCmp(pooltable[i + 1]) < 0); + assert(*pool < pools[i + 1]); } - else if (i + 1 == npools) + else if (i + 1 == pools.length) { assert(maxAddr == pool.topAddr); } } - if (roots) - { - assert(rootdim != 0); - assert(nroots <= rootdim); - } + roots.Invariant(); + ranges.Invariant(); - if (ranges) + for (i = 0; i < ranges.length; i++) { - assert(rangedim != 0); - assert(nranges <= rangedim); - - for (i = 0; i < nranges; i++) - { - assert(ranges[i].pbot); - assert(ranges[i].ptop); - assert(ranges[i].pbot <= ranges[i].ptop); - } + assert(ranges[i].pbot); + assert(ranges[i].ptop); + assert(ranges[i].pbot <= ranges[i].ptop); } for (i = 0; i < B_PAGE; i++) @@ -1549,120 +1433,23 @@ struct Gcx } - /** - * - */ - void addRoot(void *p) - { - if (nroots == rootdim) - { - size_t newdim = rootdim * 2 + 16; - void** newroots; - - newroots = cast(void**) libc.malloc(newdim * newroots[0].sizeof); - if (!newroots) - onOutOfMemoryError(); - if (roots) - { - libc.memcpy(newroots, roots, nroots * newroots[0].sizeof); - libc.free(roots); - } - roots = newroots; - rootdim = newdim; - } - roots[nroots] = p; - nroots++; - } - - - /** - * - */ - void removeRoot(void *p) - { - for (size_t i = nroots; i--;) - { - if (roots[i] == p) - { - nroots--; - libc.memmove(roots + i, roots + i + 1, - (nroots - i) * roots[0].sizeof); - return; - } - } - assert(0); - } - - - /** - * - */ - void addRange(void *pbot, void *ptop) - { - if (nranges == rangedim) - { - size_t newdim = rangedim * 2 + 16; - Range *newranges; - - newranges = cast(Range*) libc.malloc(newdim * newranges[0].sizeof); - if (!newranges) - onOutOfMemoryError(); - if (ranges) - { - libc.memcpy(newranges, ranges, nranges * newranges[0].sizeof); - libc.free(ranges); - } - ranges = newranges; - rangedim = newdim; - } - ranges[nranges].pbot = pbot; - ranges[nranges].ptop = ptop; - nranges++; - } - - - /** - * - */ - void removeRange(void *pbot) - { - for (size_t i = nranges; i--;) - { - if (ranges[i].pbot == pbot) - { - nranges--; - libc.memmove(ranges + i, ranges + i + 1, - (nranges - i) * ranges[0].sizeof); - return; - } - } - - // This is a fatal error, but ignore it. - // The problem is that we can get a Close() call on a thread - // other than the one the range was allocated on. - //assert(zero); - } - - /** * Find Pool that pointer is in. * Return null if not in a Pool. - * Assume pooltable[] is sorted. + * Assume pools is sorted. */ Pool *findPool(void *p) { if (p >= minAddr && p < maxAddr) { - if (npools == 1) + if (pools.length == 1) { - return pooltable[0]; + return pools[0]; } - for (size_t i = 0; i < npools; i++) + for (size_t i = 0; i < pools.length; i++) { - Pool *pool; - - pool = pooltable[i]; + Pool* pool = pools[i]; if (p < pool.topAddr) { if (pool.baseAddr <= p) @@ -1864,7 +1651,7 @@ struct Gcx /** * Allocate a new pool of at least size bytes. - * Sort it into pooltable[]. + * Sort it into pools. * Mark all memory in the pool as B_FREE. * Return the actual number of bytes reserved or 0 on error. */ @@ -1888,27 +1675,22 @@ struct Gcx size_t pn; Pool* pool; - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; for (pn = 0; pn < pool.npages; pn++) { if (cast(Bins)pool.pagetable[pn] != B_FREE) break; } if (pn < pool.npages) - { - n++; continue; - } pool.Dtor(); - libc.free(pool); - libc.memmove(pooltable + n, - pooltable + n + 1, - (--npools - n) * (Pool*).sizeof); - minAddr = pooltable[0].baseAddr; - maxAddr = pooltable[npools - 1].topAddr; + pools.remove_at(n); + n--; } + minAddr = pools[0].baseAddr; + maxAddr = pools[pools.length - 1].topAddr; } @@ -1933,9 +1715,9 @@ struct Gcx // This code could use some refinement when repeatedly // allocating very large arrays. - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; pn = pool.allocPages(npages); if (pn != OPFAIL) goto L1; @@ -1952,7 +1734,7 @@ struct Gcx } // Try collecting freedpages = fullcollectshell(); - if (freedpages >= npools * ((POOLSIZE / PAGESIZE) / 4)) + if (freedpages >= pools.length * ((POOLSIZE / PAGESIZE) / 4)) { state = 1; continue; @@ -1989,10 +1771,10 @@ struct Gcx L1: pool.pagetable[pn] = B_PAGE; if (npages > 1) - libc.memset(&pool.pagetable[pn + 1], B_PAGEPLUS, npages - 1); + memset(&pool.pagetable[pn + 1], B_PAGEPLUS, npages - 1); p = pool.baseAddr + pn * PAGESIZE; - libc.memset(cast(char *)p + size, 0, npages * PAGESIZE - size); - debug (MEMSTOMP) libc.memset(p, 0xF1, size); + memset(cast(char *)p + size, 0, npages * PAGESIZE - size); + debug (MEMSTOMP) memset(p, 0xF1, size); return p; Lnomemory: @@ -2002,16 +1784,11 @@ struct Gcx /** * Allocate a new pool with at least npages in it. - * Sort it into pooltable[]. + * Sort it into pools. * Return null if failed. */ Pool *newPool(size_t npages) { - Pool* pool; - Pool** newpooltable; - size_t newnpools; - size_t i; - // Minimum of POOLSIZE if (npages < POOLSIZE/PAGESIZE) npages = POOLSIZE/PAGESIZE; @@ -2024,9 +1801,9 @@ struct Gcx } // Allocate successively larger pools up to 8 megs - if (npools) + if (pools.length) { - size_t n = npools; + size_t n = pools.length; if (n > 8) n = 8; // cap pool size at 8 megs n *= (POOLSIZE / PAGESIZE); @@ -2034,41 +1811,21 @@ struct Gcx npages = n; } - pool = cast(Pool *) libc.calloc(1, Pool.sizeof); - if (pool) + Pool p; + p.initialize(npages); + if (!p.baseAddr) { - pool.initialize(npages); - if (!pool.baseAddr) - goto Lerr; - - newnpools = npools + 1; - newpooltable = cast(Pool **) libc.realloc(pooltable, - newnpools * (Pool *).sizeof); - if (!newpooltable) - goto Lerr; - - // Sort pool into newpooltable[] - for (i = 0; i < npools; i++) - { - if (pool.opCmp(newpooltable[i]) < 0) - break; - } - libc.memmove(newpooltable + i + 1, newpooltable + i, - (npools - i) * (Pool *).sizeof); - newpooltable[i] = pool; - - pooltable = newpooltable; - npools = newnpools; + p.Dtor(); + return null; + } - minAddr = pooltable[0].baseAddr; - maxAddr = pooltable[npools - 1].topAddr; + Pool* pool = pools.insert_sorted(p); + if (pool) + { + minAddr = pools[0].baseAddr; + maxAddr = pools[pools.length - 1].topAddr; } return pool; - - Lerr: - pool.Dtor(); - libc.free(pool); - return null; } @@ -2085,9 +1842,9 @@ struct Gcx byte* p; byte* ptop; - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; pn = pool.allocPages(1); if (pn != OPFAIL) goto L1; @@ -2170,7 +1927,6 @@ struct Gcx pool.scan.set(biti); changes = 1; } - log_parent(sentinel_add(pool.baseAddr + biti * 16), sentinel_add(pbot)); } } } @@ -2282,9 +2038,9 @@ struct Gcx size_cache = 0; anychanges = 0; - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; pool.mark.zero(); pool.scan.zero(); pool.freebits.zero(); @@ -2301,9 +2057,9 @@ struct Gcx } } - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; pool.mark.copy(&pool.freebits); } @@ -2315,14 +2071,14 @@ struct Gcx thread_scanAll( &mark, stackTop ); } - // Scan roots[] + // Scan roots debug(COLLECT_PRINTF) printf("scan roots[]\n"); - mark(roots, roots + nroots); + mark(roots.ptr, roots.ptr + roots.length); - // Scan ranges[] + // Scan ranges debug(COLLECT_PRINTF) printf("scan ranges[]\n"); //log++; - for (n = 0; n < nranges; n++) + for (n = 0; n < ranges.length; n++) { debug(COLLECT_PRINTF) printf("\t%x .. %x\n", ranges[n].pbot, ranges[n].ptop); mark(ranges[n].pbot, ranges[n].ptop); @@ -2333,13 +2089,13 @@ struct Gcx while (anychanges) { anychanges = 0; - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { uint *bbase; uint *b; uint *btop; - pool = pooltable[n]; + pool = pools[n]; bbase = pool.scan.base(); btop = bbase + pool.scan.nwords; @@ -2399,9 +2155,9 @@ struct Gcx debug(COLLECT_PRINTF) printf("\tfree'ing\n"); size_t freedpages = 0; size_t freed = 0; - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; uint* bbase = pool.mark.base(); size_t pn; for (pn = 0; pn < pool.npages; pn++, bbase += PAGESIZE / (32 * 16)) @@ -2429,9 +2185,8 @@ struct Gcx gcx.clrBits(pool, biti, BlkAttr.ALL_BITS); List *list = cast(List *)p; - log_free(sentinel_add(list)); - debug (MEMSTOMP) libc.memset(p, 0xF3, size); + debug (MEMSTOMP) memset(p, 0xF3, size); } pool.pagetable[pn] = B_FREE; freed += PAGESIZE; @@ -2450,9 +2205,8 @@ struct Gcx clrBits(pool, biti, BlkAttr.ALL_BITS); List *list = cast(List *)p; - log_free(sentinel_add(list)); - debug (MEMSTOMP) libc.memset(p, 0xF3, size); + debug (MEMSTOMP) memset(p, 0xF3, size); freed += size; } @@ -2470,10 +2224,9 @@ struct Gcx clrBits(pool, biti, BlkAttr.ALL_BITS); debug(COLLECT_PRINTF) printf("\tcollecting big %x\n", p); - log_free(sentinel_add(p)); pool.pagetable[pn] = B_FREE; freedpages++; - debug (MEMSTOMP) libc.memset(p, 0xF3, PAGESIZE); + debug (MEMSTOMP) memset(p, 0xF3, PAGESIZE); while (pn + 1 < pool.npages && pool.pagetable[pn + 1] == B_PAGEPLUS) { pn++; @@ -2483,7 +2236,7 @@ struct Gcx debug (MEMSTOMP) { p += PAGESIZE; - libc.memset(p, 0xF3, PAGESIZE); + memset(p, 0xF3, PAGESIZE); } } } @@ -2497,9 +2250,9 @@ struct Gcx // Free complete pages, rebuild free list debug(COLLECT_PRINTF) printf("\tfree complete pages\n"); size_t recoveredpages = 0; - for (n = 0; n < npools; n++) + for (n = 0; n < pools.length; n++) { - pool = pooltable[n]; + pool = pools[n]; for (size_t pn = 0; pn < pool.npages; pn++) { Bins bin = cast(Bins)pool.pagetable[pn]; @@ -2542,7 +2295,7 @@ struct Gcx } debug(COLLECT_PRINTF) printf("recovered pages = %d\n", recoveredpages); - debug(COLLECT_PRINTF) printf("\tfree'd %u bytes, %u pages from %u pools\n", freed, freedpages, npools); + debug(COLLECT_PRINTF) printf("\tfree'd %u bytes, %u pages from %u pools\n", freed, freedpages, pools.length); return freedpages + recoveredpages; } @@ -2619,111 +2372,6 @@ struct Gcx // pool.nomove.clear(biti); } - - /***** Leak Detector ******/ - - - debug (LOGGING) - { - LogArray current; - LogArray prev; - - - void log_init() - { - current.reserve(1000); - prev.reserve(1000); - } - - - void log_malloc(void *p, size_t size) - { - Log log; - - log.p = p; - log.size = size; - log.line = GC.line; - log.file = GC.file; - log.parent = null; - - GC.line = 0; - GC.file = null; - - current.push(log); - } - - - void log_free(void *p) - { - size_t i; - - i = current.find(p); - if (i != OPFAIL) - current.remove(i); - } - - - void log_collect() - { - // Print everything in current that is not in prev - size_t used = 0; - for (size_t i = 0; i < current.dim; i++) - { - size_t j; - - j = prev.find(current.data[i].p); - if (j == OPFAIL) - current.data[i].print(); - else - used++; - } - - for (size_t i = 0; i < current.dim; i++) - { - void *p; - size_t j; - - p = current.data[i].p; - if (!findPool(current.data[i].parent)) - { - j = prev.find(current.data[i].p); - current.data[i].print(); - } - } - - prev.copy(¤t); - } - - - void log_parent(void *p, void *parent) - { - size_t i; - - i = current.find(p); - if (i == OPFAIL) - { - Pool *pool; - pool = findPool(p); - assert(pool); - size_t offset = cast(size_t)(p - pool.baseAddr); - size_t biti; - size_t pn = offset / PAGESIZE; - Bins bin = cast(Bins)pool.pagetable[pn]; - biti = (offset & notbinsize[bin]); - } - else - current.data[i].parent = parent; - } - - } - else - { - void log_init() { } - void log_malloc(void *p, size_t size) { } - void log_free(void *p) { } - void log_collect() { } - void log_parent(void *p, void *parent) { } - } } @@ -2766,10 +2414,10 @@ struct Pool freebits.alloc(cast(size_t)poolsize / 16); noscan.alloc(cast(size_t)poolsize / 16); - pagetable = cast(ubyte*) libc.malloc(npages); + pagetable = cast(ubyte*) cstdlib.malloc(npages); if (!pagetable) onOutOfMemoryError(); - libc.memset(pagetable, B_FREE, npages); + memset(pagetable, B_FREE, npages); this.npages = npages; } @@ -2791,8 +2439,9 @@ struct Pool baseAddr = null; topAddr = null; } + // See Gcx.Dtor() for the rationale of the null check. if (pagetable) - libc.free(pagetable); + cstdlib.free(pagetable); mark.Dtor(); scan.Dtor(); @@ -2857,19 +2506,19 @@ struct Pool */ void freePages(size_t pagenum, size_t npages) { - libc.memset(&pagetable[pagenum], B_FREE, npages); + memset(&pagetable[pagenum], B_FREE, npages); } /** - * Used for sorting pooltable[] + * Used for sorting pools */ - int opCmp(Pool *p2) + int opCmp(in Pool other) { - if (baseAddr < p2.baseAddr) + if (baseAddr < other.baseAddr) return -1; else - return cast(int)(baseAddr > p2.baseAddr); + return cast(int)(baseAddr > other.baseAddr); } } @@ -2942,3 +2591,5 @@ else } } + +// vim: set et sw=4 sts=4 :