# HG changeset patch # User kbarrett # Date 1516649266 18000 # Node ID b3e39bc817a741370c386f0d6e68b5fd7c46d9c5 # Parent a74480137e6e6656c5e850aa87fdb01a4b9ef324 8192025: Less referential references Reviewed-by: coleenp, eosterlund, mchung, ahgross, rhalade diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/classfile/javaClasses.cpp Mon Jan 22 14:27:46 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, 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 @@ -2373,6 +2373,31 @@ *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() { + klassOop 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_MethodHandle @@ -2942,6 +2967,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; @@ -3141,6 +3168,8 @@ } sun_misc_AtomicLongCSImpl::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 a74480137e6e -r b3e39bc817a7 src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/classfile/javaClasses.hpp Mon Jan 22 14:27:46 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, 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 @@ -849,6 +849,12 @@ static HeapWord* discovered_addr(oop ref) { return ref->obj_field_addr(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(); @@ -881,6 +887,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 #define METHODHANDLE_INJECTED_FIELDS(macro) \ diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/classfile/systemDictionary.cpp Mon Jan 22 14:27:46 2018 -0500 @@ -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 @@ -2008,6 +2008,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); diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Jan 22 14:27:46 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, 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 @@ -125,6 +125,7 @@ template(PhantomReference_klass, java_lang_ref_PhantomReference, Pre) \ template(Cleaner_klass, sun_misc_Cleaner, Pre) \ template(Finalizer_klass, java_lang_ref_Finalizer, Pre) \ + template(ReferenceQueue_klass, java_lang_ref_ReferenceQueue, Pre) \ \ template(Thread_klass, java_lang_Thread, Pre) \ template(ThreadGroup_klass, java_lang_ThreadGroup, Pre) \ diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Jan 22 14:27:46 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, 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 @@ -82,6 +82,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") \ @@ -384,6 +385,8 @@ template(array_klass_name, "array_klass") \ template(oop_size_name, "oop_size") \ template(static_oop_field_count_name, "static_oop_field_count") \ + template(referencequeue_null_name, "NULL") \ + template(referencequeue_enqueued_name, "ENQUEUED") \ \ /* non-intrinsic name/signature pairs: */ \ template(register_method_name, "register") \ @@ -473,6 +476,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(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \ template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \ template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \ diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/oops/klass.cpp --- a/src/share/vm/oops/klass.cpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/oops/klass.cpp Mon Jan 22 14:27:46 2018 -0500 @@ -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 @@ -35,6 +35,19 @@ #include "oops/oop.inline2.hpp" #include "runtime/atomic.hpp" +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->as_klassOop())->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(); diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/oops/klass.hpp Mon Jan 22 14:27:46 2018 -0500 @@ -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 @@ -673,8 +673,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(); } diff -r a74480137e6e -r b3e39bc817a7 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Mar 15 17:02:56 2018 +0300 +++ b/src/share/vm/prims/jvm.cpp Mon Jan 22 14:27:46 2018 -0500 @@ -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 @@ -78,6 +78,10 @@ # include "jvm_bsd.h" #endif +#if INCLUDE_ALL_GCS +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" +#endif // INCLUDE_ALL_GCS + #include #ifndef USDT2 @@ -543,6 +547,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)); @@ -569,11 +595,16 @@ // Make shallow object copy const int size = obj->size(); + ReferenceType ref_type = REF_NONE; oop new_obj = NULL; if (obj->is_javaArray()) { const int length = ((arrayOop)obj())->length(); new_obj = 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 = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); } // 4839641 (4840070): We must do an oop-atomic copy, because if another thread @@ -596,6 +627,12 @@ assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); bs->write_region(MemRegion((HeapWord*)new_obj, 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); + } + // Caution: this involves a java upcall, so the clone should be // "gc-robust" by this stage. if (klass->has_finalizer()) {