/************** Debugging ***************************/
-//debug = PRINTF; // turn on printf's
//debug = COLLECT_PRINTF; // turn on printf's
//debug = LOGGING; // log allocations / frees
//debug = MEMSTOMP; // stomp on memory
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 cstdlib = tango.stdc.stdlib;
+import cstring = tango.stdc.string;
version (GNU)
void Dtor()
{
if (data)
- libc.free(data);
+ cstdlib.free(data);
data = null;
}
assert(dim + nentries <= allocdim);
if (!data)
{
- data = cast(Log*) libc.malloc(allocdim * Log.sizeof);
+ data = cast(Log*) cstdlib.malloc(allocdim * Log.sizeof);
if (!data && allocdim)
onOutOfMemoryError();
}
else
{
- Log *newdata = cast(Log*) libc.malloc(
+ Log *newdata = cast(Log*) cstdlib.malloc(
allocdim * Log.sizeof);
if (!newdata && allocdim)
onOutOfMemoryError();
- libc.memcpy(newdata, data, dim * Log.sizeof);
- libc.free(data);
+ cstring.memcpy(newdata, data, dim * Log.sizeof);
+ cstdlib.free(data);
data = newdata;
}
}
void remove(size_t i)
{
- libc.memmove(data + i, data + i + 1, (dim - i) * Log.sizeof);
+ cstring.memmove(data + i, data + i + 1, (dim - i) * Log.sizeof);
dim--;
}
{
reserve(from.dim - dim);
assert(from.dim <= allocdim);
- libc.memcpy(data, from.data, from.dim * Log.sizeof);
+ cstring.memcpy(data, from.data, from.dim * Log.sizeof);
dim = from.dim;
}
}
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();
if (gcx)
{
gcx.Dtor();
- libc.free(gcx);
+ cstdlib.free(gcx);
gcx = null;
}
}
void *p = null;
Bins bin;
- //debug(PRINTF) printf("GC::malloc(size = %d, gcx = %p)\n", size, gcx);
assert(gcx);
size += SENTINEL_EXTRA;
// 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(PRINTF) printf("\tmalloc => %x\n", p);
- debug (MEMSTOMP) libc.memset(p, 0xF0, size);
+ cstring.memset(p + size, 0, binsize[bin] - size);
+ debug (MEMSTOMP) cstring.memset(p, 0xF0, size);
}
else
{
{
assert(size != 0);
- //debug(PRINTF) printf("calloc: %x len %d\n", p, len);
void *p = mallocNoSync(size, bits);
- libc.memset(p, 0, size);
+ cstring.memset(p, 0, size);
return p;
}
void *p2;
size_t psize;
- //debug(PRINTF) printf("GC::realloc(p = %x, size = %u)\n", p, size);
version (SENTINEL)
{
sentinel_Invariant(p);
p2 = mallocNoSync(size, bits);
if (psize < size)
size = psize;
- //debug(PRINTF) printf("\tcopying %d bytes\n",size);
- libc.memcpy(p2, p, size);
+ cstring.memcpy(p2, p, size);
p = p2;
}
}
synchronized (gcLock)
{
debug (MEMSTOMP)
- libc.memset(p + size, 0xF2, psize - size);
+ cstring.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,
+ cstring.memset(p + psize, 0xF0,
size - psize);
- libc.memset(&pool.pagetable[pagenum + psz],
- B_PAGEPLUS, newsz - psz);
+ cstring.memset(pool.pagetable + pagenum +
+ psz, B_PAGEPLUS, newsz - psz);
return p;
}
if (i == pool.npages)
p2 = mallocNoSync(size, bits);
if (psize < size)
size = psize;
- //debug(PRINTF) printf("\tcopying %d bytes\n",size);
- libc.memcpy(p2, p, size);
+ cstring.memcpy(p2, p, size);
p = p2;
}
}
}
body
{
- //debug(PRINTF) printf("GC::extend(p = %x, minsize = %u, maxsize = %u)\n", p, minsize, maxsize);
version (SENTINEL)
{
return 0;
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);
+ cstring.memset(p + psize, 0xF0, (psz + sz) * PAGESIZE - psize);
+ cstring.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) cstring.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) cstring.memset(p, 0xF2, binsize[bin]);
list.next = gcx.bucket[bin];
gcx.bucket[bin] = list;
//p = (void *)((uint *)p + 4);
if (p > gcx.stackBottom)
{
- //debug(PRINTF) printf("setStackBottom(%x)\n", p);
gcx.stackBottom = p;
}
}
//p = (void *)((uint *)p - 4);
if (p < gcx.stackBottom)
{
- //debug(PRINTF) printf("setStackBottom(%x)\n", p);
gcx.stackBottom = cast(char*)p;
}
}
return;
}
- //debug(PRINTF) printf("+GC.addRange(pbot = x%x, ptop = x%x)\n", pbot, ptop);
if (!thread_needLock())
{
gcx.addRange(p, p + sz);
{
gcx.addRange(p, p + sz);
}
- //debug(PRINTF) printf("-GC.addRange()\n");
}
*/
void fullCollect()
{
- debug(PRINTF) printf("GC.fullCollect()\n");
if (!thread_needLock())
{
version (none)
{
GCStats stats;
-
getStats(stats);
- debug(PRINTF) printf("poolsize = %x, usedsize = %x, freelistsize = %x\n",
- stats.poolsize, stats.usedsize, stats.freelistsize);
}
gcx.log_collect();
size_t n;
size_t bsize = 0;
- //debug(PRINTF) printf("getStats()\n");
- libc.memset(&stats, 0, GCStats.sizeof);
+ cstring.memset(&stats, 0, GCStats.sizeof);
for (n = 0; n < gcx.npools; n++)
{
for (n = 0; n < B_PAGE; n++)
{
- //debug(PRINTF) printf("bin %d\n", n);
for (List *list = gcx.bucket[n]; list; list = list.next)
- {
- //debug(PRINTF) printf("\tlist %x\n", list);
flsize += binsize[n];
- }
}
usize = bsize - flsize;
// 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);
}
}
{
Pool *pool = pooltable[i];
pool.Dtor();
- libc.free(pool);
+ cstdlib.free(pool);
}
if (pooltable)
- libc.free(pooltable);
+ cstdlib.free(pooltable);
if (roots)
- libc.free(roots);
+ cstdlib.free(roots);
if (ranges)
- libc.free(ranges);
+ cstdlib.free(ranges);
}
size_t newdim = rootdim * 2 + 16;
void** newroots;
- newroots = cast(void**) libc.malloc(newdim * newroots[0].sizeof);
+ newroots = cast(void**) cstdlib.malloc(newdim * newroots[0].sizeof);
if (!newroots)
onOutOfMemoryError();
if (roots)
{
- libc.memcpy(newroots, roots, nroots * newroots[0].sizeof);
- libc.free(roots);
+ cstring.memcpy(newroots, roots, nroots * newroots[0].sizeof);
+ cstdlib.free(roots);
}
roots = newroots;
rootdim = newdim;
if (roots[i] == p)
{
nroots--;
- libc.memmove(roots + i, roots + i + 1,
+ cstring.memmove(roots + i, roots + i + 1,
(nroots - i) * roots[0].sizeof);
return;
}
*/
void addRange(void *pbot, void *ptop)
{
- debug (PRINTF) printf("%x.Gcx::addRange(%x, %x), nranges = %d\n", this,
- pbot, ptop, nranges);
if (nranges == rangedim)
{
size_t newdim = rangedim * 2 + 16;
Range *newranges;
- newranges = cast(Range*) libc.malloc(newdim * newranges[0].sizeof);
+ newranges = cast(Range*) cstdlib.malloc(newdim * Range.sizeof);
if (!newranges)
onOutOfMemoryError();
if (ranges)
{
- libc.memcpy(newranges, ranges, nranges * newranges[0].sizeof);
- libc.free(ranges);
+ cstring.memcpy(newranges, ranges, nranges * Range.sizeof);
+ cstdlib.free(ranges);
}
ranges = newranges;
rangedim = newdim;
*/
void removeRange(void *pbot)
{
- debug (PRINTF) printf("%x.Gcx.removeRange(%x), nranges = %d\n", this,
- pbot, nranges);
for (size_t i = nranges; i--;)
{
if (ranges[i].pbot == pbot)
{
nranges--;
- libc.memmove(ranges + i, ranges + i + 1,
+ cstring.memmove(ranges + i, ranges + i + 1,
(nranges - i) * ranges[0].sizeof);
return;
}
}
- debug(PRINTF) printf("Wrong thread\n");
// This is a fatal error, but ignore it.
// The problem is that we can get a Close() call on a thread
continue;
}
pool.Dtor();
- libc.free(pool);
- libc.memmove(pooltable + n,
+ cstdlib.free(pool);
+ cstring.memmove(pooltable + n,
pooltable + n + 1,
(--npools - n) * (Pool*).sizeof);
minAddr = pooltable[0].baseAddr;
L1:
pool.pagetable[pn] = B_PAGE;
if (npages > 1)
- libc.memset(&pool.pagetable[pn + 1], B_PAGEPLUS, npages - 1);
+ cstring.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);
- //debug(PRINTF) printf("\tp = %x\n", p);
+ cstring.memset(cast(char *)p + size, 0, npages * PAGESIZE - size);
+ debug (MEMSTOMP) cstring.memset(p, 0xF1, size);
return p;
Lnomemory:
size_t newnpools;
size_t i;
- //debug(PRINTF) printf("************Gcx::newPool(npages = %d)****************\n", npages);
-
// Minimum of POOLSIZE
if (npages < POOLSIZE/PAGESIZE)
npages = POOLSIZE/PAGESIZE;
npages = n;
}
- pool = cast(Pool *) libc.calloc(1, Pool.sizeof);
+ pool = cast(Pool *) cstdlib.calloc(1, Pool.sizeof);
if (pool)
{
pool.initialize(npages);
goto Lerr;
newnpools = npools + 1;
- newpooltable = cast(Pool **) libc.realloc(pooltable,
+ newpooltable = cast(Pool **) cstdlib.realloc(pooltable,
newnpools * (Pool *).sizeof);
if (!newpooltable)
goto Lerr;
if (pool.opCmp(newpooltable[i]) < 0)
break;
}
- libc.memmove(newpooltable + i + 1, newpooltable + i,
+ cstring.memmove(newpooltable + i + 1, newpooltable + i,
(npools - i) * (Pool *).sizeof);
newpooltable[i] = pool;
Lerr:
pool.Dtor();
- libc.free(pool);
+ cstdlib.free(pool);
return null;
}
byte* p;
byte* ptop;
- //debug(PRINTF) printf("Gcx::allocPage(bin = %d)\n", bin);
for (n = 0; n < npools; n++)
{
pool = pooltable[n];
Pool *pool;
byte *p = cast(byte *)(*p1);
- //if (log) debug(PRINTF) printf("\tmark %x\n", p);
if (p >= minAddr && p < maxAddr)
{
if ((cast(size_t)p & ~(PAGESIZE-1)) == pcache)
size_t pn = offset / PAGESIZE;
Bins bin = cast(Bins)pool.pagetable[pn];
- //debug(PRINTF) printf("\t\tfound pool %x, base=%x, pn = %d, bin = %d, biti = x%x\n", pool, pool.baseAddr, pn, bin, biti);
-
// Adjust bit to be at start of allocated memory block
if (bin <= B_PAGE)
- {
biti = (offset & notbinsize[bin]) >> 4;
- //debug(PRINTF) printf("\t\tbiti = x%x\n", biti);
- }
else if (bin == B_PAGEPLUS)
{
do
if (bin >= B_PAGE) // Cache B_PAGE and B_PAGEPLUS lookups
pcache = cast(size_t)p & ~(PAGESIZE-1);
- //debug(PRINTF) printf("\t\tmark(x%x) = %d\n", biti, pool.mark.test(biti));
if (!pool.mark.test(biti))
{
- //if (log) debug(PRINTF) printf("\t\tmarking %x\n", p);
pool.mark.set(biti);
if (!pool.noscan.test(biti))
{
gcx.clrBits(pool, biti, BlkAttr.ALL_BITS);
List *list = cast(List *)p;
- //debug(PRINTF) printf("\tcollecting %x\n", list);
log_free(sentinel_add(list));
- debug (MEMSTOMP) libc.memset(p, 0xF3, size);
+ debug (MEMSTOMP) cstring.memset(p, 0xF3, size);
}
pool.pagetable[pn] = B_FREE;
freed += PAGESIZE;
- //debug(PRINTF) printf("freeing entire page %d\n", pn);
continue;
}
}
clrBits(pool, biti, BlkAttr.ALL_BITS);
List *list = cast(List *)p;
- debug(PRINTF) printf("\tcollecting %x\n", list);
log_free(sentinel_add(list));
- debug (MEMSTOMP) libc.memset(p, 0xF3, size);
+ debug (MEMSTOMP) cstring.memset(p, 0xF3, size);
freed += size;
}
log_free(sentinel_add(p));
pool.pagetable[pn] = B_FREE;
freedpages++;
- debug (MEMSTOMP) libc.memset(p, 0xF3, PAGESIZE);
+ debug (MEMSTOMP) cstring.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);
+ cstring.memset(p, 0xF3, PAGESIZE);
}
}
}
void log_init()
{
- //debug(PRINTF) printf("+log_init()\n");
current.reserve(1000);
prev.reserve(1000);
- //debug(PRINTF) printf("-log_init()\n");
}
void log_malloc(void *p, size_t size)
{
- //debug(PRINTF) printf("+log_malloc(p = %x, size = %d)\n", p, size);
Log log;
log.p = p;
GC.file = null;
current.push(log);
- //debug(PRINTF) printf("-log_malloc()\n");
}
void log_free(void *p)
{
- //debug(PRINTF) printf("+log_free(%x)\n", p);
size_t i;
i = current.find(p);
- if (i == OPFAIL)
- {
- debug(PRINTF) printf("free'ing unallocated memory %x\n", p);
- }
- else
+ if (i != OPFAIL)
current.remove(i);
- //debug(PRINTF) printf("-log_free()\n");
}
void log_collect()
{
- //debug(PRINTF) printf("+log_collect()\n");
// Print everything in current that is not in prev
-
- debug(PRINTF) printf("New pointers this cycle: --------------------------------\n");
size_t used = 0;
for (size_t i = 0; i < current.dim; i++)
{
used++;
}
- debug(PRINTF) printf("All roots this cycle: --------------------------------\n");
for (size_t i = 0; i < current.dim; i++)
{
void *p;
if (!findPool(current.data[i].parent))
{
j = prev.find(current.data[i].p);
- if (j == OPFAIL)
- debug(PRINTF) printf("N");
- else
- debug(PRINTF) printf(" ");;
current.data[i].print();
}
}
- debug(PRINTF) printf("Used = %d-------------------------------------------------\n", used);
prev.copy(¤t);
-
- debug(PRINTF) printf("-log_collect()\n");
}
void log_parent(void *p, void *parent)
{
- //debug(PRINTF) printf("+log_parent()\n");
size_t i;
i = current.find(p);
if (i == OPFAIL)
{
- debug(PRINTF) printf("parent'ing unallocated memory %x, parent = %x\n", p, parent);
Pool *pool;
pool = findPool(p);
assert(pool);
size_t pn = offset / PAGESIZE;
Bins bin = cast(Bins)pool.pagetable[pn];
biti = (offset & notbinsize[bin]);
- debug(PRINTF) printf("\tbin = %d, offset = x%x, biti = x%x\n", bin, offset, biti);
}
else
- {
current.data[i].parent = parent;
- }
- //debug(PRINTF) printf("-log_parent()\n");
}
}
void initialize(size_t npages)
{
- size_t poolsize;
-
- //debug(PRINTF) printf("Pool::Pool(%u)\n", npages);
- poolsize = npages * PAGESIZE;
+ size_t poolsize = npages * PAGESIZE;
assert(poolsize >= POOLSIZE);
baseAddr = cast(byte *) alloc.os_mem_map(poolsize);
if (!baseAddr)
{
- //debug(PRINTF) printf("GC fail: poolsize = x%x, errno = %d\n", poolsize, errno);
- //debug(PRINTF) printf("message = '%s'\n", sys_errlist[errno]);
-
npages = 0;
poolsize = 0;
}
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);
+ cstring.memset(pagetable, B_FREE, npages);
this.npages = npages;
}
topAddr = null;
}
if (pagetable)
- libc.free(pagetable);
+ cstdlib.free(pagetable);
mark.Dtor();
scan.Dtor();
size_t i;
size_t n2;
- //debug(PRINTF) printf("Pool::allocPages(n = %d)\n", n);
n2 = n;
for (i = 0; i < npages; i++)
{
if (pagetable[i] == B_FREE)
{
if (--n2 == 0)
- {
- //debug(PRINTF) printf("\texisting pn = %d\n", i - n + 1);
return i - n + 1;
- }
}
else
n2 = n;
*/
void freePages(size_t pagenum, size_t npages)
{
- libc.memset(&pagetable[pagenum], B_FREE, npages);
+ cstring.memset(&pagetable[pagenum], B_FREE, npages);
}
}
}
+
+// vim: set et sw=4 sts=4 :