# HG changeset patch # User kbarrett # Date 1525827598 14400 # Node ID 50c0d24d397197392e1630214f81a19a38ca54f4 # Parent e64e3cd120b7a886d33034012a530b499882b7fc 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 diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/classfile/javaClasses.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(); diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/classfile/javaClasses.hpp --- 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; diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/classfile/javaClasses.inline.hpp --- 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(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; } diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/classfile/systemDictionary.cpp --- 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); diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/classfile/systemDictionary.hpp --- 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 ) \ diff -r e64e3cd120b7 -r 50c0d24d3971 src/hotspot/share/classfile/vmSymbols.hpp --- 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, "") \ template(init_lock_name, "") \ - 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;") \ 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.