changeset 5093:208419914859

Merge
author asaha
date Wed, 08 Jan 2014 14:13:12 -0800
parents f8a1ba5693e9 (diff) 619b904e420a (current diff)
children 46236fe5d1fe
files .hgtags
diffstat 9 files changed, 133 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Jan 08 13:23:53 2014 -0800
+++ b/.hgtags	Wed Jan 08 14:13:12 2014 -0800
@@ -593,3 +593,19 @@
 c373a733d5d5147f99eaa2b91d6b937c28214fc9 jdk7u45-b33
 0bcb43482f2ac5615437541ffb8dc0f79ece3148 jdk7u45-b34
 12ea8d416f105f5971c808c89dddc1006bfc4c53 jdk7u45-b35
+429884602206fcf5314c8b953c06d54d337558ca jdk7u51-b00
+68f03ff066f2341b89b52a6d6e21ae09de008351 jdk7u51-b01
+67910a581eca113847c5320c49436a9816c5d5c6 jdk7u51-b02
+4138fb11955a528e5ee5448d9c6c8e88e0e268b2 jdk7u51-b03
+683458c333ced92d515daa1b9bcdb5be679e535a jdk7u51-b04
+ed2db7a82229e7adbfe8a8166bf98f3ef4a09be5 jdk7u51-b05
+fec027762cf37d033d82d5b3725020f40c771690 jdk7u51-b06
+f673c581ebf91073b5bbdbdc5e4d4407910fa006 jdk7u51-b07
+b0a355aae00427e74cc0b89697c7c7f6fb520176 jdk7u51-b08
+4f56f2e206fd878809f70ca06f4bc21563a7c530 jdk7u51-b09
+1b7aaef3df78970c9a5ef5cc353ca927241555ee jdk7u51-b10
+1f11dff734af98f5bf11d4fceeda221ab1416971 jdk7u51-b11
+dee2a38ef6b26534c44c550ef4da2c3146c612c2 jdk7u51-b12
+6c6a2299029ad02fa2820b8ff8c61c2bbcae799c jdk7u51-b13
+a398ddc79d2310ad37b131cc3794b3cf574f088e jdk7u51-b30
+cf4110c35afb10456d8264c47b7cde1c20150cab jdk7u51-b31
--- a/make/hotspot_version	Wed Jan 08 13:23:53 2014 -0800
+++ b/make/hotspot_version	Wed Jan 08 14:13:12 2014 -0800
@@ -34,8 +34,8 @@
 HOTSPOT_VM_COPYRIGHT=Copyright 2013
 
 HS_MAJOR_VER=24
-HS_MINOR_VER=45
-HS_BUILD_NUMBER=08
+HS_MINOR_VER=51
+HS_BUILD_NUMBER=03
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
--- a/src/os/linux/vm/os_linux.cpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/os/linux/vm/os_linux.cpp	Wed Jan 08 14:13:12 2014 -0800
@@ -2696,6 +2696,14 @@
           alignment_hint, exec, strerror(err), err);
 }
 
+static void warn_fail_commit_memory(char* addr, size_t size,
+                                    size_t alignment_hint, bool exec,
+                                    int err, const char* msg) {
+  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
+          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d); %s", addr, size,
+          alignment_hint, exec, strerror(err), err, msg);
+}
+
 // NOTE: Linux kernel does not really reserve the pages for us.
 //       All it does is to check if there are enough free pages
 //       left at the time of mmap(). This could be a potential
@@ -2746,6 +2754,8 @@
 #define MADV_HUGEPAGE 14
 #endif
 
+volatile jint os::Linux::num_largepage_commit_fails = 0;
+
 int os::Linux::commit_memory_impl(char* addr, size_t size,
                                   size_t alignment_hint, bool exec) {
   int err;
@@ -2770,7 +2780,9 @@
       // from the loss. For now, we just issue a warning and we don't
       // call vm_exit_out_of_memory(). This issue is being tracked by
       // JBS-8007074.
-      warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
+      Atomic::inc(&os::Linux::num_largepage_commit_fails);
+      warn_fail_commit_memory(addr, size, alignment_hint, exec, err,
+        "Cannot allocate large pages, falling back to regular pages");
 //    vm_exit_out_of_memory(size, "committing reserved memory.");
     }
     // Fall through and try to use small pages
--- a/src/os/linux/vm/os_linux.hpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/os/linux/vm/os_linux.hpp	Wed Jan 08 14:13:12 2014 -0800
@@ -100,6 +100,7 @@
 
  public:
   static bool _stack_is_executable;
+  static volatile jint num_largepage_commit_fails;
   static void *dlopen_helper(const char *name, char *ebuf, int ebuflen);
   static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen);
 
--- a/src/share/vm/prims/methodHandles.cpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/share/vm/prims/methodHandles.cpp	Wed Jan 08 14:13:12 2014 -0800
@@ -175,30 +175,32 @@
 }
 
 oop MethodHandles::init_method_MemberName(oop mname_oop, methodOop m, bool do_dispatch,
-                                          klassOop receiver_limit) {
+                                          klassOop resolved_klass) {
   AccessFlags mods = m->access_flags();
   int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
   int vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
-  klassOop mklass = m->method_holder();
-  if (receiver_limit == NULL)
-    receiver_limit = mklass;
+  bool is_itable_call = false;
+  klassOop m_klass = m->method_holder();
+  // resolved_klass is a copy of CallInfo::resolved_klass, if available
+  if (resolved_klass == NULL)
+    resolved_klass = m_klass;
   if (m->is_initializer()) {
     flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
   } else if (mods.is_static()) {
     flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
-  } else if (receiver_limit != mklass &&
-             !Klass::cast(receiver_limit)->is_subtype_of(mklass)) {
+  } else if (resolved_klass != m_klass &&
+             !Klass::cast(resolved_klass)->is_subtype_of(m_klass)) {
     return NULL;  // bad receiver limit
-  } else if (Klass::cast(receiver_limit)->is_interface() &&
-             Klass::cast(mklass)->is_interface()) {
+  } else if (Klass::cast(resolved_klass)->is_interface() &&
+             Klass::cast(m_klass)->is_interface()) {
     flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
-    receiver_limit = mklass;  // ignore passed-in limit; interfaces are interconvertible
     vmindex = klassItable::compute_itable_index(m);
-  } else if (mklass != receiver_limit && Klass::cast(mklass)->is_interface()) {
+    is_itable_call = true;
+  } else if (m_klass != resolved_klass && Klass::cast(m_klass)->is_interface()) {
     flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
     // it is a miranda method, so m->vtable_index is not what we want
     ResourceMark rm;
-    klassVtable* vt = instanceKlass::cast(receiver_limit)->vtable();
+    klassVtable* vt = instanceKlass::cast(resolved_klass)->vtable();
     vmindex = vt->index_of_miranda(m->name(), m->signature());
   } else if (!do_dispatch || m->can_be_statically_bound()) {
     flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
@@ -207,10 +209,36 @@
     vmindex = m->vtable_index();
   }
 
+  if (vmindex >= 0 && !is_itable_call) {
+    if (Klass::cast(m_klass)->is_interface()) {
+      // This is a vtable call to an interface method (abstract "miranda method").
+      // The vtable index is meaningless without a class (not interface) receiver type, so get one.
+      // (LinkResolver should help us figure this out.)
+      KlassHandle m_klass_non_interface = resolved_klass;
+      if (m_klass_non_interface->is_interface()) {
+        m_klass_non_interface = SystemDictionary::Object_klass();
+#ifdef ASSERT
+        { ResourceMark rm;
+          methodOop m2 = m_klass_non_interface->vtable()->method_at(vmindex);
+          assert(m->name() == m2->name() && m->signature() == m2->signature(),
+                 err_msg("at %d, %s != %s", vmindex,
+                         m->name_and_sig_as_C_string(), m2->name_and_sig_as_C_string()));
+        }
+#endif //ASSERT
+      }
+      if (!m->is_public()) {
+        assert(m->is_public(), "virtual call must be to public interface method");
+        return NULL;  // elicit an error later in product build
+      }
+      assert(Klass::cast(resolved_klass)->is_subtype_of(m_klass_non_interface()), "virtual call must be type-safe");
+      m_klass = m_klass_non_interface();
+    }
+  }
+
   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
   java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);   // vtable/itable index
-  java_lang_invoke_MemberName::set_clazz(mname_oop,    Klass::cast(receiver_limit)->java_mirror());
+  java_lang_invoke_MemberName::set_clazz(mname_oop,    Klass::cast(m_klass)->java_mirror());
   // Note:  name and type can be lazily computed by resolve_MemberName,
   // if Java code needs them as resolved String and MethodType objects.
   // The clazz must be eagerly stored, because it provides a GC
@@ -571,7 +599,7 @@
 // An unresolved member name is a mere symbolic reference.
 // Resolving it plants a vmtarget/vmindex in it,
 // which refers dirctly to JVM internals.
-Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
+Handle MethodHandles::resolve_MemberName(Handle mname, KlassHandle caller, TRAPS) {
   Handle empty;
   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
 
@@ -650,21 +678,49 @@
         if (ref_kind == JVM_REF_invokeStatic) {
           //do_dispatch = false;  // no need, since statics are never dispatched
           LinkResolver::resolve_static_call(result,
-                        defc, name, type, KlassHandle(), false, false, THREAD);
+                        defc, name, type, caller, caller.not_null(), false, THREAD);
         } else if (ref_kind == JVM_REF_invokeInterface) {
           LinkResolver::resolve_interface_call(result, Handle(), defc,
-                        defc, name, type, KlassHandle(), false, false, THREAD);
+                        defc, name, type, caller, caller.not_null(), false, THREAD);
         } else if (mh_invoke_id != vmIntrinsics::_none) {
           assert(!is_signature_polymorphic_static(mh_invoke_id), "");
           LinkResolver::resolve_handle_call(result,
-                        defc, name, type, KlassHandle(), THREAD);
+                        defc, name, type, caller, THREAD);
         } else if (ref_kind == JVM_REF_invokeSpecial) {
           do_dispatch = false;  // force non-virtual linkage
           LinkResolver::resolve_special_call(result,
-                        defc, name, type, KlassHandle(), false, THREAD);
+                        defc, name, type, caller, caller.not_null(), THREAD);
+          // CR 8029533:
+          // As a corner case, invokespecial can return a method *below* its resolved_klass.
+          // Since method search *starts* at the resolved_klass, the eventual
+          // method is almost always in a supertype *above* the resolved_klass.
+          // This pattern breaks when an invokespecial "over-reaches" beyond an
+          // immediate super to a method overridden by a super class.
+          // In that case, the selected method will be below the resolved_klass.
+          // (This is the behavior enabled by the famous ACC_SUPER classfile flag.)
+          //
+          // Downstream of this code, we make assumptions about resolved_klass being below m.
+          // (See init_method_MemberName, the comment "bad receiver limit".)
+          // We basically want to patch result._resolved_klass to be m.method_holder().
+          // The simplest way to get this happier outcome is to re-resolve.
+          if (!HAS_PENDING_EXCEPTION &&
+              caller.not_null() &&
+              result.resolved_method().not_null()) {
+            // this is the m_klass value that will be checked later:
+            klassOop m_klass = result.resolved_method()->method_holder();
+            if (m_klass != result.resolved_klass()() &&
+                Klass::cast(m_klass)->is_subtype_of(result.resolved_klass()())) {
+              KlassHandle adjusted_defc(THREAD, m_klass);
+              LinkResolver::resolve_special_call(result,
+                            adjusted_defc, name, type, caller, caller.not_null(), THREAD);
+              assert(HAS_PENDING_EXCEPTION  // if there is something like an OOM, pass it up to caller
+                     || result.resolved_method()->method_holder() == adjusted_defc(),
+                     "same method, different resolved_klass");
+            }
+          }
         } else if (ref_kind == JVM_REF_invokeVirtual) {
           LinkResolver::resolve_virtual_call(result, Handle(), defc,
-                        defc, name, type, KlassHandle(), false, false, THREAD);
+                        defc, name, type, caller, caller.not_null(), false, THREAD);
         } else {
           assert(false, err_msg("ref_kind=%d", ref_kind));
         }
@@ -681,7 +737,7 @@
         assert(!HAS_PENDING_EXCEPTION, "");
         if (name == vmSymbols::object_initializer_name()) {
           LinkResolver::resolve_special_call(result,
-                        defc, name, type, KlassHandle(), false, THREAD);
+                        defc, name, type, caller, caller.not_null(), THREAD);
         } else {
           break;                // will throw after end of switch
         }
@@ -1025,7 +1081,12 @@
   if (VerifyMethodHandles && caller_jh != NULL &&
       java_lang_invoke_MemberName::clazz(mname()) != NULL) {
     klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname()));
-    if (reference_klass != NULL) {
+    if (reference_klass != NULL && Klass::cast(reference_klass)->oop_is_objArray()) {
+      reference_klass = objArrayKlass::cast(reference_klass)->bottom_klass();
+    }
+
+    // Reflection::verify_class_access can only handle instance classes.
+    if (reference_klass != NULL && Klass::cast(reference_klass)->oop_is_instance()) {
       // Emulate LinkResolver::check_klass_accessability.
       klassOop caller = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh));
       if (!Reflection::verify_class_access(caller,
@@ -1036,7 +1097,11 @@
     }
   }
 
-  Handle resolved = MethodHandles::resolve_MemberName(mname, CHECK_NULL);
+  KlassHandle caller(THREAD,
+                     caller_jh == NULL ? (klassOop) NULL :
+                     java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
+  Handle resolved = MethodHandles::resolve_MemberName(mname, caller, CHECK_NULL);
+
   if (resolved.is_null()) {
     int flags = java_lang_invoke_MemberName::flags(mname());
     int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
--- a/src/share/vm/prims/methodHandles.hpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/share/vm/prims/methodHandles.hpp	Wed Jan 08 14:13:12 2014 -0800
@@ -51,12 +51,12 @@
 
  public:
   // working with member names
-  static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
+  static Handle resolve_MemberName(Handle mname, KlassHandle caller, TRAPS); // compute vmtarget/vmindex from name/type
   static void expand_MemberName(Handle mname, int suppress, TRAPS);  // expand defc/name/type if missing
   static Handle new_MemberName(TRAPS);  // must be followed by init_MemberName
   static oop init_MemberName(oop mname_oop, oop target_oop); // compute vmtarget/vmindex from target
   static oop init_method_MemberName(oop mname_oop, methodOop m, bool do_dispatch,
-                                    klassOop receiver_limit);
+                                    klassOop resolved_klass);
   static oop init_field_MemberName(oop mname_oop, klassOop field_holder,
                                    AccessFlags mods, oop type, oop name,
                                    intptr_t offset, bool is_setter = false);
--- a/src/share/vm/runtime/os.cpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/share/vm/runtime/os.cpp	Wed Jan 08 14:13:12 2014 -0800
@@ -1139,9 +1139,6 @@
         "%/lib/jce.jar:"
         "%/lib/charsets.jar:"
         "%/lib/jfr.jar:"
-#ifdef __APPLE__
-        "%/lib/JObjC.jar:"
-#endif
         "%/classes";
     char* sysclasspath = format_boot_path(classpath_format, home, home_len, fileSep, pathSep);
     if (sysclasspath == NULL) return false;
--- a/src/share/vm/runtime/reflection.cpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/share/vm/runtime/reflection.cpp	Wed Jan 08 14:13:12 2014 -0800
@@ -460,7 +460,7 @@
   // doesn't have a classloader.
   if ((current_class == NULL) ||
       (current_class == new_class) ||
-      (instanceKlass::cast(new_class)->is_public()) ||
+      (Klass::cast(new_class)->is_public()) ||
       is_same_class_package(current_class, new_class)) {
     return true;
   }
--- a/src/share/vm/utilities/vmError.cpp	Wed Jan 08 13:23:53 2014 -0800
+++ b/src/share/vm/utilities/vmError.cpp	Wed Jan 08 14:13:12 2014 -0800
@@ -698,6 +698,18 @@
        st->cr();
      }
 
+#ifdef LINUX
+  STEP(193, "(printing large pages allocation errors)")
+
+     if (_verbose) {
+       jint largepage_failures = os::Linux::num_largepage_commit_fails;
+       if (largepage_failures > 0) {
+         st->print_cr("Large page allocation failures have occurred " INT32_FORMAT " times", largepage_failures);
+         st->cr();
+       }
+     }
+#endif
+
   STEP(195, "(printing code cache information)" )
 
      if (_verbose && Universe::is_fully_initialized()) {