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