Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
refactoring - remove malloc state machine
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinNowak committed Jan 7, 2015
1 parent 8f655bb commit b548dd1
Showing 1 changed file with 24 additions and 31 deletions.
55 changes: 24 additions & 31 deletions src/gc/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ class GC
{
assert(size != 0);

void *p = null;
Bins bin;

//debug(PRINTF) printf("GC::malloc(size = %d, gcx = %p)\n", size, gcx);
Expand All @@ -489,45 +488,39 @@ class GC
bin = gcx.findBin(size);
Pool *pool;

void *p;

if (bin < B_PAGE)
{
bool tryAlloc() nothrow
{
if (!gcx.bucket[bin] && !gcx.allocPage(bin))
return false;
p = gcx.bucket[bin];
return true;
}

alloc_size = binsize[bin];
int state = gcx.disabled ? 1 : 0;
bool collected = false;

while (!gcx.bucket[bin] && !gcx.allocPage(bin))
if (!tryAlloc())
{
switch (state)
// disabled => allocate a new pool instead of collecting
if (gcx.disabled && !gcx.newPool(1, false))
{
case 0:
auto freedpages = gcx.fullcollect();
collected = true;
if (freedpages < gcx.npools * ((POOLSIZE / PAGESIZE) / 8))
{ /* Didn't free much, so try allocating more anyway.
* Note: freedpages is not the amount of memory freed, it's the amount
* of full pages freed. Perhaps this should instead be the amount of
* memory freed.
*/
gcx.newPool(1,false);
state = 2;
}
else
state = 1;
continue;
case 1:
// disabled but out of memory => try to free some memory
gcx.fullcollect();
}
else if (gcx.fullcollect() < gcx.npools * ((POOLSIZE / PAGESIZE) / 8))
{
// very little memory was freed => allocate a new pool for anticipated heap growth
gcx.newPool(1, false);
state = 2;
continue;
case 2:
if (collected)
onOutOfMemoryError();
state = 0;
continue;
default:
assert(false);
}
// tryAlloc will succeed if a new pool was allocated above, if it fails allocate a new pool now
if (!tryAlloc() && (!gcx.newPool(1, false) || !tryAlloc()))
// out of luck or memory
onOutOfMemoryError();
}
p = gcx.bucket[bin];
assert(p !is null);

// Return next item from free list
gcx.bucket[bin] = (cast(List*)p).next;
Expand Down

0 comments on commit b548dd1

Please sign in to comment.