hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp
SparsePRTEntry::AddCardResult SparsePRTEntry::add_card(CardIdx_t card_index) {
{- -------------------------------------------
(1) 以下で _cards 配列への記録処理を行う.
* _cards 配列内に同じ要素が既に登録されていれば,
何もせずに found をリターンするだけ.
* _cards 配列内に空き領域(NullEntry)が見つかれば,
そこに書き込んだ後, added をリターン
* _cards 配列を最後まで探したが, 同じ要素も空き領域も無かった場合
overflow をリターン
(なお, UNROLL_CARD_LOOPS の値に応じて 2通りの実装が書かれている.
と言ってもどちらも同じコードで, 片方は手動でループアンローリングされているだけ.
UNROLL_CARD_LOOPS が 1 だとアンロールされたコードが使用される.
現在は UNROLL_CARD_LOOPS は 1 に #define されている.)
---------------------------------------- -}
#if UNROLL_CARD_LOOPS
{- -------------------------------------------
(1.1) (以下は, UNROLL_CARD_LOOPS が 1 の場合のコード)
---------------------------------------- -}
assert((cards_num() & (UnrollFactor - 1)) == 0, "Invalid number of cards in the entry");
CardIdx_t c;
for (int i = 0; i < cards_num(); i += UnrollFactor) {
c = _cards[i];
if (c == card_index) return found;
if (c == NullEntry) { _cards[i] = card_index; return added; }
c = _cards[i + 1];
if (c == card_index) return found;
if (c == NullEntry) { _cards[i + 1] = card_index; return added; }
c = _cards[i + 2];
if (c == card_index) return found;
if (c == NullEntry) { _cards[i + 2] = card_index; return added; }
c = _cards[i + 3];
if (c == card_index) return found;
if (c == NullEntry) { _cards[i + 3] = card_index; return added; }
}
#else
{- -------------------------------------------
(1.1) (以下は, UNROLL_CARD_LOOPS が 1ではない場合のコード)
---------------------------------------- -}
for (int i = 0; i < cards_num(); i++) {
CardIdx_t c = _cards[i];
if (c == card_index) return found;
if (c == NullEntry) { _cards[i] = card_index; return added; }
}
#endif
// Otherwise, we're full.
return overflow;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.