--- old/src/hotspot/share/gc/shared/referenceProcessor.hpp 2018-05-08 09:41:56.270918506 +0200 +++ new/src/hotspot/share/gc/shared/referenceProcessor.hpp 2018-05-08 09:41:55.982909607 +0200 @@ -38,18 +38,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; @@ -168,16 +163,14 @@ }; class ReferenceProcessor : public ReferenceDiscoverer { - - 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 @@ -257,19 +250,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, @@ -312,7 +296,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. @@ -321,7 +304,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; @@ -346,9 +329,11 @@ // Update (advance) the soft ref master clock field. void update_soft_ref_master_clock(); - public: + bool is_subject_to_discovery(oop 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, @@ -373,9 +358,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); @@ -435,6 +419,26 @@ void verify_referent(oop obj) PRODUCT_RETURN; }; +// A subject-to-discovery closure that uses a single memory span to determine the area that +// is subject to discovery. Useful for collectors which have contiguous generations. +class SpanSubjectToDiscoveryClosure : public BoolObjectClosure { + MemRegion _span; + +public: + SpanSubjectToDiscoveryClosure() : BoolObjectClosure(), _span() { } + SpanSubjectToDiscoveryClosure(MemRegion span) : BoolObjectClosure(), _span(span) { } + + MemRegion span() const { return _span; } + + void set_span(MemRegion mr) { + _span = mr; + } + + virtual bool do_object_b(oop obj) { + return _span.contains(obj); + } +}; + // A utility class to disable reference discovery in // the scope which contains it, for given ReferenceProcessor. class NoRefDiscovery: StackObj { @@ -456,24 +460,41 @@ } }; +// A utility class to temporarily mutate the subject discovery closure of the +// given ReferenceProcessor in the scope that contains it. +class ReferenceProcessorSubjectToDiscoveryMutator : StackObj { + 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: +class ReferenceProcessorSpanMutator : StackObj { ReferenceProcessor* _rp; - MemRegion _saved_span; + SpanSubjectToDiscoveryClosure _discoverer; + BoolObjectClosure* _old_discoverer; - public: +public: ReferenceProcessorSpanMutator(ReferenceProcessor* rp, MemRegion span): - _rp(rp) { - _saved_span = _rp->span(); - _rp->set_span(span); + _rp(rp), _discoverer(span) { + _old_discoverer = rp->is_subject_to_discovery_closure(); + rp->set_is_subject_to_discovery_closure(&_discoverer); } ~ReferenceProcessorSpanMutator() { - _rp->set_span(_saved_span); + _rp->set_is_subject_to_discovery_closure(_old_discoverer); } }; @@ -498,7 +519,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.