changeset 8660:bd08b7f27e11 jdk8u171-b11-aarch32-180511

Merge
author snazarki
date Fri, 11 May 2018 14:35:42 +0300
parents e6d2a4f9233d 23addae1b843
children 87becc0b4eb2
files .hgtags src/share/vm/classfile/verifier.cpp
diffstat 17 files changed, 225 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Feb 22 11:13:05 2018 +0300
+++ b/.hgtags	Fri May 11 14:35:42 2018 +0300
@@ -1048,6 +1048,11 @@
 59be99637c595046499bb636a796a6c7aa66e1c0 jdk8u152-b16-aarch32-171102
 f8b1fb10236456e48dd8d49f58c4e59fdda534e4 jdk8u152-b17-aarch32-171102
 98b4b0661837817cc39047000e1a7efa6015af7c jdk8u152-b16
+91894ffc746c1681172aaa37e2cf5bff69560f20 jdk8u152-b31
+d278f122e65dfb5d239ed420a534df75f527a504 jdk8u152-b32
+c066fe30d0a141b14ab7788cbbd35eba11196e72 jdk8u152-b33
+12a0cebfae93a638dc69a34f8276e1ef43b11b7a jdk8u152-b34
+f6719c3d02787da6e232703f61efc931ead7683b jdk8u152-b35
 2d5100bddeb80cf767485b787fc3051311e3d7b9 jdk8u151-b00
 596b584c68b73ec635347807571463580deb955f jdk8u151-b01
 1f6f436360d5cd375b806aec1c78abb8fcb4e5f6 jdk8u151-b02
@@ -1140,3 +1145,16 @@
 c3618e1cdefdda6c262f082791bfd988e0e9d9c9 jdk8u162-b10
 39e2895b795aded8b584626fb019d35f12e9d1e7 jdk8u162-b11
 2dc629cf3eccfc0c8af9fbb53e7d60b1a91d0ef2 jdk8u162-b12-aarch32-180220
+69aec2ca5d905dde1d0f29a89076d02a531808a3 jdk8u162-b12
+caac74fe3cfa9a8c859c28c97d1046a58252af27 jdk8u162-b31
+a17bab9405474602b18cd62e060a09b17d6413ac jdk8u171-b00
+ebfd57cc21e6b7f0c22b17c666b6b28c9340e207 jdk8u171-b01
+1acd7c1b80241def8fac90f70b0df16356adad47 jdk8u171-b02
+5587cde50bbc2aa031aefb47eaa36b041f5e7c4b jdk8u171-b03
+99ef466523302cfbd00496cf6575a00c8637b884 jdk8u171-b04
+08326a76b14888908523cf2bb1105de63b43544d jdk8u171-b05
+4e1445535b6d9c25ed34aba2768139da283847d0 jdk8u171-b06
+fd0e42431b94c889b3fea8d8aad048f51d559761 jdk8u171-b07
+56123fdca84a3b253b8ea6f72be85bd2ebf39fd0 jdk8u171-b08
+4fefe015a728955c9c25ef79e51501b68839ae75 jdk8u171-b09
+6d890180aeb43ee727b2f2cc0952ae0e1b8566c8 jdk8u171-b10
--- a/src/cpu/zero/vm/methodHandles_zero.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/cpu/zero/vm/methodHandles_zero.cpp	Fri May 11 14:35:42 2018 +0300
@@ -180,3 +180,9 @@
     return NULL;
   }
 }
+
+#ifndef PRODUCT
+void MethodHandles::trace_method_handle(MacroAssembler* _masm, const char* adaptername) {
+  // This is just a stub.
+}
+#endif //PRODUCT
--- a/src/share/vm/classfile/javaClasses.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri May 11 14:35:42 2018 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -2679,6 +2679,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() {
+  Klass* 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;
@@ -3197,6 +3223,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;
@@ -3378,6 +3406,8 @@
   if (JDK_Version::is_jdk18x_version())
     java_lang_reflect_Parameter::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 Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri May 11 14:35:42 2018 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -929,6 +929,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();
@@ -962,6 +968,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 Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/systemDictionary.cpp	Fri May 11 14:35:42 2018 +0300
@@ -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
@@ -1927,6 +1927,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 Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/systemDictionary.hpp	Fri May 11 14:35:42 2018 +0300
@@ -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
@@ -130,6 +130,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                 ) \
--- a/src/share/vm/classfile/verificationType.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/verificationType.cpp	Fri May 11 14:35:42 2018 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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
@@ -63,6 +63,7 @@
         name(), Handle(THREAD, klass->class_loader()),
         Handle(THREAD, klass->protection_domain()), true, CHECK_false);
     KlassHandle this_class(THREAD, obj);
+    klass->class_loader_data()->record_dependency(obj, CHECK_false);
 
     if (this_class->is_interface() && (!from_field_is_protected ||
         from.name() != vmSymbols::java_lang_Object())) {
@@ -74,6 +75,7 @@
       Klass* from_class = SystemDictionary::resolve_or_fail(
           from.name(), Handle(THREAD, klass->class_loader()),
           Handle(THREAD, klass->protection_domain()), true, CHECK_false);
+      klass->class_loader_data()->record_dependency(from_class, CHECK_false);
       bool result = InstanceKlass::cast(from_class)->is_subclass_of(this_class());
       if (result && DumpSharedSpaces) {
         if (klass()->is_subclass_of(from_class) && klass()->is_subclass_of(this_class())) {
--- a/src/share/vm/classfile/verifier.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/verifier.cpp	Fri May 11 14:35:42 2018 +0300
@@ -1952,9 +1952,11 @@
   oop loader = current_class()->class_loader();
   oop protection_domain = current_class()->protection_domain();
 
-  return SystemDictionary::resolve_or_fail(
+  Klass* kls = SystemDictionary::resolve_or_fail(
     name, Handle(THREAD, loader), Handle(THREAD, protection_domain),
     true, CHECK_NULL);
+  current_class()->class_loader_data()->record_dependency(kls, CHECK_NULL);
+  return kls;
 }
 
 bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
--- a/src/share/vm/classfile/vmSymbols.hpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri May 11 14:35:42 2018 +0300
@@ -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
@@ -81,6 +81,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")            \
@@ -417,6 +418,8 @@
   template(getProtectionDomain_name,                  "getProtectionDomain")                      \
   template(getProtectionDomain_signature,             "(Ljava/security/CodeSource;)Ljava/security/ProtectionDomain;") \
   template(url_code_signer_array_void_signature,      "(Ljava/net/URL;[Ljava/security/CodeSigner;)V") \
+  template(referencequeue_null_name,                  "NULL")                                     \
+  template(referencequeue_enqueued_name,              "ENQUEUED")                                 \
                                                                                                   \
   /* non-intrinsic name/signature pairs: */                                                       \
   template(register_method_name,                      "register")                                 \
@@ -508,6 +511,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(executable_signature,                      "Ljava/lang/reflect/Executable;")                           \
   template(concurrenthashmap_signature,               "Ljava/util/concurrent/ConcurrentHashMap;")                 \
   template(String_StringBuilder_signature,            "(Ljava/lang/String;)Ljava/lang/StringBuilder;")            \
--- a/src/share/vm/code/dependencies.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/code/dependencies.cpp	Fri May 11 14:35:42 2018 +0300
@@ -793,6 +793,14 @@
     _signature = NULL;
     initialize(participant);
   }
+  ClassHierarchyWalker(Klass* 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.
@@ -891,6 +899,24 @@
       // Search class hierarchy first.
       Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature);
       if (!Dependencies::is_concrete_method(m, k)) {
+        // Check for re-abstraction of method
+        if (!k->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);
+          Klass* w = wf.find_witness_subtype(k);
+          if (w != NULL) {
+            Method* wm = InstanceKlass::cast(w)->find_instance_method(_name, _signature);
+            if (!Dependencies::is_concrete_method(wm, w)) {
+              // 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;
+            }
+          }
+        }
         // Check interface defaults also, if any exist.
         Array<Method*>* default_methods = InstanceKlass::cast(k)->default_methods();
         if (default_methods == NULL)
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Fri May 11 14:35:42 2018 +0300
@@ -2569,13 +2569,35 @@
 
         // this could definitely be cleaned up QQQ
         Method* callee;
-        Klass* iclass = cache->f1_as_klass();
-        // InstanceKlass* interface = (InstanceKlass*) iclass;
+        Method *interface_method = cache->f2_as_interface_method();
+        InstanceKlass* iclass = interface_method->method_holder();
+
         // get receiver
         int parms = cache->parameter_size();
         oop rcvr = STACK_OBJECT(-parms);
         CHECK_NULL(rcvr);
         InstanceKlass* int2 = (InstanceKlass*) rcvr->klass();
+
+        // Receiver subtype check against resolved interface klass (REFC).
+        {
+          Klass* refc = cache->f1_as_klass();
+          itableOffsetEntry* scan;
+          for (scan = (itableOffsetEntry*) int2->start_of_itable();
+               scan->interface_klass() != NULL;
+               scan++) {
+            if (scan->interface_klass() == refc) {
+              break;
+            }
+          }
+          // Check that the entry is non-null.  A null entry means
+          // that the receiver class doesn't implement the
+          // interface, and wasn't the same as when the caller was
+          // compiled.
+          if (scan->interface_klass() == NULL) {
+            VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "", note_no_trap);
+          }
+        }
+
         itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable();
         int i;
         for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) {
@@ -2587,7 +2609,8 @@
         if (i == int2->itable_length()) {
           VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "", note_no_trap);
         }
-        int mindex = cache->f2_as_index();
+        int mindex = interface_method->itable_index();
+
         itableMethodEntry* im = ki->first_method_entry(rcvr->klass());
         callee = im[mindex].method();
         if (callee == NULL) {
--- a/src/share/vm/oops/cpCache.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/oops/cpCache.cpp	Fri May 11 14:35:42 2018 +0300
@@ -226,14 +226,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/klass.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/oops/klass.cpp	Fri May 11 14:35:42 2018 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -48,6 +48,19 @@
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 #endif // INCLUDE_ALL_GCS
 
+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)->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 Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/oops/klass.hpp	Fri May 11 14:35:42 2018 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -582,8 +582,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/prims/jvm.cpp	Thu Feb 22 11:13:05 2018 +0300
+++ b/src/share/vm/prims/jvm.cpp	Fri May 11 14:35:42 2018 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoader.hpp"
+#include "classfile/classLoaderData.inline.hpp"
 #include "classfile/classLoaderExt.hpp"
 #include "classfile/javaAssertions.hpp"
 #include "classfile/javaClasses.hpp"
@@ -37,6 +38,7 @@
 #include "gc_interface/collectedHeap.inline.hpp"
 #include "interpreter/bytecode.hpp"
 #include "memory/oopFactory.hpp"
+#include "memory/referenceType.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/fieldStreams.hpp"
 #include "oops/instanceKlass.hpp"
@@ -89,6 +91,10 @@
 # include "jvm_bsd.h"
 #endif
 
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
+#endif // INCLUDE_ALL_GCS
+
 #include <errno.h>
 
 #ifndef USDT2
@@ -577,6 +583,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.
+#if INCLUDE_ALL_GCS
+  if (UseG1GC) {
+    oop referent = java_lang_ref_Reference::referent(clone);
+    if (referent != NULL) {
+      G1SATBCardTableModRefBS::enqueue(referent);
+    }
+  }
+#endif // INCLUDE_ALL_GCS
+  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));
@@ -602,12 +630,17 @@
   }
 
   // Make shallow object copy
+  ReferenceType ref_type = REF_NONE;
   const int size = obj->size();
   oop new_obj_oop = NULL;
   if (obj->is_array()) {
     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);
   }
 
@@ -631,6 +664,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.
@@ -952,6 +991,12 @@
   Handle h_prot  (THREAD, protection_domain);
   jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
                                                h_prot, true, thread);
+  if (result != NULL) {
+    oop mirror = JNIHandles::resolve_non_null(result);
+    Klass* to_class = java_lang_Class::as_Klass(mirror);
+    ClassLoaderData* cld = ClassLoaderData::class_loader_data(h_loader());
+    cld->record_dependency(to_class, CHECK_NULL);
+  }
 
   if (TraceClassResolution && result != NULL) {
     // this function is generally only used for class loading during verification.
@@ -3654,15 +3699,16 @@
 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()) {
     // UseNewReflection
     vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection
     oop loader = vfst.method()->method_holder()->class_loader();
-    if (loader != NULL) {
+    if (loader != NULL && !SystemDictionary::is_ext_class_loader(loader)) {
       return JNIHandles::make_local(env, loader);
     }
   }
--- a/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java	Thu Feb 22 11:13:05 2018 +0300
+++ b/test/gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java	Fri May 11 14:35:42 2018 +0300
@@ -37,6 +37,11 @@
 
 public class CompressedClassSpaceSizeInJmapHeap {
     public static void main(String[] args) throws Exception {
+        if (!Platform.shouldSAAttach()) {
+            System.out.println("SA attach not expected to work - test skipped.");
+            return;
+        }
+
         String pid = Integer.toString(ProcessTools.getProcessId());
 
         JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
--- a/test/runtime/RedefineTests/RedefineInterfaceCall.java	Thu Feb 22 11:13:05 2018 +0300
+++ b/test/runtime/RedefineTests/RedefineInterfaceCall.java	Fri May 11 14:35:42 2018 +0300
@@ -25,16 +25,13 @@
  * @test
  * @bug 8174962
  * @summary Redefine class with interface method call
- * @library /testlibrary /test/lib
- * @modules java.base/jdk.internal.misc
- * @modules java.compiler
- *          java.instrument
- *          jdk.jartool/sun.tools.jar
+ * @library /testlibrary
+ * @build RedefineClassHelper
  * @run main RedefineClassHelper
- * @run main/othervm -javaagent:redefineagent.jar RedefineInterfaceCall
+ * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=3174407 RedefineInterfaceCall
  */
 
-import static jdk.testlibrary.Asserts.assertEquals;
+import static com.oracle.java.testlibrary.Asserts.assertEquals;
 
 interface I1 { default int m() { return 0; } }
 interface I2 extends I1 {}