United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7200261 G1: Liveness counting inconsistencies during marking verification
JDK-7200261 : G1: Liveness counting inconsistencies during marking verification

Details
Type:
Bug
Submit Date:
2012-09-21
Status:
Resolved
Updated Date:
2013-04-30
Project Name:
JDK
Resolved Date:
2012-09-28
Component:
hotspot
OS:
generic
Sub-Component:
gc
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
7u6
Fixed Versions:
hs25 (b04)

Related Reports
Backport:
Backport:
Backport:
Backport:
Duplicate:
Duplicate:

Sub Tasks

Description
After merging up some of my in-progress workspaces with the latest changes in hotspot-gc, I started to see marking verification failures that are caused by inconsistencies in the liveness counting:

2.919: [GC cleanup VerifyDuringGC:(before)[Verifying threads Roots HeapRegionSets HeapRegions RemSet syms strs zone dict cldg hand C-heap code cache ]
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=/concurrentMark.cpp:1936
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/export/workspaces/7188263/src/share/vm/gc_implementation/g1/concurrentMark.cpp:1936), pid=26746, tid=14
#  guarantee(g1_par_verify_task.failures() == 0) failed: Unexpected accounting failures
#
# JRE version: Java(TM) SE Runtime Environment (7.0-b142)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.0-b02-internal-fastdebug mixed mode solaris-amd64 compressed oops)
# Core dump written. Default location: /export/GC-TEST-SUITES/gc_test_suite/gc_test_suite_3/specjvm98/core or core.26746
#
# An error report file with more information is saved as:
# /export/GC-TEST-SUITES/gc_test_suite/gc_test_suite_3/specjvm98/hs_err_pid26746.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp

Errors of this type indicate that the liveness counting data, that is collected concurrently, is out of whack when compared against some reference data generated by walking the marking bitmap.

                                    

Comments
EVALUATION

Attempting to clip the range in set_card_bitmap_range to the card bitmap size incorrectly calculated the end of the range as the end of the card bitmap - resulting in incorrectly setting bits for cards not spanned by live objects. In the following:

  void set_card_bitmap_range(BitMap::idx_t start_idx, BitMap::idx_t last_idx) {
    assert(start_idx <= last_idx, "sanity");

    // Set the inclusive bit range [start_idx, last_idx].
    // For small ranges (up to 8 cards) use a simple loop; otherwise
    // use par_at_put_range.
    if ((last_idx - start_idx) < 8) {
      for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
        _card_bm->par_set_bit(i);
      }
    } else {
      assert(last_idx < _card_bm->size(), "sanity");
      // Note BitMap::par_at_put_range() is exclusive.
      BitMap::idx_t max_idx = MAX2(last_idx+1, _card_bm->size());
      _card_bm->par_at_put_range(start_idx, max_idx, true);
    }
  }

we should be using MIN2 to calculate max_idx instead on MAX2.
                                     
2012-09-21
SUGGESTED FIX

See evaluation
                                     
2012-09-21
URL:   http://hg.openjdk.java.net/hsx/hotspot-gc/hotspot/rev/988bf00cc564
User:  johnc
Date:  2012-09-28 01:36:11 +0000

                                     
2012-09-28
URL:   http://hg.openjdk.java.net/hsx/hsx25/hotspot/rev/988bf00cc564
User:  amurillo
Date:  2012-10-05 22:35:18 +0000

                                     
2012-10-05



Hardware and Software, Engineered to Work Together