changeset 6648:942409603ae4

Merge jdk7u181-b00
author andrew
date Thu, 19 Apr 2018 17:55:26 +0100
parents a68f2a94f319 (current diff) 5559874a74ad (diff)
children 56142fb6814b
files .hgtags src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/javaClasses.hpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/interpreter/linkResolver.cpp src/share/vm/oops/cpCacheOop.cpp src/share/vm/oops/instanceKlass.cpp src/share/vm/oops/instanceKlass.hpp src/share/vm/oops/methodOop.cpp src/share/vm/prims/jvm.cpp
diffstat 17 files changed, 292 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Apr 19 04:49:54 2018 +0100
+++ b/.hgtags	Thu Apr 19 17:55:26 2018 +0100
@@ -919,3 +919,4 @@
 ce3abb5889fb01808cab7489e83c1dc448743b70 jdk7u171-b02
 f96baf6b460751580465a599ed2fba0c912e4bad icedtea-2.6.13
 79d8447a461c7319969585c363649901b4c2773a icedtea-2.6.14pre01
+205c34770f355f726055a716ecc8991dd3bbd8fd jdk7u181-b00
--- a/src/share/vm/classfile/classFileParser.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/classfile/classFileParser.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1779,8 +1779,7 @@
   vmSymbols::SID sid = vmSymbols::find_sid(name);
   // Privileged code can use all annotations.  Other code silently drops some.
   const bool privileged = class_loader.is_null() || is_anonymous ||
-                          class_loader()->klass()->klass_part()->name() ==
-                            vmSymbols::sun_misc_Launcher_ExtClassLoader();
+                          SystemDictionary::is_ext_class_loader(class_loader);
   switch (sid) {
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
     if (_location != _in_method)  break;  // only allow for methods
--- a/src/share/vm/classfile/javaClasses.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/classfile/javaClasses.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -2430,6 +2430,32 @@
   *offset = value;
 }
 
+// Support for java_lang_ref_ReferenceQueue
+
+oop java_lang_ref_ReferenceQueue::NULL_queue() {
+  instanceKlass* ik = instanceKlass::cast(SystemDictionary::ReferenceQueue_klass());
+  oop mirror = ik->java_mirror();
+  return mirror->obj_field(static_NULL_queue_offset);
+}
+
+oop java_lang_ref_ReferenceQueue::ENQUEUED_queue() {
+  instanceKlass* ik = instanceKlass::cast(SystemDictionary::ReferenceQueue_klass());
+  oop mirror = ik->java_mirror();
+  return mirror->obj_field(static_ENQUEUED_queue_offset);
+}
+
+void java_lang_ref_ReferenceQueue::compute_offsets() {
+  klassOop k = SystemDictionary::ReferenceQueue_klass();
+  compute_offset(static_NULL_queue_offset,
+                 k,
+                 vmSymbols::referencequeue_null_name(),
+                 vmSymbols::referencequeue_signature());
+  compute_offset(static_ENQUEUED_queue_offset,
+                 k,
+                 vmSymbols::referencequeue_enqueued_name(),
+                 vmSymbols::referencequeue_signature());
+}
+
 // Support for java_lang_invoke_DirectMethodHandle
 
 int java_lang_invoke_DirectMethodHandle::_member_offset;
@@ -2938,6 +2964,8 @@
 int java_lang_ref_Reference::static_lock_offset;
 int java_lang_ref_Reference::static_pending_offset;
 int java_lang_ref_Reference::number_of_fake_oop_fields;
+int java_lang_ref_ReferenceQueue::static_NULL_queue_offset;
+int java_lang_ref_ReferenceQueue::static_ENQUEUED_queue_offset;
 int java_lang_ref_SoftReference::timestamp_offset;
 int java_lang_ref_SoftReference::static_clock_offset;
 int java_lang_ClassLoader::parent_offset;
@@ -3117,6 +3145,8 @@
     sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
   }
 
+  java_lang_ref_ReferenceQueue::compute_offsets();
+
   // generated interpreter code wants to know about the offsets we just computed:
   AbstractAssembler::update_delayed_values();
 }
--- a/src/share/vm/classfile/javaClasses.hpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/classfile/javaClasses.hpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -860,6 +860,12 @@
   static HeapWord* discovered_addr(oop ref) {
     return ref->obj_field_addr<HeapWord>(discovered_offset);
   }
+  static inline oop queue(oop ref) {
+    return ref->obj_field(queue_offset);
+  }
+  static inline void set_queue(oop ref, oop value) {
+    return ref->obj_field_put(queue_offset, value);
+  }
   // Accessors for statics
   static oop  pending_list_lock();
   static oop  pending_list();
@@ -892,6 +898,20 @@
 };
 
 
+// Interface to java.lang.ref.ReferenceQueue objects
+
+class java_lang_ref_ReferenceQueue: public AllStatic {
+public:
+  static int static_NULL_queue_offset;
+  static int static_ENQUEUED_queue_offset;
+
+  // Accessors
+  static oop NULL_queue();
+  static oop ENQUEUED_queue();
+
+  static void compute_offsets();
+};
+
 // Interface to java.lang.invoke.MethodHandle objects
 
 class MethodHandleEntry;
--- a/src/share/vm/classfile/systemDictionary.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/classfile/systemDictionary.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -145,6 +145,17 @@
    }
    return false;
 }
+
+/**
+ * Returns true if the passed class loader is the extension class loader.
+ */
+bool SystemDictionary::is_ext_class_loader(Handle class_loader) {
+  if (class_loader.is_null()) {
+    return false;
+  }
+  return (class_loader->klass()->klass_part()->name() == vmSymbols::sun_misc_Launcher_ExtClassLoader());
+}
+
 // ----------------------------------------------------------------------------
 // Resolving of classes
 
@@ -1892,6 +1903,8 @@
   instanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
   instanceKlass::cast(WK_KLASS(Cleaner_klass))->set_reference_type(REF_CLEANER);
 
+  initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(ReferenceQueue_klass), scan, CHECK);
+
   // JSR 292 classes
   WKID jsr292_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass);
   WKID jsr292_group_end   = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
--- a/src/share/vm/classfile/systemDictionary.hpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -128,6 +128,7 @@
   do_klass(PhantomReference_klass,                      java_lang_ref_PhantomReference,            Pre                 ) \
   do_klass(Cleaner_klass,                               sun_misc_Cleaner,                          Pre                 ) \
   do_klass(Finalizer_klass,                             java_lang_ref_Finalizer,                   Pre                 ) \
+  do_klass(ReferenceQueue_klass,                        java_lang_ref_ReferenceQueue,              Pre                 ) \
                                                                                                                          \
   do_klass(Thread_klass,                                java_lang_Thread,                          Pre                 ) \
   do_klass(ThreadGroup_klass,                           java_lang_ThreadGroup,                     Pre                 ) \
@@ -612,6 +613,10 @@
   static bool is_parallelCapable(Handle class_loader);
   static bool is_parallelDefine(Handle class_loader);
 
+public:
+  static bool is_ext_class_loader(Handle class_loader);
+
+private:
   static klassOop find_shared_class(Symbol* class_name);
 
   // Setup link to hierarchy
@@ -622,7 +627,6 @@
                                     Handle initiating_loader);
   static void post_class_unload_events(BoolObjectClosure* is_alive);
 
-private:
   // We pass in the hashtable index so we can calculate it outside of
   // the SystemDictionary_lock.
 
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -83,6 +83,7 @@
   template(java_lang_ref_PhantomReference,            "java/lang/ref/PhantomReference")           \
   template(sun_misc_Cleaner,                          "sun/misc/Cleaner")                         \
   template(java_lang_ref_Finalizer,                   "java/lang/ref/Finalizer")                  \
+  template(java_lang_ref_ReferenceQueue,              "java/lang/ref/ReferenceQueue")             \
   template(java_lang_reflect_AccessibleObject,        "java/lang/reflect/AccessibleObject")       \
   template(java_lang_reflect_Method,                  "java/lang/reflect/Method")                 \
   template(java_lang_reflect_Constructor,             "java/lang/reflect/Constructor")            \
@@ -379,6 +380,8 @@
   template(array_klass_name,                          "array_klass")                              \
   template(oop_size_name,                             "oop_size")                                 \
   template(static_oop_field_count_name,               "static_oop_field_count")                   \
+  template(referencequeue_null_name,                  "NULL")                                     \
+  template(referencequeue_enqueued_name,              "ENQUEUED")                                 \
                                                                                                   \
   /* non-intrinsic name/signature pairs: */                                                       \
   template(register_method_name,                      "register")                                 \
@@ -469,6 +472,7 @@
   template(class_signature,                           "Ljava/lang/Class;")                                        \
   template(string_signature,                          "Ljava/lang/String;")                                       \
   template(reference_signature,                       "Ljava/lang/ref/Reference;")                                \
+  template(referencequeue_signature,                  "Ljava/lang/ref/ReferenceQueue;")                           \
   template(concurrenthashmap_signature,               "Ljava/util/concurrent/ConcurrentHashMap;")                 \
   template(String_StringBuilder_signature,            "(Ljava/lang/String;)Ljava/lang/StringBuilder;")            \
   template(int_StringBuilder_signature,               "(I)Ljava/lang/StringBuilder;")                             \
--- a/src/share/vm/code/dependencies.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/code/dependencies.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -723,6 +723,14 @@
     _signature = NULL;
     initialize(participant);
   }
+  ClassHierarchyWalker(klassOop participants[], int num_participants) {
+    _name      = NULL;
+    _signature = NULL;
+    initialize(NULL);
+    for (int i = 0; i < num_participants; ++i) {
+      add_participant(participants[i]);
+    }
+  }
 
   // This is common code for two searches:  One for concrete subtypes,
   // the other for concrete method implementations and overrides.
@@ -810,8 +818,29 @@
     if (doing_subtype_search()) {
       return Dependencies::is_concrete_klass(k);
     } else {
-      methodOop m = instanceKlass::cast(k)->find_method(_name, _signature);
-      if (m == NULL || !Dependencies::is_concrete_method(m))  return false;
+      // Search class hierarchy first.
+      methodOop m = instanceKlass::cast(k)->find_instance_method(_name, _signature);
+      if (!Dependencies::is_concrete_method(m)) {
+        // Check for re-abstraction of method
+	if (!k->klass_part()->is_interface() && m != NULL && m->is_abstract()) {
+	  // Found a matching abstract method 'm' in the class hierarchy.
+	  // This is fine iff 'k' is an abstract class and all concrete subtypes
+          // of 'k' override 'm' and are participates of the current search.
+          ClassHierarchyWalker wf(_participants, _num_participants);
+          klassOop w = wf.find_witness_subtype(k);
+          if (w != NULL) {
+            methodOop wm = instanceKlass::cast(w)->find_instance_method(_name, _signature);
+            if (!Dependencies::is_concrete_method(wm)) {
+              // Found a concrete subtype 'w' which does not override abstract method 'm'.
+              // Bail out because 'm' could be called with 'w' as receiver (leading to an
+              // AbstractMethodError) and thus the method we are looking for is not unique.
+              _found_methods[_num_participants] = m;
+              return true;
+            }
+          }
+        }
+	return false;
+      }
       _found_methods[_num_participants] = m;
       // Note:  If add_participant(k) is called,
       // the method m will already be memoized for it.
@@ -1104,15 +1133,12 @@
 }
 
 bool Dependencies::is_concrete_method(methodOop m) {
-  // Statics are irrelevant to virtual call sites.
-  if (m->is_static())  return false;
-
-  // We could also return false if m does not yet appear to be
-  // executed, if the VM version supports this distinction also.
-  return !m->is_abstract();
+  // NULL is not a concrete method,
+  // statics are irrelevant to virtual call sites,
+  // abstract methods are not concrete,
+  return ! ( m == NULL || m -> is_static() || m -> is_abstract());
 }
 
-
 Klass* Dependencies::find_finalizable_subclass(Klass* k) {
   if (k->is_interface())  return NULL;
   if (k->has_finalizer()) return k;
@@ -1134,16 +1160,6 @@
   return true;
 }
 
-bool Dependencies::is_concrete_method(ciMethod* m) {
-  // Statics are irrelevant to virtual call sites.
-  if (m->is_static())  return false;
-
-  // We could also return false if m does not yet appear to be
-  // executed, if the VM version supports this distinction also.
-  return !m->is_abstract();
-}
-
-
 bool Dependencies::has_finalizable_subclass(ciInstanceKlass* k) {
   return k->has_finalizable_subclass();
 }
@@ -1387,61 +1403,6 @@
   return wf.find_witness_definer(ctxk, changes);
 }
 
-// Find the set of all non-abstract methods under ctxk that match m[0].
-// (The method m[0] must be defined or inherited in ctxk.)
-// Include m itself in the set, unless it is abstract.
-// Fill the given array m[0..(mlen-1)] with this set, and return the length.
-// (The length may be zero if no concrete methods are found anywhere.)
-// If there are too many concrete methods to fit in marray, return -1.
-int Dependencies::find_exclusive_concrete_methods(klassOop ctxk,
-                                                  int mlen,
-                                                  methodOop marray[]) {
-  methodOop m0 = marray[0];
-  ClassHierarchyWalker wf(m0);
-  assert(wf.check_method_context(ctxk, m0), "proper context");
-  wf.record_witnesses(mlen);
-  bool participants_hide_witnesses = true;
-  klassOop wit = wf.find_witness_definer(ctxk);
-  if (wit != NULL)  return -1;  // Too many witnesses.
-  int num = wf.num_participants();
-  assert(num <= mlen, "oob");
-  // Keep track of whether m is also part of the result set.
-  int mfill = 0;
-  assert(marray[mfill] == m0, "sanity");
-  if (Dependencies::is_concrete_method(m0))
-    mfill++;  // keep m0 as marray[0], the first result
-  for (int i = 0; i < num; i++) {
-    methodOop fm = wf.found_method(i);
-    if (fm == m0)  continue;  // Already put this guy in the list.
-    if (mfill == mlen) {
-      return -1;              // Oops.  Too many methods after all!
-    }
-    marray[mfill++] = fm;
-  }
-#ifndef PRODUCT
-  // Make sure the dependency mechanism will pass this discovery:
-  if (VerifyDependencies) {
-    // Turn off dependency tracing while actually testing deps.
-    FlagSetting fs(TraceDependencies, false);
-    switch (mfill) {
-    case 1:
-      guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]),
-                "verify dep.");
-      break;
-    case 2:
-      guarantee(NULL == (void *)
-                check_exclusive_concrete_methods(ctxk, marray[0], marray[1]),
-                "verify dep.");
-      break;
-    default:
-      ShouldNotReachHere();  // mlen > 2 yet supported
-    }
-  }
-#endif //PRODUCT
-  return mfill;
-}
-
-
 klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk, KlassDepChange* changes) {
   Klass* search_at = ctxk->klass_part();
   if (changes != NULL)
@@ -1453,7 +1414,6 @@
   return result->as_klassOop();
 }
 
-
 klassOop Dependencies::check_call_site_target_value(oop call_site, oop method_handle, CallSiteDepChange* changes) {
   assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "sanity");
   assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "sanity");
--- a/src/share/vm/code/dependencies.hpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/code/dependencies.hpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, 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
@@ -301,7 +301,6 @@
   // not go back into the VM to get their value; they must cache the
   // bit in the CI, either eagerly or lazily.)
   static bool is_concrete_klass(ciInstanceKlass* k); // k appears instantiable
-  static bool is_concrete_method(ciMethod* m);       // m appears invocable
   static bool has_finalizable_subclass(ciInstanceKlass* k);
 
   // As a general rule, it is OK to compile under the assumption that
@@ -348,7 +347,6 @@
   static klassOop  find_unique_concrete_subtype(klassOop ctxk);
   static methodOop find_unique_concrete_method(klassOop ctxk, methodOop m);
   static int       find_exclusive_concrete_subtypes(klassOop ctxk, int klen, klassOop k[]);
-  static int       find_exclusive_concrete_methods(klassOop ctxk, int mlen, methodOop m[]);
 
   // Create the encoding which will be stored in an nmethod.
   void encode_content_bytes();
--- a/src/share/vm/interpreter/linkResolver.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/interpreter/linkResolver.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -188,6 +188,7 @@
 //
 // According to JVM spec. $5.4.3c & $5.4.3d
 
+// Look up method in klasses, including static methods
 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
   methodOop result_oop = klass->uncached_lookup_method(name, signature);
 
@@ -213,8 +214,8 @@
   methodOop result_oop = klass->uncached_lookup_method(name, signature);
   result = methodHandle(THREAD, result_oop);
   while (!result.is_null() && result->is_static()) {
-    klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
-    result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature));
+    KlassHandle super_klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super());
+    result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature));
   }
 }
 
--- a/src/share/vm/oops/cpCacheOop.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/oops/cpCacheOop.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -231,14 +231,13 @@
       // virtual method in java.lang.Object. This is a corner case in the spec
       // but is presumably legal. javac does not generate this code.
       //
-      // We set bytecode_1() to _invokeinterface, because that is the
-      // bytecode # used by the interpreter to see if it is resolved.
+      // We do not set bytecode_1() to _invokeinterface, because that is the
+      // bytecode # used by the interpreter to see if it is resolved.  In this
+      // case, the method gets reresolved with caller for each interface call
+      // because the actual selected method may not be public.
+      //
       // We set bytecode_2() to _invokevirtual.
       // See also interpreterRuntime.cpp. (8/25/2000)
-      // Only set resolved for the invokeinterface case if method is public.
-      // Otherwise, the method needs to be reresolved with caller for each
-      // interface call.
-      if (method->is_public()) set_bytecode_1(invoke_code);
     } else {
       assert(invoke_code == Bytecodes::_invokevirtual, "");
     }
--- a/src/share/vm/oops/instanceKlass.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/oops/instanceKlass.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1046,11 +1046,7 @@
 }
 #endif
 
-methodOop instanceKlass::find_method(Symbol* name, Symbol* signature) const {
-  return instanceKlass::find_method(methods(), name, signature);
-}
-
-methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) {
+static int binary_search(objArrayOop methods, Symbol* name) {
   int len = methods->length();
   // methods are sorted, so do binary search
   int l = 0;
@@ -1061,43 +1057,100 @@
     assert(m->is_method(), "must be method");
     int res = m->name()->fast_compare(name);
     if (res == 0) {
-      // found matching name; do linear search to find matching signature
-      // first, quick check for common case
-      if (m->signature() == signature) return m;
-      // search downwards through overloaded methods
-      int i;
-      for (i = mid - 1; i >= l; i--) {
-        methodOop m = (methodOop)methods->obj_at(i);
-        assert(m->is_method(), "must be method");
-        if (m->name() != name) break;
-        if (m->signature() == signature) return m;
-      }
-      // search upwards
-      for (i = mid + 1; i <= h; i++) {
-        methodOop m = (methodOop)methods->obj_at(i);
-        assert(m->is_method(), "must be method");
-        if (m->name() != name) break;
-        if (m->signature() == signature) return m;
-      }
-      // not found
-#ifdef ASSERT
-      int index = linear_search(methods, name, signature);
-      assert(index == -1, err_msg("binary search should have found entry %d", index));
-#endif
-      return NULL;
+      return mid;
     } else if (res < 0) {
       l = mid + 1;
     } else {
       h = mid - 1;
     }
   }
+  return -1;
+}
+
+// find_method looks up the name/signature in the local methods array
+methodOop instanceKlass::find_method(Symbol* name, Symbol* signature) const {
+  return instanceKlass::find_method(methods(), name, signature);
+}
+
+// find_instance_method looks up the name/signature in the local methods array
+// and skips over static methods
+methodOop instanceKlass::find_instance_method(Symbol* name, Symbol* signature) {
+  return instanceKlass::find_instance_method(methods(), name, signature);
+}
+
+// find_instance_method looks up the name/signature in the local methods array
+// and skips over static methods
+methodOop instanceKlass::find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature) {
+  methodOop meth = instanceKlass::find_method_impl(methods, name, signature, true);
+  return meth;
+}
+
+// find_method looks up the name/signature in the local methods array
+methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) {
+  return instanceKlass::find_method_impl(methods, name, signature, false);
+}
+
+methodOop instanceKlass::find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) {
+  int hit = find_method_index(methods, name, signature, skipping_static);
+  return hit >= 0 ? (methodOop) methods->obj_at(hit): NULL;
+}
+
+bool instanceKlass::method_matches(methodOop m, Symbol* signature, bool skipping_static) {
+    return (m->signature() == signature) && (!skipping_static || !m->is_static());
+}
+
+// Used indirectly by find_method
+// find_method_index looks in the local methods array to return the index
+// of the matching name/signature
+int instanceKlass::find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) {
+  int hit = binary_search(methods, name);
+  if (hit != -1) {
+    methodOop m = (methodOop) methods->obj_at(hit);
+
+    // Do linear search to find matching signature.  First, quick check
+    // for common case
+    if (method_matches(m, signature, skipping_static)) return hit;
+    // search downwards through overloaded methods
+    int i;
+    for (i = hit - 1; i >= 0; --i) {
+        methodOop m = (methodOop) methods->obj_at(i);
+        assert(m->is_method(), "must be method");
+        if (m->name() != name) break;
+        if (method_matches(m, signature, skipping_static)) return i;
+    }
+    // search upwards
+    for (i = hit + 1; i < methods->length(); ++i) {
+        methodOop m = (methodOop) methods->obj_at(i);
+        assert(m->is_method(), "must be method");
+        if (m->name() != name) break;
+        if (method_matches(m, signature, skipping_static)) return i;
+    }
+    // not found
 #ifdef ASSERT
-  int index = linear_search(methods, name, signature);
-  assert(index == -1, err_msg("binary search should have found entry %d", index));
+    int index = skipping_static ? -1 : linear_search(methods, name, signature);
+    assert(index == -1, err_msg("binary search should have found entry %d", index));
 #endif
-  return NULL;
+  }
+  return -1;
+}
+int instanceKlass::find_method_by_name(Symbol* name, int* end) {
+  return find_method_by_name(methods(), name, end);
 }
 
+int instanceKlass::find_method_by_name(objArrayOop methods, Symbol* name, int* end_ptr) {
+  assert(end_ptr != NULL, "just checking");
+  int start = binary_search(methods, name);
+  int end = start + 1;
+  if (start != -1) {
+    while (start - 1 >= 0 && ((methodOop)(methods->obj_at(start - 1)))->name() == name) --start;
+    while (end < methods->length() && ((methodOop)(methods->obj_at(end)))->name() == name) ++end;
+    *end_ptr = end;
+    return start;
+  }
+  return -1;
+}
+
+// lookup_method searches both the local methods array and all superclasses methods arrays
 methodOop instanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
   klassOop klass = as_klassOop();
   while (klass != NULL) {
--- a/src/share/vm/oops/instanceKlass.hpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/oops/instanceKlass.hpp	Thu Apr 19 17:55:26 2018 +0100
@@ -494,6 +494,16 @@
   methodOop find_method(Symbol* name, Symbol* signature) const;
   static methodOop find_method(objArrayOop methods, Symbol* name, Symbol* signature);
 
+  // find a local method, but skip static methods
+  methodOop find_instance_method(Symbol* name, Symbol* signature);
+  static methodOop find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature);
+
+  // true if method matches signature and conforms to skipping_X conditions.
+  static bool method_matches(methodOop m, Symbol* signature, bool skipping_static);
+
+  // find a local method index in default_methods (returns -1 if not found)
+  static int find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static);
+
   // lookup operation (returns NULL if not found)
   methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const;
 
@@ -501,6 +511,13 @@
   // (returns NULL if not found)
   methodOop lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const;
 
+  // Find method indices by name.  If a method with the specified name is
+  // found the index to the first method is returned, and 'end' is filled in
+  // with the index of first non-name-matching method.  If no method is found
+  // -1 is returned.
+  int find_method_by_name(Symbol* name, int* end);
+  static int find_method_by_name(objArrayOop methods, Symbol* name, int* end);
+
   // constant pool
   constantPoolOop constants() const        { return _constants; }
   void set_constants(constantPoolOop c)    { oop_store_without_check((oop*) &_constants, (oop) c); }
@@ -973,6 +990,9 @@
   // Returns the array class with this class as element type
   klassOop array_klass_impl(bool or_null, TRAPS);
 
+  // find a local method (returns NULL if not found)
+  static methodOop find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static);
+
 public:
   // sharing support
   virtual void remove_unshareable_info();
--- a/src/share/vm/oops/klass.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/oops/klass.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -36,6 +36,19 @@
 #include "runtime/atomic.hpp"
 #include "trace/traceMacros.hpp"
 
+bool Klass::is_cloneable() const {
+  return _access_flags.is_cloneable() ||
+         is_subtype_of(SystemDictionary::Cloneable_klass());
+}
+
+void Klass::set_is_cloneable() {
+  if (oop_is_instance() && instanceKlass::cast(this->as_klassOop())->reference_type() != REF_NONE) {
+    // Reference cloning should not be intrinsified and always happen in JVM_Clone.
+  } else {
+    _access_flags.set_is_cloneable();
+  }
+}
+
 void Klass::set_name(Symbol* n) {
   _name = n;
   if (_name != NULL) _name->increment_refcount();
--- a/src/share/vm/oops/klass.hpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/oops/klass.hpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -673,8 +673,8 @@
   bool has_final_method() const         { return _access_flags.has_final_method(); }
   void set_has_finalizer()              { _access_flags.set_has_finalizer(); }
   void set_has_final_method()           { _access_flags.set_has_final_method(); }
-  bool is_cloneable() const             { return _access_flags.is_cloneable(); }
-  void set_is_cloneable()               { _access_flags.set_is_cloneable(); }
+  bool is_cloneable() const;
+  void set_is_cloneable();
   bool has_vanilla_constructor() const  { return _access_flags.has_vanilla_constructor(); }
   void set_has_vanilla_constructor()    { _access_flags.set_has_vanilla_constructor(); }
   bool has_miranda_methods () const     { return access_flags().has_miranda_methods(); }
--- a/src/share/vm/oops/methodOop.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/oops/methodOop.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1122,13 +1122,13 @@
   // because we are not loading from core libraries
   // exception: the AES intrinsics come from lib/ext/sunjce_provider.jar
   // which does not use the class default class loader so we check for its loader here
-  if ((instanceKlass::cast(holder)->class_loader() != NULL) &&
-       instanceKlass::cast(holder)->class_loader()->klass()->klass_part()->name() != vmSymbols::sun_misc_Launcher_ExtClassLoader()) {
+  instanceKlass* ik = instanceKlass::cast(holder);
+  if ((ik->class_loader() != NULL) && !SystemDictionary::is_ext_class_loader(ik->class_loader())) {
     return vmSymbols::NO_SID;   // regardless of name, no intrinsics here
   }
 
   // see if the klass name is well-known:
-  Symbol* klass_name = instanceKlass::cast(holder)->name();
+  Symbol* klass_name = ik->name();
   return vmSymbols::find_sid(klass_name);
 }
 
--- a/src/share/vm/prims/jvm.cpp	Thu Apr 19 04:49:54 2018 +0100
+++ b/src/share/vm/prims/jvm.cpp	Thu Apr 19 17:55:26 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -31,6 +31,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/referenceType.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/fieldStreams.hpp"
 #include "oops/instanceKlass.hpp"
@@ -82,6 +83,10 @@
 # include "jvm_bsd.h"
 #endif
 
+#ifndef SERIALGC
+#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+#endif // !SERIALGC
+
 #include <errno.h>
 
 #ifndef USDT2
@@ -574,6 +579,28 @@
 JVM_END
 
 
+static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {
+  // If G1 is enabled then we need to register a non-null referent
+  // with the SATB barrier.
+#ifndef SERIALGC
+  if (UseG1GC) {
+    oop referent = java_lang_ref_Reference::referent(clone);
+    if (referent != NULL) {
+      G1SATBCardTableModRefBS::enqueue(referent);
+    }
+  }
+#endif // !SERIALGC
+  if ((java_lang_ref_Reference::next(clone) != NULL) ||
+      (java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) {
+    // If the source has been enqueued or is being enqueued, don't
+    // register the clone with a queue.
+    java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue());
+  }
+  // discovered and next are list links; the clone is not in those lists.
+  java_lang_ref_Reference::set_discovered(clone, NULL);
+  java_lang_ref_Reference::set_next(clone, NULL);
+}
+
 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
   JVMWrapper("JVM_Clone");
   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
@@ -599,12 +626,17 @@
   }
 
   // Make shallow object copy
+  ReferenceType ref_type = REF_NONE;
   const int size = obj->size();
   oop new_obj_oop = NULL;
   if (obj->is_javaArray()) {
     const int length = ((arrayOop)obj())->length();
     new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
   } else {
+    ref_type = instanceKlass::cast(klass())->reference_type();
+    assert((ref_type == REF_NONE) ==
+           !klass->is_subclass_of(SystemDictionary::Reference_klass()),
+           "invariant");
     new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
   }
   // 4839641 (4840070): We must do an oop-atomic copy, because if another thread
@@ -627,6 +659,12 @@
   assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
   bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));
 
+  // If cloning a Reference, set Reference fields to a safe state.
+  // Fixup must be completed before any safepoint.
+  if (ref_type != REF_NONE) {
+    fixup_cloned_reference(ref_type, obj(), new_obj_oop);
+  }
+
   Handle new_obj(THREAD, new_obj_oop);
   // Special handling for MemberNames.  Since they contain Method* metadata, they
   // must be registered so that RedefineClasses can fix metadata contained in them.
@@ -3488,8 +3526,9 @@
 JVM_END
 
 
-// Return the first non-null class loader up the execution stack, or null
-// if only code from the null class loader is on the stack.
+// Returns first non-privileged class loader on the stack (excluding reflection
+// generated frames) or null if only classes loaded by the boot class loader
+// and extension class loader are found on the stack.
 
 JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env))
   for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) {
@@ -3497,7 +3536,7 @@
     vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection
     klassOop holder = vfst.method()->method_holder();
     oop loader = instanceKlass::cast(holder)->class_loader();
-    if (loader != NULL) {
+    if (loader != NULL && !SystemDictionary::is_ext_class_loader(loader)) {
       return JNIHandles::make_local(env, loader);
     }
   }