JDK-6956639 : G1: assert(cached_ptr != card_ptr) failed: shouldn't be, concurrentG1Refine.cpp:307
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2010-05-28
  • Updated: 2013-09-18
  • Resolved: 2010-08-04
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u21pFixed 7Fixed hs19Fixed
Description
Igor reported that he was seeing this assertion while testing tiered through JPRT - though this particular assert was seen when running on C1. Here's Igor's email:

This one appeared again in during my testing today:

#  Internal Error (/tmp/jprt/P1/B/150025.iv159533/source/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp:307),
  pid=19418, tid=3031919504
#  assert(cached_ptr != card_ptr) failed: shouldn't be

It's linux x86 c1.
It was preceded by the cleanup.

igor

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-rt/hotspot/rev/5cbac8938c4c
25-07-2010

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot/hotspot/rev/5cbac8938c4c
23-07-2010

SUGGESTED FIX During concurrent refinement, defer the filtering of cards in young regions until during the iteration of the oops on the card. In the iteration code there is an intersection call with the MemRegion for the card and the used part of the HeapRegion. If the intersection is non-empty then we iterate over the card. If this intersection is non-empty then we know that the region has been used to allocate from and so should have it's young type set. (When the region becomes the current allocation region, its young type is set before it is used to satisfy an allocation.)
20-07-2010

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/5cbac8938c4c
19-07-2010

EVALUATION There are couple reasons why we may see cards in a young region coming out of the card cache. One of this is that the while the card was in the cache, its region was freed during a cleanup pause, and subsequently re-used as the current allocation region. Adding additional filters for young regions in the concurrent refine code was still problematic as the concurrent thread could see the region's young type change from NonYoung to Young at any time. The better solution to this is to defer the filtering of cards in young regions until during the iteration of the oops on the card. In the iteration code there is an intersection call with the MemRegion for the card and the used part of the HeapRegion. If the intersection is non-empty then we iterate over the card. If this intersection is non-empty then we know that the region has been used to allocate from and so should have it's young type set. (When the region becomes the current allocation region, its young type is set before it is used to satisfy an allocation.)
19-07-2010

EVALUATION This is an assert I added. I thought the "is_young" checks in the caller and in this routine would ensure that we had different cards. The card we got back from the cache is the same as the card we were adding to the cache and while we were checking the cache the region got freed and then allocated again. The assert is too strong and if the card we get back is the same as the card we are inserting (and it's now young), then we can set the value of "defer" (while still returning NULL) so that the caller won't process the card.
28-05-2010