--- old/src/hotspot/share/gc/shared/referenceProcessor.hpp 2018-04-17 15:16:34.683917369 +0200 +++ new/src/hotspot/share/gc/shared/referenceProcessor.hpp 2018-04-17 15:16:34.411909000 +0200 @@ -37,18 +37,13 @@ // of java.lang.Reference objects for GC. The interface is useful for supporting // a generational abstraction, in particular when there are multiple // generations that are being independently collected -- possibly -// concurrently and/or incrementally. Note, however, that the +// concurrently and/or incrementally. // ReferenceProcessor class abstracts away from a generational setting -// by using only a heap interval (called "span" below), thus allowing -// its use in a straightforward manner in a general, non-generational -// setting. +// by using a closure that determines whether a given reference or referent are +// subject to this ReferenceProcessor's discovery, thus allowing its use in a +// straightforward manner in a general, non-generational, non-contiguous generation +// (or heap) setting. // -// The basic idea is that each ReferenceProcessor object concerns -// itself with ("weak") reference processing in a specific "span" -// of the heap of interest to a specific collector. Currently, -// the span is a convex interval of the heap, but, efficiency -// apart, there seems to be no reason it couldn't be extended -// (with appropriate modifications) to any "non-convex interval". // forward references class ReferencePolicy; @@ -167,16 +162,14 @@ }; class ReferenceProcessor : public CHeapObj { - - private: size_t total_count(DiscoveredList lists[]) const; - protected: // The SoftReference master timestamp clock static jlong _soft_ref_timestamp_clock; - MemRegion _span; // (right-open) interval of heap - // subject to wkref discovery + BoolObjectClosure* _is_subject_to_discovery; // determines whether a given oop is subject + // to this ReferenceProcessor's discovery + // (and further processing). bool _discovering_refs; // true when discovery enabled bool _discovery_is_atomic; // if discovery is atomic wrt @@ -256,19 +249,10 @@ VoidClosure* complete_gc); // Phase2: remove all those references whose referents are // reachable. - inline void process_phase2(DiscoveredList& refs_list, - BoolObjectClosure* is_alive, - OopClosure* keep_alive, - VoidClosure* complete_gc) { - if (discovery_is_atomic()) { - // complete_gc is ignored in this case for this phase - pp2_work(refs_list, is_alive, keep_alive); - } else { - assert(complete_gc != NULL, "Error"); - pp2_work_concurrent_discovery(refs_list, is_alive, - keep_alive, complete_gc); - } - } + void process_phase2(DiscoveredList& refs_list, + BoolObjectClosure* is_alive, + OopClosure* keep_alive, + VoidClosure* complete_gc); // Work methods in support of process_phase2 void pp2_work(DiscoveredList& refs_list, BoolObjectClosure* is_alive, @@ -311,7 +295,6 @@ void enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor, ReferenceProcessorPhaseTimes* phase_times); - protected: // "Preclean" the given discovered reference list // by removing references with strongly reachable referents. // Currently used in support of CMS only. @@ -320,7 +303,7 @@ OopClosure* keep_alive, VoidClosure* complete_gc, YieldClosure* yield); - +private: // round-robin mod _num_q (not: _not_ mode _max_num_q) uint next_id() { uint id = _next_id; @@ -345,9 +328,11 @@ // Update (advance) the soft ref master clock field. void update_soft_ref_master_clock(); - public: + template + bool is_subject_to_discovery(T const obj) const; +public: // Default parameters give you a vanilla reference processor. - ReferenceProcessor(MemRegion span, + ReferenceProcessor(BoolObjectClosure* is_subject_to_discovery, bool mt_processing = false, uint mt_processing_degree = 1, bool mt_discovery = false, uint mt_discovery_degree = 1, bool atomic_discovery = true, @@ -372,9 +357,8 @@ _is_alive_non_header = is_alive_non_header; } - // get and set span - MemRegion span() { return _span; } - void set_span(MemRegion span) { _span = span; } + BoolObjectClosure* is_subject_to_discovery_closure() const { return _is_subject_to_discovery; } + void set_is_subject_to_discovery_closure(BoolObjectClosure* cl) { _is_subject_to_discovery = cl; } // start and stop weak ref discovery void enable_discovery(bool check_no_refs = true); @@ -434,6 +418,33 @@ void verify_referent(oop obj) PRODUCT_RETURN; }; +// A reference processor that uses a single memory span to determine the area that +// is subject to discovery. Useful for collectors which have contiguous generations. +class SpanReferenceProcessor : public ReferenceProcessor { + class SpanBasedDiscoverer : public BoolObjectClosure { + public: + MemRegion _span; + + SpanBasedDiscoverer(MemRegion span) : BoolObjectClosure(), _span(span) { } + + virtual bool do_object_b(oop obj) { + return _span.contains(obj); + } + }; + + SpanBasedDiscoverer _span_based_discoverer; +public: + SpanReferenceProcessor(MemRegion span, + bool mt_processing = false, uint mt_processing_degree = 1, + bool mt_discovery = false, uint mt_discovery_degree = 1, + bool atomic_discovery = true, + BoolObjectClosure* is_alive_non_header = NULL); + + // get and set span + MemRegion span() { return _span_based_discoverer._span; } + void set_span(MemRegion span) { _span_based_discoverer._span = span; } +}; + // A utility class to disable reference discovery in // the scope which contains it, for given ReferenceProcessor. class NoRefDiscovery: StackObj { @@ -455,16 +466,34 @@ } }; +// A utility class to temporarily mutate the subject discovery closure of the +// given ReferenceProcessor in the scope that contains it. +class ReferenceProcessorSubjectToDiscoveryMutator : StackObj { + private: + ReferenceProcessor* _rp; + BoolObjectClosure* _saved_cl; + + public: + ReferenceProcessorSubjectToDiscoveryMutator(ReferenceProcessor* rp, BoolObjectClosure* cl): + _rp(rp) { + _saved_cl = _rp->is_subject_to_discovery_closure(); + _rp->set_is_subject_to_discovery_closure(cl); + } + + ~ReferenceProcessorSubjectToDiscoveryMutator() { + _rp->set_is_subject_to_discovery_closure(_saved_cl); + } +}; // A utility class to temporarily mutate the span of the // given ReferenceProcessor in the scope that contains it. class ReferenceProcessorSpanMutator: StackObj { private: - ReferenceProcessor* _rp; - MemRegion _saved_span; + SpanReferenceProcessor* _rp; + MemRegion _saved_span; public: - ReferenceProcessorSpanMutator(ReferenceProcessor* rp, + ReferenceProcessorSpanMutator(SpanReferenceProcessor* rp, MemRegion span): _rp(rp) { _saved_span = _rp->span(); @@ -497,7 +526,6 @@ } }; - // A utility class to temporarily change the disposition // of the "is_alive_non_header" closure field of the // given ReferenceProcessor in the scope that contains it.