--- old/src/share/vm/gc/g1/g1OopClosures.hpp 2017-04-25 12:03:57.370531226 +0200 +++ new/src/share/vm/gc/g1/g1OopClosures.hpp 2017-04-25 12:03:57.222525408 +0200 @@ -56,7 +56,8 @@ ~G1ParClosureSuper() { } public: - virtual bool apply_to_weak_ref_discovered_field() { return true; } + // This closure needs special handling for InstanceRefKlass. + virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; } }; class G1ParPushHeapRSClosure : public G1ParClosureSuper { @@ -189,8 +190,6 @@ _from = from; } - bool apply_to_weak_ref_discovered_field() { return true; } - bool self_forwarded(oop obj) { markOop m = obj->mark(); bool result = (m->is_marked() && ((oop)m->decode_pointer() == obj)); @@ -202,6 +201,9 @@ template inline void do_oop_nv(T* p); virtual inline void do_oop(narrowOop* p); virtual inline void do_oop(oop* p); + + // This closure needs special handling for InstanceRefKlass. + virtual ReferenceIterationMode reference_iteration_mode() { return DO_DISCOVERED_AND_DISCOVERY; } }; #endif // SHARE_VM_GC_G1_G1OOPCLOSURES_HPP --- old/src/share/vm/memory/iterator.hpp 2017-04-25 12:03:58.006556227 +0200 +++ new/src/share/vm/memory/iterator.hpp 2017-04-25 12:03:57.854550252 +0200 @@ -68,8 +68,9 @@ // Iteration of InstanceRefKlasses differ depending on the closure, // the below enum describes the different alternatives. enum ReferenceIterationMode { - DO_DISCOVERY, // Apply closure and discover references - DO_FIELDS // Apply closure to all fields + DO_DISCOVERY, // Apply closure and discover references + DO_DISCOVERED_AND_DISCOVERY, // Apply closure to discovered field and do discovery + DO_FIELDS // Apply closure to all fields }; // The default iteration mode is to do discovery. @@ -102,7 +103,6 @@ // True iff this closure may be safely applied more than once to an oop // location without an intervening "major reset" (like the end of a GC). virtual bool idempotent() { return false; } - virtual bool apply_to_weak_ref_discovered_field() { return false; } #ifdef ASSERT // Default verification of each visited oop field. --- old/src/share/vm/oops/instanceRefKlass.hpp 2017-04-25 12:03:58.678582643 +0200 +++ new/src/share/vm/oops/instanceRefKlass.hpp 2017-04-25 12:03:58.538577140 +0200 @@ -123,6 +123,12 @@ template static void oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains); + // Used for a special case in G1 where the closure needs to be applied + // to the discovered field. Reference discovery is also done if the + // closure provides a ReferenceProcessor. + template + static void oop_oop_iterate_discovered_and_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains); + // Apply the closure to all fields. No reference discovery is done. template static void oop_oop_iterate_fields(oop obj, OopClosureType* closure, Contains& contains); --- old/src/share/vm/oops/instanceRefKlass.inline.hpp 2017-04-25 12:03:59.302607173 +0200 +++ new/src/share/vm/oops/instanceRefKlass.inline.hpp 2017-04-25 12:03:59.166601827 +0200 @@ -79,11 +79,6 @@ void InstanceRefKlass::oop_oop_iterate_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) { log_develop_trace(gc, ref)("Process reference with discovery " PTR_FORMAT, p2i(obj)); - // Special case for some closures. - if (closure->apply_to_weak_ref_discovered_field()) { - do_discovered(obj, closure, contains); - } - // Try to discover reference and return if it succeeds. if (try_discover(obj, type, closure)) { return; @@ -116,11 +111,22 @@ } template +void InstanceRefKlass::oop_oop_iterate_discovered_and_discovery(oop obj, ReferenceType type, OopClosureType* closure, Contains& contains) { + // Explicitly apply closure to the discovered field. + do_discovered(obj, closure, contains); + // Then do normal reference processing with discovery. + oop_oop_iterate_discovery(obj, type, closure, contains); +} + +template void InstanceRefKlass::oop_oop_iterate_ref_processing_specialized(oop obj, OopClosureType* closure, Contains& contains) { switch (closure->reference_iteration_mode()) { case ExtendedOopClosure::DO_DISCOVERY: oop_oop_iterate_discovery(obj, reference_type(), closure, contains); break; + case ExtendedOopClosure::DO_DISCOVERED_AND_DISCOVERY: + oop_oop_iterate_discovered_and_discovery(obj, reference_type(), closure, contains); + break; case ExtendedOopClosure::DO_FIELDS: oop_oop_iterate_fields(obj, closure, contains); break;