hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
void
PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
{
{- -------------------------------------------
(1) (assert)
---------------------------------------- -}
assert(id < last_space_id, "id out of range");
assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom() ||
ParallelOldGCSplitALot && id == old_space_id,
"should have been reset in summarize_spaces_quick()");
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
const MutableSpace* space = _space_info[id].space();
{- -------------------------------------------
(1) 以下の if ブロック内の処理は,
もし処理対象の領域内に live オブジェクトが一つも無い場合には (= new_top() と bottom() が等しければ), 省略する
(PSParallelCompact::summarize_spaces_quick() によって
SpaceInfo::new_top() にはその領域の live オブジェクト量が格納されていると想定)
---------------------------------------- -}
if (_space_info[id].new_top() != space->bottom()) {
{- -------------------------------------------
(1) PSParallelCompact::compute_dense_prefix() を呼んで,
最適な dense prefix のアドレスを取得する (以下の dense_prefix_end).
(ついでにこのアドレスは, SpaceInfo::set_dense_prefix() で, 対応する SpaceInfo オブジェクト内に記録しておく)
---------------------------------------- -}
HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
_space_info[id].set_dense_prefix(dense_prefix_end);
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
#ifndef PRODUCT
if (TraceParallelOldGCDensePrefix) {
print_dense_prefix_stats("ratio", id, maximum_compaction,
dense_prefix_end);
HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
print_dense_prefix_stats("density", id, maximum_compaction, addr);
}
#endif // #ifndef PRODUCT
{- -------------------------------------------
(1) 最適な dense prefix を考慮に入れて, 再度 summary data を計算し直す.
(ただし, 引数の maximum_compaction が true の場合 (= 空き容量が逼迫している場合) は,
dense prefix を用意している場合ではないので, この再計算処理は行わない.
また, dense prefix 量が 0 の場合 (= dense_prefix_end が bottom() と同じ場合) には,
再計算しても同じ結果になるので, この再計算処理は行わない.)
再計算処理は, 具体的には以下の処理を行う.
* PSParallelCompact::fill_dense_prefix_end() を呼んで,
dense prefix の終端部分にダミーの live オブジェクトを埋めておく.
(これは以降の copy/update 処理を簡単にするための処理.
See: ... #TODO)
* dense_prefix_end より前の範囲 (= bottom 〜 dense_prefix_end) については,
ParallelCompactData::summarize_dense_prefix() で処理する.
(具体的には, 対応する ParallelCompactData::RegionData の値を変更する)
* dense_prefix_end より後の範囲 (= dense_prefix_end 〜 top) については,
ParallelCompactData::summarize() で処理する.
(具体的には, 対応する ParallelCompactData::RegionData の値を変更する)
---------------------------------------- -}
// Recompute the summary data, taking into account the dense prefix. If
// every last byte will be reclaimed, then the existing summary data which
// compacts everything can be left in place.
if (!maximum_compaction && dense_prefix_end != space->bottom()) {
// If dead space crosses the dense prefix boundary, it is (at least
// partially) filled with a dummy object, marked live and added to the
// summary data. This simplifies the copy/update phase and must be done
// before the final locations of objects are determined, to prevent
// leaving a fragment of dead space that is too small to fill.
fill_dense_prefix_end(id);
// Compute the destination of each Region, and thus each object.
_summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
_summary_data.summarize(_space_info[id].split_info(),
dense_prefix_end, space->top(), NULL,
dense_prefix_end, space->end(),
_space_info[id].new_top_addr());
}
}
{- -------------------------------------------
(1) (トレース出力)
---------------------------------------- -}
if (TraceParallelOldGCSummaryPhase) {
const size_t region_size = ParallelCompactData::RegionSize;
HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);
const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());
HeapWord* const new_top = _space_info[id].new_top();
const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top);
const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
"dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
"cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
id, space->capacity_in_words(), dense_prefix_end,
dp_region, dp_words / region_size,
cr_words / region_size, new_top);
}
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.