Skip to content

Commit

Permalink
Move chunk reclaiming into freelist rebuild
Browse files Browse the repository at this point in the history
  • Loading branch information
dbussink committed May 23, 2012
1 parent 6d1341a commit 56fc03a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 46 deletions.
24 changes: 5 additions & 19 deletions vm/capi/handles.cpp
Expand Up @@ -77,30 +77,16 @@ namespace rubinius {
}

// Cleanup cached handles
for(std::list<Handle*>::iterator i = cached->begin(); i != cached->end();) {
Handle* handle = *i;
for(std::list<Handle*>::iterator it = cached->begin(); it != cached->end();) {
Handle* handle = *it;
if(handle->in_use_p()) {
++i;
} else {
i = cached->erase(i);
}
}

i = 0;
for(std::vector<Handle*>::iterator it = allocator_->chunks_.begin();
it != allocator_->chunks_.end();) {
// No header was marked, so it's completely empty. Free it.
if(!chunk_marks[i]) {
Handle* chunk = *it;
delete[] chunk;
it = allocator_->chunks_.erase(it);
} else {
++it;
} else {
it = cached->erase(it);
}
++i;
}

allocator_->rebuild_freelist();
allocator_->rebuild_freelist(&chunk_marks);
}
}
}
3 changes: 3 additions & 0 deletions vm/capi/handles.hpp
Expand Up @@ -30,6 +30,9 @@ namespace rubinius {

Handle* allocate(STATE, Object* obj);

uint32_t allocate_index(STATE, Object* obj);
Handle* find_index(STATE, uint32_t index);

void deallocate_handles(std::list<Handle*>* cached, int mark, BakerGC* young);

void flush_all(NativeMethodEnvironment* env);
Expand Down
23 changes: 8 additions & 15 deletions vm/gc/inflated_headers.cpp
Expand Up @@ -36,33 +36,26 @@ namespace rubinius {
* this mark will be retained.
*/
void InflatedHeaders::deallocate_headers(int mark) {
// Detect and free any full chunks first!
for(std::vector<InflatedHeader*>::iterator i = allocator_->chunks_.begin();
i != allocator_->chunks_.end();) {
InflatedHeader* chunk = *i;

bool used = false;
std::vector<bool> chunk_marks(allocator_->chunks_.size(), false);
size_t i = 0;
for(std::vector<InflatedHeader*>::iterator it = allocator_->chunks_.begin();
it != allocator_->chunks_.end(); ++it) {
InflatedHeader* chunk = *it;

for(size_t j = 0; j < allocator_->cChunkSize; j++) {
InflatedHeader* header = &chunk[j];

if(header->marked_p(mark)) {
used = true;
chunk_marks[i] = true;
break;
} else {
header->clear();
}
}

// No header was marked, so it's completely empty. Free it.
if(!used) {
delete[] chunk;
i = allocator_->chunks_.erase(i);
} else {
++i;
}
++i;
}

allocator_->rebuild_freelist();
allocator_->rebuild_freelist(&chunk_marks);
}
}
31 changes: 19 additions & 12 deletions vm/util/allocator.hpp
Expand Up @@ -55,22 +55,29 @@ namespace rubinius {
return t;
}

void rebuild_freelist() {
void rebuild_freelist(std::vector<bool>* chunk_marks) {
size_t i = 0;
free_list_ = NULL;
in_use_ = 0;
for(typename std::vector<T*>::iterator i = chunks_.begin(); i != chunks_.end(); ++i) {
T* chunk = *i;

for(size_t j = 0; j < cChunkSize; j++) {
T* t = &chunk[j];

if(!t->in_use_p()) {
t->set_next(free_list_);
free_list_ = t;
} else {
in_use_++;
for(typename std::vector<T*>::iterator it = chunks_.begin(); it != chunks_.end();) {
T* chunk = *it;
if(!chunk_marks->at(i)) {
delete[] chunk;
it = chunks_.erase(it);
} else {
for(size_t j = 0; j < cChunkSize; j++) {
T* t = &chunk[j];

if(!t->in_use_p()) {
t->set_next(free_list_);
free_list_ = t;
} else {
in_use_++;
}
}
++it;
}
++i;
}
}

Expand Down

0 comments on commit 56fc03a

Please sign in to comment.