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