/hg/icedtea7-forest/hotspot: 15 new changesets

andrew at icedtea.classpath.org andrew at icedtea.classpath.org
Mon Oct 19 07:31:47 UTC 2015


changeset 53dd9d3ceef9 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=53dd9d3ceef9
author: sla
date: Fri Oct 16 01:49:56 2015 +0100

	8035150, PR2674: ShouldNotReachHere() in ConstantPool::copy_entry_to
	Reviewed-by: dcubed, mgronlun


changeset dfd19321884f in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=dfd19321884f
author: iveresov
date: Mon Sep 08 18:11:37 2014 -0700

	8056124, PR2674: Hotspot should use PICL interface to get cacheline size on SPARC
	Summary: Using libpicl to get L1 data and L2 cache line sizes
	Reviewed-by: kvn, roland, morris


changeset 59220e7c5c67 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=59220e7c5c67
author: iveresov
date: Sat Oct 25 21:02:29 2014 -1000

	8059200, PR2674: Promoted JDK9 b31 for Solaris-amd64 fails (Error: dl failure on line 744, no picl library) on Solaris 11.1
	Summary: Manually load libpicl.so (used on SPARC only)
	Reviewed-by: kvn


changeset dea053e78892 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=dea053e78892
author: iveresov
date: Fri Apr 10 15:24:50 2015 -0700

	8062591, PR2674: SPARC PICL causes significantly longer startup times
	Summary: Optimize traversals of the PICL tree
	Reviewed-by: kvn


changeset dfe1fb7041b6 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=dfe1fb7041b6
author: iveresov
date: Fri Apr 10 15:27:05 2015 -0700

	8076968, PR2674: PICL based initialization of L2 cache line size on some SPARC systems is incorrect
	Summary: Chcek both l2-dcache-line-size and l2-cache-line-size properties to determine the size of the line
	Reviewed-by: kvn


changeset d9ffc7c1a9f2 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=d9ffc7c1a9f2
author: poonam
date: Mon Jul 06 10:33:54 2015 -0700

	8080012, PR2674: JVM times out with vdbench on SPARC M7-16
	Summary: check cacheline sine only for one core on sun4v SPARC systems.
	Reviewed-by: kvn


changeset 68b5c0f589dc in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=68b5c0f589dc
author: dsamersoff
date: Fri Oct 16 21:47:31 2015 +0100

	6904403, PR2674: assert(f == k->has_finalizer(),"inconsistent has_finalizer") with debug VM
	Summary: Don't assert if one of classes in hierarhy was redefined
	Reviewed-by: coleenp, sspitsyn


changeset e4a01e2fac48 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=e4a01e2fac48
author: ctornqvi
date: Mon Jun 02 19:08:18 2014 +0200

	8044364, PR2674: runtime/RedefineFinalizer test fails on windows
	Summary: Rewrote the test in pure Java, added RedefineClassHelper utility class
	Reviewed-by: coleenp, allwin, gtriantafill, dsamersoff


changeset cccb37654caf in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=cccb37654caf
author: hseigel
date: Mon Oct 19 04:28:04 2015 +0100

	7127066, PR2674: Class verifier accepts an invalid class file
	Summary: For *store bytecodes, compare incoming, not outgoing, type state with exception handlers' stack maps.
	Reviewed-by: acorn, dholmes


changeset 94e773531435 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=94e773531435
author: zmajo
date: Thu Mar 19 19:53:34 2015 +0100

	8074869, PR2674: C2 code generator can replace -0.0f with +0.0f on Linux
	Summary: Instead of 'fpclass', use cast float->int and double->long to check if value is +0.0f and +0.0d, respectively.
	Reviewed-by: kvn, simonis, dlong


changeset 6b4c80f14bf3 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=6b4c80f14bf3
author: kvn
date: Mon Oct 19 06:23:59 2015 +0100

	8078113, PR2674: 8011102 changes may cause incorrect results
	Summary: replace Vzeroupper instruction in stubs with zeroing only used ymm registers.
	Reviewed-by: kvn
	Contributed-by: sandhya.viswanathan at intel.com


changeset c5a85ccbea89 in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=c5a85ccbea89
author: dbuck
date: Tue Apr 28 00:37:33 2015 -0700

	8072863, PR2674: Replace fatal() with vm_exit_during_initialization() when an incorrect class is found on the bootclasspath
	Reviewed-by: dholmes, coleenp
	Contributed-by: Cheleswer Sahu <cheleswer.sahu at oracle.com>


changeset a5ed90cde0ec in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=a5ed90cde0ec
author: aeriksso
date: Tue Jun 16 15:59:57 2015 +0200

	8133636, PR2674: [TEST_BUG] Import/add tests for the problem seen in 8076110
	Reviewed-by: coleenp, sspitsyn


changeset d93620c5685d in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=d93620c5685d
author: vkempik
date: Mon Oct 19 07:58:06 2015 +0100

	8048353: jstack -l crashes VM when a Java mirror for a primitive type is locked
	Reviewed-by: coleenp, dcubed


changeset 43c066bdfc9f in /hg/icedtea7-forest/hotspot
details: http://icedtea.classpath.org/hg/icedtea7-forest/hotspot?cmd=changeset;node=43c066bdfc9f
author: kevinw
date: Thu Aug 06 00:08:57 2015 -0700

	8075773, PR2674: jps running as root fails after the fix of JDK-8050807
	Reviewed-by: sla, dsamersoff, gthornbr
	Contributed-by: cheleswer.sahu at oracle.com


diffstat:

 src/cpu/ppc/vm/ppc.ad                                                      |    6 +-
 src/cpu/sparc/vm/sparc.ad                                                  |   12 +-
 src/cpu/sparc/vm/vm_version_sparc.cpp                                      |    6 +-
 src/cpu/sparc/vm/vm_version_sparc.hpp                                      |    8 +-
 src/cpu/x86/vm/assembler_x86.cpp                                           |   10 +-
 src/cpu/x86/vm/stubGenerator_x86_32.cpp                                    |    3 +-
 src/cpu/x86/vm/stubGenerator_x86_64.cpp                                    |    6 +-
 src/os/linux/vm/perfMemory_linux.cpp                                       |    6 +-
 src/os/solaris/vm/perfMemory_solaris.cpp                                   |    6 +-
 src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp                   |  242 +++++++++-
 src/share/vm/classfile/classFileParser.cpp                                 |   10 +-
 src/share/vm/classfile/javaClasses.cpp                                     |   21 +-
 src/share/vm/classfile/javaClasses.hpp                                     |    1 +
 src/share/vm/classfile/verifier.cpp                                        |   23 +-
 src/share/vm/interpreter/bytecodes.hpp                                     |    3 +-
 src/share/vm/oops/instanceKlass.cpp                                        |   15 +
 src/share/vm/oops/instanceKlass.hpp                                        |    5 +
 src/share/vm/prims/whitebox.cpp                                            |    2 +-
 src/share/vm/runtime/vframe.cpp                                            |    3 +-
 src/share/vm/utilities/globalDefinitions_gcc.hpp                           |    8 -
 src/share/vm/utilities/globalDefinitions_sparcWorks.hpp                    |    9 -
 src/share/vm/utilities/globalDefinitions_xlc.hpp                           |    8 -
 test/compiler/loopopts/ConstFPVectorization.java                           |   63 ++
 test/runtime/RedefineFinalizer/RedefineFinalizer.java                      |   64 ++
 test/runtime/RedefineTests/RedefineRunningMethodsWithResolutionErrors.java |  143 +++++
 test/runtime/stackMapCheck/BadMap.jasm                                     |  152 +++++
 test/runtime/stackMapCheck/BadMapDstore.jasm                               |   79 +++
 test/runtime/stackMapCheck/BadMapIstore.jasm                               |   79 +++
 test/runtime/stackMapCheck/StackMapCheck.java                              |   63 ++
 test/serviceability/jvmti/TestRedefineWithUnresolvedClass.java             |   82 +++
 test/serviceability/jvmti/UnresolvedClassAgent.java                        |   69 ++
 test/serviceability/jvmti/UnresolvedClassAgent.mf                          |    3 +
 test/testlibrary/RedefineClassHelper.java                                  |   79 +++
 test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java             |   81 +++-
 test/testlibrary/com/oracle/java/testlibrary/Utils.java                    |  263 ++++++++++
 test/testlibrary_tests/RedefineClassTest.java                              |   54 ++
 36 files changed, 1616 insertions(+), 71 deletions(-)

diffs (truncated from 2079 to 500 lines):

diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/ppc/vm/ppc.ad
--- a/src/cpu/ppc/vm/ppc.ad	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/ppc/vm/ppc.ad	Thu Aug 06 00:08:57 2015 -0700
@@ -6625,11 +6625,11 @@
   interface(CONST_INTER);
 %}
 
-// constant 'float +0.0'.
+// Float Immediate: +0.0f.
 operand immF_0() %{
-  predicate((n->getf() == 0) &&
-            (fpclassify(n->getf()) == FP_ZERO) && (signbit(n->getf()) == 0));
+  predicate(jint_cast(n->getf()) == 0);
   match(ConF);
+  
   op_cost(0);
   format %{ %}
   interface(CONST_INTER);
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/sparc/vm/sparc.ad
--- a/src/cpu/sparc/vm/sparc.ad	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/sparc/vm/sparc.ad	Thu Aug 06 00:08:57 2015 -0700
@@ -3750,13 +3750,9 @@
   interface(CONST_INTER);
 %}
 
+// Double Immediate: +0.0d
 operand immD0() %{
-#ifdef _LP64
-  // on 64-bit architectures this comparision is faster
   predicate(jlong_cast(n->getd()) == 0);
-#else
-  predicate((n->getd() == 0) && (fpclass(n->getd()) == FP_PZERO));
-#endif
   match(ConD);
 
   op_cost(0);
@@ -3773,9 +3769,9 @@
   interface(CONST_INTER);
 %}
 
-// Float Immediate: 0
-operand immF0() %{
-  predicate((n->getf() == 0) && (fpclass(n->getf()) == FP_PZERO));
+// Float Immediate: +0.0f
+operand immF0() %{ 
+  predicate(jint_cast(n->getf()) == 0);  
   match(ConF);
 
   op_cost(0);
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/sparc/vm/vm_version_sparc.cpp
--- a/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/sparc/vm/vm_version_sparc.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -37,6 +37,7 @@
 
 int VM_Version::_features = VM_Version::unknown_m;
 const char* VM_Version::_features_str = "";
+unsigned int VM_Version::_L2_data_cache_line_size = 0;
 
 void VM_Version::initialize() {
   _features = determine_features();
@@ -205,7 +206,7 @@
   }
 
   assert(BlockZeroingLowLimit > 0, "invalid value");
-  if (has_block_zeroing()) {
+  if (has_block_zeroing() && cache_line_size > 0) {
     if (FLAG_IS_DEFAULT(UseBlockZeroing)) {
       FLAG_SET_DEFAULT(UseBlockZeroing, true);
     }
@@ -215,7 +216,7 @@
   }
 
   assert(BlockCopyLowLimit > 0, "invalid value");
-  if (has_block_zeroing()) { // has_blk_init() && is_T4(): core's local L2 cache
+  if (has_block_zeroing() && cache_line_size > 0) { // has_blk_init() && is_T4(): core's local L2 cache
     if (FLAG_IS_DEFAULT(UseBlockCopy)) {
       FLAG_SET_DEFAULT(UseBlockCopy, true);
     }
@@ -275,6 +276,7 @@
 
 #ifndef PRODUCT
   if (PrintMiscellaneous && Verbose) {
+    tty->print_cr("L2 data cache line size: %u", L2_data_cache_line_size());
     tty->print("Allocation");
     if (AllocatePrefetchStyle <= 0) {
       tty->print_cr(": no prefetching");
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/sparc/vm/vm_version_sparc.hpp
--- a/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/sparc/vm/vm_version_sparc.hpp	Thu Aug 06 00:08:57 2015 -0700
@@ -88,6 +88,9 @@
   static int  _features;
   static const char* _features_str;
 
+  static unsigned int _L2_data_cache_line_size;
+  static unsigned int L2_data_cache_line_size() { return _L2_data_cache_line_size; }
+
   static void print_features();
   static int  determine_features();
   static int  platform_features(int features);
@@ -155,9 +158,8 @@
 
   static const char* cpu_features()     { return _features_str; }
 
-  static intx prefetch_data_size()  {
-    return is_T4() && !is_T7() ? 32 : 64;  // default prefetch block size on sparc
-  }
+  // default prefetch block size on sparc
+  static intx prefetch_data_size()      { return L2_data_cache_line_size();  }
 
   // Prefetch
   static intx prefetch_copy_interval_in_bytes() {
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/x86/vm/assembler_x86.cpp
--- a/src/cpu/x86/vm/assembler_x86.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/x86/vm/assembler_x86.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -11085,7 +11085,7 @@
     subl(cnt2, stride2);
     jccb(Assembler::notZero, COMPARE_WIDE_VECTORS_LOOP);
     // clean upper bits of YMM registers
-    vzeroupper();
+    vpxor(vec1, vec1);
 
     // compare wide vectors tail
     bind(COMPARE_WIDE_TAIL);
@@ -11100,7 +11100,7 @@
     // Identifies the mismatching (higher or lower)16-bytes in the 32-byte vectors.
     bind(VECTOR_NOT_EQUAL);
     // clean upper bits of YMM registers
-    vzeroupper();
+    vpxor(vec1, vec1);
     lea(str1, Address(str1, result, scale));
     lea(str2, Address(str2, result, scale));
     jmp(COMPARE_16_CHARS);
@@ -11359,7 +11359,8 @@
   bind(DONE);
   if (UseAVX >= 2) {
     // clean upper bits of YMM registers
-    vzeroupper();
+    vpxor(vec1, vec1);
+    vpxor(vec2, vec2);
   }
 }
 
@@ -11493,7 +11494,8 @@
 
         BIND(L_check_fill_8_bytes);
         // clean upper bits of YMM registers
-        vzeroupper();
+        movdl(xtmp, value);
+        pshufd(xtmp, xtmp, 0);
       } else {
         // Fill 32-byte chunks
         pshufd(xtmp, xtmp, 0);
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/x86/vm/stubGenerator_x86_32.cpp
--- a/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/x86/vm/stubGenerator_x86_32.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -867,7 +867,8 @@
 
     if (UseUnalignedLoadStores && (UseAVX >= 2)) {
       // clean upper bits of YMM registers
-      __ vzeroupper();
+      __ vpxor(xmm0, xmm0);
+      __ vpxor(xmm1, xmm1);
     }
     __ addl(qword_count, 8);
     __ jccb(Assembler::zero, L_exit);
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/cpu/x86/vm/stubGenerator_x86_64.cpp
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -1357,7 +1357,8 @@
       __ BIND(L_end);
       if (UseAVX >= 2) {
         // clean upper bits of YMM registers
-        __ vzeroupper();
+        __ vpxor(xmm0, xmm0);
+        __ vpxor(xmm1, xmm1);
       }
     } else {
       // Copy 32-bytes per iteration
@@ -1434,7 +1435,8 @@
       __ BIND(L_end);
       if (UseAVX >= 2) {
         // clean upper bits of YMM registers
-        __ vzeroupper();
+        __ vpxor(xmm0, xmm0);
+        __ vpxor(xmm1, xmm1);
       }
     } else {
       // Copy 32-bytes per iteration
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/os/linux/vm/perfMemory_linux.cpp
--- a/src/os/linux/vm/perfMemory_linux.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/os/linux/vm/perfMemory_linux.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -217,9 +217,9 @@
     //
     return false;
   }
-  // See if the uid of the directory matches the effective uid of the process.
-  //
-  if (statp->st_uid != geteuid()) {
+  // If user is not root then see if the uid of the directory matches the effective uid of the process.
+  uid_t euid = geteuid();
+  if ((euid != 0) && (statp->st_uid != euid)) {
     // The directory was not created by this user, declare it insecure.
     //
     return false;
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/os/solaris/vm/perfMemory_solaris.cpp
--- a/src/os/solaris/vm/perfMemory_solaris.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/os/solaris/vm/perfMemory_solaris.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -219,9 +219,9 @@
     //
     return false;
   }
-  // See if the uid of the directory matches the effective uid of the process.
-  //
-  if (statp->st_uid != geteuid()) {
+  // If user is not root then see if the uid of the directory matches the effective uid of the process.
+  uid_t euid = geteuid();
+  if ((euid != 0) && (statp->st_uid != euid)) {
     // The directory was not created by this user, declare it insecure.
     //
     return false;
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
--- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -26,10 +26,240 @@
 #include "runtime/os.hpp"
 #include "vm_version_sparc.hpp"
 
-# include <sys/auxv.h>
-# include <sys/auxv_SPARC.h>
-# include <sys/systeminfo.h>
-# include <kstat.h>
+#include <sys/auxv.h>
+#include <sys/auxv_SPARC.h>
+#include <sys/systeminfo.h>
+#include <kstat.h>
+#include <picl.h>
+#include <dlfcn.h>
+#include <link.h>
+
+extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result);
+
+// Functions from the library we need (signatures should match those in picl.h)
+extern "C" {
+  typedef int (*picl_initialize_func_t)(void);
+  typedef int (*picl_shutdown_func_t)(void);
+  typedef int (*picl_get_root_func_t)(picl_nodehdl_t *nodehandle);
+  typedef int (*picl_walk_tree_by_class_func_t)(picl_nodehdl_t rooth,
+      const char *classname, void *c_args,
+      int (*callback_fn)(picl_nodehdl_t hdl, void *args));
+  typedef int (*picl_get_prop_by_name_func_t)(picl_nodehdl_t nodeh, const char *nm,
+      picl_prophdl_t *ph);
+  typedef int (*picl_get_propval_func_t)(picl_prophdl_t proph, void *valbuf, size_t sz);
+  typedef int (*picl_get_propinfo_func_t)(picl_prophdl_t proph, picl_propinfo_t *pi);
+}
+
+class PICL {
+  // Pointers to functions in the library
+  picl_initialize_func_t _picl_initialize;
+  picl_shutdown_func_t _picl_shutdown;
+  picl_get_root_func_t _picl_get_root;
+  picl_walk_tree_by_class_func_t _picl_walk_tree_by_class;
+  picl_get_prop_by_name_func_t _picl_get_prop_by_name;
+  picl_get_propval_func_t _picl_get_propval;
+  picl_get_propinfo_func_t _picl_get_propinfo;
+  // Handle to the library that is returned by dlopen
+  void *_dl_handle;
+
+  bool open_library();
+  void close_library();
+
+  template<typename FuncType> bool bind(FuncType& func, const char* name);
+  bool bind_library_functions();
+
+  // Get a value of the integer property. The value in the tree can be either 32 or 64 bit
+  // depending on the platform. The result is converted to int.
+  int get_int_property(picl_nodehdl_t nodeh, const char* name, int* result) {
+    picl_propinfo_t pinfo;
+    picl_prophdl_t proph;
+    if (_picl_get_prop_by_name(nodeh, name, &proph) != PICL_SUCCESS ||
+        _picl_get_propinfo(proph, &pinfo) != PICL_SUCCESS) {
+      return PICL_FAILURE;
+    }
+
+    if (pinfo.type != PICL_PTYPE_INT && pinfo.type != PICL_PTYPE_UNSIGNED_INT) {
+      assert(false, "Invalid property type");
+      return PICL_FAILURE;
+    }
+    if (pinfo.size == sizeof(int64_t)) {
+      int64_t val;
+      if (_picl_get_propval(proph, &val, sizeof(int64_t)) != PICL_SUCCESS) {
+        return PICL_FAILURE;
+      }
+      *result = static_cast<int>(val);
+    } else if (pinfo.size == sizeof(int32_t)) {
+      int32_t val;
+      if (_picl_get_propval(proph, &val, sizeof(int32_t)) != PICL_SUCCESS) {
+        return PICL_FAILURE;
+      }
+      *result = static_cast<int>(val);
+    } else {
+      assert(false, "Unexpected integer property size");
+      return PICL_FAILURE;
+    }
+    return PICL_SUCCESS;
+  }
+
+  // Visitor and a state machine that visits integer properties and verifies that the
+  // values are the same. Stores the unique value observed.
+  class UniqueValueVisitor {
+    PICL *_picl;
+    enum {
+      INITIAL,        // Start state, no assignments happened
+      ASSIGNED,       // Assigned a value
+      INCONSISTENT    // Inconsistent value seen
+    } _state;
+    int _value;
+  public:
+    UniqueValueVisitor(PICL* picl) : _picl(picl), _state(INITIAL) { }
+    int value() {
+      assert(_state == ASSIGNED, "Precondition");
+      return _value;
+    }
+    void set_value(int value) {
+      assert(_state == INITIAL, "Precondition");
+      _value = value;
+      _state = ASSIGNED;
+    }
+    bool is_initial()       { return _state == INITIAL;      }
+    bool is_assigned()      { return _state == ASSIGNED;     }
+    bool is_inconsistent()  { return _state == INCONSISTENT; }
+    void set_inconsistent() { _state = INCONSISTENT;         }
+
+    bool visit(picl_nodehdl_t nodeh, const char* name) {
+      assert(!is_inconsistent(), "Precondition");
+      int curr;
+      if (_picl->get_int_property(nodeh, name, &curr) == PICL_SUCCESS) {
+        if (!is_assigned()) { // first iteration
+          set_value(curr);
+        } else if (curr != value()) { // following iterations
+          set_inconsistent();
+        }
+        return true;
+      }
+      return false;
+    }
+  };
+
+  class CPUVisitor {
+    UniqueValueVisitor _l1_visitor;
+    UniqueValueVisitor _l2_visitor;
+    int _limit; // number of times visit() can be run
+  public:
+    CPUVisitor(PICL *picl, int limit) : _l1_visitor(picl), _l2_visitor(picl), _limit(limit) {}
+    static int visit(picl_nodehdl_t nodeh, void *arg) {
+      CPUVisitor *cpu_visitor = static_cast<CPUVisitor*>(arg);
+      UniqueValueVisitor* l1_visitor = cpu_visitor->l1_visitor();
+      UniqueValueVisitor* l2_visitor = cpu_visitor->l2_visitor();
+      if (!l1_visitor->is_inconsistent()) {
+        l1_visitor->visit(nodeh, "l1-dcache-line-size");
+      }
+      static const char* l2_data_cache_line_property_name = NULL;
+      // On the first visit determine the name of the l2 cache line size property and memoize it.
+      if (l2_data_cache_line_property_name == NULL) {
+        assert(!l2_visitor->is_inconsistent(), "First iteration cannot be inconsistent");
+        l2_data_cache_line_property_name = "l2-cache-line-size";
+        if (!l2_visitor->visit(nodeh, l2_data_cache_line_property_name)) {
+          l2_data_cache_line_property_name = "l2-dcache-line-size";
+          l2_visitor->visit(nodeh, l2_data_cache_line_property_name);
+        }
+      } else {
+        if (!l2_visitor->is_inconsistent()) {
+          l2_visitor->visit(nodeh, l2_data_cache_line_property_name);
+        }
+      }
+
+      if (l1_visitor->is_inconsistent() && l2_visitor->is_inconsistent()) {
+        return PICL_WALK_TERMINATE;
+      }
+      cpu_visitor->_limit--;
+      if (cpu_visitor->_limit <= 0) {
+        return PICL_WALK_TERMINATE;
+      }
+      return PICL_WALK_CONTINUE;
+    }
+    UniqueValueVisitor* l1_visitor() { return &_l1_visitor; }
+    UniqueValueVisitor* l2_visitor() { return &_l2_visitor; }
+  };
+  int _L1_data_cache_line_size;
+  int _L2_data_cache_line_size;
+public:
+  static int visit_cpu(picl_nodehdl_t nodeh, void *state) {
+    return CPUVisitor::visit(nodeh, state);
+  }
+
+  PICL(bool is_fujitsu, bool is_sun4v) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
+    if (!open_library()) {
+      return;
+    }
+    if (_picl_initialize() == PICL_SUCCESS) {
+      picl_nodehdl_t rooth;
+      if (_picl_get_root(&rooth) == PICL_SUCCESS) {
+        const char* cpu_class = "cpu";
+        // If it's a Fujitsu machine, it's a "core"
+        if (is_fujitsu) {
+          cpu_class = "core";
+        }
+        CPUVisitor cpu_visitor(this, (is_sun4v && !is_fujitsu) ? 1 : os::processor_count());
+        _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper);
+        if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
+          _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
+        }
+        if (cpu_visitor.l2_visitor()->is_assigned()) {
+          _L2_data_cache_line_size = cpu_visitor.l2_visitor()->value();
+        }
+      }
+      _picl_shutdown();
+    }
+    close_library();
+  }
+
+  unsigned int L1_data_cache_line_size() const { return _L1_data_cache_line_size; }
+  unsigned int L2_data_cache_line_size() const { return _L2_data_cache_line_size; }
+};
+
+
+extern "C" static int PICL_visit_cpu_helper(picl_nodehdl_t nodeh, void *result) {
+  return PICL::visit_cpu(nodeh, result);
+}
+
+template<typename FuncType>
+bool PICL::bind(FuncType& func, const char* name) {
+  func = reinterpret_cast<FuncType>(dlsym(_dl_handle, name));
+  return func != NULL;
+}
+
+bool PICL::bind_library_functions() {
+  assert(_dl_handle != NULL, "library should be open");
+  return bind(_picl_initialize,         "picl_initialize"        ) &&
+         bind(_picl_shutdown,           "picl_shutdown"          ) &&
+         bind(_picl_get_root,           "picl_get_root"          ) &&
+         bind(_picl_walk_tree_by_class, "picl_walk_tree_by_class") &&
+         bind(_picl_get_prop_by_name,   "picl_get_prop_by_name"  ) &&
+         bind(_picl_get_propval,        "picl_get_propval"       ) &&
+         bind(_picl_get_propinfo,       "picl_get_propinfo"      );
+}
+
+bool PICL::open_library() {
+  _dl_handle = dlopen("libpicl.so.1", RTLD_LAZY);
+  if (_dl_handle == NULL) {
+    warning("PICL (libpicl.so.1) is missing. Performance will not be optimal.");
+    return false;
+  }
+  if (!bind_library_functions()) {
+    assert(false, "unexpected PICL API change");
+    close_library();
+    return false;
+  }
+  return true;
+}
+
+void PICL::close_library() {
+  assert(_dl_handle != NULL, "library should be open");
+  dlclose(_dl_handle);
+  _dl_handle = NULL;
+}
 
 // We need to keep these here as long as we have to build on Solaris
 // versions before 10.
@@ -243,5 +473,9 @@
     kstat_close(kc);
   }
 
+  // Figure out cache line sizes using PICL
+  PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0);
+  _L2_data_cache_line_size = picl.L2_data_cache_line_size();
+
   return features;
 }
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/share/vm/classfile/classFileParser.cpp
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Oct 15 21:42:27 2015 +0100
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Aug 06 00:08:57 2015 -0700
@@ -3908,9 +3908,15 @@
   methodOop m = k->lookup_method(vmSymbols::finalize_method_name(),
                                  vmSymbols::void_method_signature());
   if (m != NULL && !m->is_empty_method()) {
-    f = true;
+      f = true;
   }
-  assert(f == k->has_finalizer(), "inconsistent has_finalizer");
+
+  // Spec doesn't prevent agent from redefinition of empty finalizer.
+  // Despite the fact that it's generally bad idea and redefined finalizer
+  // will not work as expected we shouldn't abort vm in this case
+  if (!k->has_redefined_this_or_super()) {
+    assert(f == k->has_finalizer(), "inconsistent has_finalizer");
+  }
 #endif
 
   // Check if this klass supports the java.lang.Cloneable interface
diff -r 17a0db5c0e76 -r 43c066bdfc9f src/share/vm/classfile/javaClasses.cpp


More information about the distro-pkg-dev mailing list