/************** 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
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)
{
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 =============================== */
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();
}
- void Dtor()
- {
- if (gcx)
- {
- gcx.Dtor();
- libc.free(gcx);
- gcx = null;
- }
- }
-
-
/**
*
*/
// 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
{
size -= SENTINEL_EXTRA;
p = sentinel_add(p);
sentinel_init(p, size);
- gcx.log_malloc(p, size);
if (bits)
{
assert(size != 0);
void *p = mallocNoSync(size, bits);
- libc.memset(p, 0, size);
+ memset(p, 0, size);
return p;
}
p2 = mallocNoSync(size, bits);
if (psize < size)
size = psize;
- libc.memcpy(p2, p, size);
+ cstring.memcpy(p2, p, size);
p = p2;
}
}
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;
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)
p2 = mallocNoSync(size, bits);
if (psize < size)
size = psize;
- libc.memcpy(p2, p, size);
+ cstring.memcpy(p2, p, size);
p = p2;
}
}
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;
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
// 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));
}
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();
}
}
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);
}
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();
}
}
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);
}
getStats(stats);
}
- gcx.log_collect();
}
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++)
{
// 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;
if (wp.reference)
rt_detachDisposeEvent(wp.reference, &wp.ondestroy);
});
- libc.free(wp);
+ cstdlib.free(wp);
}
}
{
void *pbot;
void *ptop;
+ int opCmp(in Range other)
+ {
+ if (pbot < other.pbot)
+ return -1;
+ else
+ return cast(int)(pbot > other.pbot);
+ }
}
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 =============================== */
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;
byte *minAddr; // min(baseAddr)
byte *maxAddr; // max(topAddr)
- size_t npools;
- Pool **pooltable;
-
List *bucket[B_MAX]; // free list for each size
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() { }
//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++)
}
- /**
- *
- */
- 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)
/**
* 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.
*/
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;
}
// 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;
}
// Try collecting
freedpages = fullcollectshell();
- if (freedpages >= npools * ((POOLSIZE / PAGESIZE) / 4))
+ if (freedpages >= pools.length * ((POOLSIZE / PAGESIZE) / 4))
{
state = 1;
continue;
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:
/**
* 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;
}
// 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);
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;
}
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;
pool.scan.set(biti);
changes = 1;
}
- log_parent(sentinel_add(pool.baseAddr + biti * 16), sentinel_add(pbot));
}
}
}
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();
}
}
- for (n = 0; n < npools; n++)
+ for (n = 0; n < pools.length; n++)
{
- pool = pooltable[n];
+ pool = pools[n];
pool.mark.copy(&pool.freebits);
}
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);
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;
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))
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;
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;
}
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++;
debug (MEMSTOMP)
{
p += PAGESIZE;
- libc.memset(p, 0xF3, PAGESIZE);
+ memset(p, 0xF3, PAGESIZE);
}
}
}
// 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];
}
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;
}
// 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) { }
- }
}
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;
}
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();
*/
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);
}
}
}
}
+
+// vim: set et sw=4 sts=4 :