--- old/src/share/vm/gc/shared/blockOffsetTable.cpp Mon Jun 22 11:43:12 2015 +++ new/src/share/vm/gc/shared/blockOffsetTable.cpp Mon Jun 22 11:43:11 2015 @@ -447,56 +447,60 @@ } 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; - 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; - } + 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) { - // 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)) { + + // 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 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++; } }