< prev index next >
src/share/vm/gc/shared/referenceProcessor.cpp
Print this page
*** 29,38 ****
--- 29,39 ----
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTraceTime.hpp"
#include "gc/shared/referencePolicy.hpp"
#include "gc/shared/referenceProcessor.hpp"
+ #include "logging/log.hpp"
#include "memory/allocation.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/jniHandles.hpp"
*** 184,208 ****
total += lists[i].length();
}
return total;
}
- static void log_ref_count(size_t count, bool doit) {
- if (doit) {
- gclog_or_tty->print(", " SIZE_FORMAT " refs", count);
- }
- }
-
- class GCRefTraceTime : public StackObj {
- GCTraceTimeImpl _gc_trace_time;
- public:
- GCRefTraceTime(const char* title, bool doit, GCTimer* timer, size_t count) :
- _gc_trace_time(title, doit, false, timer) {
- log_ref_count(count, doit);
- }
- };
-
ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
BoolObjectClosure* is_alive,
OopClosure* keep_alive,
VoidClosure* complete_gc,
AbstractRefProcTaskExecutor* task_executor,
--- 185,194 ----
*** 220,231 ****
// here so that we use the new value during processing of the
// discovered soft refs.
_soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
- bool trace_time = PrintGCDetails && PrintReferenceGC;
-
// Include cleaners in phantom statistics. We expect Cleaner
// references to be temporary, and don't want to deal with
// possible incompatibilities arising from making it more visible.
ReferenceProcessorStats stats(
total_count(_discoveredSoftRefs),
--- 206,215 ----
*** 233,266 ****
total_count(_discoveredFinalRefs),
total_count(_discoveredPhantomRefs) + total_count(_discoveredCleanerRefs));
// Soft references
{
! GCRefTraceTime tt("SoftReference", trace_time, gc_timer, stats.soft_count());
process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
is_alive, keep_alive, complete_gc, task_executor);
}
update_soft_ref_master_clock();
// Weak references
{
! GCRefTraceTime tt("WeakReference", trace_time, gc_timer, stats.weak_count());
process_discovered_reflist(_discoveredWeakRefs, NULL, true,
is_alive, keep_alive, complete_gc, task_executor);
}
// Final references
{
! GCRefTraceTime tt("FinalReference", trace_time, gc_timer, stats.final_count());
process_discovered_reflist(_discoveredFinalRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
}
// Phantom references
{
! GCRefTraceTime tt("PhantomReference", trace_time, gc_timer, stats.phantom_count());
process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
// Process cleaners, but include them in phantom timing. We expect
// Cleaner references to be temporary, and don't want to deal with
--- 217,250 ----
total_count(_discoveredFinalRefs),
total_count(_discoveredPhantomRefs) + total_count(_discoveredCleanerRefs));
// Soft references
{
! GCTraceTime(Debug, gc, ref) tt("SoftReference", gc_timer);
process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true,
is_alive, keep_alive, complete_gc, task_executor);
}
update_soft_ref_master_clock();
// Weak references
{
! GCTraceTime(Debug, gc, ref) tt("WeakReference", gc_timer);
process_discovered_reflist(_discoveredWeakRefs, NULL, true,
is_alive, keep_alive, complete_gc, task_executor);
}
// Final references
{
! GCTraceTime(Debug, gc, ref) tt("FinalReference", gc_timer);
process_discovered_reflist(_discoveredFinalRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
}
// Phantom references
{
! GCTraceTime(Debug, gc, ref) tt("PhantomReference", gc_timer);
process_discovered_reflist(_discoveredPhantomRefs, NULL, false,
is_alive, keep_alive, complete_gc, task_executor);
// Process cleaners, but include them in phantom timing. We expect
// Cleaner references to be temporary, and don't want to deal with
*** 273,309 ****
// traverse these simultaneously with the regular weak references above, but
// that is not how the JDK1.2 specification is. See #4126360. Native code can
// thus use JNI weak references to circumvent the phantom references and
// resurrect a "post-mortem" object.
{
! GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer);
! NOT_PRODUCT(log_ref_count(count_jni_refs(), trace_time);)
if (task_executor != NULL) {
task_executor->set_single_threaded_mode();
}
process_phaseJNI(is_alive, keep_alive, complete_gc);
}
return stats;
}
#ifndef PRODUCT
// Calculate the number of jni handles.
! uint ReferenceProcessor::count_jni_refs() {
class AlwaysAliveClosure: public BoolObjectClosure {
public:
virtual bool do_object_b(oop obj) { return true; }
};
class CountHandleClosure: public OopClosure {
private:
! int _count;
public:
CountHandleClosure(): _count(0) {}
void do_oop(oop* unused) { _count++; }
void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
! int count() { return _count; }
};
CountHandleClosure global_handle_count;
AlwaysAliveClosure always_alive;
JNIHandles::weak_oops_do(&always_alive, &global_handle_count);
return global_handle_count.count();
--- 257,296 ----
// traverse these simultaneously with the regular weak references above, but
// that is not how the JDK1.2 specification is. See #4126360. Native code can
// thus use JNI weak references to circumvent the phantom references and
// resurrect a "post-mortem" object.
{
! GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", gc_timer);
if (task_executor != NULL) {
task_executor->set_single_threaded_mode();
}
process_phaseJNI(is_alive, keep_alive, complete_gc);
}
+ log_debug(gc, ref)("Ref Counts: Soft " SIZE_FORMAT " Weak: " SIZE_FORMAT " Final: " SIZE_FORMAT " Phantom: " SIZE_FORMAT,
+ stats.soft_count(), stats.weak_count(), stats.final_count(), stats.phantom_count());
+ log_develop(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());
+
return stats;
}
#ifndef PRODUCT
// Calculate the number of jni handles.
! size_t ReferenceProcessor::count_jni_refs() {
class AlwaysAliveClosure: public BoolObjectClosure {
public:
virtual bool do_object_b(oop obj) { return true; }
};
class CountHandleClosure: public OopClosure {
private:
! size_t _count;
public:
CountHandleClosure(): _count(0) {}
void do_oop(oop* unused) { _count++; }
void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
! size_t count() { return _count; }
};
CountHandleClosure global_handle_count;
AlwaysAliveClosure always_alive;
JNIHandles::weak_oops_do(&always_alive, &global_handle_count);
return global_handle_count.count();
*** 360,387 ****
// in all places in the reference processor where we manipulate the discovered
// field we make sure to do the barrier here where we anyway iterate through
// all linked Reference objects. Note that it is important to not dirty any
// cards during reference processing since this will cause card table
// verification to fail for G1.
! if (TraceReferenceGC && PrintGCDetails) {
! gclog_or_tty->print_cr("ReferenceProcessor::enqueue_discovered_reflist list "
! INTPTR_FORMAT, p2i(refs_list.head()));
! }
oop obj = NULL;
oop next_d = refs_list.head();
// Walk down the list, self-looping the next field
// so that the References are not considered active.
while (obj != next_d) {
obj = next_d;
assert(obj->is_instance(), "should be an instance object");
assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
next_d = java_lang_ref_Reference::discovered(obj);
! if (TraceReferenceGC && PrintGCDetails) {
! gclog_or_tty->print_cr(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT,
! p2i(obj), p2i(next_d));
! }
assert(java_lang_ref_Reference::next(obj) == NULL,
"Reference not active; should not be discovered");
// Self-loop next, so as to make Ref not active.
java_lang_ref_Reference::set_next_raw(obj, obj);
if (next_d != obj) {
--- 347,368 ----
// in all places in the reference processor where we manipulate the discovered
// field we make sure to do the barrier here where we anyway iterate through
// all linked Reference objects. Note that it is important to not dirty any
// cards during reference processing since this will cause card table
// verification to fail for G1.
! log_develop(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(refs_list.head()));
oop obj = NULL;
oop next_d = refs_list.head();
// Walk down the list, self-looping the next field
// so that the References are not considered active.
while (obj != next_d) {
obj = next_d;
assert(obj->is_instance(), "should be an instance object");
assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
next_d = java_lang_ref_Reference::discovered(obj);
! log_develop(gc, ref)(" obj " INTPTR_FORMAT "/next_d " INTPTR_FORMAT, p2i(obj), p2i(next_d));
assert(java_lang_ref_Reference::next(obj) == NULL,
"Reference not active; should not be discovered");
// Self-loop next, so as to make Ref not active.
java_lang_ref_Reference::set_next_raw(obj, obj);
if (next_d != obj) {
*** 515,528 ****
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
if (referent_is_dead &&
!policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy",
p2i(iter.obj()), iter.obj()->klass()->internal_name());
- }
// Remove Reference object from list
iter.remove();
// keep the referent around
iter.make_referent_alive();
iter.move_to_next();
--- 496,507 ----
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */));
bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
if (referent_is_dead &&
!policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
! log_develop(gc, ref)("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy",
p2i(iter.obj()), iter.obj()->klass()->internal_name());
// Remove Reference object from list
iter.remove();
// keep the referent around
iter.make_referent_alive();
iter.move_to_next();
*** 530,547 ****
iter.next();
}
}
// Close the reachable set
complete_gc->do_void();
! NOT_PRODUCT(
! if (PrintGCDetails && TraceReferenceGC) {
! gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT
! " discovered Refs by policy, from list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
- )
- }
// Traverse the list and remove any Refs that are not active, or
// whose referents are either alive or NULL.
void
ReferenceProcessor::pp2_work(DiscoveredList& refs_list,
--- 509,521 ----
iter.next();
}
}
// Close the reachable set
complete_gc->do_void();
! log_develop(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
// Traverse the list and remove any Refs that are not active, or
// whose referents are either alive or NULL.
void
ReferenceProcessor::pp2_work(DiscoveredList& refs_list,
*** 552,565 ****
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
assert(next == NULL, "Should not discover inactive Reference");
if (iter.is_referent_alive()) {
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
p2i(iter.obj()), iter.obj()->klass()->internal_name());
- }
// The referent is reachable after all.
// Remove Reference object from list.
iter.remove();
// Update the referent pointer as necessary: Note that this
// should not entail any recursive marking because the
--- 526,537 ----
while (iter.has_next()) {
iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
assert(next == NULL, "Should not discover inactive Reference");
if (iter.is_referent_alive()) {
! log_develop(gc, ref)("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
p2i(iter.obj()), iter.obj()->klass()->internal_name());
// The referent is reachable after all.
// Remove Reference object from list.
iter.remove();
// Update the referent pointer as necessary: Note that this
// should not entail any recursive marking because the
*** 569,580 ****
} else {
iter.next();
}
}
NOT_PRODUCT(
! if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
! gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
" Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
)
}
--- 541,552 ----
} else {
iter.next();
}
}
NOT_PRODUCT(
! if (iter.processed() > 0) {
! log_develop(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
" Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
)
}
*** 608,619 ****
}
}
// Now close the newly reachable set
complete_gc->do_void();
NOT_PRODUCT(
! if (PrintGCDetails && TraceReferenceGC && (iter.processed() > 0)) {
! gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
" Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
)
}
--- 580,591 ----
}
}
// Now close the newly reachable set
complete_gc->do_void();
NOT_PRODUCT(
! if (iter.processed() > 0) {
! log_develop(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT
" Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
)
}
*** 636,650 ****
iter.clear_referent();
} else {
// keep the referent around
iter.make_referent_alive();
}
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
! clear_referent ? "cleared " : "",
! p2i(iter.obj()), iter.obj()->klass()->internal_name());
! }
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
iter.next();
}
// Close the reachable set
complete_gc->do_void();
--- 608,619 ----
iter.clear_referent();
} else {
// keep the referent around
iter.make_referent_alive();
}
! log_develop(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
! clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name());
assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
iter.next();
}
// Close the reachable set
complete_gc->do_void();
*** 664,675 ****
}
void ReferenceProcessor::abandon_partial_discovery() {
// loop over the lists
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
! if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
! gclog_or_tty->print_cr("\nAbandoning %s discovered list", list_name(i));
}
clear_discovered_references(_discovered_refs[i]);
}
}
--- 633,644 ----
}
void ReferenceProcessor::abandon_partial_discovery() {
// loop over the lists
for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
! if ((i % _max_num_q) == 0) {
! log_develop(gc, ref)("\nAbandoning %s discovered list", list_name(i));
}
clear_discovered_references(_discovered_refs[i]);
}
}
*** 734,764 ****
}
private:
bool _clear_referent;
};
// Balances reference queues.
// Move entries from all queues[0, 1, ..., _max_num_q-1] to
// queues[0, 1, ..., _num_q-1] because only the first _num_q
// corresponding to the active workers will be processed.
void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
{
// calculate total length
size_t total_refs = 0;
! if (TraceReferenceGC && PrintGCDetails) {
! gclog_or_tty->print_cr("\nBalance ref_lists ");
! }
for (uint i = 0; i < _max_num_q; ++i) {
total_refs += ref_lists[i].length();
- if (TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print(SIZE_FORMAT " ", ref_lists[i].length());
- }
- }
- if (TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr(" = " SIZE_FORMAT, total_refs);
}
size_t avg_refs = total_refs / _num_q + 1;
uint to_idx = 0;
for (uint from_idx = 0; from_idx < _max_num_q; from_idx++) {
bool move_all = false;
if (from_idx >= _num_q) {
--- 703,740 ----
}
private:
bool _clear_referent;
};
+ #ifndef PRODUCT
+ void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], size_t total_refs) {
+ if (!Log<LogTag::gc, LogTag::ref>::is_level(LogLevel::Trace)) {
+ return;
+ }
+
+ stringStream st;
+ for (uint i = 0; i < _max_num_q; ++i) {
+ st.print(SIZE_FORMAT " ", ref_lists[i].length());
+ }
+ log_develop(gc, ref)("%s= " SIZE_FORMAT, st.as_string(), total_refs);
+ }
+ #endif
+
// Balances reference queues.
// Move entries from all queues[0, 1, ..., _max_num_q-1] to
// queues[0, 1, ..., _num_q-1] because only the first _num_q
// corresponding to the active workers will be processed.
void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
{
// calculate total length
size_t total_refs = 0;
! log_develop(gc, ref)("Balance ref_lists ");
for (uint i = 0; i < _max_num_q; ++i) {
total_refs += ref_lists[i].length();
}
+ log_reflist_counts(ref_lists, total_refs);
size_t avg_refs = total_refs / _num_q + 1;
uint to_idx = 0;
for (uint from_idx = 0; from_idx < _max_num_q; from_idx++) {
bool move_all = false;
if (from_idx >= _num_q) {
*** 818,835 ****
}
#ifdef ASSERT
size_t balanced_total_refs = 0;
for (uint i = 0; i < _max_num_q; ++i) {
balanced_total_refs += ref_lists[i].length();
- if (TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print(SIZE_FORMAT " ", ref_lists[i].length());
- }
- }
- if (TraceReferenceGC && PrintGCDetails) {
- gclog_or_tty->print_cr(" = " SIZE_FORMAT, balanced_total_refs);
- gclog_or_tty->flush();
}
assert(total_refs == balanced_total_refs, "Balancing was incomplete");
#endif
}
void ReferenceProcessor::balance_all_queues() {
--- 794,805 ----
}
#ifdef ASSERT
size_t balanced_total_refs = 0;
for (uint i = 0; i < _max_num_q; ++i) {
balanced_total_refs += ref_lists[i].length();
}
+ log_reflist_counts(ref_lists, balanced_total_refs);
assert(total_refs == balanced_total_refs, "Balancing was incomplete");
#endif
}
void ReferenceProcessor::balance_all_queues() {
*** 948,960 ****
case REF_NONE:
// we should not reach here if we are an InstanceRefKlass
default:
ShouldNotReachHere();
}
! if (TraceReferenceGC && PrintGCDetails) {
! gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT, id, p2i(list));
! }
return list;
}
inline void
ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
--- 918,928 ----
case REF_NONE:
// we should not reach here if we are an InstanceRefKlass
default:
ShouldNotReachHere();
}
! log_develop(gc, ref)("Thread %d gets list " INTPTR_FORMAT, id, p2i(list));
return list;
}
inline void
ReferenceProcessor::add_to_discovered_list_mt(DiscoveredList& refs_list,
*** 974,996 ****
// We have separate lists for enqueueing, so no synchronization
// is necessary.
refs_list.set_head(obj);
refs_list.inc_length(1);
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
p2i(obj), obj->klass()->internal_name());
- }
} else {
// If retest was non NULL, another thread beat us to it:
// The reference has already been discovered...
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
p2i(obj), obj->klass()->internal_name());
}
}
- }
#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.
--- 942,960 ----
// We have separate lists for enqueueing, so no synchronization
// is necessary.
refs_list.set_head(obj);
refs_list.inc_length(1);
! log_develop(gc, ref)("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
p2i(obj), obj->klass()->internal_name());
} else {
// If retest was non NULL, another thread beat us to it:
// The reference has already been discovered...
! log_develop(gc, ref)("Already discovered reference (" INTPTR_FORMAT ": %s)",
p2i(obj), obj->klass()->internal_name());
}
}
#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.
*** 1076,1089 ****
HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
const oop discovered = java_lang_ref_Reference::discovered(obj);
assert(discovered->is_oop_or_null(), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
if (discovered != NULL) {
// The reference has already been discovered...
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
p2i(obj), obj->klass()->internal_name());
- }
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
// assumes that an object is not processed twice;
// if it's been already discovered it must be on another
// generation's discovered list; so we won't discover it.
return false;
--- 1040,1051 ----
HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj);
const oop discovered = java_lang_ref_Reference::discovered(obj);
assert(discovered->is_oop_or_null(), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered));
if (discovered != NULL) {
// The reference has already been discovered...
! log_develop(gc, ref)("Already discovered reference (" INTPTR_FORMAT ": %s)",
p2i(obj), obj->klass()->internal_name());
if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
// assumes that an object is not processed twice;
// if it's been already discovered it must be on another
// generation's discovered list; so we won't discover it.
return false;
*** 1134,1147 ****
assert(discovered == NULL, "control point invariant");
oop_store_raw(discovered_addr, next_discovered);
list->set_head(obj);
list->inc_length(1);
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
! p2i(obj), obj->klass()->internal_name());
! }
}
assert(obj->is_oop(), "Discovered a bad reference");
verify_referent(obj);
return true;
}
--- 1096,1106 ----
assert(discovered == NULL, "control point invariant");
oop_store_raw(discovered_addr, next_discovered);
list->set_head(obj);
list->inc_length(1);
! log_develop(gc, ref)("Discovered reference (" INTPTR_FORMAT ": %s)", p2i(obj), obj->klass()->internal_name());
}
assert(obj->is_oop(), "Discovered a bad reference");
verify_referent(obj);
return true;
}
*** 1157,1168 ****
YieldClosure* yield,
GCTimer* gc_timer) {
// Soft references
{
! GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
! false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
--- 1116,1126 ----
YieldClosure* yield,
GCTimer* gc_timer) {
// Soft references
{
! GCTraceTime(Debug, gc, ref) tm("Preclean SoftReferences", gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
*** 1170,1181 ****
}
}
// Weak references
{
! GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
! false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
--- 1128,1138 ----
}
}
// Weak references
{
! GCTraceTime(Debug, gc, ref) tm("Preclean WeakReferences", gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
*** 1183,1194 ****
}
}
// Final references
{
! GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
! false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
--- 1140,1150 ----
}
}
// Final references
{
! GCTraceTime(Debug, gc, ref) tm("Preclean FinalReferences", gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
*** 1196,1207 ****
}
}
// Phantom references
{
! GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
! false, gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
--- 1152,1162 ----
}
}
// Phantom references
{
! GCTraceTime(Debug, gc, ref) tm("Preclean PhantomReferences", gc_timer);
for (uint i = 0; i < _max_num_q; i++) {
if (yield->should_return()) {
return;
}
preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
*** 1242,1255 ****
oop next = java_lang_ref_Reference::next(obj);
if (iter.referent() == NULL || iter.is_referent_alive() ||
next != NULL) {
// The referent has been cleared, or is alive, or the Reference is not
// active; we need to trace and mark its cohort.
! if (TraceReferenceGC) {
! gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)",
p2i(iter.obj()), iter.obj()->klass()->internal_name());
- }
// Remove Reference object from list
iter.remove();
// Keep alive its cohort.
iter.make_referent_alive();
if (UseCompressedOops) {
--- 1197,1208 ----
oop next = java_lang_ref_Reference::next(obj);
if (iter.referent() == NULL || iter.is_referent_alive() ||
next != NULL) {
// The referent has been cleared, or is alive, or the Reference is not
// active; we need to trace and mark its cohort.
! log_develop(gc, ref)("Precleaning Reference (" INTPTR_FORMAT ": %s)",
p2i(iter.obj()), iter.obj()->klass()->internal_name());
// Remove Reference object from list
iter.remove();
// Keep alive its cohort.
iter.make_referent_alive();
if (UseCompressedOops) {
*** 1266,1278 ****
}
// Close the reachable set
complete_gc->do_void();
NOT_PRODUCT(
! if (PrintGCDetails && PrintReferenceGC && (iter.processed() > 0)) {
! gclog_or_tty->print_cr(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT
! " Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
)
}
--- 1219,1230 ----
}
// Close the reachable set
complete_gc->do_void();
NOT_PRODUCT(
! if (iter.processed() > 0) {
! log_develop(gc, ref)(" Dropped " SIZE_FORMAT " Refs out of " SIZE_FORMAT " Refs in discovered list " INTPTR_FORMAT,
iter.removed(), iter.processed(), p2i(refs_list.head()));
}
)
}
< prev index next >