< prev index next >

src/hotspot/share/gc/shared/cardTableRS.cpp

Print this page




 262       // Mark it as both cur and prev youngergen; card cleaning thread will
 263       // eventually remove the previous stuff.
 264       jbyte new_val = cur_youngergen_and_prev_nonclean_card;
 265       jbyte res = Atomic::cmpxchg(new_val, entry, entry_val);
 266       // Did the CAS succeed?
 267       if (res == entry_val) return;
 268       // Otherwise, retry, to see the new value.
 269       continue;
 270     } else {
 271       assert(entry_val == cur_youngergen_and_prev_nonclean_card
 272              || entry_val == cur_youngergen_card_val(),
 273              "should be only possibilities.");
 274       return;
 275     }
 276   } while (true);
 277 }
 278 
 279 void CardTableRS::younger_refs_in_space_iterate(Space* sp,
 280                                                 OopsInGenClosure* cl,
 281                                                 uint n_threads) {


 282   const MemRegion urasm = sp->used_region_at_save_marks();



 283 #ifdef ASSERT
 284   // Convert the assertion check to a warning if we are running
 285   // CMS+ParNew until related bug is fixed.
 286   MemRegion ur    = sp->used_region();
 287   assert(ur.contains(urasm) || (UseConcMarkSweepGC),


 288          "Did you forget to call save_marks()? "
 289          "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
 290          "[" PTR_FORMAT ", " PTR_FORMAT ")",
 291          p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));
 292   // In the case of CMS+ParNew, issue a warning
 293   if (!ur.contains(urasm)) {
 294     assert(UseConcMarkSweepGC, "Tautology: see assert above");
 295     log_warning(gc)("CMS+ParNew: Did you forget to call save_marks()? "
 296                     "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
 297                     "[" PTR_FORMAT ", " PTR_FORMAT ")",
 298                     p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));
 299     MemRegion ur2 = sp->used_region();
 300     MemRegion urasm2 = sp->used_region_at_save_marks();
 301     if (!ur.equals(ur2)) {
 302       log_warning(gc)("CMS+ParNew: Flickering used_region()!!");
 303     }
 304     if (!urasm.equals(urasm2)) {
 305       log_warning(gc)("CMS+ParNew: Flickering used_region_at_save_marks()!!");
 306     }
 307     ShouldNotReachHere();
 308   }
 309 #endif
 310   non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
 311 }

 312 
 313 void CardTableRS::clear_into_younger(Generation* old_gen) {
 314   assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
 315          "Should only be called for the old generation");
 316   // The card tables for the youngest gen need never be cleared.
 317   // There's a bit of subtlety in the clear() and invalidate()
 318   // methods that we exploit here and in invalidate_or_clear()
 319   // below to avoid missing cards at the fringes. If clear() or
 320   // invalidate() are changed in the future, this code should
 321   // be revisited. 20040107.ysr
 322   clear(old_gen->prev_used_region());
 323 }
 324 
 325 void CardTableRS::invalidate_or_clear(Generation* old_gen) {
 326   assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
 327          "Should only be called for the old generation");
 328   // Invalidate the cards for the currently occupied part of
 329   // the old generation and clear the cards for the
 330   // unoccupied part of the generation (if any, making use
 331   // of that generation's prev_used_region to determine that


 594       // Then, the case analysis above reveals that, in the worst case,
 595       // any such stale card will be scanned unnecessarily at most twice.
 596       //
 597       // It is nonetheless advisable to try and get rid of some of this
 598       // redundant work in a subsequent (low priority) re-design of
 599       // the card-scanning code, if only to simplify the underlying
 600       // state machine analysis/proof. ysr 1/28/2002. XXX
 601       cur_entry++;
 602     }
 603   }
 604 }
 605 
 606 void CardTableRS::verify() {
 607   // At present, we only know how to verify the card table RS for
 608   // generational heaps.
 609   VerifyCTGenClosure blk(this);
 610   GenCollectedHeap::heap()->generation_iterate(&blk, false);
 611   CardTable::verify();
 612 }
 613 
 614 CardTableRS::CardTableRS(MemRegion whole_heap) :
 615   CardTable(whole_heap, /* scanned concurrently */ UseConcMarkSweepGC && CMSPrecleaningEnabled),
 616   _cur_youngergen_card_val(youngergenP1_card),
 617   // LNC functionality
 618   _lowest_non_clean(NULL),
 619   _lowest_non_clean_chunk_size(NULL),
 620   _lowest_non_clean_base_chunk_index(NULL),
 621   _last_LNC_resizing_collection(NULL)
 622 {
 623   // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
 624   // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
 625   uint max_gens = 2;
 626   _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
 627                          mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
 628   if (_last_cur_val_in_gen == NULL) {
 629     vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
 630   }
 631   for (uint i = 0; i < max_gens + 1; i++) {
 632     _last_cur_val_in_gen[i] = clean_card_val();
 633   }
 634 }
 635 


 681 bool CardTableRS::card_will_be_scanned(jbyte cv) {
 682   return card_is_dirty_wrt_gen_iter(cv) || is_prev_nonclean_card_val(cv);
 683 }
 684 
 685 bool CardTableRS::card_may_have_been_dirty(jbyte cv) {
 686   return
 687     cv != clean_card &&
 688     (card_is_dirty_wrt_gen_iter(cv) ||
 689      CardTableRS::youngergen_may_have_been_dirty(cv));
 690 }
 691 
 692 void CardTableRS::non_clean_card_iterate_possibly_parallel(
 693   Space* sp,
 694   MemRegion mr,
 695   OopsInGenClosure* cl,
 696   CardTableRS* ct,
 697   uint n_threads)
 698 {
 699   if (!mr.is_empty()) {
 700     if (n_threads > 0) {
 701 #if INCLUDE_ALL_GCS
 702       non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);
 703 #else  // INCLUDE_ALL_GCS
 704       fatal("Parallel gc not supported here.");
 705 #endif // INCLUDE_ALL_GCS
 706     } else {
 707       // clear_cl finds contiguous dirty ranges of cards to process and clear.
 708 
 709       // This is the single-threaded version used by DefNew.
 710       const bool parallel = false;
 711 
 712       DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
 713       ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
 714 
 715       clear_cl.do_MemRegion(mr);
 716     }
 717   }






 718 }
 719 
 720 bool CardTableRS::is_in_young(oop obj) const {
 721   return GenCollectedHeap::heap()->is_in_young(obj);
 722 }


 262       // Mark it as both cur and prev youngergen; card cleaning thread will
 263       // eventually remove the previous stuff.
 264       jbyte new_val = cur_youngergen_and_prev_nonclean_card;
 265       jbyte res = Atomic::cmpxchg(new_val, entry, entry_val);
 266       // Did the CAS succeed?
 267       if (res == entry_val) return;
 268       // Otherwise, retry, to see the new value.
 269       continue;
 270     } else {
 271       assert(entry_val == cur_youngergen_and_prev_nonclean_card
 272              || entry_val == cur_youngergen_card_val(),
 273              "should be only possibilities.");
 274       return;
 275     }
 276   } while (true);
 277 }
 278 
 279 void CardTableRS::younger_refs_in_space_iterate(Space* sp,
 280                                                 OopsInGenClosure* cl,
 281                                                 uint n_threads) {
 282   verify_used_region_at_save_marks(sp);
 283 
 284   const MemRegion urasm = sp->used_region_at_save_marks();
 285   non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this, n_threads);
 286 }
 287 
 288 #ifdef ASSERT
 289 void CardTableRS::verify_used_region_at_save_marks(Space* sp) const {

 290   MemRegion ur    = sp->used_region();
 291   MemRegion urasm = sp->used_region_at_save_marks();
 292 
 293   assert(ur.contains(urasm),
 294          "Did you forget to call save_marks()? "
 295          "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
 296          "[" PTR_FORMAT ", " PTR_FORMAT ")",
 297          p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));



















 298 }
 299 #endif
 300 
 301 void CardTableRS::clear_into_younger(Generation* old_gen) {
 302   assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
 303          "Should only be called for the old generation");
 304   // The card tables for the youngest gen need never be cleared.
 305   // There's a bit of subtlety in the clear() and invalidate()
 306   // methods that we exploit here and in invalidate_or_clear()
 307   // below to avoid missing cards at the fringes. If clear() or
 308   // invalidate() are changed in the future, this code should
 309   // be revisited. 20040107.ysr
 310   clear(old_gen->prev_used_region());
 311 }
 312 
 313 void CardTableRS::invalidate_or_clear(Generation* old_gen) {
 314   assert(GenCollectedHeap::heap()->is_old_gen(old_gen),
 315          "Should only be called for the old generation");
 316   // Invalidate the cards for the currently occupied part of
 317   // the old generation and clear the cards for the
 318   // unoccupied part of the generation (if any, making use
 319   // of that generation's prev_used_region to determine that


 582       // Then, the case analysis above reveals that, in the worst case,
 583       // any such stale card will be scanned unnecessarily at most twice.
 584       //
 585       // It is nonetheless advisable to try and get rid of some of this
 586       // redundant work in a subsequent (low priority) re-design of
 587       // the card-scanning code, if only to simplify the underlying
 588       // state machine analysis/proof. ysr 1/28/2002. XXX
 589       cur_entry++;
 590     }
 591   }
 592 }
 593 
 594 void CardTableRS::verify() {
 595   // At present, we only know how to verify the card table RS for
 596   // generational heaps.
 597   VerifyCTGenClosure blk(this);
 598   GenCollectedHeap::heap()->generation_iterate(&blk, false);
 599   CardTable::verify();
 600 }
 601 
 602 CardTableRS::CardTableRS(MemRegion whole_heap, bool scanned_concurrently) :
 603   CardTable(whole_heap, scanned_concurrently),
 604   _cur_youngergen_card_val(youngergenP1_card),
 605   // LNC functionality
 606   _lowest_non_clean(NULL),
 607   _lowest_non_clean_chunk_size(NULL),
 608   _lowest_non_clean_base_chunk_index(NULL),
 609   _last_LNC_resizing_collection(NULL)
 610 {
 611   // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
 612   // (which is always 2, young & old), but GenCollectedHeap has not been initialized yet.
 613   uint max_gens = 2;
 614   _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
 615                          mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
 616   if (_last_cur_val_in_gen == NULL) {
 617     vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
 618   }
 619   for (uint i = 0; i < max_gens + 1; i++) {
 620     _last_cur_val_in_gen[i] = clean_card_val();
 621   }
 622 }
 623 


 669 bool CardTableRS::card_will_be_scanned(jbyte cv) {
 670   return card_is_dirty_wrt_gen_iter(cv) || is_prev_nonclean_card_val(cv);
 671 }
 672 
 673 bool CardTableRS::card_may_have_been_dirty(jbyte cv) {
 674   return
 675     cv != clean_card &&
 676     (card_is_dirty_wrt_gen_iter(cv) ||
 677      CardTableRS::youngergen_may_have_been_dirty(cv));
 678 }
 679 
 680 void CardTableRS::non_clean_card_iterate_possibly_parallel(
 681   Space* sp,
 682   MemRegion mr,
 683   OopsInGenClosure* cl,
 684   CardTableRS* ct,
 685   uint n_threads)
 686 {
 687   if (!mr.is_empty()) {
 688     if (n_threads > 0) {

 689       non_clean_card_iterate_parallel_work(sp, mr, cl, ct, n_threads);



 690     } else {
 691       // clear_cl finds contiguous dirty ranges of cards to process and clear.
 692 
 693       // This is the single-threaded version used by DefNew.
 694       const bool parallel = false;
 695 
 696       DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision(), cl->gen_boundary(), parallel);
 697       ClearNoncleanCardWrapper clear_cl(dcto_cl, ct, parallel);
 698 
 699       clear_cl.do_MemRegion(mr);
 700     }
 701   }
 702 }
 703 
 704 void CardTableRS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr,
 705                                                        OopsInGenClosure* cl, CardTableRS* ct,
 706                                                        uint n_threads) {
 707   fatal("Parallel gc not supported here.");
 708 }
 709 
 710 bool CardTableRS::is_in_young(oop obj) const {
 711   return GenCollectedHeap::heap()->is_in_young(obj);
 712 }
< prev index next >