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
--- 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.