hotspot/src/share/vm/memory/space.cpp
HeapWord* CompactibleSpace::forward(oop q, size_t size,
CompactPoint* cp, HeapWord* compact_top) {
{- -------------------------------------------
(1)
---------------------------------------- -}
// q is alive
// First check if we should switch compaction space
assert(this == cp->space, "'this' should be current compaction space.");
{- -------------------------------------------
(1) もし現在のコンパクション先の領域に空きがなければ,
CompactPoint で管理しているコンパクト先領域を(同じ世代内の)別の領域に切り替える.
同じ世代内で空き領域がなくなれば, 一つ若い世代の領域に切り替える.
---------------------------------------- -}
size_t compaction_max_size = pointer_delta(end(), compact_top);
while (size > compaction_max_size) {
{- -------------------------------------------
(1.1) (同じ世代内の別の領域へ切り替え)
---------------------------------------- -}
// switch to next compaction space
cp->space->set_compaction_top(compact_top);
cp->space = cp->space->next_compaction_space();
{- -------------------------------------------
(1.1) (同じ世代内にもう領域がなければ, 一つ若い世代に切り替え)
---------------------------------------- -}
if (cp->space == NULL) {
cp->gen = GenCollectedHeap::heap()->prev_gen(cp->gen);
assert(cp->gen != NULL, "compaction must succeed");
cp->space = cp->gen->first_compaction_space();
assert(cp->space != NULL, "generation must have a first compaction space");
}
{- -------------------------------------------
(1)
---------------------------------------- -}
compact_top = cp->space->bottom();
cp->space->set_compaction_top(compact_top);
cp->threshold = cp->space->initialize_threshold();
compaction_max_size = pointer_delta(cp->space->end(), compact_top);
}
{- -------------------------------------------
(1)
---------------------------------------- -}
// store the forwarding pointer into the mark word
if ((HeapWord*)q != compact_top) {
q->forward_to(oop(compact_top));
assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
} else {
// if the object isn't moving we can just set the mark to the default
// mark and handle it specially later on.
q->init_mark();
assert(q->forwardee() == NULL, "should be forwarded to NULL");
}
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, size));
compact_top += size;
// we need to update the offset table so that the beginnings of objects can be
// found during scavenge. Note that we are updating the offset table based on
// where the object will be once the compaction phase finishes.
if (compact_top > cp->threshold)
cp->threshold =
cp->space->cross_threshold(compact_top - size, compact_top);
return compact_top;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.