Merge
authoriveresov
Thu, 11 Aug 2016 16:22:08 -0700
changeset 40376 15e772ff7ff4
parent 40375 492761e17d4b (current diff)
parent 40360 437ce272aa84 (diff)
child 40377 b77bf599c11b
child 40642 7f337136f657
Merge
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java	Thu Aug 11 16:22:08 2016 -0700
@@ -46,7 +46,6 @@
   private static final int SENDER_SP_OFFSET           =  0;
 
   // Interpreter frames
-  private static final int INTERPRETER_FRAME_MIRROR_OFFSET = -3; // for native calls only
   private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -4;
   private static final int INTERPRETER_FRAME_LAST_SP_OFFSET = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
   private static final int INTERPRETER_FRAME_MDX_OFFSET = INTERPRETER_FRAME_LAST_SP_OFFSET -1;
@@ -55,7 +54,8 @@
   private static final int INTERPRETER_FRAME_CACHE_OFFSET =INTERPRETER_FRAME_BCX_OFFSET - 1;
   private static final int INTERPRETER_FRAME_MONITORS_OFFSET = INTERPRETER_FRAME_CACHE_OFFSET - 1;
   private static final int INTERPRETER_FRAME_LOCALS_OFFSET = INTERPRETER_FRAME_MONITORS_OFFSET - 1;
-  private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_MIRROR_OFFSET = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
+  private static final int INTERPRETER_FRAME_METHOD_OFFSET = INTERPRETER_FRAME_MIRROR_OFFSET - 1;
   private static final int INTERPRETER_FRAME_INITIAL_SP_OFFSET = INTERPRETER_FRAME_BCX_OFFSET - 1; // FIXME: probably wrong, but unused anyway
   private static final int INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
   private static final int INTERPRETER_FRAME_MONITOR_BLOCK_BOTTOM_OFFSET = INTERPRETER_FRAME_INITIAL_SP_OFFSET;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Thu Aug 11 16:22:08 2016 -0700
@@ -714,11 +714,7 @@
   /** 2 words, also used to save float regs across  calls to C */
   public static final int INTERPRETER_FRAME_D_SCRATCH_FP_OFFSET           = -2;
   public static final int INTERPRETER_FRAME_L_SCRATCH_FP_OFFSET           = -4;
-  /** For native calls only */
-  public static final int INTERPRETER_FRAME_PADDING_OFFSET                = -5;
-  /** For native calls only */
-  public static final int INTERPRETER_FRAME_MIRROR_OFFSET                 = -6;
-  /** Should be same as above, and should be zero mod 8 */
+  public static final int INTERPRETER_FRAME_MIRROR_OFFSET                 = -5;
   public static final int INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET           = -6;
   public static final int INTERPRETER_FRAME_VM_LOCAL_WORDS                = -INTERPRETER_FRAME_VM_LOCALS_FP_OFFSET;
 
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Thu Aug 11 16:22:08 2016 -0700
@@ -48,10 +48,10 @@
   private static final int SENDER_SP_OFFSET           =  2;
 
   // Interpreter frames
-  private static final int INTERPRETER_FRAME_MIRROR_OFFSET    =  2; // for native calls only
   private static final int INTERPRETER_FRAME_SENDER_SP_OFFSET = -1;
   private static final int INTERPRETER_FRAME_LAST_SP_OFFSET   = INTERPRETER_FRAME_SENDER_SP_OFFSET - 1;
   private static final int INTERPRETER_FRAME_METHOD_OFFSET    = INTERPRETER_FRAME_LAST_SP_OFFSET - 1;
+  private static       int INTERPRETER_FRAME_MIRROR_OFFSET;
   private static       int INTERPRETER_FRAME_MDX_OFFSET;         // Non-core builds only
   private static       int INTERPRETER_FRAME_CACHE_OFFSET;
   private static       int INTERPRETER_FRAME_LOCALS_OFFSET;
@@ -74,7 +74,8 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
-    INTERPRETER_FRAME_MDX_OFFSET                  = INTERPRETER_FRAME_METHOD_OFFSET - 1;
+    INTERPRETER_FRAME_MIRROR_OFFSET               = INTERPRETER_FRAME_METHOD_OFFSET - 1;
+    INTERPRETER_FRAME_MDX_OFFSET                  = INTERPRETER_FRAME_MIRROR_OFFSET - 1;
     INTERPRETER_FRAME_CACHE_OFFSET                = INTERPRETER_FRAME_MDX_OFFSET - 1;
     INTERPRETER_FRAME_LOCALS_OFFSET               = INTERPRETER_FRAME_CACHE_OFFSET - 1;
     INTERPRETER_FRAME_BCX_OFFSET                  = INTERPRETER_FRAME_LOCALS_OFFSET - 1;
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/ObjectReader.java	Thu Aug 11 16:22:08 2016 -0700
@@ -26,6 +26,7 @@
 
 import java.lang.reflect.Modifier;
 import java.util.*;
+import java.util.stream.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
@@ -204,15 +205,29 @@
       }
    }
 
-   protected Object getHashtable(Instance oop, boolean isProperties) {
+   private void setPropertiesEntry(java.util.Properties p, Oop oop) {
+      InstanceKlass ik = (InstanceKlass)oop.getKlass();
+      OopField keyField = (OopField)ik.findField("key", "Ljava/lang/Object;");
+      OopField valueField = (OopField)ik.findField("val", "Ljava/lang/Object;");
+
+      try {
+         p.setProperty((String)readObject(keyField.getValue(oop)),
+                       (String)readObject(valueField.getValue(oop)));
+      } catch (ClassNotFoundException ce) {
+         if (DEBUG) {
+            debugPrintStackTrace(ce);
+         }
+      }
+   }
+
+   protected Object getHashtable(Instance oop) {
       InstanceKlass k = (InstanceKlass)oop.getKlass();
       OopField tableField = (OopField)k.findField("table", "[Ljava/util/Hashtable$Entry;");
       if (tableField == null) {
          debugPrintln("Could not find field of [Ljava/util/Hashtable$Entry;");
          return null;
       }
-      java.util.Hashtable table = (isProperties) ? new java.util.Properties()
-                                                 : new java.util.Hashtable();
+      java.util.Hashtable table = new java.util.Hashtable();
       ObjArray kvs = (ObjArray)tableField.getValue(oop);
       long size = kvs.getLength();
       debugPrintln("Hashtable$Entry Size = " + size);
@@ -225,6 +240,39 @@
       return table;
    }
 
+   private Properties getProperties(Instance oop) {
+      InstanceKlass k = (InstanceKlass)oop.getKlass();
+      OopField mapField = (OopField)k.findField("map", "Ljava/util/concurrent/ConcurrentHashMap;");
+      if (mapField == null) {
+         debugPrintln("Could not find field of Ljava/util/concurrent/ConcurrentHashMap");
+         return null;
+      }
+
+      Instance mapObj = (Instance)mapField.getValue(oop);
+      if (mapObj == null) {
+         debugPrintln("Could not get map field from java.util.Properties");
+         return null;
+      }
+
+      InstanceKlass mk = (InstanceKlass)mapObj.getKlass();
+      OopField tableField = (OopField)mk.findField("table", "[Ljava/util/concurrent/ConcurrentHashMap$Node;");
+      if (tableField == null) {
+         debugPrintln("Could not find field of [Ljava/util/concurrent/ConcurrentHashMap$Node");
+         return null;
+      }
+
+      java.util.Properties props = new java.util.Properties();
+      ObjArray kvs = (ObjArray)tableField.getValue(mapObj);
+      long size = kvs.getLength();
+      debugPrintln("ConcurrentHashMap$Node Size = " + size);
+      LongStream.range(0, size)
+                .mapToObj(kvs::getObjAt)
+                .filter(o -> o != null)
+                .forEach(o -> setPropertiesEntry(props, o));
+
+      return props;
+   }
+
    public Object readInstance(Instance oop) throws ClassNotFoundException {
       Object result = getFromObjTable(oop);
       if (result == null) {
@@ -240,11 +288,11 @@
          }
 
          if (kls.getName().equals(javaUtilHashtable())) {
-            return getHashtable(oop, false);
+            return getHashtable(oop);
          }
 
          if (kls.getName().equals(javaUtilProperties())) {
-            return getHashtable(oop, true);
+            return getProperties(oop);
          }
 
          Class clz = readClass(kls);
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Thu Aug 11 16:22:08 2016 -0700
@@ -126,13 +126,17 @@
 // ClassLoaderData, no other non-GC thread has knowledge of the anonymous class while
 // it is being defined, therefore _keep_alive is not volatile or atomic.
 void ClassLoaderData::inc_keep_alive() {
-  assert(_keep_alive >= 0, "Invalid keep alive count");
-  _keep_alive++;
+  if (is_anonymous()) {
+    assert(_keep_alive >= 0, "Invalid keep alive increment count");
+    _keep_alive++;
+  }
 }
 
 void ClassLoaderData::dec_keep_alive() {
-  assert(_keep_alive > 0, "Invalid keep alive count");
-  _keep_alive--;
+  if (is_anonymous()) {
+    assert(_keep_alive > 0, "Invalid keep alive decrement count");
+    _keep_alive--;
+  }
 }
 
 void ClassLoaderData::oops_do(OopClosure* f, KlassClosure* klass_closure, bool must_claim) {
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Thu Aug 11 16:22:08 2016 -0700
@@ -176,9 +176,9 @@
   Mutex* _metaspace_lock;  // Locks the metaspace for allocations and setup.
   bool _unloading;         // true if this class loader goes away
   bool _is_anonymous;      // if this CLD is for an anonymous class
-  int _keep_alive;         // if this CLD is kept alive without a keep_alive_object().
-                           // Currently used solely for anonymous classes.
-                           // _keep_alive does not need to be volatile or
+  s2 _keep_alive;          // if this CLD is kept alive without a keep_alive_object().
+                           // Used for anonymous classes and the boot class
+                           // loader. _keep_alive does not need to be volatile or
                            // atomic since there is one unique CLD per anonymous class.
   volatile int _claimed;   // true if claimed, for example during GC traces.
                            // To avoid applying oop closure more than once.
@@ -289,6 +289,8 @@
     return _unloading;
   }
 
+  // Used to refcount an anonymous class's CLD in order to
+  // indicate their aliveness without a keep_alive_object().
   void inc_keep_alive();
   void dec_keep_alive();
 
--- a/hotspot/src/share/vm/logging/logTagSet.hpp	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/share/vm/logging/logTagSet.hpp	Thu Aug 11 16:22:08 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, 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
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Tue Aug 09 16:47:47 2016 +0300
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Aug 11 16:22:08 2016 -0700
@@ -2643,7 +2643,7 @@
   /* DEFAULT_CACHE_LINE_SIZE (globalDefinitions.hpp) */                   \
   /***************************************************/                   \
                                                                           \
-  declare_constant(DEFAULT_CACHE_LINE_SIZE)                               \
+  declare_preprocessor_constant("DEFAULT_CACHE_LINE_SIZE", DEFAULT_CACHE_LINE_SIZE) \
                                                                           \
   declare_constant(Deoptimization::Unpack_deopt)                          \
   declare_constant(Deoptimization::Unpack_exception)                      \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/sa/sadebugd/SADebugDTest.java	Thu Aug 11 16:22:08 2016 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Checks that the jshdb debugd utility sucessfully starts
+ *          and tries to attach to a running process
+ * @modules java.base/jdk.internal.misc
+ * @library /test/lib/share/classes
+ *
+ * @ignore 8163805
+ * @run main/othervm SADebugDTest
+ */
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.io.Reader;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+import static jdk.test.lib.Asserts.assertTrue;
+import static jdk.test.lib.Platform.shouldSAAttach;
+import static jdk.test.lib.process.ProcessTools.startProcess;
+
+public class SADebugDTest {
+
+    private static final String GOLDEN = "Attaching to process ID %d and starting RMI services, please wait...";
+
+    private static final String JAVA_HOME = (System.getProperty("test.jdk") != null)
+            ? System.getProperty("test.jdk") : System.getProperty("java.home");
+
+    private static final String JAVA_BIN_DIR
+            = JAVA_HOME + File.separator + "bin" + File.separator;
+
+    private static final String JHSDB = JAVA_BIN_DIR + "jhsdb";
+
+    public static void main(String[] args) throws Exception {
+
+        if (!shouldSAAttach()) {
+            log("Not possible to attach the SA. Skipping the test");
+            return;
+        }
+
+        long ourPid = ProcessHandle.current().getPid();
+
+        // The string we are expecting in the debugd ouput
+        String golden = String.format(GOLDEN, ourPid);
+
+        // We are going to run 'jhsdb debugd <our pid>'
+        // The startProcess will block untl the 'golden' string appears in either process' stdout or stderr
+        // In case of timeout startProcess kills the debugd process
+        ProcessBuilder pb = new ProcessBuilder();
+        pb.command(JHSDB, "debugd", String.valueOf(ourPid));
+        Process debugd = startProcess("debugd", pb, null, (line) -> line.trim().contains(golden), 0, TimeUnit.SECONDS);
+
+        // If we are here, this means we have received the golden line and the test has passed
+        // The debugd remains running, we have to kill it
+        debugd.destroy();
+
+    }
+
+    private static void log(String string) {
+        System.out.println(string);
+    }
+
+}