hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
ParMarkBitMap::IterationStatus
ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
ParMarkBitMapClosure* dead_closure,
idx_t range_beg, idx_t range_end,
idx_t dead_range_end) const
{
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
DEBUG_ONLY(verify_bit(range_beg);)
DEBUG_ONLY(verify_bit(range_end);)
DEBUG_ONLY(verify_bit(dead_range_end);)
assert(range_beg <= range_end, "live range invalid");
assert(range_end <= dead_range_end, "dead range invalid");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
// The bitmap routines require the right boundary to be word-aligned.
const idx_t live_search_end = BitMap::word_align_up(range_end);
const idx_t dead_search_end = BitMap::word_align_up(dead_range_end);
idx_t cur_beg = range_beg;
{- -------------------------------------------
(1) もし, 処理対象範囲の先頭が dead オブジェクトだった場合には,
最初の live オブジェクトの頭出しを行う.
(ついでに, (dead space があるということなので)
引数で渡された ParMarkBitMapClosure (以下の dead_closure) の
ParMarkBitMapClosure::do_addr() も呼び出しておく)
---------------------------------------- -}
if (range_beg < range_end && is_unmarked(range_beg)) {
// The range starts with dead space. Look for the next object, then fill.
cur_beg = find_obj_beg(range_beg + 1, dead_search_end);
const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
const size_t size = obj_size(range_beg, dead_space_end);
dead_closure->do_addr(bit_to_addr(range_beg), size);
}
{- -------------------------------------------
(1) 処理対象範囲の終端(range_end)に達するまで, 以下の whlie ループを繰り返す.
ループ内で行う処理は以下の通り.
(1) 現在処理対象となっているオブジェクトに対して,
ParMarkBitMap::find_obj_end() でその終端を見つける.
(もし, 終端が今回の処理範囲(range_end)を超えていたら, ここでリターン.
返値は ParMarkBitMap::incomplete)
(1) そのオブジェクトの処理を行うために
引数で渡された ParMarkBitMapClosure (以下の live_closure) に対して
ParMarkBitMapClosure::do_addr() を呼び出す.
(もし, do_addr() の返値が ParMarkBitMap::incomplete でなかった場合,
もうコンパクション先が一杯で作業が続けられないということなので, ここでリターン.
返値は, do_addr() の返値をそのまま使用.)
(1) ParMarkBitMap::find_obj_beg() を呼び出して, 次のオブジェクトの先頭アドレスを見つける.
次のオブジェクトが前回のオブジェクトの直後にない場合には (= dead space がある場合),
引数で渡された ParMarkBitMapClosure (以下の dead_closure) の
ParMarkBitMapClosure::do_addr() も呼び出しておく.
---------------------------------------- -}
while (cur_beg < range_end) {
const idx_t cur_end = find_obj_end(cur_beg, live_search_end);
if (cur_end >= range_end) {
// The obj ends outside the range.
live_closure->set_source(bit_to_addr(cur_beg));
return incomplete;
}
const size_t size = obj_size(cur_beg, cur_end);
IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
if (status != incomplete) {
assert(status == would_overflow || status == full, "sanity");
return status;
}
// Look for the start of the next object.
const idx_t dead_space_beg = cur_end + 1;
cur_beg = find_obj_beg(dead_space_beg, dead_search_end);
if (cur_beg > dead_space_beg) {
// Found dead space; compute the size and invoke the dead closure.
const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
const size_t size = obj_size(dead_space_beg, dead_space_end);
dead_closure->do_addr(bit_to_addr(dead_space_beg), size);
}
}
{- -------------------------------------------
(1) 引数で渡された ParMarkBitMapClosure (以下の live_closure) の _source フィールドに
今回の処理対象範囲の終端アドレス(range_end)をセットしておく.
---------------------------------------- -}
live_closure->set_source(bit_to_addr(range_end));
{- -------------------------------------------
(1) リターン.
---------------------------------------- -}
return complete;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.