8202631: JVM_Clone to throw CloneNotSupportException for Reference object
authorkbarrett
Tue, 08 May 2018 20:59:58 -0400
changeset 50063 50c0d24d3971
parent 50062 e64e3cd120b7
child 50064 e4a7bacf99b1
8202631: JVM_Clone to throw CloneNotSupportException for Reference object Summary: JVM_Clone throws; delete previous partial support for cloning. Reviewed-by: eosterlund, mchung, dholmes, coleenp
src/hotspot/share/classfile/javaClasses.cpp
src/hotspot/share/classfile/javaClasses.hpp
src/hotspot/share/classfile/javaClasses.inline.hpp
src/hotspot/share/classfile/systemDictionary.cpp
src/hotspot/share/classfile/systemDictionary.hpp
src/hotspot/share/classfile/vmSymbols.hpp
src/hotspot/share/prims/jvm.cpp
--- a/src/hotspot/share/classfile/javaClasses.cpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Tue May 08 20:59:58 2018 -0400
@@ -3556,34 +3556,6 @@
   base->long_field_put(static_clock_offset, value);
 }
 
-// Support for java_lang_ref_ReferenceQueue
-
-oop java_lang_ref_ReferenceQueue::NULL_queue() {
-  InstanceKlass* ik = 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 = SystemDictionary::ReferenceQueue_klass();
-  oop mirror = ik->java_mirror();
-  return mirror->obj_field(static_ENQUEUED_queue_offset);
-}
-
-void java_lang_ref_ReferenceQueue::compute_offsets() {
-  InstanceKlass* k = SystemDictionary::ReferenceQueue_klass();
-  compute_offset(static_NULL_queue_offset,
-                 k,
-                 vmSymbols::referencequeue_null_name(),
-                 vmSymbols::referencequeue_signature(),
-                 true /* is_static */);
-  compute_offset(static_ENQUEUED_queue_offset,
-                 k,
-                 vmSymbols::referencequeue_enqueued_name(),
-                 vmSymbols::referencequeue_signature(),
-                 true /* is_static */);
-}
-
 // Support for java_lang_invoke_DirectMethodHandle
 
 int java_lang_invoke_DirectMethodHandle::_member_offset;
@@ -4263,8 +4235,6 @@
 int java_lang_ref_Reference::queue_offset;
 int java_lang_ref_Reference::next_offset;
 int java_lang_ref_Reference::discovered_offset;
-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;
@@ -4509,7 +4479,6 @@
   java_lang_StackTraceElement::compute_offsets();
   java_lang_StackFrameInfo::compute_offsets();
   java_lang_LiveStackFrameInfo::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/hotspot/share/classfile/javaClasses.hpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Tue May 08 20:59:58 2018 -0400
@@ -946,20 +946,6 @@
   static void serialize(SerializeClosure* f) NOT_CDS_RETURN;
 };
 
-// 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/hotspot/share/classfile/javaClasses.inline.hpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/classfile/javaClasses.inline.hpp	Tue May 08 20:59:58 2018 -0400
@@ -127,12 +127,6 @@
 HeapWord* java_lang_ref_Reference::discovered_addr_raw(oop ref) {
   return ref->obj_field_addr_raw<HeapWord>(discovered_offset);
 }
-oop java_lang_ref_Reference::queue(oop ref) {
-  return ref->obj_field(queue_offset);
-}
-void java_lang_ref_Reference::set_queue(oop ref, oop value) {
-  return ref->obj_field_put(queue_offset, value);
-}
 bool java_lang_ref_Reference::is_phantom(oop ref) {
   return InstanceKlass::cast(ref->klass())->reference_type() == REF_PHANTOM;
 }
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue May 08 20:59:58 2018 -0400
@@ -2076,8 +2076,6 @@
   InstanceKlass::cast(WK_KLASS(FinalReference_klass))->set_reference_type(REF_FINAL);
   InstanceKlass::cast(WK_KLASS(PhantomReference_klass))->set_reference_type(REF_PHANTOM);
 
-  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/hotspot/share/classfile/systemDictionary.hpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Tue May 08 20:59:58 2018 -0400
@@ -135,7 +135,6 @@
   do_klass(FinalReference_klass,                        java_lang_ref_FinalReference,              Pre                 ) \
   do_klass(PhantomReference_klass,                      java_lang_ref_PhantomReference,            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/hotspot/share/classfile/vmSymbols.hpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Tue May 08 20:59:58 2018 -0400
@@ -86,7 +86,6 @@
   template(java_lang_ref_FinalReference,              "java/lang/ref/FinalReference")             \
   template(java_lang_ref_PhantomReference,            "java/lang/ref/PhantomReference")           \
   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")            \
@@ -439,8 +438,6 @@
   template(module_entry_name,                         "module_entry")                             \
   template(resolved_references_name,                  "<resolved_references>")                    \
   template(init_lock_name,                            "<init_lock>")                              \
-  template(referencequeue_null_name,                  "NULL")                                     \
-  template(referencequeue_enqueued_name,              "ENQUEUED")                                 \
                                                                                                   \
   /* name symbols needed by intrinsics */                                                         \
   VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
@@ -534,8 +531,6 @@
   template(string_signature,                          "Ljava/lang/String;")                                       \
   template(string_array_signature,                    "[Ljava/lang/String;")                                      \
   template(reference_signature,                       "Ljava/lang/ref/Reference;")                                \
-  template(referencequeue_signature,                  "Ljava/lang/ref/ReferenceQueue;")                           \
-  template(sun_misc_Cleaner_signature,                "Lsun/misc/Cleaner;")                                       \
   template(executable_signature,                      "Ljava/lang/reflect/Executable;")                           \
   template(module_signature,                          "Ljava/lang/Module;")                                       \
   template(concurrenthashmap_signature,               "Ljava/util/concurrent/ConcurrentHashMap;")                 \
--- a/src/hotspot/share/prims/jvm.cpp	Tue May 08 17:58:14 2018 -0700
+++ b/src/hotspot/share/prims/jvm.cpp	Tue May 08 20:59:58 2018 -0400
@@ -629,35 +629,6 @@
 JVM_END
 
 
-template<DecoratorSet decorators>
-static void fixup_clone_referent(oop src, oop new_obj) {
-  typedef HeapAccess<decorators> RefAccess;
-  const int ref_offset = java_lang_ref_Reference::referent_offset;
-  oop referent = RefAccess::oop_load_at(src, ref_offset);
-  RefAccess::oop_store_at(new_obj, ref_offset, referent);
-}
-
-static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {
-  // Kludge: After unbarriered clone, re-copy the referent with
-  // correct barriers. This works for current collectors, but won't
-  // work for ZGC and maybe other future collectors or variants of
-  // existing ones (like G1 with concurrent reference processing).
-  if (ref_type == REF_PHANTOM) {
-    fixup_clone_referent<ON_PHANTOM_OOP_REF>(src, clone);
-  } else {
-    fixup_clone_referent<ON_WEAK_OOP_REF>(src, clone);
-  }
-  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));
@@ -676,35 +647,27 @@
 #endif
 
   // Check if class of obj supports the Cloneable interface.
-  // All arrays are considered to be cloneable (See JLS 20.1.5)
-  if (!klass->is_cloneable()) {
+  // All arrays are considered to be cloneable (See JLS 20.1.5).
+  // All j.l.r.Reference classes are considered non-cloneable.
+  if (!klass->is_cloneable() ||
+      (klass->is_instance_klass() &&
+       InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
     ResourceMark rm(THREAD);
     THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
   }
 
   // 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);
   }
 
   HeapAccess<>::clone(obj(), 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);
   // Caution: this involves a java upcall, so the clone should be
   // "gc-robust" by this stage.