< prev index next >
src/hotspot/share/gc/shared/referenceProcessor.hpp
Print this page
rev 49912 : imported patch 8201492-properly-implement-non-contiguous-reference-processing
rev 49913 : imported patch 8201492-stefanj-review
rev 49914 : [mq]: 8201492-kim-review
@@ -36,22 +36,17 @@
// ReferenceProcessor class encapsulates the per-"collector" processing
// 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;
class AbstractRefProcTaskExecutor;
@@ -166,20 +161,18 @@
NOT_PRODUCT(_processed++);
}
};
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
// other collectors in configuration
bool _discovery_is_mt; // true if reference discovery is MT.
@@ -255,23 +248,14 @@
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc);
// Phase2: remove all those references whose referents are
// reachable.
- inline void process_phase2(DiscoveredList& refs_list,
+ 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);
- }
- }
+ VoidClosure* complete_gc);
// Work methods in support of process_phase2
void pp2_work(DiscoveredList& refs_list,
BoolObjectClosure* is_alive,
OopClosure* keep_alive);
void pp2_work_concurrent_discovery(
@@ -310,20 +294,19 @@
const char* list_name(uint i);
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.
void preclean_discovered_reflist(DiscoveredList& refs_list,
BoolObjectClosure* is_alive,
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;
assert(!_discovery_is_mt, "Round robin should only be used in serial discovery");
if (++_next_id == _num_q) {
@@ -344,13 +327,15 @@
void balance_queues(DiscoveredList ref_lists[]);
// 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,
BoolObjectClosure* is_alive_non_header = NULL);
@@ -371,13 +356,12 @@
}
void set_is_alive_non_header(BoolObjectClosure* is_alive_non_header) {
_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);
void disable_discovery() { _discovering_refs = false; }
bool discovery_enabled() { return _discovering_refs; }
@@ -433,10 +417,30 @@
// debugging
void verify_no_references_recorded() PRODUCT_RETURN;
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 {
private:
ReferenceProcessor* _rp;
@@ -454,28 +458,47 @@
_rp->enable_discovery(false /*check_no_refs*/);
}
}
};
+// 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);
}
};
// A utility class to temporarily change the MT'ness of
// reference discovery for the given ReferenceProcessor
@@ -496,11 +519,10 @@
~ReferenceProcessorMTDiscoveryMutator() {
_rp->set_mt_discovery(_saved_mt);
}
};
-
// 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.
class ReferenceProcessorIsAliveMutator: StackObj {
private:
< prev index next >