src/share/vm/memory/cardTableRS.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/memory

src/share/vm/memory/cardTableRS.cpp

Print this page
rev 7214 : imported patch remove_n_gen
rev 7215 : imported patch remove_levels


 101   return 0;
 102 }
 103 
 104 void CardTableRS::prepare_for_younger_refs_iterate(bool parallel) {
 105   // Parallel or sequential, we must always set the prev to equal the
 106   // last one written.
 107   if (parallel) {
 108     // Find a parallel value to be used next.
 109     jbyte next_val = find_unused_youngergenP_card_value();
 110     set_cur_youngergen_card_val(next_val);
 111 
 112   } else {
 113     // In an sequential traversal we will always write youngergen, so that
 114     // the inline barrier is  correct.
 115     set_cur_youngergen_card_val(youngergen_card);
 116   }
 117 }
 118 
 119 void CardTableRS::younger_refs_iterate(Generation* g,
 120                                        OopsInGenClosure* blk) {
 121   _last_cur_val_in_gen[g->level()+1] = cur_youngergen_card_val();
 122   g->younger_refs_iterate(blk);
 123 }
 124 
 125 inline bool ClearNoncleanCardWrapper::clear_card(jbyte* entry) {
 126   if (_is_par) {
 127     return clear_card_parallel(entry);
 128   } else {
 129     return clear_card_serial(entry);
 130   }
 131 }
 132 
 133 inline bool ClearNoncleanCardWrapper::clear_card_parallel(jbyte* entry) {
 134   while (true) {
 135     // In the parallel case, we may have to do this several times.
 136     jbyte entry_val = *entry;
 137     assert(entry_val != CardTableRS::clean_card_val(),
 138            "We shouldn't be looking at clean cards, and this should "
 139            "be the only place they get cleaned.");
 140     if (CardTableRS::card_is_dirty_wrt_gen_iter(entry_val)
 141         || _ct->is_prev_youngergen_card_val(entry_val)) {


 299     assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above");
 300     warning("CMS+ParNew: Did you forget to call save_marks()? "
 301             "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
 302             "[" PTR_FORMAT ", " PTR_FORMAT ")",
 303              p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));
 304     MemRegion ur2 = sp->used_region();
 305     MemRegion urasm2 = sp->used_region_at_save_marks();
 306     if (!ur.equals(ur2)) {
 307       warning("CMS+ParNew: Flickering used_region()!!");
 308     }
 309     if (!urasm.equals(urasm2)) {
 310       warning("CMS+ParNew: Flickering used_region_at_save_marks()!!");
 311     }
 312     ShouldNotReachHere();
 313   }
 314 #endif
 315   _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this);
 316 }
 317 
 318 void CardTableRS::clear_into_younger(Generation* old_gen) {
 319   assert(old_gen->level() == 1, "Should only be called for the old generation");

 320   // The card tables for the youngest gen need never be cleared.
 321   // There's a bit of subtlety in the clear() and invalidate()
 322   // methods that we exploit here and in invalidate_or_clear()
 323   // below to avoid missing cards at the fringes. If clear() or
 324   // invalidate() are changed in the future, this code should
 325   // be revisited. 20040107.ysr
 326   clear(old_gen->prev_used_region());
 327 }
 328 
 329 void CardTableRS::invalidate_or_clear(Generation* old_gen) {
 330   assert(old_gen->level() == 1, "Should only be called for the old generation");

 331   // Invalidate the cards for the currently occupied part of
 332   // the old generation and clear the cards for the
 333   // unoccupied part of the generation (if any, making use
 334   // of that generation's prev_used_region to determine that
 335   // region). No need to do anything for the youngest
 336   // generation. Also see note#20040107.ysr above.
 337   MemRegion used_mr = old_gen->used_region();
 338   MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr);
 339   if (!to_be_cleared_mr.is_empty()) {
 340     clear(to_be_cleared_mr);
 341   }
 342   invalidate(used_mr);
 343 }
 344 
 345 
 346 class VerifyCleanCardClosure: public OopClosure {
 347 private:
 348   HeapWord* _boundary;
 349   HeapWord* _begin;
 350   HeapWord* _end;


 376   virtual void do_oop(oop* p)       { VerifyCleanCardClosure::do_oop_work(p); }
 377   virtual void do_oop(narrowOop* p) { VerifyCleanCardClosure::do_oop_work(p); }
 378 };
 379 
 380 class VerifyCTSpaceClosure: public SpaceClosure {
 381 private:
 382   CardTableRS* _ct;
 383   HeapWord* _boundary;
 384 public:
 385   VerifyCTSpaceClosure(CardTableRS* ct, HeapWord* boundary) :
 386     _ct(ct), _boundary(boundary) {}
 387   virtual void do_space(Space* s) { _ct->verify_space(s, _boundary); }
 388 };
 389 
 390 class VerifyCTGenClosure: public GenCollectedHeap::GenClosure {
 391   CardTableRS* _ct;
 392 public:
 393   VerifyCTGenClosure(CardTableRS* ct) : _ct(ct) {}
 394   void do_generation(Generation* gen) {
 395     // Skip the youngest generation.
 396     if (gen->level() == 0) return;


 397     // Normally, we're interested in pointers to younger generations.
 398     VerifyCTSpaceClosure blk(_ct, gen->reserved().start());
 399     gen->space_iterate(&blk, true);
 400   }
 401 };
 402 
 403 void CardTableRS::verify_space(Space* s, HeapWord* gen_boundary) {
 404   // We don't need to do young-gen spaces.
 405   if (s->end() <= gen_boundary) return;
 406   MemRegion used = s->used_region();
 407 
 408   jbyte* cur_entry = byte_for(used.start());
 409   jbyte* limit = byte_after(used.last());
 410   while (cur_entry < limit) {
 411     if (*cur_entry == CardTableModRefBS::clean_card) {
 412       jbyte* first_dirty = cur_entry+1;
 413       while (first_dirty < limit &&
 414              *first_dirty == CardTableModRefBS::clean_card) {
 415         first_dirty++;
 416       }




 101   return 0;
 102 }
 103 
 104 void CardTableRS::prepare_for_younger_refs_iterate(bool parallel) {
 105   // Parallel or sequential, we must always set the prev to equal the
 106   // last one written.
 107   if (parallel) {
 108     // Find a parallel value to be used next.
 109     jbyte next_val = find_unused_youngergenP_card_value();
 110     set_cur_youngergen_card_val(next_val);
 111 
 112   } else {
 113     // In an sequential traversal we will always write youngergen, so that
 114     // the inline barrier is  correct.
 115     set_cur_youngergen_card_val(youngergen_card);
 116   }
 117 }
 118 
 119 void CardTableRS::younger_refs_iterate(Generation* g,
 120                                        OopsInGenClosure* blk) {
 121   _last_cur_val_in_gen[2 /* Number of generations */] = cur_youngergen_card_val();
 122   g->younger_refs_iterate(blk);
 123 }
 124 
 125 inline bool ClearNoncleanCardWrapper::clear_card(jbyte* entry) {
 126   if (_is_par) {
 127     return clear_card_parallel(entry);
 128   } else {
 129     return clear_card_serial(entry);
 130   }
 131 }
 132 
 133 inline bool ClearNoncleanCardWrapper::clear_card_parallel(jbyte* entry) {
 134   while (true) {
 135     // In the parallel case, we may have to do this several times.
 136     jbyte entry_val = *entry;
 137     assert(entry_val != CardTableRS::clean_card_val(),
 138            "We shouldn't be looking at clean cards, and this should "
 139            "be the only place they get cleaned.");
 140     if (CardTableRS::card_is_dirty_wrt_gen_iter(entry_val)
 141         || _ct->is_prev_youngergen_card_val(entry_val)) {


 299     assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above");
 300     warning("CMS+ParNew: Did you forget to call save_marks()? "
 301             "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in "
 302             "[" PTR_FORMAT ", " PTR_FORMAT ")",
 303              p2i(urasm.start()), p2i(urasm.end()), p2i(ur.start()), p2i(ur.end()));
 304     MemRegion ur2 = sp->used_region();
 305     MemRegion urasm2 = sp->used_region_at_save_marks();
 306     if (!ur.equals(ur2)) {
 307       warning("CMS+ParNew: Flickering used_region()!!");
 308     }
 309     if (!urasm.equals(urasm2)) {
 310       warning("CMS+ParNew: Flickering used_region_at_save_marks()!!");
 311     }
 312     ShouldNotReachHere();
 313   }
 314 #endif
 315   _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this);
 316 }
 317 
 318 void CardTableRS::clear_into_younger(Generation* old_gen) {
 319   assert(old_gen == GenCollectedHeap::heap()->old_gen(),
 320          "Should only be called for the old generation");
 321   // The card tables for the youngest gen need never be cleared.
 322   // There's a bit of subtlety in the clear() and invalidate()
 323   // methods that we exploit here and in invalidate_or_clear()
 324   // below to avoid missing cards at the fringes. If clear() or
 325   // invalidate() are changed in the future, this code should
 326   // be revisited. 20040107.ysr
 327   clear(old_gen->prev_used_region());
 328 }
 329 
 330 void CardTableRS::invalidate_or_clear(Generation* old_gen) {
 331   assert(old_gen == GenCollectedHeap::heap()->old_gen(),
 332          "Should only be called for the old generation");
 333   // Invalidate the cards for the currently occupied part of
 334   // the old generation and clear the cards for the
 335   // unoccupied part of the generation (if any, making use
 336   // of that generation's prev_used_region to determine that
 337   // region). No need to do anything for the youngest
 338   // generation. Also see note#20040107.ysr above.
 339   MemRegion used_mr = old_gen->used_region();
 340   MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr);
 341   if (!to_be_cleared_mr.is_empty()) {
 342     clear(to_be_cleared_mr);
 343   }
 344   invalidate(used_mr);
 345 }
 346 
 347 
 348 class VerifyCleanCardClosure: public OopClosure {
 349 private:
 350   HeapWord* _boundary;
 351   HeapWord* _begin;
 352   HeapWord* _end;


 378   virtual void do_oop(oop* p)       { VerifyCleanCardClosure::do_oop_work(p); }
 379   virtual void do_oop(narrowOop* p) { VerifyCleanCardClosure::do_oop_work(p); }
 380 };
 381 
 382 class VerifyCTSpaceClosure: public SpaceClosure {
 383 private:
 384   CardTableRS* _ct;
 385   HeapWord* _boundary;
 386 public:
 387   VerifyCTSpaceClosure(CardTableRS* ct, HeapWord* boundary) :
 388     _ct(ct), _boundary(boundary) {}
 389   virtual void do_space(Space* s) { _ct->verify_space(s, _boundary); }
 390 };
 391 
 392 class VerifyCTGenClosure: public GenCollectedHeap::GenClosure {
 393   CardTableRS* _ct;
 394 public:
 395   VerifyCTGenClosure(CardTableRS* ct) : _ct(ct) {}
 396   void do_generation(Generation* gen) {
 397     // Skip the youngest generation.
 398     if (gen == GenCollectedHeap::heap()->young_gen()) {
 399       return;
 400     }
 401     // Normally, we're interested in pointers to younger generations.
 402     VerifyCTSpaceClosure blk(_ct, gen->reserved().start());
 403     gen->space_iterate(&blk, true);
 404   }
 405 };
 406 
 407 void CardTableRS::verify_space(Space* s, HeapWord* gen_boundary) {
 408   // We don't need to do young-gen spaces.
 409   if (s->end() <= gen_boundary) return;
 410   MemRegion used = s->used_region();
 411 
 412   jbyte* cur_entry = byte_for(used.start());
 413   jbyte* limit = byte_after(used.last());
 414   while (cur_entry < limit) {
 415     if (*cur_entry == CardTableModRefBS::clean_card) {
 416       jbyte* first_dirty = cur_entry+1;
 417       while (first_dirty < limit &&
 418              *first_dirty == CardTableModRefBS::clean_card) {
 419         first_dirty++;
 420       }


src/share/vm/memory/cardTableRS.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File