Thu, 14 Aug 2008 17:58:35 -0700
6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
Summary: When an object array overflows during precleaning, we should have been marking the entire array dirty, not just its first card.
Reviewed-by: jmasa, poonam, tonyp
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Sun Aug 10 21:58:54 2008 -0700 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 14 17:58:35 2008 -0700 1.3 @@ -6867,11 +6867,9 @@ 1.4 // during the preclean or remark phase. (CMSCleanOnEnter) 1.5 if (CMSCleanOnEnter) { 1.6 size_t sz = _collector->block_size_using_printezis_bits(addr); 1.7 - HeapWord* start_card_addr = (HeapWord*)round_down( 1.8 - (intptr_t)addr, CardTableModRefBS::card_size); 1.9 HeapWord* end_card_addr = (HeapWord*)round_to( 1.10 (intptr_t)(addr+sz), CardTableModRefBS::card_size); 1.11 - MemRegion redirty_range = MemRegion(start_card_addr, end_card_addr); 1.12 + MemRegion redirty_range = MemRegion(addr, end_card_addr); 1.13 assert(!redirty_range.is_empty(), "Arithmetical tautology"); 1.14 // Bump _threshold to end_card_addr; note that 1.15 // _threshold cannot possibly exceed end_card_addr, anyhow. 1.16 @@ -7460,12 +7458,25 @@ 1.17 ) 1.18 if (simulate_overflow || !_mark_stack->push(obj)) { 1.19 if (_concurrent_precleaning) { 1.20 - // During precleaning we can just dirty the appropriate card 1.21 + // During precleaning we can just dirty the appropriate card(s) 1.22 // in the mod union table, thus ensuring that the object remains 1.23 - // in the grey set and continue. Note that no one can be intefering 1.24 - // with us in this action of dirtying the mod union table, so 1.25 - // no locking is required. 1.26 - _mod_union_table->mark(addr); 1.27 + // in the grey set and continue. In the case of object arrays 1.28 + // we need to dirty all of the cards that the object spans, 1.29 + // since the rescan of object arrays will be limited to the 1.30 + // dirty cards. 1.31 + // Note that no one can be intefering with us in this action 1.32 + // of dirtying the mod union table, so no locking or atomics 1.33 + // are required. 1.34 + if (obj->is_objArray()) { 1.35 + size_t sz = obj->size(); 1.36 + HeapWord* end_card_addr = (HeapWord*)round_to( 1.37 + (intptr_t)(addr+sz), CardTableModRefBS::card_size); 1.38 + MemRegion redirty_range = MemRegion(addr, end_card_addr); 1.39 + assert(!redirty_range.is_empty(), "Arithmetical tautology"); 1.40 + _mod_union_table->mark_range(redirty_range); 1.41 + } else { 1.42 + _mod_union_table->mark(addr); 1.43 + } 1.44 _collector->_ser_pmc_preclean_ovflw++; 1.45 } else { 1.46 // During the remark phase, we need to remember this oop