hotspot full gc擬似コード
5430 ワード
class Object {
bool _gc_mark = false;
Object* _forwardee; // null for normal objects non-null for forwarded objects
void forward_to(address new_addr) {
_forwardee = new_addr;
}
Object* forwardee() {
return _forwardee;
}
bool forwarded() {
return _forwardee != null;
}
void copy_to_forwardee() {
// copy current obj to the forwardee address and clear its forwardee
}
void set_gc_mark() {
_gc_mark = true;
}
bool gc_marked() {
return _gc_mark;
}
void clear_gc_mark() {
_gc_mark = false;
}
size_t size();
void adjust_object_fields() {
foreach(Object** p : this->object_fiels()) {
*p = (*p)->forwardee();
}
}
Iterator<Object**> object_fields();
};
class Heap {
ContigCompatibleSpace* _the_space;
Heap(address bottom, address end);
address allocate(size_t size);
void collect();
void process_root(Object** slot);
void mark_compact_phase1();
void mark_compact_phase2();
void mark_compact_phase3();
void mark_compact_phase4();
};
class ContigCompatibleSpace {
address _bottom;
address _top;
address _end;
Object* _first_dead;
public:
ContigCompatibleSpace(address bottom, address end);
address bottom() {
return _bottom;
}
address top() {
return _top;
}
address end() {
return _end;
}
bool contains(address obj);
address allocate(size_t size);
void reset();
void scan_and_forward();
void adjust_pointers();
void compact();
};
Heap::Heap(address bottom, address end) {
_the_space = new ContigCompatibleSpace(bottom, end);
}
address Heap::allocate(size_t size) {
return _the_space->allocate();
}
void Heap::collect() {
mark_compact_phase1();
mark_compact_phase2();
mark_compact_phase3();
mark_compact_phase4();
}
void Heap::mark_compact_phase1() {
foreach(Object** slot : ROOTS) {
process_root(slot);
}
}
void Heap::process_root(Object** slot) {
Stack s;
Object* oop = *slot;
oop->set_gc_mark();
s.push(oop);
while (!s.empty()) {
oop = s.pop();
foreach(Object** obj_field : oop->object_fields()) {
if (!(*obj_field)->gc_marked()) {
(*obj_field)->set_gc_mark();
s.push(*obj_filed);
}
}
}
}
void Heap::mark_compact_phase2() {
_the_space->scan_and_forward();
}
void Heap::mark_compact_phase3() {
foreach(Object** slot : ROOTS) {
*slot = (*slot)->forwardee();
}
_the_space->adjust_pointers();
}
void Heap::mark_compact_phase4() {
_the_space->compact();
}
ContigCompatibleSpace::ContigCompatibleSpace(address bottom, address end) {
_bottom = bottom;
_top = bottom;
_end = end;
}
address ContigCompatibleSpace::contains(address obj) {
return _bottom <= obj && obj < _top;
}
address ContigCompatibleSpace::allocate(size_t size) {
if (_top + size <= _end) {
Object* obj = _top;
_top += size;
return obj;
} else {
return null;
}
}
void ContigCompatibleSpace::reset() {
_top = _bottom;
}
void ContigCompatibleSpace::scan_and_forward() {
Object* q = _bottom;
address compacting_top = _bottom;
_first_dead = _end;
while (q < _end) {
if (q->gc_marked()) {
if (compacting_top == q) {
q->clear_gc_mark();
q->forward_to(null);
} else
q->forward_to(compacting_top);
compacting_top += q->size();
q += q->size();
} else {
if (_first_dead == _end)
_first_dead = q;
Object* p = q;
do {
p += p->size();
} while (!p->gc_marked());
q->forward_to(p);
q = p;
}
}
}
void ContigCompatibleSpace::adjust_pointers() {
Object* q = _bottom;
while (q < _first_dead) {
q->adjust_object_fields();
q += q->size();
}
q = _first_dead->forwardee();
while (q < _end) {
if (q->gc_marked()) {
q->adjust_object_fields();
q += q->size();
} else {
q = q->forwardee();
}
}
}
void ContigCompatibleSpace::compact() {
Object* q = _first_dead->forwardee();
while (q < _end) {
if (q->gc_marked()) {
q->clear_gc_mark();
q->copy_to_forwardee();
q += q->size();
} else {
q = q->forwardee();
}
}
}