Request for review: (small): 6722112 CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
Y Srinivas Ramakrishna
Y.S.Ramakrishna at Sun.COM
Thu Aug 7 23:17:29 UTC 2008
webrev: http://analemma.sfbay.sun.com/net/spot/workspaces/ysr/cms_ovflw/webrev/
[I reproduce the small 1-file patch below -- scroll past my signoff below.]
6722112 CMS: Incorrect encoding of overflown object arrays during concurrent precleaning
[This is one of 3 sub-bugs created to address the fixes entailed in CR 6578335;
the other two on the anvil are CR 6722113 and 6722116 which we shall submit for
review soon.]
When encoding the "greyness" of objects that overflowed the
grey bag (i.e. marking stack), we were dirtying the card in the
mod-union table that started the object, with the expectation
that a subsequent round of precleaning or a final remark phase
would scan those overflown objects.
However, for precleaning/remark efficiency of large object arrays,
we (both mark and) scan object arrays precisely (i.e. only the portions
of such arrays that lie on dirty cards). This would obviously
be vulnerable to missing those references that were installed before
the start of the marking cycle and not modified since.
The fix is to dirty the entire overflow object array in the mod union
table.
Many thanks to Poonam Bajaj for crucial help in identifying the problem(s)
and for subsequent verification/testing.
Testing: the failing big apps test w/stress options, refworkload, jprt
thanks for yr reviews.
-- ramki
---- patch ----
--- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 7 15:49:55 2008
+++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Aug 7 15:49:54 2008
@@ -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
More information about the hotspot-gc-dev
mailing list