6722112: CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
authorysr
Thu, 14 Aug 2008 17:58:35 -0700
changeset 991 5b25d0a7116f
parent 985 5d1e7eafc504
child 992 494cf8c1a5ed
child 1060 e4cfd5e4ff05
child 1388 3677f5f3d66b
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
hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Sun Aug 10 21:58:54 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Aug 14 17:58:35 2008 -0700
@@ -6867,11 +6867,9 @@
         // during the preclean or remark phase. (CMSCleanOnEnter)
         if (CMSCleanOnEnter) {
           size_t sz = _collector->block_size_using_printezis_bits(addr);
-          HeapWord* start_card_addr = (HeapWord*)round_down(
-                                         (intptr_t)addr, CardTableModRefBS::card_size);
           HeapWord* end_card_addr   = (HeapWord*)round_to(
                                          (intptr_t)(addr+sz), CardTableModRefBS::card_size);
-          MemRegion redirty_range = MemRegion(start_card_addr, end_card_addr);
+          MemRegion redirty_range = MemRegion(addr, end_card_addr);
           assert(!redirty_range.is_empty(), "Arithmetical tautology");
           // Bump _threshold to end_card_addr; note that
           // _threshold cannot possibly exceed end_card_addr, anyhow.
@@ -7460,12 +7458,25 @@
     )
     if (simulate_overflow || !_mark_stack->push(obj)) {
       if (_concurrent_precleaning) {
-         // During precleaning we can just dirty the appropriate card
+         // During precleaning we can just dirty the appropriate card(s)
          // in the mod union table, thus ensuring that the object remains
-         // in the grey set  and continue. Note that no one can be intefering
-         // with us in this action of dirtying the mod union table, so
-         // no locking is required.
-         _mod_union_table->mark(addr);
+         // in the grey set  and continue. In the case of object arrays
+         // we need to dirty all of the cards that the object spans,
+         // since the rescan of object arrays will be limited to the
+         // dirty cards.
+         // Note that no one can be intefering with us in this action
+         // of dirtying the mod union table, so no locking or atomics
+         // are required.
+         if (obj->is_objArray()) {
+           size_t sz = obj->size();
+           HeapWord* end_card_addr = (HeapWord*)round_to(
+                                        (intptr_t)(addr+sz), CardTableModRefBS::card_size);
+           MemRegion redirty_range = MemRegion(addr, end_card_addr);
+           assert(!redirty_range.is_empty(), "Arithmetical tautology");
+           _mod_union_table->mark_range(redirty_range);
+         } else {
+           _mod_union_table->mark(addr);
+         }
          _collector->_ser_pmc_preclean_ovflw++;
       } else {
          // During the remark phase, we need to remember this oop