< 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,504 ****
// 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;
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;
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;
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.");
}
i++;
- break;
- }
- i++;
- }
// Fix the rest of the power blocks.
! 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;
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");
_array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);
i++;
}
}
} // else no more cards to fix in suffix
} // else nothing needs to be done
--- 445,508 ----
// 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.
! 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 first num_pref_cards
! // cards in each power block of the "old" ranges plumbed
! // from pref_addr.
uint i = 1;
size_t back_by = power_to_cards_back(i);
!
! 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;
}
!
// 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 */);
! 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++;
// Fix the rest of the power blocks.
! while (i < N_powers) {
size_t back_by = power_to_cards_back(i);
! 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;
}
}
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 >