Commit 6377dc55 authored by Chris Toshok's avatar Chris Toshok

use a vector of chunks for the TraceStack, instead of a vector of individual pointers.

also keep a free list of chunks around to make subsequent collections faster.

results in TraceStack::pop and ::push being inlined and disappearing from the perf report (::push was at 3.99% before).

Also drops aggregate GC times for ray trace by ~5%.

before: gc_collections_us: 2151827
after: gc_collections_us: 2023809
parent 8628cdc9
......@@ -39,11 +39,44 @@ namespace gc {
class TraceStack {
private:
std::vector<void*> v;
const int CHUNK_SIZE = 256;
const int MAX_FREE_CHUNKS = 50;
std::vector<void**> chunks;
static std::vector<void**> free_chunks;
void** cur;
void** start;
void** end;
void get_chunk() {
if (free_chunks.size()) {
start = free_chunks.back();
free_chunks.pop_back();
} else {
start = (void**)malloc(sizeof(void*) * CHUNK_SIZE);
}
cur = start;
end = start + CHUNK_SIZE;
}
void release_chunk(void** chunk) {
if (free_chunks.size() == MAX_FREE_CHUNKS)
free(chunk);
else
free_chunks.push_back(chunk);
}
void pop_chunk() {
start = chunks.back();
chunks.pop_back();
end = start + CHUNK_SIZE;
cur = end;
}
public:
TraceStack() {}
TraceStack() { get_chunk(); }
TraceStack(const std::vector<void*>& rhs) {
get_chunk();
for (void* p : rhs) {
assert(!isMarked(GCAllocation::fromUserData(p)));
push(p);
......@@ -52,27 +85,38 @@ public:
void push(void* p) {
GCAllocation* al = GCAllocation::fromUserData(p);
if (isMarked(al))
return;
if (!isMarked(al)) {
setMark(al);
setMark(al);
v.push_back(p);
*cur++ = p;
if (cur == end) {
chunks.push_back(start);
get_chunk();
}
}
int size() { return v.size(); }
void* pop_chunk_and_item() {
release_chunk(start);
if (chunks.size()) {
pop_chunk();
assert(cur == end);
return *--cur; // no need for any bounds checks here since we're guaranteed we're CHUNK_SIZE from the start
}
return NULL;
}
void reserve(int num) { v.reserve(num + v.size()); }
void* pop() {
if (v.size()) {
void* r = v.back();
v.pop_back();
return r;
}
return NULL;
if (cur > start)
return *--cur;
return pop_chunk_and_item();
}
};
std::vector<void**> TraceStack::free_chunks;
static std::vector<void*> roots;
void registerPermanentRoot(void* obj) {
......
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