changeset 4258:6e4feb17117d icedtea-2.4-branchpoint

Merge jdk7u12-b09
author andrew
date Mon, 14 Jan 2013 15:00:16 +0000
parents a57f19258524 (current diff) 0d5d62e38450 (diff)
children 1933e8414246
files .hgtags make/bsd/makefiles/buildtree.make make/hotspot_version make/linux/makefiles/buildtree.make make/linux/makefiles/vm.make make/solaris/makefiles/buildtree.make src/share/vm/prims/jni.cpp src/share/vm/runtime/arguments.cpp
diffstat 12 files changed, 284 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Jan 04 22:21:54 2013 +0000
+++ b/.hgtags	Mon Jan 14 15:00:16 2013 +0000
@@ -341,6 +341,16 @@
 ca6943c94e6075fc28353d52ac6ea52c80aef9bb jdk7u9-b02
 ed42837374ac730ddaf2fd28814017c665634a8b jdk7u9-b04
 da4aa289ac100017f850ed4d492e8054db6a1e28 jdk7u9-b05
+d2e25680db9d4209b3f0f51e5c848284cedea508 jdk7u10-b10
+d37fd995683ab5bc2d941648ce7bf8bd194732f2 jdk7u10-b11
+f26f3d92e6d9ef7842b2d785f92439dbb15e670e jdk7u10-b12
+58881c615a5179bcea69148d0b3eb47a1f1a7de8 jdk7u10-b13
+cdbf4d442b56ece8ac521c65b59087682e5ae918 jdk7u10-b14
+63e8b49b329e4b50547b13f5c732665bed535732 jdk7u10-b15
+1cb34ef50bddc334c8538cf85d8612383debc74f jdk7u10-b16
+5c154a591de987d515f5b102a988bcf96d439f53 jdk7u10-b17
+78c7e1b4a006342230e04fbb73f637834207abef jdk7u10-b18
+c6b78bbaf6976197ead9d5aa3f65e0224cd13541 jdk7u10-b30
 02a6c89432d724119565f9ba25672829b136fc5f jdk7u8-b01
 528502f930967f70c320472a002418f1e38029e0 jdk7u8-b02
 db63a909e1ad950ef2b9050389f51e68581b2d4e jdk7u8-b03
@@ -416,3 +426,7 @@
 4e4026772caf17fbd5234d6941af8be56fc0c260 jdk7u12-b05
 364bc54d7096ed229d61fa015626276d4f1cedf5 hs24-b27
 2e497fde1807e9e97cb3dfd90bfbbcdcc19f0883 jdk7u12-b06
+c5ee80cc06234ef93e4b6a6ac77597e62fbd99f4 hs24-b28
+4f7ad6299356bfd2cfb448ea4c11e8ce0fbf69f4 jdk7u12-b07
+3bb803664f3d9c831d094cbe22b4ee5757e780c8 jdk7u12-b08
+92e382c3cccc0afbc7f72fccea4f996e05b66b3e jdk7u12-b09
--- a/make/hotspot_version	Fri Jan 04 22:21:54 2013 +0000
+++ b/make/hotspot_version	Mon Jan 14 15:00:16 2013 +0000
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=24
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=27
+HS_BUILD_NUMBER=28
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/make/linux/makefiles/vm.make	Fri Jan 04 22:21:54 2013 +0000
+++ b/make/linux/makefiles/vm.make	Mon Jan 14 15:00:16 2013 +0000
@@ -400,7 +400,7 @@
 
 #----------------------------------------------------------------------
 
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR) dtraceCheck
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
 
 install: install_jvm install_jsig install_saproc
 
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Mon Jan 14 15:00:16 2013 +0000
@@ -434,7 +434,7 @@
 
   // the frame is greater than one page in size, so check against
   // the bottom of the stack
-  __ cmp_and_brx_short(SP, Rscratch, Assembler::greater, Assembler::pt, after_frame_check);
+  __ cmp_and_brx_short(SP, Rscratch, Assembler::greaterUnsigned, Assembler::pt, after_frame_check);
 
   // the stack will overflow, throw an exception
 
--- a/src/os/posix/vm/os_posix.cpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/os/posix/vm/os_posix.cpp	Mon Jan 14 15:00:16 2013 +0000
@@ -93,6 +93,47 @@
   return;
 }
 
+// Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
+// so on posix, unmap the section at the start and at the end of the chunk that we mapped
+// rather than unmapping and remapping the whole chunk to get requested alignment.
+char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+  assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
+      "Alignment must be a multiple of allocation granularity (page size)");
+  assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
+
+  size_t extra_size = size + alignment;
+  assert(extra_size >= size, "overflow, size is too large to allow alignment");
+
+  char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+
+  if (extra_base == NULL) {
+    return NULL;
+  }
+
+  // Do manual alignment
+  char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);
+
+  // [  |                                       |  ]
+  // ^ extra_base
+  //    ^ extra_base + begin_offset == aligned_base
+  //     extra_base + begin_offset + size       ^
+  //                       extra_base + extra_size ^
+  // |<>| == begin_offset
+  //                              end_offset == |<>|
+  size_t begin_offset = aligned_base - extra_base;
+  size_t end_offset = (extra_base + extra_size) - (aligned_base + size);
+
+  if (begin_offset > 0) {
+      os::release_memory(extra_base, begin_offset);
+  }
+
+  if (end_offset > 0) {
+      os::release_memory(extra_base + begin_offset + size, end_offset);
+  }
+
+  return aligned_base;
+}
+
 void os::Posix::print_load_average(outputStream* st) {
   st->print("load average:");
   double loadavg[3];
--- a/src/os/windows/vm/os_windows.cpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/os/windows/vm/os_windows.cpp	Mon Jan 14 15:00:16 2013 +0000
@@ -2941,6 +2941,36 @@
   }
 }
 
+// Multiple threads can race in this code but it's not possible to unmap small sections of
+// virtual space to get requested alignment, like posix-like os's.
+// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
+char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+  assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
+      "Alignment must be a multiple of allocation granularity (page size)");
+  assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
+
+  size_t extra_size = size + alignment;
+  assert(extra_size >= size, "overflow, size is too large to allow alignment");
+
+  char* aligned_base = NULL;
+
+  do {
+    char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+    if (extra_base == NULL) {
+      return NULL;
+    }
+    // Do manual alignment
+    aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);
+
+    os::release_memory(extra_base, extra_size);
+
+    aligned_base = os::reserve_memory(size, aligned_base);
+
+  } while (aligned_base == NULL);
+
+  return aligned_base;
+}
+
 char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
   assert((size_t)addr % os::vm_allocation_granularity() == 0,
          "reserve alignment");
--- a/src/share/vm/runtime/os.hpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/share/vm/runtime/os.hpp	Mon Jan 14 15:00:16 2013 +0000
@@ -255,6 +255,7 @@
   static int    vm_allocation_granularity();
   static char*  reserve_memory(size_t bytes, char* addr = 0,
                                size_t alignment_hint = 0);
+  static char*  reserve_memory_aligned(size_t size, size_t alignment);
   static char*  attempt_reserve_memory_at(size_t bytes, char* addr);
   static void   split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc);
--- a/src/share/vm/runtime/virtualspace.cpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/share/vm/runtime/virtualspace.cpp	Mon Jan 14 15:00:16 2013 +0000
@@ -341,20 +341,9 @@
     if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) {
       // Base not aligned, retry
       if (!os::release_memory(base, size)) fatal("os::release_memory failed");
-      // Reserve size large enough to do manual alignment and
-      // increase size to a multiple of the desired alignment
+      // Make sure that size is aligned
       size = align_size_up(size, alignment);
-      size_t extra_size = size + alignment;
-      do {
-        char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
-        if (extra_base == NULL) return;
-        // Do manual alignement
-        base = (char*) align_size_up((uintptr_t) extra_base, alignment);
-        assert(base >= extra_base, "just checking");
-        // Re-reserve the region at the aligned base address.
-        os::release_memory(extra_base, extra_size);
-        base = os::reserve_memory(size, base);
-      } while (base == NULL);
+      base = os::reserve_memory_aligned(size, alignment);
 
       if (requested_address != 0 &&
           failed_to_reserve_as_requested(base, requested_address, size, false)) {
--- a/src/share/vm/services/management.cpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/share/vm/services/management.cpp	Mon Jan 14 15:00:16 2013 +0000
@@ -1812,31 +1812,37 @@
 
 class ThreadTimesClosure: public ThreadClosure {
  private:
-  objArrayOop _names;
+  objArrayHandle _names_strings;
+  char **_names_chars;
   typeArrayOop _times;
   int _names_len;
   int _times_len;
   int _count;
 
  public:
-  ThreadTimesClosure(objArrayOop names, typeArrayOop times);
+  ThreadTimesClosure(objArrayHandle names, typeArrayOop times);
+  ~ThreadTimesClosure();
   virtual void do_thread(Thread* thread);
+  void do_unlocked();
   int count() { return _count; }
 };
 
-ThreadTimesClosure::ThreadTimesClosure(objArrayOop names,
+ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
                                        typeArrayOop times) {
-  assert(names != NULL, "names was NULL");
+  assert(names() != NULL, "names was NULL");
   assert(times != NULL, "times was NULL");
-  _names = names;
+  _names_strings = names;
   _names_len = names->length();
+  _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
   _times = times;
   _times_len = times->length();
   _count = 0;
 }
 
+//
+// Called with Threads_lock held
+//
 void ThreadTimesClosure::do_thread(Thread* thread) {
-  Handle s;
   assert(thread != NULL, "thread was NULL");
 
   // exclude externally visible JavaThreads
@@ -1850,16 +1856,32 @@
   }
 
   EXCEPTION_MARK;
+  ResourceMark rm(THREAD); // thread->name() uses ResourceArea
 
   assert(thread->name() != NULL, "All threads should have a name");
-  s = java_lang_String::create_from_str(thread->name(), CHECK);
-  _names->obj_at_put(_count, s());
-
+  _names_chars[_count] = strdup(thread->name());
   _times->long_at_put(_count, os::is_thread_cpu_time_supported() ?
                         os::thread_cpu_time(thread) : -1);
   _count++;
 }
 
+// Called without Threads_lock, we can allocate String objects.
+void ThreadTimesClosure::do_unlocked() {
+
+  EXCEPTION_MARK;
+  for (int i = 0; i < _count; i++) {
+    Handle s = java_lang_String::create_from_str(_names_chars[i],  CHECK);
+    _names_strings->obj_at_put(i, s());
+  }
+}
+
+ThreadTimesClosure::~ThreadTimesClosure() {
+  for (int i = 0; i < _count; i++) {
+    free(_names_chars[i]);
+  }
+  FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal);
+}
+
 // Fills names with VM internal thread names and times with the corresponding
 // CPU times.  If names or times is NULL, a NullPointerException is thrown.
 // If the element type of names is not String, an IllegalArgumentException is
@@ -1886,12 +1908,12 @@
   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));
   typeArrayHandle times_ah(THREAD, ta);
 
-  ThreadTimesClosure ttc(names_ah(), times_ah());
+  ThreadTimesClosure ttc(names_ah, times_ah());
   {
     MutexLockerEx ml(Threads_lock);
     Threads::threads_do(&ttc);
   }
-
+  ttc.do_unlocked();
   return ttc.count();
 JVM_END
 
--- a/src/share/vm/services/nmtDCmd.cpp	Fri Jan 04 22:21:54 2013 +0000
+++ b/src/share/vm/services/nmtDCmd.cpp	Mon Jan 14 15:00:16 2013 +0000
@@ -84,28 +84,31 @@
   }
 
   int nopt = 0;
-  if(_summary.is_set()) { ++nopt; }
-  if(_detail.is_set()) { ++nopt; }
-  if(_baseline.is_set()) { ++nopt; }
-  if(_summary_diff.is_set()) { ++nopt; }
-  if(_detail_diff.is_set()) { ++nopt; }
-  if(_shutdown.is_set()) { ++nopt; }
+  if(_summary.is_set() && _summary.value()) { ++nopt; }
+  if(_detail.is_set() && _detail.value()) { ++nopt; }
+  if(_baseline.is_set() && _baseline.value()) { ++nopt; }
+  if(_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
+  if(_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
+  if(_shutdown.is_set() && _shutdown.value()) { ++nopt; }
 #ifndef PRODUCT
-  if(_debug.is_set()) { ++nopt; }
+  if(_debug.is_set() && _debug.value()) { ++nopt; }
 #endif
 
   if(nopt > 1) {
       output()->print_cr("At most one of the following option can be specified: " \
         "summary, detail, baseline, summary.diff, detail.diff, shutdown"
 #ifndef PRODUCT
-        " ,debug"
+        ", debug"
 #endif
       );
       return;
-  }
-
-  if(nopt == 0) {
+  } else if (nopt == 0) {
+    if (_summary.is_set()) {
+      output()->print_cr("No command to execute");
+      return;
+    } else {
       _summary.set_value(true);
+    }
   }
 
 #ifndef PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/7196045/Test7196045.java	Mon Jan 14 15:00:16 2013 +0000
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 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
+ * @bug 7196045
+ * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
+ * @run main/othervm Test7196045
+ */
+
+import java.lang.management.ManagementFactory;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+public class Test7196045 {
+
+    public static long duration = 1000 * 60 * 2;
+    private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
+
+    public static void main(String[] args) {
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        ObjectName objName= null;
+        try {
+            ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL);
+            try {
+                server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal);
+            } catch (JMException e) {
+                throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e);
+            }
+            objName= new ObjectName("sun.management:type=HotspotThreading");
+
+        } catch (MalformedObjectNameException e1) {
+            throw new RuntimeException("Bad object name" + e1);
+        }
+
+        long endTime = System.currentTimeMillis() + duration;
+        long i = 0;
+        while (true) {
+            try {
+                server.getAttribute(objName, "InternalThreadCpuTimes");
+            } catch (Exception ex) {
+                System.err.println("Exception while getting attribute: " + ex);
+            }
+            i++;
+            if (i % 10000 == 0) {
+                System.out.println("Successful iterations: " + i);
+            }
+            if (System.currentTimeMillis() > endTime) {
+                break;
+            }
+        }
+        System.out.println("PASSED.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/serviceability/7170638/SDTProbesGNULinuxTest.sh	Mon Jan 14 15:00:16 2013 +0000
@@ -0,0 +1,68 @@
+# 
+#  Copyright (c) 2012, Red Hat, Inc.
+#  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 SDTProbesGNULinuxTest.sh
+# @bug 7170638
+# @summary Test SDT probes available on GNU/Linux when DTRACE_ENABLED
+# @run shell SDTProbesGNULinuxTest.sh
+
+# This test only matters on GNU/Linux, others trivially PASS.
+OS=`uname -s`
+case "$OS" in
+  Linux )
+    ;;
+  *)
+    echo "Not testing on anything but GNU/Linux. PASSED"
+    exit 0;
+    ;;
+esac
+
+# Where is our java (parent) directory? 
+if [ "${TESTJAVA}" = "" ]; then
+  PARENT=$(dirname $(readlink -f $(which java)))
+  TESTJAVA=`dirname ${PARENT}`
+  echo "TESTJAVA directory not set, using " ${TESTJAVA}
+fi
+
+# This test only matters when build with DTRACE_ENABLED. 
+${TESTJAVA}/bin/java -XX:+ExtendedDTraceProbes -version
+if [ "$?" != "0" ]; then
+  echo "Not build using DTRACE_ENABLED. PASSED"
+  exit 0
+fi
+
+# Test all available libjvm.so variants
+for libjvm in $(find ${TESTJAVA} -name libjvm.so); do
+  echo "Testing ${libjvm}"
+  # Check whether the SDT probes are compiled in.
+  readelf -S ${libjvm} | grep '.note.stapsdt'
+  if [ "$?" != "0" ]; then
+    echo "Failed: ${libjvm} doesn't contain SDT probes."
+    exit 1
+  fi
+  # We could iterate over all SDT probes and test them individually
+  # with readelf -n, but older readelf versions don't understand them.
+done
+
+echo "Passed."
+exit 0