JDK-6912621 : iCMS: Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: hs20,7
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2009-12-22
  • Updated: 2012-02-01
  • Resolved: 2011-03-07
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 7 Other
7Fixed hs21Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Saw this assertion failure in the 2009-12-18 nightly testing.

[2009-12-19T11:09:12.05] #  Internal Error (/tmp/jprt/P1/B/005121.iv159533/source/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp:6238), pid=13350, tid=51
[2009-12-19T11:09:12.05] #  Error: assert(_markBitMap.isMarked(addr + 1),"Missing Printezis bit?")
[2009-12-19T11:09:12.05] #
[2009-12-19T11:09:12.05] # JRE version: 7.0-b77
[2009-12-19T11:09:12.05] # Java VM: OpenJDK 64-Bit Server VM (17.0-b05-2009-12-17-005121.iv159533.hotspot-gc-update-sched2-fastdebug mixed mode solaris-sparc compressed oops)
[2009-12-19T11:09:12.05] # An error report file with more information is saved as:
[2009-12-19T11:09:12.05] # /export/local/27915.JDK7.NIGHTLY.VM+solaris-sparcv9_server_mixed_vm.parallel_class_loading.testlist/results/ResultDir/anonymous-complex_copy_1/hs_err_pid13350.log
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/anonymous-simple

-----------------  lwp# 3 / thread# 3  --------------------
 ce6ca9b5 _lwp_kill (3, 6) + 15
 ce671e03 raise    (6) + 1f
 ce651c4d abort    (ce32f2e8, ce299440, 0, 50, 0, 2) + cd
 cd7f41f2 __1cCosFabort6Fb_v_ (1, ce203082, 1, ce349680) + 112
 cdcfbc97 __1cHVMErrorOreport_and_die6M_v_ (cbcbe960, cdf1138d, cbcbea38, ccac022c) + a7f
 ccac0251 __1cPreport_vm_error6Fpkci11_v_ (cdf113d2, 185e, cdf113a4, cdf1138d) + 5ad
 cca3a4d4 __1cMCMSCollectorbCblock_size_if_printezis_bits6kMpnIHeapWord__I_ (8095a40, c4acf3d8, c4acf280, c4800168) + 470
 cc966473 __1cYCompactibleFreeListSpaceTblock_size_no_stall6kMpnIHeapWord_pknMCMSCollector__I_ (808da90, c4acf3d8, 8095a40, cd74c2c6) + 2b7
 cca6332e __1cWMarkDeadObjectsClosureGdo_blk6MpnIHeapWord__I_ (cbcbeb70, c4acf3d8, cbcbeb48, cca67ca8) + 1a
 cc964735 __1cYCompactibleFreeListSpaceLblk_iterate6MpnKBlkClosure__v_ (808da90, cbcbeb70, cbcbec88, cca36bd2) + 3d
 cca36e10 __1cMCMSCollectorFsweep6Mb_v_ (8095a40, 1, 64, cca19157) + 25c
 cca196ad __1cMCMSCollectorVcollect_in_background6Mb_v_ (8095a40, 0, 0, 0) + 5cd
 cca675e4 __1cZConcurrentMarkSweepThreadDrun6M_v_ (8096400, ce355f20, 0, cd7f0880) + 480
 cd7f0f20 java_start (8096400) + 708
 ce6c7055 _thr_setup (cbf50a00) + 4e
 ce6c7340 _lwp_start (cbf50a00, 0, 0, cbcbeff8, ce6c7340, cbf50a00)


Details can be found at or near:-

http://sqeweb.sfbay.sun.com/nfs/results/vm/gtee/JDK7/NIGHTLY/VM/2010-08-09/Main_Baseline/vm/solaris-i586/server/mixed/solaris-i586_vm_server_mixed_vm.parallel_class_loading.testlist/ResultDir/anonymous-simple
From:-

http://sqeweb.sfbay.sun.com/nfs/results/vm/gtee/JDK7/NIGHTLY/VM/2010-12-14/Main_Baseline/new_unknown_failures.html


runtime/ParallelClassLoading/stress-redefine/holdLock/reflect/anonymous-simple
runtime/ParallelClassLoading/stress-redefine/holdLock/reflect/anonymous-complex
runtime/ParallelClassLoading/stress-redefine/holdLock/loadClass/tree
runtime/ParallelClassLoading/stress-redefine/holdLock/loadClass/dynamic-init/init-simple
runtime/ParallelClassLoading/stress-redefine/holdLock/loadClass/dynamic-init/anonymous-complex
runtime/ParallelClassLoading/stress-redefine/holdLock/loadClass/dynamic-init/abstract
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/tree
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/init-simple
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/init-complex
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/independent
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/dynamic-init/init-simple
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/dynamic-init/init-complex
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/dynamic-init/abstract
runtime/ParallelClassLoading/stress-redefine/holdLock/forName/anonymous-simple
runtime/ParallelClassLoading/stress-redefine/freeLock/loadClass/init-complex
runtime/ParallelClassLoading/stress-redefine/freeLock/loadClass/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/stress-redefine/freeLock/loadClass/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/URLClassLoader/reflect/redefine/independent
runtime/ParallelClassLoading/std_CLs/URLClassLoader/reflect/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/URLClassLoader/loadClass/redefine/tree
runtime/ParallelClassLoading/std_CLs/URLClassLoader/loadClass/redefine/independent
runtime/ParallelClassLoading/std_CLs/URLClassLoader/loadClass/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/URLClassLoader/loadClass/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/URLClassLoader/loadClass/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/tree
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/independent
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/dynamic-init/anonymous-complex
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/URLClassLoader/forName/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/reflect/redefine/dynamic-init/inner-complex
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/reflect/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/reflect/redefine/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/reflect/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/loadClass/redefine/inner-complex
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/loadClass/redefine/independent
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/loadClass/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/loadClass/redefine/anonymous-simple

runtime/ParallelClassLoading/std_CLs/SecureClassLoader/forName/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/forName/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/SecureClassLoader/forName/redefine/anonymous-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/tree
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/init-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/independent
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/PrivateMLet/reflect/redefine/anonymous-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/loadClass/redefine/init-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/loadClass/redefine/independent
runtime/ParallelClassLoading/std_CLs/PrivateMLet/loadClass/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/loadClass/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/PrivateMLet/loadClass/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/PrivateMLet/forName/redefine/init-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/forName/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/forName/redefine/dynamic-init/anonymous-simple
runtime/ParallelClassLoading/std_CLs/PrivateMLet/forName/redefine/dynamic-init/anonymous-complex
runtime/ParallelClassLoading/std_CLs/PrivateMLet/forName/redefine/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/MLet/reflect/redefine/independent
runtime/ParallelClassLoading/std_CLs/MLet/reflect/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/MLet/reflect/redefine/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/MLet/reflect/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/MLet/loadClass/redefine/init-complex
runtime/ParallelClassLoading/std_CLs/MLet/loadClass/redefine/independent
runtime/ParallelClassLoading/std_CLs/MLet/loadClass/redefine/dynamic-init/anonymous-complex
runtime/ParallelClassLoading/std_CLs/MLet/loadClass/redefine/dynamic-init/abstract
runtime/ParallelClassLoading/std_CLs/MLet/loadClass/redefine/anonymous-simple
runtime/ParallelClassLoading/std_CLs/MLet/forName/redefine/tree
runtime/ParallelClassLoading/std_CLs/MLet/forName/redefine/init-complex
runtime/ParallelClassLoading/std_CLs/MLet/forName/redefine/dynamic-init/init-complex
runtime/ParallelClassLoading/std_CLs/MLet/forName/redefine/anonymous-complex
See:-

http://sqeweb.sfbay.sun.com/nfs/results/vm/gtee/JDK7/NIGHTLY/VM/2010-12-21/Main_Baseline/vm/linux-i586/server/mixed/linux-i586_vm_server_mixed_vm.parallel_class_loading.testlist/analysis.html

Comments
EVALUATION If 6912621 is ever backported to an earlier release, 7018302 should be backported at that time as well so as to avoid a bug in fastdebug builds that this CR introduced. See 7018302 for more details.
11-02-2011

EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/c5a923563727
08-02-2011

EVALUATION It appears as though the intent of "conc_unsafe" was for checking the contents of an object in as much as it could be internally inconsistent. However, an object still appears to faithfully report its size even when it is conc_unsafe, just as long as it is_parsable(). Once the size of an object that is_parsable() but possibly conc_unsafe() can be correctly found (is_parsable() is a-priori bounded), the unboundedness of conc_unsafe is no longer an imediment to the progress of heap iteration which had been the problem earlier (and as described above). See suggested fix section. Fix under test and review.
25-01-2011

SUGGESTED FIX diff -r 377371490991 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Jan 20 13:57:12 2011 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Jan 25 01:08:52 2011 -0800 @@ -1041,8 +1041,7 @@ const { // must read from what 'p' points to in each loop. klassOop k = ((volatile oopDesc*)p)->klass_or_null(); if (k != NULL && - ((oopDesc*)p)->is_parsable() && - ((oopDesc*)p)->is_conc_safe()) { + ((oopDesc*)p)->is_parsable() /* && ((oopDesc*)p)->is_conc_safe() */ ) { assert(k->is_oop(), "Should really be klass oop."); oop o = (oop)p; assert(o->is_oop(), "Should be an oop"); @@ -1051,6 +1050,7 @@ const { assert(res != 0, "Block size should not be 0"); return res; } else { + // May return 0 if P-bits not present. return c->block_size_if_printezis_bits(p); } } diff -r 377371490991 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 20 13:57:12 2011 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Jan 25 01:08:53 2011 -0800 @@ -6359,18 +6359,16 @@ size_t CMSCollector::block_size_using_pr // A variant of the above (block_size_using_printezis_bits()) except // that we return 0 if the P-bits are not yet set. size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const { - if (_markBitMap.isMarked(addr)) { - assert(_markBitMap.isMarked(addr + 1), "Missing Printezis bit?"); + if (_markBitMap.isMarked(addr + 1)) { + assert(_markBitMap.isMarked(addr), "P-bit can be set only for marked objects"); HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2); size_t size = pointer_delta(nextOneAddr + 1, addr); assert(size == CompactibleFreeListSpace::adjustObjectSize(size), "alignment problem"); assert(size >= 3, "Necessary for Printezis marks to work"); return size; - } else { - assert(!_markBitMap.isMarked(addr + 1), "Bit map inconsistency?"); - return 0; - } + } + return 0; } HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const { @@ -9211,7 +9209,6 @@ bool MarkRefsIntoAndScanClosure::take_fr size_t MarkDeadObjectsClosure::do_blk(HeapWord* addr) { size_t res = _sp->block_size_no_stall(addr, _collector); - assert(res != 0, "Should always be able to compute a size"); if (_sp->block_is_obj(addr)) { if (_live_bit_map->isMarked(addr)) { // It can't have been dead in a previous cycle
25-01-2011

EVALUATION That was too simple wasn't it? Turns out that there is no a priori bound on how long an object can stay in the conc_unsafe state. This is because objects are constructed piecemeal and wired together, and certain objects will remain conc_unsafe until certain other objects have been allocated and wired. In other words, there can be safepoints during which we may find objects to be conc_unsafe, and indeed it seems as though an object may be stranded in that state if a subsequent allocation of another related object is not completed. It is possible that "conc_unsafeness" is perhaps being too conservative, or if not, then it must be the case that other GC's are similarly vulnerable, except that the unsafeness is probably much less so for contiguous spaces. This _may_ become moot once metadata moves out of the Java heap (i.e. perm gen as we know it goes away). Until then it seems as though we can only narrow the window of vulnerability, not completely close it. I'll need to talk with the class rewriting cognoscenti before deciding on the best approach forward. Meanwhile, I'll avoid the problem in the concurrent phase and punt the problem over to a stop-world phase in case of situations where we are out of space. This might require partially unwinding out of an in-progress sweep phase.
24-01-2011

EVALUATION During class redefinition an existing reachable object in the perm gen may transiently transition from "conc_safe" to unsafe and back to safe. If class unloading is disabled, this allowed a call to block_size_no_stall() to find such an object and assert in block_size_if_printezis_bits() which was incorrectly structured. The fix is to correct block_size_if_printezis_bits() so it does what its spec stated, and for the concurrent callers of block_size_no_stall() to always be prepared to get back a zero size for such an object. Adjusted the caller from MarkDeadObjectsClosure::do_blk() who was not previously prepared for such a sero return value. With the fix, the parallel class loading benchmarks pass whereas many of them failed intermittently before the fix. Disabling class unloading makes the problem happen more easily when running without the fiux, but is not essential for the bug to occur. The bug can be made to occur readily by running the parallel class loading / class redefinition tests with the timing window of "unsafeness" artificially increased.
21-01-2011

WORK AROUND It appears as though -XX:+CMSClassUnloadingEnabled makes the bug go away, although lacking a diagnosis it is not known why or even whether this is a reliable workaround.
19-01-2011