src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp

Print this page
rev 3849 : 7194633: G1: Assertion and guarantee failures in block offset table
Summary: Add detailed error messages to assertions and guarantees in G1's block offset table.
Reviewed-by:


 285         break;
 286       }
 287       default:
 288         ShouldNotReachHere();
 289     }
 290   }
 291 }
 292 
 293 // The card-interval [start_card, end_card] is a closed interval; this
 294 // is an expensive check -- use with care and only under protection of
 295 // suitable flag.
 296 void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
 297 
 298   if (end_card < start_card) {
 299     return;
 300   }
 301   guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
 302   for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
 303     u_char entry = _array->offset_array(c);
 304     if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
 305       guarantee(entry > N_words, "Should be in logarithmic region");





 306     }
 307     size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
 308     size_t landing_card = c - backskip;
 309     guarantee(landing_card >= (start_card - 1), "Inv");
 310     if (landing_card >= start_card) {
 311       guarantee(_array->offset_array(landing_card) <= entry, "monotonicity");



 312     } else {
 313       guarantee(landing_card == start_card - 1, "Tautology");
 314       guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");




 315     }
 316   }
 317 }
 318 
 319 // The range [blk_start, blk_end) represents a single contiguous block
 320 // of storage; modify the block offset table to represent this
 321 // information; Right-open interval: [blk_start, blk_end)
 322 // NOTE: this method does _not_ adjust _unallocated_block.
 323 void
 324 G1BlockOffsetArray::single_block(HeapWord* blk_start, HeapWord* blk_end) {
 325   do_block_internal(blk_start, blk_end, Action_single);
 326 }
 327 
 328 // Mark the BOT such that if [blk_start, blk_end) straddles a card
 329 // boundary, the card following the first such boundary is marked
 330 // with the appropriate offset.
 331 // NOTE: this method does _not_ adjust _unallocated_block or
 332 // any cards subsequent to the first one.
 333 void
 334 G1BlockOffsetArray::mark_block(HeapWord* blk_start, HeapWord* blk_end) {


 524 
 525   index = end_index + 1;
 526   // Calculate threshold_ this way because end_index
 527   // may be the last valid index in the covered region.
 528   threshold = _array->address_for_index(end_index) + N_words;
 529   assert(threshold >= blk_end, "Incorrect offset threshold");
 530 
 531   // index_ and threshold_ updated here.
 532   *threshold_ = threshold;
 533   *index_ = index;
 534 
 535 #ifdef ASSERT
 536   // The offset can be 0 if the block starts on a boundary.  That
 537   // is checked by an assertion above.
 538   size_t start_index = _array->index_for(blk_start);
 539   HeapWord* boundary    = _array->address_for_index(start_index);
 540   assert((_array->offset_array(orig_index) == 0 &&
 541           blk_start == boundary) ||
 542           (_array->offset_array(orig_index) > 0 &&
 543          _array->offset_array(orig_index) <= N_words),
 544          "offset array should have been set");





 545   for (size_t j = orig_index + 1; j <= end_index; j++) {
 546     assert(_array->offset_array(j) > 0 &&
 547            _array->offset_array(j) <=
 548              (u_char) (N_words+BlockOffsetArray::N_powers-1),
 549            "offset array should have been set");




 550   }
 551 #endif
 552 }
 553 
 554 bool
 555 G1BlockOffsetArray::verify_for_object(HeapWord* obj_start,
 556                                       size_t word_size) const {
 557   size_t first_card = _array->index_for(obj_start);
 558   size_t last_card = _array->index_for(obj_start + word_size - 1);
 559   if (!_array->is_card_boundary(obj_start)) {
 560     // If the object is not on a card boundary the BOT entry of the
 561     // first card should point to another object so we should not
 562     // check that one.
 563     first_card += 1;
 564   }
 565   for (size_t card = first_card; card <= last_card; card += 1) {
 566     HeapWord* card_addr = _array->address_for_index(card);
 567     HeapWord* block_start = block_start_const(card_addr);
 568     if (block_start != obj_start) {
 569       gclog_or_tty->print_cr("block start: "PTR_FORMAT" is incorrect - "




 285         break;
 286       }
 287       default:
 288         ShouldNotReachHere();
 289     }
 290   }
 291 }
 292 
 293 // The card-interval [start_card, end_card] is a closed interval; this
 294 // is an expensive check -- use with care and only under protection of
 295 // suitable flag.
 296 void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
 297 
 298   if (end_card < start_card) {
 299     return;
 300   }
 301   guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
 302   for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
 303     u_char entry = _array->offset_array(c);
 304     if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
 305       guarantee(entry > N_words,
 306                 err_msg("Should be in logarithmic region - "
 307                         "entry: "UINT32_FORMAT", "
 308                         "_array->offset_array(c): "UINT32_FORMAT", "
 309                         "N_words: "UINT32_FORMAT,
 310                         entry, _array->offset_array(c), N_words));
 311     }
 312     size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
 313     size_t landing_card = c - backskip;
 314     guarantee(landing_card >= (start_card - 1), "Inv");
 315     if (landing_card >= start_card) {
 316       guarantee(_array->offset_array(landing_card) <= entry,
 317                 err_msg("Monotonicity - landing_card offset: "UINT32_FORMAT", "
 318                         "entry: "UINT32_FORMAT,
 319                         _array->offset_array(landing_card), entry));
 320     } else {
 321       guarantee(landing_card == start_card - 1, "Tautology");
 322       // Note that N_words is the maximum offset value
 323       guarantee(_array->offset_array(landing_card) <= N_words,
 324                 err_msg("landing card offset: "UINT32_FORMAT", "
 325                         "N_words: "UINT32_FORMAT,
 326                         _array->offset_array(landing_card), N_words));
 327     }
 328   }
 329 }
 330 
 331 // The range [blk_start, blk_end) represents a single contiguous block
 332 // of storage; modify the block offset table to represent this
 333 // information; Right-open interval: [blk_start, blk_end)
 334 // NOTE: this method does _not_ adjust _unallocated_block.
 335 void
 336 G1BlockOffsetArray::single_block(HeapWord* blk_start, HeapWord* blk_end) {
 337   do_block_internal(blk_start, blk_end, Action_single);
 338 }
 339 
 340 // Mark the BOT such that if [blk_start, blk_end) straddles a card
 341 // boundary, the card following the first such boundary is marked
 342 // with the appropriate offset.
 343 // NOTE: this method does _not_ adjust _unallocated_block or
 344 // any cards subsequent to the first one.
 345 void
 346 G1BlockOffsetArray::mark_block(HeapWord* blk_start, HeapWord* blk_end) {


 536 
 537   index = end_index + 1;
 538   // Calculate threshold_ this way because end_index
 539   // may be the last valid index in the covered region.
 540   threshold = _array->address_for_index(end_index) + N_words;
 541   assert(threshold >= blk_end, "Incorrect offset threshold");
 542 
 543   // index_ and threshold_ updated here.
 544   *threshold_ = threshold;
 545   *index_ = index;
 546 
 547 #ifdef ASSERT
 548   // The offset can be 0 if the block starts on a boundary.  That
 549   // is checked by an assertion above.
 550   size_t start_index = _array->index_for(blk_start);
 551   HeapWord* boundary = _array->address_for_index(start_index);
 552   assert((_array->offset_array(orig_index) == 0 &&
 553           blk_start == boundary) ||
 554           (_array->offset_array(orig_index) > 0 &&
 555          _array->offset_array(orig_index) <= N_words),
 556          err_msg("offset array should have been set - "
 557                   "orig_index offset: "UINT32_FORMAT", "
 558                   "blk_start: "PTR_FORMAT", "
 559                   "boundary: "PTR_FORMAT,
 560                   _array->offset_array(orig_index),
 561                   blk_start, boundary));
 562   for (size_t j = orig_index + 1; j <= end_index; j++) {
 563     assert(_array->offset_array(j) > 0 &&
 564            _array->offset_array(j) <=
 565              (u_char) (N_words+BlockOffsetArray::N_powers-1),
 566            err_msg("offset array should have been set - "
 567                    UINT32_FORMAT" not > 0 OR "UINT32_FORMAT" not <= "UINT32_FORMAT,
 568                    _array->offset_array(j),
 569                    _array->offset_array(j),
 570                    (u_char) (N_words+BlockOffsetArray::N_powers-1)));
 571   }
 572 #endif
 573 }
 574 
 575 bool
 576 G1BlockOffsetArray::verify_for_object(HeapWord* obj_start,
 577                                       size_t word_size) const {
 578   size_t first_card = _array->index_for(obj_start);
 579   size_t last_card = _array->index_for(obj_start + word_size - 1);
 580   if (!_array->is_card_boundary(obj_start)) {
 581     // If the object is not on a card boundary the BOT entry of the
 582     // first card should point to another object so we should not
 583     // check that one.
 584     first_card += 1;
 585   }
 586   for (size_t card = first_card; card <= last_card; card += 1) {
 587     HeapWord* card_addr = _array->address_for_index(card);
 588     HeapWord* block_start = block_start_const(card_addr);
 589     if (block_start != obj_start) {
 590       gclog_or_tty->print_cr("block start: "PTR_FORMAT" is incorrect - "