< 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 >