Wed, 18 Aug 2010 11:39:21 -0700
6977970: CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
Summary: Allow for the possibility (when the heap is expanding) that the sweep might skip over and past, rather than necessarily step on, the sweep limit determined at the beginning of a concurrent marking cycle.
Reviewed-by: jmasa, 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 Tue Aug 17 14:40:00 2010 -0400 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Aug 18 11:39:21 2010 -0700 1.3 @@ -7937,14 +7937,20 @@ 1.4 FreeChunk* fc = (FreeChunk*)addr; 1.5 size_t res; 1.6 1.7 - // check if we are done sweepinrg 1.8 - if (addr == _limit) { // we have swept up to the limit, do nothing more 1.9 + // Check if we are done sweeping. Below we check "addr >= _limit" rather 1.10 + // than "addr == _limit" because although _limit was a block boundary when 1.11 + // we started the sweep, it may no longer be one because heap expansion 1.12 + // may have caused us to coalesce the block ending at the address _limit 1.13 + // with a newly expanded chunk (this happens when _limit was set to the 1.14 + // previous _end of the space), so we may have stepped past _limit; see CR 6977970. 1.15 + if (addr >= _limit) { // we have swept up to or past the limit, do nothing more 1.16 assert(_limit >= _sp->bottom() && _limit <= _sp->end(), 1.17 "sweep _limit out of bounds"); 1.18 + assert(addr < _sp->end(), "addr out of bounds"); 1.19 // help the closure application finish 1.20 - return pointer_delta(_sp->end(), _limit); 1.21 - } 1.22 - assert(addr <= _limit, "sweep invariant"); 1.23 + return pointer_delta(_sp->end(), addr); 1.24 + } 1.25 + assert(addr < _limit, "sweep invariant"); 1.26 1.27 // check if we should yield 1.28 do_yield_check(addr);