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

Commit

Permalink
refactoring - move small alloc into Gcx
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinNowak committed Jan 7, 2015
1 parent 7b1fd14 commit 70e46a8
Showing 1 changed file with 53 additions and 52 deletions.
105 changes: 53 additions & 52 deletions src/gc/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -475,68 +475,21 @@ class GC
{
assert(size != 0);

Bins bin;

//debug(PRINTF) printf("GC::malloc(size = %d, gcx = %p)\n", size, gcx);
assert(gcx);
//debug(PRINTF) printf("gcx.self = %x, pthread_self() = %x\n", gcx.self, pthread_self());

if (gcx.running)
onInvalidMemoryOperationError();

size += SENTINEL_EXTRA;
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];

if (!tryAlloc())
{
// disabled => allocate a new pool instead of collecting
if (gcx.disabled && !gcx.newPool(1, false))
{
// 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);
}
// 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();
}
assert(p !is null);
auto p = gcx.alloc(size + SENTINEL_EXTRA, &pool, alloc_size);
if (!p)
onOutOfMemoryError();

// Return next item from free list
gcx.bucket[bin] = (cast(List*)p).next;
pool = (cast(List*)p).pool;
//debug(PRINTF) printf("\tmalloc => %p\n", p);
debug (MEMSTOMP) memset(p, 0xF0, size);
}
else
{
p = gcx.bigAlloc(size, &pool, alloc_size);
if (!p)
onOutOfMemoryError();
}
debug (SENTINEL)
{
size -= SENTINEL_EXTRA;
p = sentinel_add(p);
sentinel_init(p, size);
alloc_size = size;
Expand Down Expand Up @@ -2115,11 +2068,59 @@ struct Gcx
}


void* alloc(size_t size, Pool **ppool, ref size_t alloc_size) nothrow
{
immutable bin = findBin(size);
return bin < B_PAGE ? smallAlloc(bin, ppool, alloc_size) :
bigAlloc(size, ppool, alloc_size);
}

void* smallAlloc(Bins bin, Pool **ppool, ref size_t alloc_size) nothrow
{
alloc_size = binsize[bin];

void* p;
bool tryAlloc() nothrow
{
if (!bucket[bin] && !allocPage(bin))
return false;
p = bucket[bin];
return true;
}

if (!tryAlloc())
{
// disabled => allocate a new pool instead of collecting
if (disabled && !newPool(1, false))
{
// disabled but out of memory => try to free some memory
fullcollect();
}
else if (fullcollect() < npools * ((POOLSIZE / PAGESIZE) / 8))
{
// very little memory was freed => allocate a new pool for anticipated heap growth
newPool(1, false);
}
// tryAlloc will succeed if a new pool was allocated above, if it fails allocate a new pool now
if (!tryAlloc() && (!newPool(1, false) || !tryAlloc()))
// out of luck or memory
onOutOfMemoryError();
}
assert(p !is null);

// Return next item from free list
bucket[bin] = (cast(List*)p).next;
*ppool = (cast(List*)p).pool;
//debug(PRINTF) printf("\tmalloc => %p\n", p);
debug (MEMSTOMP) memset(p, 0xF0, size);
return p;
}

/**
* Allocate a chunk of memory that is larger than a page.
* Return null if out of memory.
*/
void *bigAlloc(size_t size, Pool **poolPtr, ref size_t alloc_size) nothrow
void* bigAlloc(size_t size, Pool **ppool, ref size_t alloc_size) nothrow
{
debug(PRINTF) printf("In bigAlloc. Size: %d\n", size);

Expand Down Expand Up @@ -2187,7 +2188,7 @@ struct Gcx
alloc_size = npages * PAGESIZE;
//debug(PRINTF) printf("\tp = %p\n", p);

*poolPtr = pool;
*ppool = pool;
return p;
}

Expand Down

0 comments on commit 70e46a8

Please sign in to comment.