Commit 2558ff26 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Try to not repeatedly scan through the 'free' bitfield

Seems to help by a couple percent.
parent 72aca8d6
...@@ -198,16 +198,20 @@ Heap::ThreadBlockCache::~ThreadBlockCache() { ...@@ -198,16 +198,20 @@ Heap::ThreadBlockCache::~ThreadBlockCache() {
} }
static GCAllocation* allocFromBlock(Block* b) { static GCAllocation* allocFromBlock(Block* b) {
int i = 0;
uint64_t mask = 0; uint64_t mask = 0;
for (; i < BITFIELD_ELTS; i++) {
mask = b->isfree[i]; int elts_scanned = 0;
for (; b->next_to_check < BITFIELD_ELTS; b->next_to_check++) {
elts_scanned++;
mask = b->isfree[b->next_to_check];
if (mask != 0L) { if (mask != 0L) {
break; break;
} }
} }
int i = b->next_to_check;
if (i == BITFIELD_ELTS) { if (i == BITFIELD_ELTS) {
b->next_to_check = 0;
return NULL; return NULL;
} }
......
...@@ -69,7 +69,7 @@ static_assert(ATOMS_PER_BLOCK % 64 == 0, ""); ...@@ -69,7 +69,7 @@ static_assert(ATOMS_PER_BLOCK % 64 == 0, "");
#define BITFIELD_SIZE (ATOMS_PER_BLOCK / 8) #define BITFIELD_SIZE (ATOMS_PER_BLOCK / 8)
#define BITFIELD_ELTS (BITFIELD_SIZE / 8) #define BITFIELD_ELTS (BITFIELD_SIZE / 8)
#define BLOCK_HEADER_SIZE (BITFIELD_SIZE + 2 * sizeof(void*) + sizeof(uint64_t)) #define BLOCK_HEADER_SIZE (BITFIELD_SIZE + 4 * sizeof(void*))
#define BLOCK_HEADER_ATOMS ((BLOCK_HEADER_SIZE + ATOM_SIZE - 1) / ATOM_SIZE) #define BLOCK_HEADER_ATOMS ((BLOCK_HEADER_SIZE + ATOM_SIZE - 1) / ATOM_SIZE)
struct Atoms { struct Atoms {
...@@ -82,6 +82,8 @@ struct Block { ...@@ -82,6 +82,8 @@ struct Block {
Block* next, **prev; Block* next, **prev;
uint64_t size; uint64_t size;
uint64_t isfree[BITFIELD_ELTS]; uint64_t isfree[BITFIELD_ELTS];
int next_to_check;
void* _header_end[0];
}; };
Atoms atoms[ATOMS_PER_BLOCK]; Atoms atoms[ATOMS_PER_BLOCK];
}; };
...@@ -95,6 +97,8 @@ struct Block { ...@@ -95,6 +97,8 @@ struct Block {
static Block* forPointer(void* ptr) { return (Block*)((uintptr_t)ptr & ~(BLOCK_SIZE - 1)); } static Block* forPointer(void* ptr) { return (Block*)((uintptr_t)ptr & ~(BLOCK_SIZE - 1)); }
}; };
static_assert(sizeof(Block) == BLOCK_SIZE, "bad size"); static_assert(sizeof(Block) == BLOCK_SIZE, "bad size");
static_assert(offsetof(Block, _header_end) >= BLOCK_HEADER_SIZE, "bad header size");
static_assert(offsetof(Block, _header_end) <= BLOCK_HEADER_SIZE, "bad header size");
constexpr const size_t sizes[] = { constexpr const size_t sizes[] = {
16, 32, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256, 16, 32, 48, 64, 80, 96, 112, 128, 160, 192, 224, 256,
......
...@@ -252,9 +252,6 @@ extern "C" void listGCHandler(GCVisitor* v, Box* b) { ...@@ -252,9 +252,6 @@ extern "C" void listGCHandler(GCVisitor* v, Box* b) {
v->visit(l->elts); v->visit(l->elts);
if (size) if (size)
v->visitRange((void**)&l->elts->elts[0], (void**)&l->elts->elts[size]); v->visitRange((void**)&l->elts->elts[0], (void**)&l->elts->elts[size]);
static StatCounter sc("gc_listelts_visited");
sc.log(size);
} }
extern "C" void setGCHandler(GCVisitor* v, Box* b) { extern "C" void setGCHandler(GCVisitor* v, Box* b) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment