diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/prims/jvm.cpp --- 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 -static void fixup_clone_referent(oop src, oop new_obj) { - typedef HeapAccess 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(src, clone); - } else { - fixup_clone_referent(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.