Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2198054 | 7 | Y. Ramakrishna | P2 | Closed | Fixed | b109 |
JDK-2197877 | 6u23 | Y. Ramakrishna | P2 | Resolved | Fixed | b01 |
JDK-2199778 | 6u22m | Y. Ramakrishna | P2 | Resolved | Fixed | b01 |
JDK-2197146 | 6u22-rev | Chris Phillips | P2 | Resolved | Fixed | b06 |
JDK-2197583 | 6u21p | Y. Ramakrishna | P2 | Resolved | Fixed | b03 |
JDK-2204495 | 5.0u29 | Yumin Qi | P3 | Closed | Fixed | b01 |
JDK-2204496 | 1.4.2_31 | Yumin Qi | P3 | Closed | Fixed | b01 |
CR 6948538. The specific change was that since the product build used
-XX:-BlockOffsetArrayUseUnallocatedBlock, the fastdebug builds were also
changed (from trueInDebug to false) so that the same code paths were
exercised in both, so we were testing the product bits. This revealed
a long-standing bug in the code that tripped an assertion that was a tad
too strong. Note that the bug itself exists in the product builds preceding
6948538; it was just that the bug was not revealed until the recent change in the
setting of the flag for debug builds.
More specifically, the CMS sweep is limited to the high water mark (if any)
of allocation at the point at which the concurrent marking cycle was started.
When we do not use +BlockOffsetArrayUseUnallocatedBlock, this is the "end"
of the committed space for a CMS generation. If the CMS generation is not
fully committed at this point and is expanded during the sweep, then the
newly expanded portion is coalesced with the previously co-terminal chunk
in order to limit fragmentation. That means that a previously recorded
"limit" (being the address of the previous "end") is no longer a block
boundary and may not be encountered by the sweep, which may skip over that
specific address. This fell afoul of the code and assertion in question,
which is reproduced below:-
7936 size_t SweepClosure::do_blk_careful(HeapWord* addr) {
7937 FreeChunk* fc = (FreeChunk*)addr;
7938 size_t res;
7939
7940 // check if we are done sweepinrg
7941 if (addr == _limit) { // we have swept up to the limit, do nothing more
7942 assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
7943 "sweep _limit out of bounds");
7944 // help the closure application finish
7945 return pointer_delta(_sp->end(), _limit);
7946 }
7947 assert(addr <= _limit, "sweep invariant");
The fix is to relax the code to allow a "skipping over" the limit,
rather than "stepping on the limit", see suggested fix section.
- backported by
-
JDK-2197146 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Resolved
-
-
JDK-2197583 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Resolved
-
-
JDK-2197877 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Resolved
-
-
JDK-2199778 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Resolved
-
-
JDK-2198054 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Closed
-
-
JDK-2204495 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Closed
-
-
JDK-2204496 CMS: concurrentMarkSweepGeneration.cpp:7947 assert(addr <= _limit) failed: sweep invariant
-
- Closed
-
- relates to
-
JDK-7008136 CMS: assert((HeapWord*)nextChunk <= _limit) failed: sweep invariant
-
- Closed
-
-
JDK-6948538 CMS: BOT walkers can fall into object allocation and initialization cracks
-
- Closed
-