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


 430   size_t end_index  = _array->index_for(end_addr - 1) + 1;
 431 
 432   // Calculate the # cards that the prefix and suffix affect.
 433   size_t num_pref_cards = suff_index - pref_index;
 434 
 435   size_t num_suff_cards = end_index  - suff_index;
 436   // Change the cards that need changing
 437   if (num_suff_cards > 0) {
 438     HeapWord* boundary = _array->address_for_index(suff_index);
 439     // Set the offset card for suffix block
 440     _array->set_offset_array(suff_index, boundary, suff_addr, true /* reducing */);
 441     // Change any further cards that need changing in the suffix
 442     if (num_pref_cards > 0) {
 443       if (num_pref_cards >= num_suff_cards) {
 444         // Unilaterally fix all of the suffix cards: closed card
 445         // index interval in args below.
 446         set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */);
 447       } else {
 448         // Unilaterally fix the first (num_pref_cards - 1) following
 449         // the "offset card" in the suffix block.
 450         const size_t right_most_fixed_index = suff_index + num_pref_cards - 1;
 451         set_remainder_to_point_to_start_incl(suff_index + 1,
 452           right_most_fixed_index, true /* reducing */);
 453         // Fix the appropriate cards in the remainder of the
 454         // suffix block -- these are the last num_pref_cards
 455         // cards in each power block of the "new" range plumbed
 456         // from suff_addr.
 457         bool more = true;
 458         uint i = 1;
 459         // Fix the first power block with  back_by > num_pref_cards.
 460         while (more && (i < N_powers)) {
 461           size_t back_by = power_to_cards_back(i);
 462           size_t right_index = suff_index + back_by - 1;
 463           size_t left_index  = right_index - num_pref_cards + 1;










 464           if (right_index >= end_index - 1) { // last iteration
 465             right_index = end_index - 1;
 466             more = false;
 467           }
 468           if (left_index <= right_most_fixed_index) {
 469                 left_index = right_most_fixed_index + 1;
 470           }
 471           if (back_by > num_pref_cards) {
 472             // Fill in the remainder of this "power block", if it
 473             // is non-null.
 474             if (left_index <= right_index) {
 475               _array->set_offset_array(left_index, right_index,
 476                                      N_words + i - 1, true /* reducing */);
 477             } else {
 478               more = false; // we are done
 479               assert((end_index - 1) == right_index, "Must be at the end.");
 480             }






 481             i++;
 482             break;
 483           }
 484           i++;
 485         }
 486         // Fix the rest of the power blocks.
 487         while (more && (i < N_powers)) {
 488           size_t back_by = power_to_cards_back(i);
 489           size_t right_index = suff_index + back_by - 1;
 490           size_t left_index  = right_index - num_pref_cards + 1;
 491           if (right_index >= end_index - 1) { // last iteration
 492             right_index = end_index - 1;
 493             if (left_index > right_index) {
 494               break;
 495             }
 496             more  = false;
 497           }
 498           assert(left_index <= right_index, "Error");

 499           _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);

 500           i++;
 501         }
 502       }
 503     } // else no more cards to fix in suffix
 504   } // else nothing needs to be done
 505   // Verify that we did the right thing
 506   verify_single_block(pref_addr, left_blk_size);
 507   verify_single_block(suff_addr, blk_size - left_blk_size);
 508 }
 509 
 510 
 511 // Mark the BOT such that if [blk_start, blk_end) straddles a card
 512 // boundary, the card following the first such boundary is marked
 513 // with the appropriate offset.
 514 // NOTE: this method does _not_ adjust _unallocated_block or
 515 // any cards subsequent to the first one.
 516 void
 517 BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start,
 518                                            HeapWord* blk_end, bool reducing) {
 519   do_block_internal(blk_start, blk_end, Action_mark, reducing);




 430   size_t end_index  = _array->index_for(end_addr - 1) + 1;
 431 
 432   // Calculate the # cards that the prefix and suffix affect.
 433   size_t num_pref_cards = suff_index - pref_index;
 434 
 435   size_t num_suff_cards = end_index  - suff_index;
 436   // Change the cards that need changing
 437   if (num_suff_cards > 0) {
 438     HeapWord* boundary = _array->address_for_index(suff_index);
 439     // Set the offset card for suffix block
 440     _array->set_offset_array(suff_index, boundary, suff_addr, true /* reducing */);
 441     // Change any further cards that need changing in the suffix
 442     if (num_pref_cards > 0) {
 443       if (num_pref_cards >= num_suff_cards) {
 444         // Unilaterally fix all of the suffix cards: closed card
 445         // index interval in args below.
 446         set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */);
 447       } else {
 448         // Unilaterally fix the first (num_pref_cards - 1) following
 449         // the "offset card" in the suffix block.
 450         size_t right_most_fixed_index = suff_index + num_pref_cards - 1;
 451         set_remainder_to_point_to_start_incl(suff_index + 1,
 452           right_most_fixed_index, true /* reducing */);
 453         // Fix the appropriate cards in the remainder of the
 454         // suffix block -- these are the first num_pref_cards
 455         // cards in each power block of the "old" ranges plumbed
 456         // from pref_addr.

 457         uint i = 1;


 458         size_t back_by = power_to_cards_back(i);
 459 
 460         while (i < N_powers) {
 461           back_by = power_to_cards_back(i);
 462           if (back_by > num_pref_cards) {
 463             break;
 464           }
 465           i++;
 466         }
 467 
 468         // Fix the first power block with  back_by > num_pref_cards.
 469         size_t left_index  = right_most_fixed_index + 1;
 470         size_t right_index = pref_index + back_by + num_pref_cards;
 471         if (right_index >= end_index - 1) { // last iteration
 472           right_index = end_index - 1;

 473         }
 474 



 475         // Fill in the remainder of this "power block", if it
 476         // is non-null.
 477         if (left_index <= right_index) {
 478           _array->set_offset_array(left_index, right_index,
 479                                    N_words + i - 1, true /* reducing */);
 480           debug_only(right_most_fixed_index = right_index;)


 481         }
 482         // Nothing may actually have been fixed if the region fixed by
 483         // the call to set_remainder_to_point_to_start_incl() aligns
 484         // evenly with the power block boundaries but still increment
 485         // to the next power block.  Otherwise, this same power block will
 486         // be tried again but there is no safety check against the 
 487         // right_most_fixed_index.
 488         i++;




 489         // Fix the rest of the power blocks.
 490         while (i < N_powers) {
 491           size_t back_by = power_to_cards_back(i);
 492           size_t left_index  = pref_index + back_by;
 493           size_t right_index = left_index + num_pref_cards;
 494           if (right_index >= end_index - 1) { // last iteration
 495             right_index = end_index - 1;
 496             if (left_index > right_index) {
 497               break;
 498             }

 499           }
 500           assert(left_index <= right_index, "Error");
 501           assert(left_index > right_most_fixed_index, "Overwriting already fixed area");
 502           _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);
 503           debug_only(right_most_fixed_index = right_index;)
 504           i++;
 505         }
 506       }
 507     } // else no more cards to fix in suffix
 508   } // else nothing needs to be done
 509   // Verify that we did the right thing
 510   verify_single_block(pref_addr, left_blk_size);
 511   verify_single_block(suff_addr, blk_size - left_blk_size);
 512 }
 513 
 514 
 515 // Mark the BOT such that if [blk_start, blk_end) straddles a card
 516 // boundary, the card following the first such boundary is marked
 517 // with the appropriate offset.
 518 // NOTE: this method does _not_ adjust _unallocated_block or
 519 // any cards subsequent to the first one.
 520 void
 521 BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start,
 522                                            HeapWord* blk_end, bool reducing) {
 523   do_block_internal(blk_start, blk_end, Action_mark, reducing);


< prev index next >