Skip to content

Commit

Permalink
hacked gc
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoqun committed Jun 4, 2012
1 parent 17aa445 commit e3d87dc
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 35 deletions.
28 changes: 26 additions & 2 deletions vm/gc/immix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,32 @@ namespace rubinius {

int live_bytes = 0;
int total_bytes = 0;
int blocks = 0;
int free_blocks = 0;
int recyclable_blocks = 0;
int unavailable_blocks = 0;
int evacuate_blocks = 0;

while(immix::Block* block = iter.next()) {
total_bytes += immix::cBlockSize;
live_bytes += block->bytes_from_lines();
switch(block->status()) {
case immix::cFree:
++free_blocks;
break;
case immix::cRecyclable:
++recyclable_blocks;
break;
case immix::cUnavailable:
++unavailable_blocks;
break;
case immix::cEvacuate:
++evacuate_blocks;
break;
default:
break;
}
++blocks;
}

double percentage_live = (double)live_bytes / (double)total_bytes;
Expand All @@ -257,6 +279,8 @@ namespace rubinius {
<< via_handles_ << " handles "
<< (int)(percentage_live * 100) << "% live"
<< ", " << live_bytes << "/" << total_bytes
<< ", " << blocks << " blocks ("
<< free_blocks << "/" << recyclable_blocks << "/" << unavailable_blocks << "/" << evacuate_blocks << ")"
<< "]\n";
}

Expand All @@ -269,7 +293,7 @@ namespace rubinius {
gc_.block_allocator().add_chunk();
}

#ifdef IMMIX_DEBUG
{
std::cout << "Immix: RS size cleared: " << cleared << "\n";

immix::Chunks& chunks = gc_.block_allocator().chunks();
Expand Down Expand Up @@ -320,7 +344,7 @@ namespace rubinius {

delete[] holes;
holes = NULL;
#endif
}
}

void ImmixGC::check_finalize() {
Expand Down
9 changes: 0 additions & 9 deletions vm/gc/marksweep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,6 @@ namespace rubinius {
return obj;
}

Object* MarkSweepGC::copy_object(Object* orig) {
bool collect;
Object* obj = allocate(orig->size_in_bytes(object_memory_->state()), &collect);

obj->initialize_full_state(object_memory_->state(), orig, 0);

return obj;
}

Object* MarkSweepGC::saw_object(Object* obj) {
if(obj->marked_p(object_memory_->mark())) return NULL;
obj->mark(object_memory_->mark());
Expand Down
1 change: 0 additions & 1 deletion vm/gc/marksweep.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ namespace rubinius {
void free_objects();
Object* allocate(size_t bytes, bool *collect_now);
Object* move_object(Object* orig, size_t bytes, bool *collect_now);
Object* copy_object(Object* obj);
void sweep_objects();
void free_object(Object* obj, bool fast = false);
virtual Object* saw_object(Object* obj);
Expand Down
3 changes: 2 additions & 1 deletion vm/oop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ namespace rubinius {
}

void ObjectHeader::initialize_full_state(VM* state, Object* other, unsigned int age) {
assert(type_id() == other->type_id());
set_obj_type(other->type_id());
set_age(age);
klass_ = other->klass_;
ivars_ = other->ivars_;
Expand All @@ -534,6 +534,7 @@ namespace rubinius {
switch(hdr.f.meaning) {
case eAuxWordObjID:
case eAuxWordLock:
case eAuxWordInflated:
header.f.meaning = hdr.f.meaning;
header.f.aux_word = hdr.f.aux_word;
}
Expand Down
53 changes: 31 additions & 22 deletions vm/util/immix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ namespace immix {
* available for allocation.
*/
void clear_lines() {
if(status_ != cFree && fragmentation_ratio() < 0.05) {
//std::cout << "fragmented..." << std::endl;
status_ = cEvacuate;
}
objects_ = 0;
object_bytes_ = 0;
memset(lines_, 0, sizeof(lines_));
Expand Down Expand Up @@ -374,10 +378,18 @@ namespace immix {
}

// The first line is always used for metadata
if(status_ == cEvacuate) {
return;
}

if(lines_used_ <= 1) {
status_ = cFree;
} else if(holes_ >= 1) {
status_ = cRecyclable;
//if(lines_used_ > 30) {
status_ = cRecyclable;
//} else {
// status_ = cEvacuate;
//}
} else {
status_ = cUnavailable;
}
Expand Down Expand Up @@ -997,7 +1009,6 @@ namespace immix {

template <typename Describer>
class GC : public Triggers {
BlockList evacuate_;
BlockAllocator block_allocator_;

Describer desc;
Expand All @@ -1024,27 +1035,19 @@ namespace immix {
return block_allocator_.get_block();
}

/**
* Sets a Block up for evacuation.
*/
void evacuate_block(Block& block) {
block.set_status(cEvacuate);
evacuate_.push_back(&block);
}

/**
* Converts evacuated Blocks back to free Blocks.
*
* @todo Does this need to check if an evacuated block is empty - what
* about pinned objects?
*/
void sweep_blocks() {
for(BlockList::const_iterator i = evacuate_.begin();
i != evacuate_.end();
++i) {
Block* block = *i;
AllBlockIterator iter(block_allocator_.chunks());

while(Block* block = iter.next()) {
if(block->status() == cEvacuate) {
block->set_status(cFree);
//block->set_status(cFree);
//block->clear_lines();
}
}

Expand Down Expand Up @@ -1076,13 +1079,19 @@ namespace immix {

// Find the Block the address relates to
Block* block = Block::from_address(addr);
if(block->status() == cEvacuate && !desc.pinned(addr)) {
// Block is marked for evacuation, so copy the object to a new Block
fwd = desc.copy(addr, alloc);
desc.set_forwarding_pointer(addr, fwd);

addr = fwd;
block = Block::from_address(addr);
if(block->status() == cEvacuate) {
if(!desc.pinned(addr)) {
//std::cout << "not pinned" << std::endl;
// Block is marked for evacuation, so copy the object to a new Block
fwd = desc.copy(addr, alloc);
desc.set_forwarding_pointer(addr, fwd);

addr = fwd;
block = Block::from_address(addr);
} else {
//std::cout << "pinned...." << std::endl;
block->set_status(cRecyclable);
}
}

// Mark the line(s) in the Block that this object occupies as in use
Expand Down

0 comments on commit e3d87dc

Please sign in to comment.