8209844: MemberNameLeak.java fails when ResolvedMethod entry is not removed
authorpchilanomate
Wed, 29 Aug 2018 10:46:59 -0400
changeset 51567 0c4f2b26849e
parent 51566 904cf5407ac7
child 51568 0157a3ab61b1
8209844: MemberNameLeak.java fails when ResolvedMethod entry is not removed Summary: Fixed MemberNameLeak.java due to intermittent failure after 8206423 Reviewed-by: coleenp, lfoltan
src/hotspot/share/prims/resolvedMethodTable.cpp
src/hotspot/share/prims/resolvedMethodTable.hpp
src/hotspot/share/prims/whitebox.cpp
test/hotspot/jtreg/ProblemList.txt
test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java
test/lib/sun/hotspot/WhiteBox.java
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp	Wed Aug 22 10:29:17 2018 +0200
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp	Wed Aug 29 10:46:59 2018 -0400
@@ -143,8 +143,7 @@
 }
 
 // Removing entries
-int ResolvedMethodTable::_oops_removed = 0;
-int ResolvedMethodTable::_oops_counted = 0;
+int ResolvedMethodTable::_total_oops_removed = 0;
 
 // There are no dead entries at start
 bool ResolvedMethodTable::_dead_entries = false;
@@ -159,8 +158,8 @@
 // This is done by the ServiceThread after being notified on class unloading
 void ResolvedMethodTable::unlink() {
   MutexLocker ml(ResolvedMethodTable_lock);
-  _oops_removed = 0;
-  _oops_counted = 0;
+  int _oops_removed = 0;
+  int _oops_counted = 0;
   for (int i = 0; i < _the_table->table_size(); ++i) {
     ResolvedMethodEntry** p = _the_table->bucket_addr(i);
     ResolvedMethodEntry* entry = _the_table->bucket(i);
@@ -185,6 +184,7 @@
   }
   log_debug(membername, table) ("ResolvedMethod entries counted %d removed %d",
                                 _oops_counted, _oops_removed);
+  _total_oops_removed += _oops_removed;
   _dead_entries = false;
 }
 
--- a/src/hotspot/share/prims/resolvedMethodTable.hpp	Wed Aug 22 10:29:17 2018 +0200
+++ b/src/hotspot/share/prims/resolvedMethodTable.hpp	Wed Aug 29 10:46:59 2018 -0400
@@ -56,8 +56,7 @@
     _table_size  = 1007
   };
 
-  static int _oops_removed;
-  static int _oops_counted;
+  static int _total_oops_removed;
 
   static bool _dead_entries;
 
@@ -95,6 +94,8 @@
   static bool has_work() { return _dead_entries; }
   static void trigger_cleanup();
 
+  static int removed_entries_count() { return _total_oops_removed; };
+
 #if INCLUDE_JVMTI
   // It is called at safepoint only for RedefineClasses
   static void adjust_method_entries(bool * trace_name_printed);
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Aug 22 10:29:17 2018 +0200
+++ b/src/hotspot/share/prims/whitebox.cpp	Wed Aug 29 10:46:59 2018 -0400
@@ -48,6 +48,7 @@
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
+#include "prims/resolvedMethodTable.hpp"
 #include "prims/wbtestmethods/parserTests.hpp"
 #include "prims/whitebox.inline.hpp"
 #include "runtime/arguments.hpp"
@@ -1972,6 +1973,10 @@
 #endif
 WB_END
 
+WB_ENTRY(jint, WB_ResolvedMethodRemovedCount(JNIEnv* env, jobject o))
+  return (jint) ResolvedMethodTable::removed_entries_count();
+WB_END
+
 
 #define CC (char*)
 
@@ -2193,6 +2198,7 @@
   {CC"isContainerized",           CC"()Z",            (void*)&WB_IsContainerized },
   {CC"printOsInfo",               CC"()V",            (void*)&WB_PrintOsInfo },
   {CC"disableElfSectionCache",    CC"()V",            (void*)&WB_DisableElfSectionCache },
+  {CC"resolvedMethodRemovedCount",     CC"()I",       (void*)&WB_ResolvedMethodRemovedCount },
 };
 
 
--- a/test/hotspot/jtreg/ProblemList.txt	Wed Aug 22 10:29:17 2018 +0200
+++ b/test/hotspot/jtreg/ProblemList.txt	Wed Aug 29 10:46:59 2018 -0400
@@ -84,7 +84,6 @@
 runtime/CompressedOops/UseCompressedOops.java 8079353 generic-all
 runtime/RedefineTests/RedefineRunningMethods.java 8208778 macosx-x64
 runtime/SharedArchiveFile/SASymbolTableTest.java 8193639 solaris-all
-runtime/MemberName/MemberNameLeak.java 8209844 generic-all
 
 #############################################################################
 
--- a/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java	Wed Aug 22 10:29:17 2018 +0200
+++ b/test/hotspot/jtreg/runtime/MemberName/MemberNameLeak.java	Wed Aug 29 10:46:59 2018 -0400
@@ -34,7 +34,7 @@
 import java.lang.invoke.*;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
-
+import sun.hotspot.WhiteBox;
 import sun.hotspot.code.Compiler;
 
 public class MemberNameLeak {
@@ -44,6 +44,9 @@
 
       public static void main(String[] args) throws Throwable {
         Leak leak = new Leak();
+        WhiteBox wb = WhiteBox.getWhiteBox();
+        int removedCountOrig =  wb.resolvedMethodRemovedCount();
+        int removedCount;
 
         for (int i = 0; i < 10; i++) {
           MethodHandles.Lookup lookup = MethodHandles.lookup();
@@ -54,6 +57,11 @@
         }
 
         System.gc();  // make mh unused
+
+        // Wait until ServiceThread cleans ResolvedMethod table
+        do {
+          removedCount = wb.resolvedMethodRemovedCount();
+        } while (removedCountOrig == removedCount);
       }
     }
 
@@ -61,6 +69,8 @@
        // Run this Leak class with logging
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
                                       "-Xlog:membername+table=trace",
+                                      "-XX:+WhiteBoxAPI",
+                                      "-Xbootclasspath/a:.",
                                       gc, Leak.class.getName());
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
         output.shouldContain("ResolvedMethod entry added for MemberNameLeak$Leak.callMe()V");
--- a/test/lib/sun/hotspot/WhiteBox.java	Wed Aug 22 10:29:17 2018 +0200
+++ b/test/lib/sun/hotspot/WhiteBox.java	Wed Aug 29 10:46:59 2018 -0400
@@ -536,4 +536,7 @@
 
   // Decoder
   public native void disableElfSectionCache();
+
+  // Resolved Method Table
+  public native int resolvedMethodRemovedCount();
 }