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