Merge
authorjiangli
Tue, 11 Nov 2014 14:52:50 -0500
changeset 27648 9ac73e5f4c18
parent 27619 72646ac2d0d3 (current diff)
parent 27617 9fe6503f11e8 (diff)
child 27649 0e79b173cc5e
Merge
--- a/hotspot/make/windows/makefiles/sa.make	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/make/windows/makefiles/sa.make	Tue Nov 11 14:52:50 2014 -0500
@@ -122,7 +122,7 @@
 SA_LFLAGS = $(SA_LFLAGS) -map -debug
 !endif
 !if "$(BUILDARCH)" == "i486"
-SA_LFLAGS = $(SAFESEH_FLAG) $(SA_LFLAGS)
+SA_LFLAGS = /SAFESEH $(SA_LFLAGS)
 !endif
 
 SA_CFLAGS = $(SA_CFLAGS) $(MP_FLAG)
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Tue Nov 11 14:52:50 2014 -0500
@@ -2059,7 +2059,7 @@
   u2** localvariable_table_start;
   u2* localvariable_type_table_length;
   u2** localvariable_type_table_start;
-  u2 method_parameters_length = 0;
+  int method_parameters_length = -1;
   u1* method_parameters_data = NULL;
   bool method_parameters_seen = false;
   bool parsed_code_attribute = false;
@@ -2278,7 +2278,8 @@
       }
       method_parameters_seen = true;
       method_parameters_length = cfs->get_u1_fast();
-      if (method_attribute_length != (method_parameters_length * 4u) + 1u) {
+      const u2 real_length = (method_parameters_length * 4u) + 1u;
+      if (method_attribute_length != real_length) {
         classfile_parse_error(
           "Invalid MethodParameters method attribute length %u in class file",
           method_attribute_length, CHECK_(nullHandle));
@@ -2288,7 +2289,7 @@
       cfs->skip_u2_fast(method_parameters_length);
       // ignore this attribute if it cannot be reflected
       if (!SystemDictionary::Parameter_klass_loaded())
-        method_parameters_length = 0;
+        method_parameters_length = -1;
     } else if (method_attribute_name == vmSymbols::tag_synthetic()) {
       if (method_attribute_length != 0) {
         classfile_parse_error(
@@ -3491,17 +3492,18 @@
           real_offset = next_nonstatic_oop_offset;
           next_nonstatic_oop_offset += heapOopSize;
         }
-        // Update oop maps
+
+        // Record this oop in the oop maps
         if( nonstatic_oop_map_count > 0 &&
             nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
             real_offset -
             int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
             heapOopSize ) {
-          // Extend current oop map
+          // This oop is adjacent to the previous one, add to current oop map
           assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
           nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
         } else {
-          // Create new oop map
+          // This oop is not adjacent to the previous one, create new oop map
           assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
           nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
           nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
@@ -3623,13 +3625,24 @@
             real_offset = next_nonstatic_padded_offset;
             next_nonstatic_padded_offset += heapOopSize;
 
-            // Create new oop map
-            assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
-            nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
-            nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
-            nonstatic_oop_map_count += 1;
-            if( first_nonstatic_oop_offset == 0 ) { // Undefined
-              first_nonstatic_oop_offset = real_offset;
+            // Record this oop in the oop maps
+            if( nonstatic_oop_map_count > 0 &&
+                nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
+                real_offset -
+                int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
+                heapOopSize ) {
+              // This oop is adjacent to the previous one, add to current oop map
+              assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
+              nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
+            } else {
+              // This oop is not adjacent to the previous one, create new oop map
+              assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
+              nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
+              nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
+              nonstatic_oop_map_count += 1;
+              if( first_nonstatic_oop_offset == 0 ) { // Undefined
+                first_nonstatic_oop_offset = real_offset;
+              }
             }
             break;
 
--- a/hotspot/src/share/vm/oops/constMethod.cpp	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/src/share/vm/oops/constMethod.cpp	Tue Nov 11 14:52:50 2014 -0500
@@ -116,7 +116,11 @@
   if (sizes->generic_signature_index() != 0) {
     extra_bytes += sizeof(u2);
   }
-  if (sizes->method_parameters_length() > 0) {
+  // This has to be a less-than-or-equal check, because we might be
+  // storing information from a zero-length MethodParameters
+  // attribute.  We have to store these, because in some cases, they
+  // cause the reflection API to throw a MalformedParametersException.
+  if (sizes->method_parameters_length() >= 0) {
     extra_bytes += sizeof(u2);
     extra_bytes += sizes->method_parameters_length() * sizeof(MethodParametersElement);
   }
@@ -237,7 +241,7 @@
     _flags |= _has_linenumber_table;
   if (sizes->generic_signature_index() != 0)
     _flags |= _has_generic_signature;
-  if (sizes->method_parameters_length() > 0)
+  if (sizes->method_parameters_length() >= 0)
     _flags |= _has_method_parameters;
   if (sizes->checked_exceptions_length() > 0)
     _flags |= _has_checked_exceptions;
@@ -272,7 +276,7 @@
   if (sizes->generic_signature_index() != 0)
     *(generic_signature_index_addr()) = sizes->generic_signature_index();
   // New data should probably go here.
-  if (sizes->method_parameters_length() > 0)
+  if (sizes->method_parameters_length() >= 0)
     *(method_parameters_length_addr()) = sizes->method_parameters_length();
   if (sizes->checked_exceptions_length() > 0)
     *(checked_exceptions_length_addr()) = sizes->checked_exceptions_length();
@@ -283,7 +287,7 @@
 }
 
 int ConstMethod::method_parameters_length() const {
-  return has_method_parameters() ? *(method_parameters_length_addr()) : 0;
+  return has_method_parameters() ? *(method_parameters_length_addr()) : -1;
 }
 
 MethodParametersElement* ConstMethod::method_parameters_start() const {
--- a/hotspot/src/share/vm/oops/constMethod.hpp	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/src/share/vm/oops/constMethod.hpp	Tue Nov 11 14:52:50 2014 -0500
@@ -372,6 +372,11 @@
   ExceptionTableElement* exception_table_start() const;
 
   // method parameters table
+
+  // This returns -1 if no parameters are present, a non-negative
+  // value otherwise.  Note: sometimes, there are 0-length parameters
+  // attributes that must be reported up to the reflection API all the
+  // same.
   int method_parameters_length() const;
   MethodParametersElement* method_parameters_start() const;
 
--- a/hotspot/src/share/vm/prims/jvm.cpp	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Tue Nov 11 14:52:50 2014 -0500
@@ -1657,7 +1657,17 @@
   Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));
   const int num_params = mh->method_parameters_length();
 
-  if (0 != num_params) {
+  if (num_params < 0) {
+    // A -1 return value from method_parameters_length means there is no
+    // parameter data.  Return null to indicate this to the reflection
+    // API.
+    assert(num_params == -1, "num_params should be -1 if it is less than zero");
+    return (jobjectArray)NULL;
+  } else {
+    // Otherwise, we return something up to reflection, even if it is
+    // a zero-length array.  Why?  Because in some cases this can
+    // trigger a MalformedParametersException.
+
     // make sure all the symbols are properly formatted
     for (int i = 0; i < num_params; i++) {
       MethodParametersElement* params = mh->method_parameters_start();
@@ -1685,8 +1695,6 @@
       result->obj_at_put(i, param);
     }
     return (jobjectArray)JNIHandles::make_local(env, result());
-  } else {
-    return (jobjectArray)NULL;
   }
 }
 JVM_END
--- a/hotspot/src/share/vm/runtime/reflection.cpp	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/src/share/vm/runtime/reflection.cpp	Tue Nov 11 14:52:50 2014 -0500
@@ -806,17 +806,16 @@
 
 oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
                               int flags, TRAPS) {
-  Handle name;
 
-  // A null symbol here translates to the empty string
+  Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
+
   if(NULL != sym) {
-    name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
+    Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
+    java_lang_reflect_Parameter::set_name(rh(), name());
   } else {
-    name = java_lang_String::create_from_str("", CHECK_NULL);
+    java_lang_reflect_Parameter::set_name(rh(), NULL);
   }
 
-  Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
-  java_lang_reflect_Parameter::set_name(rh(), name());
   java_lang_reflect_Parameter::set_modifiers(rh(), flags);
   java_lang_reflect_Parameter::set_executable(rh(), method());
   java_lang_reflect_Parameter::set_index(rh(), index);
--- a/hotspot/src/share/vm/services/mallocTracker.hpp	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/src/share/vm/services/mallocTracker.hpp	Tue Nov 11 14:52:50 2014 -0500
@@ -243,15 +243,15 @@
   size_t           _flags     : 8;
   size_t           _pos_idx   : 16;
   size_t           _bucket_idx: 40;
-#define MAX_MALLOCSITE_TABLE_SIZE ((size_t)1 << 40)
-#define MAX_BUCKET_LENGTH         ((size_t)(1 << 16))
+#define MAX_MALLOCSITE_TABLE_SIZE right_n_bits(40)
+#define MAX_BUCKET_LENGTH         right_n_bits(16)
 #else
   size_t           _size      : 32;
   size_t           _flags     : 8;
   size_t           _pos_idx   : 8;
   size_t           _bucket_idx: 16;
-#define MAX_MALLOCSITE_TABLE_SIZE  ((size_t)(1 << 16))
-#define MAX_BUCKET_LENGTH          ((size_t)(1 << 8))
+#define MAX_MALLOCSITE_TABLE_SIZE  right_n_bits(16)
+#define MAX_BUCKET_LENGTH          right_n_bits(8)
 #endif  // _LP64
 
  public:
--- a/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java	Tue Nov 11 14:52:50 2014 -0500
@@ -27,7 +27,6 @@
  * @requires sun.arch.data.model == "32"
  * @key nmt jcmd stress
  * @library /testlibrary /testlibrary/whitebox
- * @ignore 8062870
  * @build MallocSiteHashOverflow
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow
--- a/hotspot/test/runtime/NMT/MallocTrackingVerify.java	Mon Nov 10 19:52:28 2014 -0500
+++ b/hotspot/test/runtime/NMT/MallocTrackingVerify.java	Tue Nov 11 14:52:50 2014 -0500
@@ -27,7 +27,6 @@
  * @summary Test to verify correctness of malloc tracking
  * @key nmt jcmd
  * @library /testlibrary /testlibrary/whitebox
- * @ignore 8058251
  * @build MallocTrackingVerify
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTrackingVerify
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/contended/OopMapsSameGroup.java	Tue Nov 11 14:52:50 2014 -0500
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug     8015272
+ * @summary \@Contended within the same group to use the same oop map
+ *
+ * @run main/othervm -XX:-RestrictContended -XX:ContendedPaddingWidth=128 -Xmx128m OopMapsSameGroup
+ */
+public class OopMapsSameGroup {
+
+    public static final int COUNT = 10000;
+
+    public static void main(String[] args) throws Exception {
+        Object o01 = new Object();
+        Object o02 = new Object();
+        Object o03 = new Object();
+        Object o04 = new Object();
+
+        R[] rs = new R[COUNT];
+
+        for (int i = 0; i < COUNT; i++) {
+           R r = new R();
+           r.o01 = o01;
+           r.o02 = o02;
+           r.o03 = o03;
+           r.o04 = o04;
+           rs[i] = r;
+        }
+
+        System.gc();
+
+        for (int i = 0; i < COUNT; i++) {
+           R r = rs[i];
+           if (r.o01 != o01) throw new Error("Test Error: o01");
+           if (r.o02 != o02) throw new Error("Test Error: o02");
+           if (r.o03 != o03) throw new Error("Test Error: o03");
+           if (r.o04 != o04) throw new Error("Test Error: o04");
+        }
+    }
+
+    public static class R {
+        @Contended("group1")
+        Object o01;
+
+        @Contended("group1")
+        Object o02;
+
+        @Contended("group2")
+        Object o03;
+
+        @Contended("group2")
+        Object o04;
+    }
+
+}
+