hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
void PSParallelCompact::compact() {
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
EventMark m("5 compact");
// trace("5");
TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty);
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
PSOldGen* old_gen = heap->old_gen();
old_gen->start_array()->reset();
uint parallel_gc_threads = heap->gc_task_manager()->workers();
TaskQueueSetSuper* qset = ParCompactionManager::region_array();
ParallelTaskTerminator terminator(parallel_gc_threads, qset);
{- -------------------------------------------
(1) GCTaskQueue::create() で GCTaskQueue を作り,
そこに DrainStacksCompactionTask, UpdateDensePrefixTask, および
StealRegionCompactionTask をつめる.
(See: PSParallelCompact::enqueue_region_draining_tasks(),
PSParallelCompact::enqueue_dense_prefix_tasks(),
PSParallelCompact::enqueue_region_stealing_tasks())
---------------------------------------- -}
GCTaskQueue* q = GCTaskQueue::create();
enqueue_region_draining_tasks(q, parallel_gc_threads);
enqueue_dense_prefix_tasks(q, parallel_gc_threads);
enqueue_region_stealing_tasks(q, &terminator, parallel_gc_threads);
{
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty);
{- -------------------------------------------
(1) 最後に, 以上の処理が終了するまで待機するための WaitForBarrierGCTask も追加しておく.
---------------------------------------- -}
WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
q->enqueue(fin);
{- -------------------------------------------
(1) GCTaskManager::add_list() で, GCTask をキューに追加して GCTaskThread 達に実行させる.
---------------------------------------- -}
gc_task_manager()->add_list(q);
{- -------------------------------------------
(1) WaitForBarrierGCTask::wait_for() で GCTask が全て実行されるまで待機する.
待機が解けたら, WaitForBarrierGCTask::destroy() で WaitForBarrierGCTask オブジェクトを破棄する.
---------------------------------------- -}
fin->wait_for();
// We have to release the barrier tasks!
WaitForBarrierGCTask::destroy(fin);
{- -------------------------------------------
(1) (verify)
---------------------------------------- -}
#ifdef ASSERT
// Verify that all regions have been processed before the deferred updates.
// Note that perm_space_id is skipped; this type of verification is not
// valid until the perm gen is compacted by regions.
for (unsigned int id = old_space_id; id < last_space_id; ++id) {
verify_complete(SpaceId(id));
}
#endif
}
{- -------------------------------------------
(1) PSParallelCompact::update_deferred_objects() を呼んで,
複数 region にまたがっていたために
ポインタの修正が行えていないオブジェクトに対して処理を行う.
(なお, ここで使用する ParCompactionManager は何でもいいので, 適当に 0 番のものを使っている)
---------------------------------------- -}
{
// Update the deferred objects, if any. Any compaction manager can be used.
TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty);
ParCompactionManager* cm = ParCompactionManager::manager_array(0);
for (unsigned int id = old_space_id; id < last_space_id; ++id) {
update_deferred_objects(cm, SpaceId(id));
}
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.