changeset 59278:62a97593094e nestmates

8216581: Add support in JFR for hidden classes Summary: add event support and "hidden" field for Java Classes Reviewed-by: coleenp, mgronlun
author hseigel
date Tue, 17 Mar 2020 14:32:09 +0000
parents 186eb4a26b8e
children f4f1d5294876
files src/hotspot/share/classfile/classLoaderStats.cpp src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp src/hotspot/share/jfr/metadata/metadata.xml src/hotspot/share/jfr/periodic/jfrPeriodic.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp src/hotspot/share/memory/metaspaceTracer.cpp src/hotspot/share/oops/klass.hpp test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java test/jdk/jdk/jfr/event/runtime/TestClasses.java test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java
diffstat 17 files changed, 128 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classLoaderStats.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/classfile/classLoaderStats.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -26,6 +26,7 @@
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/classLoaderDataGraph.hpp"
 #include "classfile/classLoaderStats.hpp"
+#include "oops/objArrayKlass.hpp"
 #include "oops/oop.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
 
@@ -71,10 +72,16 @@
 
   ClassStatsClosure csc;
   cld->classes_do(&csc);
+  bool is_hidden = false;
   if(cld->is_shortlived()) {
-    // if cld is short lived then there should be only one klass.  See if it is
-    // hidden or unsafe anonymous.
-    if (cld->klasses()->is_hidden()) {
+    // if cld is short lived then it must be either hidden or unsafe anonymous.
+    Klass* k = cld->klasses();
+    // if it's an array class then need to see if bottom class is hidden.
+    if (k->is_array_klass()) {
+      k = ObjArrayKlass::cast(k)->bottom_klass();
+    }
+    is_hidden = k->is_hidden();
+    if (is_hidden) {
       cls->_hidden_weak_classes_count += csc._num_classes;
     } else {
       cls->_anon_classes_count += csc._num_classes;
@@ -87,7 +94,7 @@
   ClassLoaderMetaspace* ms = cld->metaspace_or_null();
   if (ms != NULL) {
     if(cld->is_shortlived()) {
-      if (cld->klasses()->is_hidden()) {
+      if (is_hidden) {
         cls->_hidden_weak_chunk_sz += ms->allocated_chunks_bytes();
         cls->_hidden_weak_block_sz += ms->allocated_blocks_bytes();
       } else {
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -162,10 +162,9 @@
 
   if (k->is_instance_klass()) {
     const InstanceKlass* ik = InstanceKlass::cast(k);
-    if (ik->is_unsafe_anonymous()) {
+    if (ik->is_unsafe_anonymous() || ik->is_hidden()) {
       return;
     }
-    assert(!ik->is_unsafe_anonymous(), "invariant");
     const Symbol* name = ik->name();
     if (name != NULL) {
       write_text("Class Name: ");
--- a/src/hotspot/share/jfr/metadata/metadata.xml	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/jfr/metadata/metadata.xml	Tue Mar 17 14:32:09 2020 +0000
@@ -219,6 +219,7 @@
     stackTrace="true">
     <Field type="ClassLoader" name="classLoader" label="Class Loader" />
     <Field type="boolean" name="unsafeAnonymousClassLoader" label="Unsafe Anonymous Class Loader" />
+    <Field type="boolean" name="hiddenWeakClassLoader" label="Hidden Weak Class Loader" />
     <Field type="ulong" contentType="bytes" name="size" label="Size" />
     <Field type="MetadataType" name="metadataType" label="Metadata Type" />
     <Field type="MetaspaceObjectType" name="metaspaceObjectType" label="Metaspace Object Type" />
@@ -227,6 +228,7 @@
   <Event name="MetaspaceOOM" category="Java Virtual Machine, GC, Metaspace" label="Metaspace Out of Memory" startTime="false" stackTrace="true">
     <Field type="ClassLoader" name="classLoader" label="Class Loader" />
     <Field type="boolean" name="unsafeAnonymousClassLoader" label="Unsafe Anonymous Class Loader" />
+    <Field type="boolean" name="hiddenWeakClassLoader" label="Hidden Weak Class Loader" />
     <Field type="ulong" contentType="bytes" name="size" label="Size" />
     <Field type="MetadataType" name="metadataType" label="Metadata Type" />
     <Field type="MetaspaceObjectType" name="metaspaceObjectType" label="Metaspace Object Type" />
@@ -724,6 +726,11 @@
       description="Total size of all allocated metaspace chunks for unsafe anonymous classes (each chunk has several blocks)" />
     <Field type="ulong" contentType="bytes" name="unsafeAnonymousBlockSize" label="Total Unsafe Anonymous Classes Block Size"
       description="Total size of all allocated metaspace blocks for unsafe anonymous classes (each chunk has several blocks)" />
+    <Field type="long" name="hiddenWeakClassCount" label="Hidden Weak Classes" description="Number of hidden weak classes" />
+    <Field type="ulong" contentType="bytes" name="hiddenWeakChunkSize" label="Total Hidden Weak Classes Chunk Size"
+      description="Total size of all allocated metaspace chunks for hidden weak classes (each chunk has several blocks)" />
+    <Field type="ulong" contentType="bytes" name="hiddenWeakBlockSize" label="Total Hidden Weak Classes Block Size"
+      description="Total size of all allocated metaspace blocks for hidden weak classes (each chunk has several blocks)" />
   </Event>
 
   <Event name="SymbolTableStatistics" category="Java Virtual Machine, Runtime, Tables" label="Symbol Table Statistics" period="everyChunk">
@@ -1093,6 +1100,7 @@
     <Field type="Symbol" name="name" label="Name" />
     <Field type="Package" name="package" label="Package" />
     <Field type="int" name="modifiers" label="Access Modifiers" />
+    <Field type="boolean" name="hidden" label="Hidden" />
   </Type>
 
   <Type name="ClassLoader" label="Java Class Loader">
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, 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
@@ -483,6 +483,9 @@
     event.set_unsafeAnonymousClassCount(cls->_anon_classes_count);
     event.set_unsafeAnonymousChunkSize(cls->_anon_chunk_sz);
     event.set_unsafeAnonymousBlockSize(cls->_anon_block_sz);
+    event.set_hiddenWeakClassCount(cls->_hidden_weak_classes_count);
+    event.set_hiddenWeakChunkSize(cls->_hidden_weak_chunk_sz);
+    event.set_hiddenWeakBlockSize(cls->_hidden_weak_block_sz);
     event.commit();
     return true;
   }
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -162,6 +162,7 @@
   if (klass->is_objArray_klass()) {
     klass = ObjArrayKlass::cast(klass)->bottom_klass();
   }
+  if (klass->is_hidden_weak()) return NULL;
   return is_unsafe_anonymous(klass) ?
     InstanceKlass::cast(klass)->unsafe_anonymous_host()->class_loader_data() : klass->class_loader_data();
 }
@@ -187,10 +188,12 @@
   assert(_artifacts != NULL, "invariant");
   assert(klass != NULL, "invariant");
   writer->write(artifact_id(klass));
-  writer->write(cld_id(get_cld(klass), leakp));
+  ClassLoaderData* cld = get_cld(klass);
+  writer->write(cld != NULL ? cld_id(cld, leakp) : 0);
   writer->write(mark_symbol(klass, leakp));
   writer->write(package_id(klass, leakp));
   writer->write(get_flags(klass));
+  writer->write<bool>(klass->is_hidden());
   return 1;
 }
 
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -189,52 +189,54 @@
 * caller needs ResourceMark
 */
 
-uintptr_t JfrSymbolId::unsafe_anonymous_klass_name_hash(const InstanceKlass* ik) {
+uintptr_t JfrSymbolId::hidden_or_anon_klass_name_hash(const InstanceKlass* ik) {
   assert(ik != NULL, "invariant");
-  assert(ik->is_unsafe_anonymous(), "invariant");
+  assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant");
   const oop mirror = ik->java_mirror_no_keepalive();
   assert(mirror != NULL, "invariant");
   return (uintptr_t)mirror->identity_hash();
 }
 
-static const char* create_unsafe_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t hash) {
+static const char* create_hidden_or_anon_klass_symbol(const InstanceKlass* ik, uintptr_t hash) {
   assert(ik != NULL, "invariant");
-  assert(ik->is_unsafe_anonymous(), "invariant");
+  assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant");
   assert(hash != 0, "invariant");
-  char* anonymous_symbol = NULL;
+  char* hidden_or_anon_symbol = NULL;
   const oop mirror = ik->java_mirror_no_keepalive();
   assert(mirror != NULL, "invariant");
   char hash_buf[40];
   sprintf(hash_buf, "/" UINTX_FORMAT, hash);
   const size_t hash_len = strlen(hash_buf);
   const size_t result_len = ik->name()->utf8_length();
-  anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-  ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
-  assert(strlen(anonymous_symbol) == result_len, "invariant");
-  strcpy(anonymous_symbol + result_len, hash_buf);
-  assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant");
-  return anonymous_symbol;
+  hidden_or_anon_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
+  ik->name()->as_klass_external_name(hidden_or_anon_symbol, (int)result_len + 1);
+  assert(strlen(hidden_or_anon_symbol) == result_len, "invariant");
+  strcpy(hidden_or_anon_symbol + result_len, hash_buf);
+  assert(strlen(hidden_or_anon_symbol) == result_len + hash_len, "invariant");
+  return hidden_or_anon_symbol;
 }
 
-bool JfrSymbolId::is_unsafe_anonymous_klass(const Klass* k) {
+bool JfrSymbolId::is_hidden_or_anon_klass(const Klass* k) {
   assert(k != NULL, "invariant");
-  return k->is_instance_klass() && ((const InstanceKlass*)k)->is_unsafe_anonymous();
+  return k->is_instance_klass() &&
+    (((const InstanceKlass*)k)->is_unsafe_anonymous() ||
+     ((const InstanceKlass*)k)->is_hidden());
 }
 
-traceid JfrSymbolId::mark_unsafe_anonymous_klass_name(const InstanceKlass* ik, bool leakp) {
+traceid JfrSymbolId::mark_hidden_or_anon_klass_name(const InstanceKlass* ik, bool leakp) {
   assert(ik != NULL, "invariant");
-  assert(ik->is_unsafe_anonymous(), "invariant");
-  const uintptr_t hash = unsafe_anonymous_klass_name_hash(ik);
-  const char* const anonymous_klass_symbol = create_unsafe_anonymous_klass_symbol(ik, hash);
-  return mark(hash, anonymous_klass_symbol, leakp);
+  assert(ik->is_unsafe_anonymous() || ik->is_hidden(), "invariant");
+  const uintptr_t hash = hidden_or_anon_klass_name_hash(ik);
+  const char* const hidden_or_anon_symbol = create_hidden_or_anon_klass_symbol(ik, hash);
+  return mark(hash, hidden_or_anon_symbol, leakp);
 }
 
 traceid JfrSymbolId::mark(const Klass* k, bool leakp) {
   assert(k != NULL, "invariant");
   traceid symbol_id = 0;
-  if (is_unsafe_anonymous_klass(k)) {
+  if (is_hidden_or_anon_klass(k)) {
     assert(k->is_instance_klass(), "invariant");
-    symbol_id = mark_unsafe_anonymous_klass_name((const InstanceKlass*)k, leakp);
+    symbol_id = mark_hidden_or_anon_klass_name((const InstanceKlass*)k, leakp);
   }
   if (0 == symbol_id) {
     Symbol* const sym = k->name();
@@ -276,9 +278,9 @@
   return _symbol_id->bootstrap_name(leakp);
 }
 
-traceid JfrArtifactSet::mark_unsafe_anonymous_klass_name(const Klass* klass, bool leakp) {
+traceid JfrArtifactSet::mark_hidden_or_anon_klass_name(const Klass* klass, bool leakp) {
   assert(klass->is_instance_klass(), "invariant");
-  return _symbol_id->mark_unsafe_anonymous_klass_name((const InstanceKlass*)klass, leakp);
+  return _symbol_id->mark_hidden_or_anon_klass_name((const InstanceKlass*)klass, leakp);
 }
 
 traceid JfrArtifactSet::mark(uintptr_t hash, const Symbol* sym, bool leakp) {
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, 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
@@ -241,9 +241,9 @@
     }
   }
 
-  traceid mark_unsafe_anonymous_klass_name(const InstanceKlass* k, bool leakp);
-  bool is_unsafe_anonymous_klass(const Klass* k);
-  uintptr_t unsafe_anonymous_klass_name_hash(const InstanceKlass* ik);
+  traceid mark_hidden_or_anon_klass_name(const InstanceKlass* k, bool leakp);
+  bool is_hidden_or_anon_klass(const Klass* k);
+  uintptr_t hidden_or_anon_klass_name_hash(const InstanceKlass* ik);
 
  public:
   JfrSymbolId();
@@ -304,7 +304,7 @@
   traceid mark(const Klass* klass, bool leakp);
   traceid mark(const Symbol* symbol, bool leakp);
   traceid mark(uintptr_t hash, const char* const str, bool leakp);
-  traceid mark_unsafe_anonymous_klass_name(const Klass* klass, bool leakp);
+  traceid mark_hidden_or_anon_klass_name(const Klass* klass, bool leakp);
   traceid bootstrap_name(bool leakp);
 
   const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const;
--- a/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/memory/metaspace/printCLDMetaspaceInfoClosure.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, 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
@@ -104,7 +104,7 @@
     _out->print(UINTX_FORMAT_W(4) ": ", _num_loaders);
 
     // Print "CLD for [<loader name>,] instance of <loader class name>"
-    // or    "CLD for <weak hidden class>, loaded by [<loader name>,] instance of <loader class name>"
+    // or    "CLD for <weak hidden or anonymous class>, loaded by [<loader name>,] instance of <loader class name>"
 
     ResourceMark rm;
     const char* name = NULL;
@@ -129,7 +129,7 @@
     }
     _out->print(":");
     if (cld->is_shortlived()) {
-      _out->print(" <weak hidden class>, loaded by");
+      _out->print(" <weak hidden or anonymous class>, loaded by");
     }
     if (name != NULL) {
       _out->print(" \"%s\"", name);
--- a/src/hotspot/share/memory/metaspaceTracer.cpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/memory/metaspaceTracer.cpp	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, 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
@@ -62,10 +62,15 @@
   E event;
   if (event.should_commit()) {
     event.set_classLoader(cld);
+    event.set_unsafeAnonymousClassLoader(false); // initialize these
+    event.set_hiddenWeakClassLoader(false);
     if (cld->is_shortlived()) {
-      event.set_unsafeAnonymousClassLoader(true);
-    } else {
-      event.set_unsafeAnonymousClassLoader(false);
+      assert(cld->klasses() != NULL, "unexpected NULL for cld->klasses()");
+      if (cld->klasses()->is_hidden_weak()) {
+        event.set_hiddenWeakClassLoader(true);
+      } else {
+        event.set_unsafeAnonymousClassLoader(true);
+      }
     }
     event.set_size(word_size * BytesPerWord);
     event.set_metadataType((u1) mdtype);
--- a/src/hotspot/share/oops/klass.hpp	Mon Mar 16 11:45:27 2020 +0000
+++ b/src/hotspot/share/oops/klass.hpp	Tue Mar 17 14:32:09 2020 +0000
@@ -617,6 +617,8 @@
   void set_is_shared()                  { _access_flags.set_is_shared_class(); }
   bool is_hidden() const                { return access_flags().is_hidden_class(); }
   void set_is_hidden()                  { _access_flags.set_is_hidden_class(); }
+  bool is_hidden_weak() const           { return access_flags().is_hidden_class() &&
+                                          class_loader_data()->is_shortlived(); }
 
   bool is_cloneable() const;
   void set_is_cloneable();
--- a/test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassDefineEvent.java	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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
@@ -41,6 +41,7 @@
  * @key jfr
  * @requires vm.hasJFR
  * @library /test/lib /test/jdk
+ * @modules java.base/jdk.internal.misc
  * @build jdk.jfr.event.runtime.TestClasses
  * @run main/othervm jdk.jfr.event.runtime.TestClassDefineEvent
  */
--- a/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoadEvent.java	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -42,6 +42,7 @@
  * @key jfr
  * @requires vm.hasJFR
  * @library /test/lib /test/jdk
+ * @modules java.base/jdk.internal.misc
  * @build jdk.jfr.event.runtime.TestClasses
  * @run main/othervm jdk.jfr.event.runtime.TestClassLoadEvent
  */
--- a/test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoaderStatsEvent.java	Tue Mar 17 14:32:09 2020 +0000
@@ -28,6 +28,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.util.List;
@@ -39,11 +40,15 @@
 import jdk.test.lib.jfr.EventNames;
 import jdk.test.lib.jfr.Events;
 
+import jdk.test.lib.compiler.InMemoryJavaCompiler;
+
 /**
  * @test
  * @key jfr
  * @requires vm.hasJFR
  * @library /test/lib /test/jdk
+ * @modules java.base/jdk.internal.misc
+ *          java.compiler
  * @build jdk.jfr.event.runtime.TestClasses
  * @run main/othervm jdk.jfr.event.runtime.TestClassLoaderStatsEvent
  */
@@ -76,9 +81,12 @@
                 Events.assertField(event, "classCount").equal(2L);
                 Events.assertField(event, "chunkSize").above(1L);
                 Events.assertField(event, "blockSize").above(1L);
-                Events.assertField(event, "unsafeAnonymousClassCount").equal(0L);
-                Events.assertField(event, "unsafeAnonymousChunkSize").equal(0L);
-                Events.assertField(event, "unsafeAnonymousBlockSize").equal(0L);
+                Events.assertField(event, "unsafeAnonymousClassCount").equal(2L);
+                Events.assertField(event, "unsafeAnonymousChunkSize").above(0L);
+                Events.assertField(event, "unsafeAnonymousBlockSize").above(0L);
+                Events.assertField(event, "hiddenWeakClassCount").equal(2L);
+                Events.assertField(event, "hiddenWeakChunkSize").above(0L);
+                Events.assertField(event, "hiddenWeakBlockSize").above(0L);
                 isAnyFound = true;
             }
         }
@@ -91,6 +99,18 @@
         if (c.getClassLoader() != dummyloader) {
             throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
         }
+
+        // Compile a class for method createNonFindableClasses() to use to create both a
+        // weak hidden class and an anonymous class.
+        byte klassbuf[] = InMemoryJavaCompiler.compile("jdk.jfr.event.runtime.TestClass",
+            "package jdk.jfr.event.runtime; " +
+            "public class TestClass { " +
+            "    public static void concat(String one, String two) throws Throwable { " +
+            " } } ");
+
+        Method m = c.getDeclaredMethod("createNonFindableClasses", byte[].class);
+        m.setAccessible(true);
+        m.invoke(null, klassbuf);
     }
 
     public static class DummyClassLoader extends ClassLoader {
--- a/test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassLoadingStatisticsEvent.java	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -39,6 +39,7 @@
  * @key jfr
  * @requires vm.hasJFR
  * @library /test/lib /test/jdk
+ * @modules java.base/jdk.internal.misc
  * @build jdk.jfr.event.runtime.TestClasses
  * @run main/othervm jdk.jfr.event.runtime.TestClassLoadingStatisticsEvent
  */
--- a/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestClassUnloadEvent.java	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -43,6 +43,7 @@
  * @key jfr
  * @requires vm.hasJFR
  * @library /test/lib /test/jdk
+ * @modules java.base/jdk.internal.misc
  * @build jdk.jfr.event.runtime.TestClasses
  * @run main/othervm -Xlog:class+unload -Xlog:gc -Xmx16m jdk.jfr.event.runtime.TestClassUnloadEvent
  */
--- a/test/jdk/jdk/jfr/event/runtime/TestClasses.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestClasses.java	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, 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
@@ -25,6 +25,14 @@
 
 package jdk.jfr.event.runtime;
 
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.Array;
+import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*;
+
+import jdk.internal.misc.Unsafe;
+
 public class TestClasses {
 
     protected TestClassPrivate testClassPrivate;
@@ -76,8 +84,20 @@
 
 class TestClass {
     static {
-        // force creation of anonymous class (for the lambda form)
+        // force creation of hidden class (for the lambda form)
         Runnable r = () -> System.out.println("Hello");
         r.run();
     }
+
+    public static void createNonFindableClasses(byte[] klassbuf) throws Throwable {
+        // Create a weak hidden class and an array of weak hidden classes.
+        Lookup lookup = MethodHandles.lookup();
+        Class<?> clh = lookup.defineHiddenClass(klassbuf, false, NESTMATE, WEAK).lookupClass();
+        Class<?> arrayOfHidden = Array.newInstance(clh, 10).getClass(); // HAS ISSUES?
+
+        // Create an Unsafe anonymous class and an array of unsafe anonymous classes.
+        Unsafe unsafe = Unsafe.getUnsafe();
+        Class<?> clu = unsafe.defineAnonymousClass(TestClass.class, klassbuf, new Object[0]);
+        final Class<?> arrayOfUAC = Array.newInstance(clu, 15).getClass();
+    }
 }
--- a/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java	Mon Mar 16 11:45:27 2020 +0000
+++ b/test/jdk/jdk/jfr/event/runtime/TestTableStatisticsEvent.java	Tue Mar 17 14:32:09 2020 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, 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
@@ -41,6 +41,7 @@
  * @key jfr
  * @requires vm.hasJFR
  * @library /test/lib /test/jdk
+ * @modules java.base/jdk.internal.misc
  * @build jdk.jfr.event.runtime.TestClasses
  * @run main/othervm jdk.jfr.event.runtime.TestTableStatisticsEvent
  * @bug 8185525