8230674: Heap dumps should exclude dormant CDS archived objects of unloaded classes
authoriklam
Wed, 11 Sep 2019 13:28:09 -0700
changeset 58090 91bc4d6c4054
parent 58089 e64fec9f1773
child 58091 c0cc906cb29c
8230674: Heap dumps should exclude dormant CDS archived objects of unloaded classes Reviewed-by: dholmes, jiangli
src/hotspot/share/services/heapDumper.cpp
--- a/src/hotspot/share/services/heapDumper.cpp	Wed Sep 11 12:32:01 2019 -0700
+++ b/src/hotspot/share/services/heapDumper.cpp	Wed Sep 11 13:28:09 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -686,6 +686,16 @@
 
   // fixes up the current dump record and writes HPROF_HEAP_DUMP_END record
   static void end_of_dump(DumpWriter* writer);
+
+  static oop mask_dormant_archived_object(oop o) {
+    if (o != NULL && o->klass()->java_mirror() == NULL) {
+      // Ignore this object since the corresponding java mirror is not loaded.
+      // Might be a dormant archive object.
+      return NULL;
+    } else {
+      return o;
+    }
+  }
 };
 
 // write a header of the given type
@@ -761,6 +771,13 @@
     case JVM_SIGNATURE_CLASS :
     case JVM_SIGNATURE_ARRAY : {
       oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset);
+      if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) {
+        ResourceMark rm;
+        log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
+                             p2i(o), o->klass()->external_name(),
+                             p2i(obj), obj->klass()->external_name());
+      }
+      o = mask_dormant_archived_object(o);
       assert(oopDesc::is_oop_or_null(o), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
       writer->write_objectID(o);
       break;
@@ -958,11 +975,6 @@
 // creates HPROF_GC_INSTANCE_DUMP record for the given object
 void DumperSupport::dump_instance(DumpWriter* writer, oop o) {
   Klass* k = o->klass();
-  if (k->java_mirror() == NULL) {
-    // Ignoring this object since the corresponding java mirror is not loaded.
-    // Might be a dormant archive object.
-    return;
-  }
 
   writer->write_u1(HPROF_GC_INSTANCE_DUMP);
   writer->write_objectID(o);
@@ -1148,6 +1160,13 @@
   // [id]* elements
   for (int index = 0; index < length; index++) {
     oop o = array->obj_at(index);
+    if (o != NULL && log_is_enabled(Debug, cds, heap) && mask_dormant_archived_object(o) == NULL) {
+      ResourceMark rm;
+      log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s) referenced by " INTPTR_FORMAT " (%s)",
+                           p2i(o), o->klass()->external_name(),
+                           p2i(array), array->klass()->external_name());
+    }
+    o = mask_dormant_archived_object(o);
     writer->write_objectID(o);
   }
 }
@@ -1427,6 +1446,11 @@
     }
   }
 
+  if (DumperSupport::mask_dormant_archived_object(o) == NULL) {
+    log_debug(cds, heap)("skipped dormant archived object " INTPTR_FORMAT " (%s)", p2i(o), o->klass()->external_name());
+    return;
+  }
+
   if (o->is_instance()) {
     // create a HPROF_GC_INSTANCE record for each object
     DumperSupport::dump_instance(writer(), o);