Commit 262cb6b2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #270 from toshok/gc-perf

use a vector of chunks for the TraceStack, instead of a vector of individual pointers.
parents b1a1a171 6377dc55
...@@ -39,11 +39,44 @@ namespace gc { ...@@ -39,11 +39,44 @@ namespace gc {
class TraceStack { class TraceStack {
private: 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: public:
TraceStack() {} TraceStack() { get_chunk(); }
TraceStack(const std::vector<void*>& rhs) { TraceStack(const std::vector<void*>& rhs) {
get_chunk();
for (void* p : rhs) { for (void* p : rhs) {
assert(!isMarked(GCAllocation::fromUserData(p))); assert(!isMarked(GCAllocation::fromUserData(p)));
push(p); push(p);
...@@ -52,27 +85,38 @@ public: ...@@ -52,27 +85,38 @@ public:
void push(void* p) { void push(void* p) {
GCAllocation* al = GCAllocation::fromUserData(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() { void* pop() {
if (v.size()) { if (cur > start)
void* r = v.back(); return *--cur;
v.pop_back();
return r; return pop_chunk_and_item();
}
return NULL;
} }
}; };
std::vector<void**> TraceStack::free_chunks;
static std::vector<void*> roots; static std::vector<void*> roots;
void registerPermanentRoot(void* obj) { 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