6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning

Thu, 14 Aug 2008 17:58:35 -0700

author
ysr
date
Thu, 14 Aug 2008 17:58:35 -0700
changeset 718
9199f248b0ee
parent 712
79276d1b7e50
child 719
92e12124e774
child 733
1e5d20c34408
child 791
1ee8caae33af

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

mercurial