RFR [10]: Fix ciInstanceKlass::ensure_metadata_alive for Shenandoah

Aleksey Shipilev shade at redhat.com
Mon Apr 9 16:09:36 UTC 2018


I have been chasing the bug that manifests on Derby occasionally:

#  Internal Error
(/home/jenkins/workspace/nightly/shenandoah-jdk10/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp:800),
pid=160323, tid=160333
#  Error: Shenandoah assert_marked_complete failed; Object should be marked (complete)

Referenced from:
  interior location: 0x00007fe8dc008fd8
  outside of Java heap
  0x00007fe8dc008fd8 is a local jni handle

Object:
  0x00000000fff70af8 - klass 0x0000000100251b88
org.apache.derby.impl.services.reflect.ReflectLoaderJava2
    not allocated after complete mark start
        allocated after next mark start
    not marked complete
        marked next
        in collection set
  region: | 2046|CS |BTE     fff00000,     fff80000,     fff80000|TAMS     fff80000,     fff00000|U
100%|T   0%|G 100%|S   0%|L  96%| |CP   0|SN            0,        0,   1917ea,   1917f1

Forwardee:
  (the object itself)

The head-scratcher is that the failure only happens in sh/jdk10, and not anywhere else. The reason
for that is, we have picked up the JDK-8190891 [1] that reshuffled ensure_metadata_alive calls, and
the *new* shared ensure_metadata_alive was effectively disabled for Shenandoah:
  https://bugs.openjdk.java.net/browse/JDK-8190891
  http://hg.openjdk.java.net/jdk/jdk/rev/e20d8f168bb6#l2.16

Thus, we started missing some roots during class (un)loading in sh/jdk10. sh/jdk9 and sh/jdk8 are
not affected, because JDK-8190891 is not there, and we have all the proper UseShenandoahGC checks.
sh/jdk is not affected, because GC API handles it correctly.

Fix is trivial:

diff -r 177d2c56166c src/hotspot/share/ci/ciInstanceKlass.cpp
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp	Fri Apr 06 17:32:05 2018 +0200
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp	Mon Apr 09 17:59:06 2018 +0200
@@ -55,7 +55,7 @@
 //
 static void ensure_metadata_alive(oop metadata_holder) {
 #if INCLUDE_ALL_GCS
-  if (!UseG1GC) {
+  if (!(UseG1GC || UseShenandoahGC)) {
     return;
   }
   if (metadata_holder != NULL) {


Testing: hotspot_gc_shenandoah, Derby (that used to fail)

Thanks,
-Aleksey


[1] https://bugs.openjdk.java.net/browse/JDK-8190891


More information about the shenandoah-dev mailing list