< prev index next >
src/share/vm/gc/shared/blockOffsetTable.cpp
Print this page
rev 8557 : 8081629: CMS split_block() does not correctly fix up block-offset-table for large blocks
New implementation of split_block().
Reviewed-by:
@@ -445,60 +445,64 @@
// index interval in args below.
set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */);
} else {
// Unilaterally fix the first (num_pref_cards - 1) following
// the "offset card" in the suffix block.
- const size_t right_most_fixed_index = suff_index + num_pref_cards - 1;
+ size_t right_most_fixed_index = suff_index + num_pref_cards - 1;
set_remainder_to_point_to_start_incl(suff_index + 1,
right_most_fixed_index, true /* reducing */);
// Fix the appropriate cards in the remainder of the
- // suffix block -- these are the last num_pref_cards
- // cards in each power block of the "new" range plumbed
- // from suff_addr.
- bool more = true;
+ // suffix block -- these are the first num_pref_cards
+ // cards in each power block of the "old" ranges plumbed
+ // from pref_addr.
uint i = 1;
- // Fix the first power block with back_by > num_pref_cards.
- while (more && (i < N_powers)) {
size_t back_by = power_to_cards_back(i);
- size_t right_index = suff_index + back_by - 1;
- size_t left_index = right_index - num_pref_cards + 1;
+
+ while (i < N_powers) {
+ back_by = power_to_cards_back(i);
+ if (back_by > num_pref_cards) {
+ break;
+ }
+ i++;
+ }
+
+ // Fix the first power block with back_by > num_pref_cards.
+ size_t left_index = right_most_fixed_index + 1;
+ size_t right_index = pref_index + back_by + num_pref_cards;
if (right_index >= end_index - 1) { // last iteration
right_index = end_index - 1;
- more = false;
}
- if (left_index <= right_most_fixed_index) {
- left_index = right_most_fixed_index + 1;
- }
- if (back_by > num_pref_cards) {
+
// Fill in the remainder of this "power block", if it
// is non-null.
if (left_index <= right_index) {
_array->set_offset_array(left_index, right_index,
N_words + i - 1, true /* reducing */);
- } else {
- more = false; // we are done
- assert((end_index - 1) == right_index, "Must be at the end.");
+ debug_only(right_most_fixed_index = right_index;)
}
+ // Nothing may actually have been fixed if the region fixed by
+ // the call to set_remainder_to_point_to_start_incl() aligns
+ // evenly with the power block boundaries but still increment
+ // to the next power block. Otherwise, this same power block will
+ // be tried again but there is no safety check against the
+ // right_most_fixed_index.
i++;
- break;
- }
- i++;
- }
// Fix the rest of the power blocks.
- while (more && (i < N_powers)) {
+ while (i < N_powers) {
size_t back_by = power_to_cards_back(i);
- size_t right_index = suff_index + back_by - 1;
- size_t left_index = right_index - num_pref_cards + 1;
+ size_t left_index = pref_index + back_by;
+ size_t right_index = left_index + num_pref_cards;
if (right_index >= end_index - 1) { // last iteration
right_index = end_index - 1;
if (left_index > right_index) {
break;
}
- more = false;
}
assert(left_index <= right_index, "Error");
+ assert(left_index > right_most_fixed_index, "Overwriting already fixed area");
_array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);
+ debug_only(right_most_fixed_index = right_index;)
i++;
}
}
} // else no more cards to fix in suffix
} // else nothing needs to be done
< prev index next >