hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
void StealTask::do_it(GCTaskManager* manager, uint which) {
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(Universe::heap()->is_gc_active(), "called outside gc");
{- -------------------------------------------
(1) PSPromotionManager::gc_thread_promotion_manager() で,
これを実行している GCTaskThread 用の PSPromotionManager オブジェクトを取得する.
---------------------------------------- -}
PSPromotionManager* pm =
PSPromotionManager::gc_thread_promotion_manager(which);
{- -------------------------------------------
(1) PSPromotionManager::drain_stacks() で,
自分のタスクキューが空になるまで処理を行う.
---------------------------------------- -}
pm->drain_stacks(true);
guarantee(pm->stacks_empty(),
"stacks should be empty at this point");
{- -------------------------------------------
(1) (自分の担当分は終わったので, 以下の while ループで,
未処理の仕事が存在しなくなるまで 他の GCTaskThread から仕事を奪って実行する.)
PSPromotionManager::steal_depth() による work stealing を行い, 成功すれば
奪ってきたポインタに対して PSPromotionManager::process_popped_location_depth() でコピー処理を行い,
さらにそこからの参照先に対しても PSPromotionManager::drain_stacks_depth() で再帰的に処理を行う.
(ループが終了する条件は,
PSPromotionManager::steal_depth() による work stealing が失敗し,
さらに ParallelTaskTerminator::offer_termination() が true を返した場合.)
---------------------------------------- -}
int random_seed = 17;
while(true) {
StarTask p;
if (PSPromotionManager::steal_depth(which, &random_seed, p)) {
TASKQUEUE_STATS_ONLY(pm->record_steal(p));
pm->process_popped_location_depth(p);
pm->drain_stacks_depth(true);
} else {
if (terminator()->offer_termination()) {
break;
}
}
}
guarantee(pm->stacks_empty(), "stacks should be empty at this point");
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.