cstring.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++)
{
~(512u-1),~(1024u-1),~(2048u-1),~(4096u-1) ];
DynArray!(void*) roots;
+
DynArray!(Range) ranges;
+DynArray!(Pool) pools;
+
+
/* ============================ Gcx =============================== */
byte *minAddr; // min(baseAddr)
byte *maxAddr; // max(topAddr)
- size_t npools;
- Pool **pooltable;
-
List *bucket[B_MAX]; // free list for each size
//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);
}
/**
* 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();
- cstdlib.free(pool);
- cstring.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;
/**
* 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 *) cstdlib.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 **) cstdlib.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;
- }
- cstring.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();
- cstdlib.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;
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);
}
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))
// 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;
}
/**
- * 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);
}
}