Skip to content
Permalink
Browse files
8273185: Rename the term "atomic" in ReferenceProcessor
Reviewed-by: ayang, shade
  • Loading branch information
Thomas Schatzl committed Sep 8, 2021
1 parent ba31eee commit e6805032ff328773eafe8b94e9f1b3b196f52196
@@ -1833,7 +1833,7 @@ void G1CollectedHeap::ref_processing_init() {
// thread counts must be considered for discovery.
(ParallelGCThreads > 1) || (ConcGCThreads > 1), // mt discovery
MAX2(ParallelGCThreads, ConcGCThreads), // degree of mt discovery
false, // Reference discovery is not atomic
true, // Reference discovery is concurrent
&_is_alive_closure_cm); // is alive closure

// STW ref processor
@@ -1842,7 +1842,7 @@ void G1CollectedHeap::ref_processing_init() {
ParallelGCThreads, // degree of mt processing
(ParallelGCThreads > 1), // mt discovery
ParallelGCThreads, // degree of mt discovery
true, // Reference discovery is atomic
false, // Reference discovery is not concurrent
&_is_alive_closure_stw); // is alive closure
}

@@ -801,7 +801,7 @@ void PSScavenge::initialize() {
ParallelGCThreads, // mt processing degree
true, // mt discovery
ParallelGCThreads, // mt discovery degree
true, // atomic_discovery
false, // concurrent_discovery
NULL); // header provides liveness info

// Cache the cardtable
@@ -88,7 +88,7 @@ ReferenceProcessor::ReferenceProcessor(BoolObjectClosure* is_subject_to_discover
uint mt_processing_degree,
bool mt_discovery,
uint mt_discovery_degree,
bool atomic_discovery,
bool concurrent_discovery,
BoolObjectClosure* is_alive_non_header) :
_is_subject_to_discovery(is_subject_to_discovery),
_discovering_refs(false),
@@ -97,11 +97,11 @@ ReferenceProcessor::ReferenceProcessor(BoolObjectClosure* is_subject_to_discover
{
assert(is_subject_to_discovery != NULL, "must be set");

_discovery_is_atomic = atomic_discovery;
_discovery_is_mt = mt_discovery;
_num_queues = MAX2(1U, mt_processing_degree);
_max_num_queues = MAX2(_num_queues, mt_discovery_degree);
_discovered_refs = NEW_C_HEAP_ARRAY(DiscoveredList,
_discovery_is_concurrent = concurrent_discovery;
_discovery_is_mt = mt_discovery;
_num_queues = MAX2(1U, mt_processing_degree);
_max_num_queues = MAX2(_num_queues, mt_discovery_degree);
_discovered_refs = NEW_C_HEAP_ARRAY(DiscoveredList,
_max_num_queues * number_of_subclasses_of_ref(), mtGC);

_discoveredSoftRefs = &_discovered_refs[0];
@@ -310,10 +310,10 @@ size_t ReferenceProcessor::process_discovered_list_work(DiscoveredList& refs_
bool do_enqueue_and_clear) {
DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
iter.load_ptrs(DEBUG_ONLY(discovery_is_concurrent() /* allow_null_referent */));
if (iter.referent() == NULL) {
// Reference has been cleared since discovery; only possible if
// discovery is not atomic (checked by load_ptrs). Remove
// discovery is concurrent (checked by load_ptrs). Remove
// reference from list.
log_dropped_ref(iter, "cleared");
iter.remove();
@@ -866,7 +866,7 @@ inline bool ReferenceProcessor::set_discovered_link_st(HeapWord* discovered_addr
oop next_discovered) {
assert(!discovery_is_mt(), "must be");

if (discovery_is_atomic()) {
if (discovery_is_stw()) {
// Do a raw store here: the field will be visited later when processing
// the discovered references.
RawAccess<>::oop_store(discovered_addr, next_discovered);
@@ -883,7 +883,7 @@ inline bool ReferenceProcessor::set_discovered_link_mt(HeapWord* discovered_addr

// We must make sure this object is only enqueued once. Try to CAS into the discovered_addr.
oop retest;
if (discovery_is_atomic()) {
if (discovery_is_stw()) {
// Try a raw store here, still making sure that we enqueue only once: the field
// will be visited later when processing the discovered references.
retest = RawAccess<>::oop_atomic_cmpxchg(discovered_addr, oop(NULL), next_discovered);
@@ -894,16 +894,15 @@ inline bool ReferenceProcessor::set_discovered_link_mt(HeapWord* discovered_addr
}

#ifndef PRODUCT
// Non-atomic (i.e. concurrent) discovery might allow us
// to observe j.l.References with NULL referents, being those
// cleared concurrently by mutators during (or after) discovery.
// Concurrent discovery might allow us to observe j.l.References with NULL
// referents, being those cleared concurrently by mutators during (or after) discovery.
void ReferenceProcessor::verify_referent(oop obj) {
bool da = discovery_is_atomic();
bool concurrent = discovery_is_concurrent();
oop referent = java_lang_ref_Reference::unknown_referent_no_keepalive(obj);
assert(da ? oopDesc::is_oop(referent) : oopDesc::is_oop_or_null(referent),
assert(concurrent ? oopDesc::is_oop_or_null(referent) : oopDesc::is_oop(referent),
"Bad referent " INTPTR_FORMAT " found in Reference "
INTPTR_FORMAT " during %satomic discovery ",
p2i(referent), p2i(obj), da ? "" : "non-");
INTPTR_FORMAT " during %sconcurrent discovery ",
p2i(referent), p2i(obj), concurrent ? "" : "non-");
}
#endif

@@ -913,7 +912,7 @@ bool ReferenceProcessor::is_subject_to_discovery(oop const obj) const {

// We mention two of several possible choices here:
// #0: if the reference object is not in the "originating generation"
// (or part of the heap being collected, indicated by our "span"
// (or part of the heap being collected, indicated by our "span")
// we don't treat it specially (i.e. we scan it as we would
// a normal oop, treating its references as strong references).
// This means that references can't be discovered unless their
@@ -925,18 +924,18 @@ bool ReferenceProcessor::is_subject_to_discovery(oop const obj) const {
// the referent is in the generation (span) being currently collected
// then we can discover the reference object, provided
// the object has not already been discovered by
// a different concurrently running collector (as may be the
// case, for instance, if the reference object is in CMS and
// the referent in DefNewGeneration), and provided the processing
// a different concurrently running discoverer (as may be the
// case, for instance, if the reference object is in G1 old gen and
// the referent in G1 young gen), and provided the processing
// of this reference object by the current collector will
// appear atomic to every other collector in the system.
// (Thus, for instance, a concurrent collector may not
// appear atomically to every other discoverer in the system.
// (Thus, for instance, a concurrent discoverer may not
// discover references in other generations even if the
// referent is in its own generation). This policy may,
// in certain cases, enqueue references somewhat sooner than
// might Policy #0 above, but at marginally increased cost
// and complexity in processing these references.
// We call this choice the "RefeferentBasedDiscovery" policy.
// We call this choice the "ReferentBasedDiscovery" policy.
bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
// Make sure we are discovering refs (rather than processing discovered refs).
if (!_discovering_refs || !RegisterReferences) {
@@ -1007,9 +1006,9 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) {
verify_referent(obj);
// Discover if and only if EITHER:
// .. reference is in our span, OR
// .. we are an atomic collector and referent is in our span
// .. we are a stw discoverer and referent is in our span
if (is_subject_to_discovery(obj) ||
(discovery_is_atomic() &&
(discovery_is_stw() &&
is_subject_to_discovery(java_lang_ref_Reference::unknown_referent_no_keepalive(obj)))) {
} else {
return false;
@@ -195,8 +195,7 @@ class ReferenceProcessor : public ReferenceDiscoverer {
// (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_concurrent; // if discovery is concurrent to the mutator
bool _discovery_is_mt; // true if reference discovery is MT.

uint _next_id; // round-robin mod _num_queues counter in
@@ -251,7 +250,7 @@ class ReferenceProcessor : public ReferenceDiscoverer {
// removed elements.

// Traverse the list and remove any Refs whose referents are alive,
// or NULL if discovery is not atomic. Enqueue and clear the reference for
// or NULL if discovery is concurrent. Enqueue and clear the reference for
// others if do_enqueue_and_clear is set.
size_t process_discovered_list_work(DiscoveredList& refs_list,
BoolObjectClosure* is_alive,
@@ -352,7 +351,7 @@ class ReferenceProcessor : public ReferenceDiscoverer {
ReferenceProcessor(BoolObjectClosure* is_subject_to_discovery,
uint mt_processing_degree = 1,
bool mt_discovery = false, uint mt_discovery_degree = 1,
bool atomic_discovery = true,
bool concurrent_discovery = false,
BoolObjectClosure* is_alive_non_header = NULL);

// RefDiscoveryPolicy values
@@ -381,8 +380,9 @@ class ReferenceProcessor : public ReferenceDiscoverer {
void disable_discovery() { _discovering_refs = false; }
bool discovery_enabled() { return _discovering_refs; }

// whether discovery is atomic wrt other collectors
bool discovery_is_atomic() const { return _discovery_is_atomic; }
// whether discovery is concurrent to the mutator, or done in an stw pause.
bool discovery_is_concurrent() const { return _discovery_is_concurrent; }
bool discovery_is_stw() const { return !discovery_is_concurrent(); }

// whether discovery is done by multiple threads same-old-timeously
bool discovery_is_mt() const { return _discovery_is_mt; }

1 comment on commit e680503

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on e680503 Sep 8, 2021

Please sign in to comment.