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
rev 7216 : imported patch cleanup


  39 #endif // INCLUDE_ALL_GCS
  40 
  41 CardTableRS::CardTableRS(MemRegion whole_heap,
  42                          int max_covered_regions) :
  43   GenRemSet(),
  44   _cur_youngergen_card_val(youngergenP1_card),
  45   _regions_to_iterate(max_covered_regions - 1)
  46 {
  47 #if INCLUDE_ALL_GCS
  48   if (UseG1GC) {
  49       _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
  50                                                   max_covered_regions);
  51   } else {
  52     _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
  53   }
  54 #else
  55   _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
  56 #endif
  57   _ct_bs->initialize();
  58   set_bs(_ct_bs);
  59   _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1,



  60                          mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
  61   if (_last_cur_val_in_gen == NULL) {
  62     vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
  63   }
  64   for (int i = 0; i < GenCollectedHeap::max_gens + 1; i++) {
  65     _last_cur_val_in_gen[i] = clean_card_val();
  66   }
  67   _ct_bs->set_CTRS(this);
  68 }
  69 
  70 CardTableRS::~CardTableRS() {
  71   if (_ct_bs) {
  72     delete _ct_bs;
  73     _ct_bs = NULL;
  74   }
  75   if (_last_cur_val_in_gen) {
  76     FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen, mtInternal);
  77   }
  78 }
  79 
  80 void CardTableRS::resize_covered_region(MemRegion new_region) {
  81   _ct_bs->resize_covered_region(new_region);
  82 }
  83 
  84 jbyte CardTableRS::find_unused_youngergenP_card_value() {


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


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

 317   // The card tables for the youngest gen need never be cleared.
 318   // There's a bit of subtlety in the clear() and invalidate()
 319   // methods that we exploit here and in invalidate_or_clear()
 320   // below to avoid missing cards at the fringes. If clear() or
 321   // invalidate() are changed in the future, this code should
 322   // be revisited. 20040107.ysr
 323   clear(old_gen->prev_used_region());
 324 }
 325 
 326 void CardTableRS::invalidate_or_clear(Generation* old_gen) {
 327   assert(old_gen->level() == 1, "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
 332   // region). No need to do anything for the youngest
 333   // generation. Also see note#20040107.ysr above.
 334   MemRegion used_mr = old_gen->used_region();
 335   MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr);
 336   if (!to_be_cleared_mr.is_empty()) {
 337     clear(to_be_cleared_mr);
 338   }
 339   invalidate(used_mr);
 340 }
 341 
 342 
 343 class VerifyCleanCardClosure: public OopClosure {
 344 private:
 345   HeapWord* _boundary;
 346   HeapWord* _begin;
 347   HeapWord* _end;


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


 394     // Normally, we're interested in pointers to younger generations.
 395     VerifyCTSpaceClosure blk(_ct, gen->reserved().start());
 396     gen->space_iterate(&blk, true);
 397   }
 398 };
 399 
 400 void CardTableRS::verify_space(Space* s, HeapWord* gen_boundary) {
 401   // We don't need to do young-gen spaces.
 402   if (s->end() <= gen_boundary) return;


 403   MemRegion used = s->used_region();
 404 
 405   jbyte* cur_entry = byte_for(used.start());
 406   jbyte* limit = byte_after(used.last());
 407   while (cur_entry < limit) {
 408     if (*cur_entry == CardTableModRefBS::clean_card) {
 409       jbyte* first_dirty = cur_entry+1;
 410       while (first_dirty < limit &&
 411              *first_dirty == CardTableModRefBS::clean_card) {
 412         first_dirty++;
 413       }
 414       // If the first object is a regular object, and it has a
 415       // young-to-old field, that would mark the previous card.
 416       HeapWord* boundary = addr_for(cur_entry);
 417       HeapWord* end = (first_dirty >= limit) ? used.end() : addr_for(first_dirty);
 418       HeapWord* boundary_block = s->block_start(boundary);
 419       HeapWord* begin = boundary;             // Until proven otherwise.
 420       HeapWord* start_block = boundary_block; // Until proven otherwise.
 421       if (boundary_block < boundary) {
 422         if (s->block_is_obj(boundary_block) && s->obj_is_alive(boundary_block)) {




  39 #endif // INCLUDE_ALL_GCS
  40 
  41 CardTableRS::CardTableRS(MemRegion whole_heap,
  42                          int max_covered_regions) :
  43   GenRemSet(),
  44   _cur_youngergen_card_val(youngergenP1_card),
  45   _regions_to_iterate(max_covered_regions - 1)
  46 {
  47 #if INCLUDE_ALL_GCS
  48   if (UseG1GC) {
  49       _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap,
  50                                                   max_covered_regions);
  51   } else {
  52     _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
  53   }
  54 #else
  55   _ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions);
  56 #endif
  57   _ct_bs->initialize();
  58   set_bs(_ct_bs);
  59   // max_gens is really GenCollectedHeap::heap()->gen_policy()->number_of_generations()
  60   // (which always is 2), but GenCollectedHeap has not been initialized yet.
  61   int max_gens = 2;
  62   _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, max_gens + 1,
  63                          mtGC, CURRENT_PC, AllocFailStrategy::RETURN_NULL);
  64   if (_last_cur_val_in_gen == NULL) {
  65     vm_exit_during_initialization("Could not create last_cur_val_in_gen array.");
  66   }
  67   for (int i = 0; i < max_gens + 1; i++) {
  68     _last_cur_val_in_gen[i] = clean_card_val();
  69   }
  70   _ct_bs->set_CTRS(this);
  71 }
  72 
  73 CardTableRS::~CardTableRS() {
  74   if (_ct_bs) {
  75     delete _ct_bs;
  76     _ct_bs = NULL;
  77   }
  78   if (_last_cur_val_in_gen) {
  79     FREE_C_HEAP_ARRAY(jbyte, _last_cur_val_in_gen, mtInternal);
  80   }
  81 }
  82 
  83 void CardTableRS::resize_covered_region(MemRegion new_region) {
  84   _ct_bs->resize_covered_region(new_region);
  85 }
  86 
  87 jbyte CardTableRS::find_unused_youngergenP_card_value() {


 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) {
 410     return;
 411   }
 412   MemRegion used = s->used_region();
 413 
 414   jbyte* cur_entry = byte_for(used.start());
 415   jbyte* limit = byte_after(used.last());
 416   while (cur_entry < limit) {
 417     if (*cur_entry == CardTableModRefBS::clean_card) {
 418       jbyte* first_dirty = cur_entry+1;
 419       while (first_dirty < limit &&
 420              *first_dirty == CardTableModRefBS::clean_card) {
 421         first_dirty++;
 422       }
 423       // If the first object is a regular object, and it has a
 424       // young-to-old field, that would mark the previous card.
 425       HeapWord* boundary = addr_for(cur_entry);
 426       HeapWord* end = (first_dirty >= limit) ? used.end() : addr_for(first_dirty);
 427       HeapWord* boundary_block = s->block_start(boundary);
 428       HeapWord* begin = boundary;             // Until proven otherwise.
 429       HeapWord* start_block = boundary_block; // Until proven otherwise.
 430       if (boundary_block < boundary) {
 431         if (s->block_is_obj(boundary_block) && s->obj_is_alive(boundary_block)) {


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