8202017: Merge Reference Enqueuing phase with phase 3 of Reference processing
Do reference enqueuing work directly in phase 3 after every Reference. Reviewed-by: kbarrett, sangheki
This commit is contained in:
parent
59d4a62f42
commit
035d0190a3
@ -5254,16 +5254,7 @@ void CMSCollector::refProcessingWork() {
|
||||
restore_preserved_marks_if_any(); // done single-threaded for now
|
||||
|
||||
rp->set_enqueuing_is_done(true);
|
||||
if (rp->processing_is_mt()) {
|
||||
rp->balance_all_queues();
|
||||
CMSRefProcTaskExecutor task_executor(*this);
|
||||
rp->enqueue_discovered_references(&task_executor, &pt);
|
||||
} else {
|
||||
rp->enqueue_discovered_references(NULL, &pt);
|
||||
}
|
||||
rp->verify_no_references_recorded();
|
||||
pt.print_enqueue_phase();
|
||||
assert(!rp->discovery_enabled(), "should have been disabled");
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
@ -1054,18 +1054,10 @@ void ParNewGeneration::collect(bool full,
|
||||
update_time_of_last_gc(now);
|
||||
|
||||
rp->set_enqueuing_is_done(true);
|
||||
if (rp->processing_is_mt()) {
|
||||
ParNewRefProcTaskExecutor task_executor(*this, *_old_gen, thread_state_set);
|
||||
rp->enqueue_discovered_references(&task_executor, &pt);
|
||||
} else {
|
||||
rp->enqueue_discovered_references(NULL, &pt);
|
||||
}
|
||||
rp->verify_no_references_recorded();
|
||||
|
||||
gch->trace_heap_after_gc(gc_tracer());
|
||||
|
||||
pt.print_enqueue_phase();
|
||||
|
||||
_gc_timer->register_gc_end();
|
||||
|
||||
_gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
|
||||
|
@ -3879,7 +3879,6 @@ void G1STWRefProcTaskExecutor::execute(EnqueueTask& enq_task) {
|
||||
|
||||
// End of weak reference support closures
|
||||
|
||||
// Weak Reference processing during an evacuation pause (part 1).
|
||||
void G1CollectedHeap::process_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
|
||||
double ref_proc_start = os::elapsedTime();
|
||||
|
||||
@ -3939,42 +3938,15 @@ void G1CollectedHeap::process_discovered_references(G1ParScanThreadStateSet* per
|
||||
// We have completed copying any necessary live referent objects.
|
||||
assert(pss->queue_is_empty(), "both queue and overflow should be empty");
|
||||
|
||||
make_pending_list_reachable();
|
||||
|
||||
rp->verify_no_references_recorded();
|
||||
|
||||
double ref_proc_time = os::elapsedTime() - ref_proc_start;
|
||||
g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0);
|
||||
}
|
||||
|
||||
// Weak Reference processing during an evacuation pause (part 2).
|
||||
void G1CollectedHeap::enqueue_discovered_references(G1ParScanThreadStateSet* per_thread_states) {
|
||||
double ref_enq_start = os::elapsedTime();
|
||||
|
||||
ReferenceProcessor* rp = _ref_processor_stw;
|
||||
assert(!rp->discovery_enabled(), "should have been disabled as part of processing");
|
||||
|
||||
ReferenceProcessorPhaseTimes* pt = g1_policy()->phase_times()->ref_phase_times();
|
||||
|
||||
// Now enqueue any remaining on the discovered lists on to
|
||||
// the pending list.
|
||||
if (!rp->processing_is_mt()) {
|
||||
// Serial reference processing...
|
||||
rp->enqueue_discovered_references(NULL, pt);
|
||||
} else {
|
||||
// Parallel reference enqueueing
|
||||
|
||||
uint n_workers = workers()->active_workers();
|
||||
|
||||
assert(n_workers <= rp->max_num_queues(),
|
||||
"Mismatch between the number of GC workers %u and the maximum number of Reference process queues %u",
|
||||
n_workers, rp->max_num_queues());
|
||||
|
||||
G1STWRefProcTaskExecutor par_task_executor(this, per_thread_states, workers(), _task_queues, n_workers);
|
||||
rp->enqueue_discovered_references(&par_task_executor, pt);
|
||||
}
|
||||
|
||||
rp->verify_no_references_recorded();
|
||||
assert(!rp->discovery_enabled(), "should have been disabled");
|
||||
|
||||
// If during an initial mark pause we install a pending list head which is not otherwise reachable
|
||||
// ensure that it is marked in the bitmap for concurrent marking to discover.
|
||||
void G1CollectedHeap::make_pending_list_reachable() {
|
||||
if (collector_state()->in_initial_mark_gc()) {
|
||||
oop pll_head = Universe::reference_pending_list();
|
||||
if (pll_head != NULL) {
|
||||
@ -3982,14 +3954,6 @@ void G1CollectedHeap::enqueue_discovered_references(G1ParScanThreadStateSet* per
|
||||
_cm->mark_in_next_bitmap(0 /* worker_id */, pll_head);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// CM's reference processing also cleans up the string and symbol tables.
|
||||
// Should we do that here also? We could, but it is a serial operation
|
||||
// and could significantly increase the pause time.
|
||||
|
||||
double ref_enq_time = os::elapsedTime() - ref_enq_start;
|
||||
g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
|
||||
}
|
||||
|
||||
void G1CollectedHeap::merge_per_thread_state_info(G1ParScanThreadStateSet* per_thread_states) {
|
||||
@ -4069,7 +4033,11 @@ void G1CollectedHeap::post_evacuate_collection_set(EvacuationInfo& evacuation_in
|
||||
// objects (and their reachable sub-graphs) that were
|
||||
// not copied during the pause.
|
||||
process_discovered_references(per_thread_states);
|
||||
enqueue_discovered_references(per_thread_states);
|
||||
|
||||
// FIXME
|
||||
// CM's reference processing also cleans up the string and symbol tables.
|
||||
// Should we do that here also? We could, but it is a serial operation
|
||||
// and could significantly increase the pause time.
|
||||
|
||||
G1STWIsAliveClosure is_alive(this);
|
||||
G1KeepAliveClosure keep_alive(this);
|
||||
|
@ -513,13 +513,13 @@ private:
|
||||
// allocated block, or else "NULL".
|
||||
HeapWord* expand_and_allocate(size_t word_size);
|
||||
|
||||
// Process any reference objects discovered during
|
||||
// an incremental evacuation pause.
|
||||
// Process any reference objects discovered.
|
||||
void process_discovered_references(G1ParScanThreadStateSet* per_thread_states);
|
||||
|
||||
// Enqueue any remaining discovered references
|
||||
// after processing.
|
||||
void enqueue_discovered_references(G1ParScanThreadStateSet* per_thread_states);
|
||||
// If during an initial mark pause we may install a pending list head which is not
|
||||
// otherwise reachable ensure that it is marked in the bitmap for concurrent marking
|
||||
// to discover.
|
||||
void make_pending_list_reachable();
|
||||
|
||||
// Merges the information gathered on a per-thread basis for all worker threads
|
||||
// during GC into global variables.
|
||||
|
@ -1677,12 +1677,7 @@ void G1ConcurrentMark::weak_refs_work(bool clear_all_soft_refs) {
|
||||
|
||||
assert(rp->num_queues() == active_workers, "why not");
|
||||
|
||||
rp->enqueue_discovered_references(executor, &pt);
|
||||
|
||||
rp->verify_no_references_recorded();
|
||||
|
||||
pt.print_enqueue_phase();
|
||||
|
||||
assert(!rp->discovery_enabled(), "Post condition");
|
||||
}
|
||||
|
||||
|
@ -108,8 +108,4 @@ void G1FullGCReferenceProcessingExecutor::execute(STWGCTimer* timer, G1FullGCTra
|
||||
pt.print_all_references();
|
||||
|
||||
assert(marker->oop_stack()->is_empty(), "Should be no oops on the stack");
|
||||
|
||||
// Now enqueue the references.
|
||||
_reference_processor->enqueue_discovered_references(executor, &pt);
|
||||
pt.print_enqueue_phase();
|
||||
}
|
||||
|
@ -129,7 +129,6 @@ void G1GCPhaseTimes::reset() {
|
||||
_cur_clear_ct_time_ms = 0.0;
|
||||
_cur_expand_heap_time_ms = 0.0;
|
||||
_cur_ref_proc_time_ms = 0.0;
|
||||
_cur_ref_enq_time_ms = 0.0;
|
||||
_cur_weak_ref_proc_time_ms = 0.0;
|
||||
_cur_collection_start_sec = 0.0;
|
||||
_root_region_scan_wait_time_ms = 0.0;
|
||||
@ -383,7 +382,6 @@ double G1GCPhaseTimes::print_post_evacuate_collection_set() const {
|
||||
_recorded_preserve_cm_referents_time_ms +
|
||||
_cur_ref_proc_time_ms +
|
||||
_cur_weak_ref_proc_time_ms +
|
||||
_cur_ref_enq_time_ms +
|
||||
_cur_clear_ct_time_ms +
|
||||
_recorded_merge_pss_time_ms +
|
||||
_cur_strong_code_root_purge_time_ms +
|
||||
@ -416,9 +414,6 @@ double G1GCPhaseTimes::print_post_evacuate_collection_set() const {
|
||||
trace_time("Remove Self Forwards",_cur_evac_fail_remove_self_forwards);
|
||||
}
|
||||
|
||||
debug_time_for_reference("Reference Enqueuing", _cur_ref_enq_time_ms);
|
||||
_ref_phase_times.print_enqueue_phase(2, false);
|
||||
|
||||
debug_time("Merge Per-Thread State", _recorded_merge_pss_time_ms);
|
||||
debug_time("Code Roots Purge", _cur_strong_code_root_purge_time_ms);
|
||||
|
||||
|
@ -261,10 +261,6 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
|
||||
_cur_weak_ref_proc_time_ms = ms;
|
||||
}
|
||||
|
||||
void record_ref_enq_time(double ms) {
|
||||
_cur_ref_enq_time_ms = ms;
|
||||
}
|
||||
|
||||
void record_root_region_scan_wait_time(double time_ms) {
|
||||
_root_region_scan_wait_time_ms = time_ms;
|
||||
}
|
||||
|
@ -260,11 +260,7 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
|
||||
DerivedPointerTable::update_pointers();
|
||||
#endif
|
||||
|
||||
ReferenceProcessorPhaseTimes pt(_gc_timer, ref_processor()->num_queues());
|
||||
|
||||
ref_processor()->enqueue_discovered_references(NULL, &pt);
|
||||
|
||||
pt.print_enqueue_phase();
|
||||
assert(!ref_processor()->discovery_enabled(), "Should have been disabled earlier");
|
||||
|
||||
// Update time of last GC
|
||||
reset_millis_since_last_gc();
|
||||
|
@ -1038,12 +1038,6 @@ void PSParallelCompact::post_compact()
|
||||
DerivedPointerTable::update_pointers();
|
||||
#endif
|
||||
|
||||
ReferenceProcessorPhaseTimes pt(&_gc_timer, ref_processor()->num_queues());
|
||||
|
||||
ref_processor()->enqueue_discovered_references(NULL, &pt);
|
||||
|
||||
pt.print_enqueue_phase();
|
||||
|
||||
if (ZapUnusedHeapArea) {
|
||||
heap->gen_mangle_unused_area();
|
||||
}
|
||||
|
@ -430,16 +430,6 @@ bool PSScavenge::invoke_no_policy() {
|
||||
|
||||
_gc_tracer.report_gc_reference_stats(stats);
|
||||
pt.print_all_references();
|
||||
|
||||
// Enqueue reference objects discovered during scavenge.
|
||||
if (reference_processor()->processing_is_mt()) {
|
||||
PSRefProcTaskExecutor task_executor;
|
||||
reference_processor()->enqueue_discovered_references(&task_executor, &pt);
|
||||
} else {
|
||||
reference_processor()->enqueue_discovered_references(NULL, &pt);
|
||||
}
|
||||
|
||||
pt.print_enqueue_phase();
|
||||
}
|
||||
|
||||
assert(promotion_manager->stacks_empty(),"stacks should be empty at this point");
|
||||
|
@ -517,9 +517,7 @@ void GenCollectedHeap::collect_generation(Generation* gen, bool full, size_t siz
|
||||
}
|
||||
gen->collect(full, clear_soft_refs, size, is_tlab);
|
||||
if (!rp->enqueuing_is_done()) {
|
||||
ReferenceProcessorPhaseTimes pt(NULL, rp->num_queues());
|
||||
rp->enqueue_discovered_references(NULL, &pt);
|
||||
pt.print_enqueue_phase();
|
||||
rp->disable_discovery();
|
||||
} else {
|
||||
rp->set_enqueuing_is_done(false);
|
||||
}
|
||||
|
@ -257,113 +257,6 @@ ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
|
||||
return stats;
|
||||
}
|
||||
|
||||
void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times) {
|
||||
// Enqueue references that are not made active again, and
|
||||
// clear the decks for the next collection (cycle).
|
||||
enqueue_discovered_reflists(task_executor, phase_times);
|
||||
|
||||
// Stop treating discovered references specially.
|
||||
disable_discovery();
|
||||
}
|
||||
|
||||
void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
|
||||
// Given a list of refs linked through the "discovered" field
|
||||
// (java.lang.ref.Reference.discovered), self-loop their "next" field
|
||||
// thus distinguishing them from active References, then
|
||||
// prepend them to the pending list.
|
||||
//
|
||||
// The Java threads will see the Reference objects linked together through
|
||||
// the discovered field. Instead of trying to do the write barrier updates
|
||||
// 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_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(&refs_list));
|
||||
|
||||
oop obj = NULL;
|
||||
oop next_discovered = refs_list.head();
|
||||
// Walk down the list, self-looping the next field
|
||||
// so that the References are not considered active.
|
||||
while (obj != next_discovered) {
|
||||
obj = next_discovered;
|
||||
assert(obj->is_instance(), "should be an instance object");
|
||||
assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object");
|
||||
next_discovered = java_lang_ref_Reference::discovered(obj);
|
||||
log_develop_trace(gc, ref)(" obj " INTPTR_FORMAT "/next_discovered " INTPTR_FORMAT, p2i(obj), p2i(next_discovered));
|
||||
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_discovered != obj) {
|
||||
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(obj, java_lang_ref_Reference::discovered_offset, next_discovered);
|
||||
} else {
|
||||
// This is the last object.
|
||||
// Swap refs_list into pending list and set obj's
|
||||
// discovered to what we read from the pending list.
|
||||
oop old = Universe::swap_reference_pending_list(refs_list.head());
|
||||
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(obj, java_lang_ref_Reference::discovered_offset, old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parallel enqueue task
|
||||
class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
|
||||
public:
|
||||
RefProcEnqueueTask(ReferenceProcessor& ref_processor,
|
||||
DiscoveredList discovered_refs[],
|
||||
int n_queues,
|
||||
ReferenceProcessorPhaseTimes* phase_times)
|
||||
: EnqueueTask(ref_processor, discovered_refs, n_queues, phase_times)
|
||||
{ }
|
||||
|
||||
virtual void work(unsigned int work_id) {
|
||||
RefProcWorkerTimeTracker tt(ReferenceProcessorPhaseTimes::RefEnqueue, _phase_times, work_id);
|
||||
|
||||
assert(work_id < (unsigned int)_ref_processor.max_num_queues(), "Index out-of-bounds");
|
||||
// Simplest first cut: static partitioning.
|
||||
int index = work_id;
|
||||
// The increment on "index" must correspond to the maximum number of queues
|
||||
// (n_queues) with which that ReferenceProcessor was created. That
|
||||
// is because of the "clever" way the discovered references lists were
|
||||
// allocated and are indexed into.
|
||||
assert(_n_queues == (int) _ref_processor.max_num_queues(), "Different number not expected");
|
||||
for (int j = 0;
|
||||
j < ReferenceProcessor::number_of_subclasses_of_ref();
|
||||
j++, index += _n_queues) {
|
||||
_ref_processor.enqueue_discovered_reflist(_refs_lists[index]);
|
||||
_refs_lists[index].set_head(NULL);
|
||||
_refs_lists[index].set_length(0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Enqueue references that are not made active again
|
||||
void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times) {
|
||||
|
||||
ReferenceProcessorStats stats(total_count(_discoveredSoftRefs),
|
||||
total_count(_discoveredWeakRefs),
|
||||
total_count(_discoveredFinalRefs),
|
||||
total_count(_discoveredPhantomRefs));
|
||||
|
||||
RefProcEnqueueTimeTracker tt(phase_times, stats);
|
||||
|
||||
if (_processing_is_mt && task_executor != NULL) {
|
||||
// Parallel code
|
||||
RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_queues, phase_times);
|
||||
task_executor->execute(tsk);
|
||||
} else {
|
||||
// Serial code: call the parent class's implementation
|
||||
for (uint i = 0; i < _max_num_queues * number_of_subclasses_of_ref(); i++) {
|
||||
enqueue_discovered_reflist(_discovered_refs[i]);
|
||||
_discovered_refs[i].set_head(NULL);
|
||||
_discovered_refs[i].set_length(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) {
|
||||
_current_discovered_addr = java_lang_ref_Reference::discovered_addr_raw(_current_discovered);
|
||||
oop discovered = java_lang_ref_Reference::discovered(_current_discovered);
|
||||
@ -409,6 +302,25 @@ void DiscoveredListIterator::clear_referent() {
|
||||
RawAccess<>::oop_store(_referent_addr, oop(NULL));
|
||||
}
|
||||
|
||||
void DiscoveredListIterator::enqueue() {
|
||||
// Self-loop next, so as to make Ref not active.
|
||||
java_lang_ref_Reference::set_next_raw(_current_discovered, _current_discovered);
|
||||
|
||||
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_current_discovered,
|
||||
java_lang_ref_Reference::discovered_offset,
|
||||
_next_discovered);
|
||||
}
|
||||
|
||||
void DiscoveredListIterator::complete_enqeue() {
|
||||
if (_prev_discovered != NULL) {
|
||||
// This is the last object.
|
||||
// Swap refs_list into pending list and set obj's
|
||||
// discovered to what we read from the pending list.
|
||||
oop old = Universe::swap_reference_pending_list(_refs_list.head());
|
||||
HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_prev_discovered, java_lang_ref_Reference::discovered_offset, old);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: process_phase*() are largely similar, and at a high level
|
||||
// merely iterate over the extant list applying a predicate to
|
||||
// each of its elements and possibly removing that element from the
|
||||
@ -556,13 +468,18 @@ void ReferenceProcessor::process_phase3(DiscoveredList& refs_list,
|
||||
// keep the referent around
|
||||
iter.make_referent_alive();
|
||||
}
|
||||
iter.enqueue();
|
||||
log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
|
||||
clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name());
|
||||
assert(oopDesc::is_oop(iter.obj(), UseConcMarkSweepGC), "Adding a bad reference");
|
||||
iter.next();
|
||||
}
|
||||
iter.complete_enqeue();
|
||||
// Close the reachable set
|
||||
complete_gc->do_void();
|
||||
// Clear the list.
|
||||
refs_list.set_head(NULL);
|
||||
refs_list.set_length(0);
|
||||
}
|
||||
|
||||
void
|
||||
@ -785,13 +702,6 @@ void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
|
||||
#endif
|
||||
}
|
||||
|
||||
void ReferenceProcessor::balance_all_queues() {
|
||||
balance_queues(_discoveredSoftRefs);
|
||||
balance_queues(_discoveredWeakRefs);
|
||||
balance_queues(_discoveredFinalRefs);
|
||||
balance_queues(_discoveredPhantomRefs);
|
||||
}
|
||||
|
||||
void ReferenceProcessor::process_discovered_reflist(
|
||||
DiscoveredList refs_lists[],
|
||||
ReferencePolicy* policy,
|
||||
|
@ -143,6 +143,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Do enqueuing work, i.e. notifying the GC about the changed discovered pointers.
|
||||
void enqueue();
|
||||
|
||||
// Move enqueued references to the reference pending list.
|
||||
void complete_enqeue();
|
||||
|
||||
// NULL out referent pointer.
|
||||
void clear_referent();
|
||||
|
||||
@ -273,9 +279,6 @@ class ReferenceProcessor : public ReferenceDiscoverer {
|
||||
OopClosure* keep_alive,
|
||||
VoidClosure* complete_gc);
|
||||
|
||||
// Enqueue references with a certain reachability level
|
||||
void enqueue_discovered_reflist(DiscoveredList& refs_list);
|
||||
|
||||
// "Preclean" all the discovered reference lists
|
||||
// by removing references with strongly reachable referents.
|
||||
// The first argument is a predicate on an oop that indicates
|
||||
@ -295,9 +298,6 @@ class ReferenceProcessor : public ReferenceDiscoverer {
|
||||
// occupying the i / _num_queues slot.
|
||||
const char* list_name(uint i);
|
||||
|
||||
void enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times);
|
||||
|
||||
// "Preclean" the given discovered reference list
|
||||
// by removing references with strongly reachable referents.
|
||||
// Currently used in support of CMS only.
|
||||
@ -387,8 +387,6 @@ public:
|
||||
// iterate over oops
|
||||
void weak_oops_do(OopClosure* f); // weak roots
|
||||
|
||||
// Balance each of the discovered lists.
|
||||
void balance_all_queues();
|
||||
void verify_list(DiscoveredList& ref_list);
|
||||
|
||||
// Discover a Reference object, using appropriate discovery criteria
|
||||
@ -405,10 +403,6 @@ public:
|
||||
AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times);
|
||||
|
||||
// Enqueue references at end of GC (called by the garbage collector)
|
||||
void enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times);
|
||||
|
||||
// If a discovery is in process that is being superceded, abandon it: all
|
||||
// the discovered lists will be empty, and all the objects on them will
|
||||
// have NULL discovered fields. Must be called only at a safepoint.
|
||||
|
@ -78,8 +78,6 @@ static const char* phase_enum_2_phase_string(ReferenceProcessorPhaseTimes::RefPr
|
||||
case ReferenceProcessorPhaseTimes::FinalRefPhase3:
|
||||
case ReferenceProcessorPhaseTimes::PhantomRefPhase3:
|
||||
return "Phase3";
|
||||
case ReferenceProcessorPhaseTimes::RefEnqueue:
|
||||
return "Reference Enqueuing";
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
return NULL;
|
||||
@ -191,21 +189,6 @@ RefProcPhaseTimesTracker::~RefProcPhaseTimesTracker() {
|
||||
times->set_ref_cleared(ref_type, discovered - after_count);
|
||||
}
|
||||
|
||||
RefProcEnqueueTimeTracker::RefProcEnqueueTimeTracker(ReferenceProcessorPhaseTimes* phase_times,
|
||||
ReferenceProcessorStats& stats) :
|
||||
RefProcPhaseTimeBaseTracker("Reference Enqueuing", phase_times) {
|
||||
phase_times->set_ref_enqueued(REF_SOFT, stats.soft_count());
|
||||
phase_times->set_ref_enqueued(REF_WEAK, stats.weak_count());
|
||||
phase_times->set_ref_enqueued(REF_FINAL, stats.final_count());
|
||||
phase_times->set_ref_enqueued(REF_PHANTOM, stats.phantom_count());
|
||||
}
|
||||
|
||||
RefProcEnqueueTimeTracker::~RefProcEnqueueTimeTracker() {
|
||||
double elapsed = elapsed_time();
|
||||
|
||||
phase_times()->set_par_phase_time_ms(ReferenceProcessorPhaseTimes::RefEnqueue, elapsed);
|
||||
}
|
||||
|
||||
ReferenceProcessorPhaseTimes::ReferenceProcessorPhaseTimes(GCTimer* gc_timer, uint max_gc_threads) :
|
||||
_gc_timer(gc_timer), _processing_is_mt(false) {
|
||||
|
||||
@ -369,17 +352,6 @@ ReferenceProcessorPhaseTimes::par_phase(RefProcPhaseNumbers phase_number) const
|
||||
return (RefProcParPhases)result;
|
||||
}
|
||||
|
||||
void ReferenceProcessorPhaseTimes::print_enqueue_phase(uint base_indent, bool print_total) const {
|
||||
if (print_total) {
|
||||
print_phase(RefEnqueue, base_indent);
|
||||
}
|
||||
|
||||
log_debug(gc, phases, ref)("%sReference Counts: Soft: " SIZE_FORMAT " Weak: " SIZE_FORMAT
|
||||
" Final: " SIZE_FORMAT " Phantom: " SIZE_FORMAT ,
|
||||
Indents[base_indent + 1], ref_enqueued(REF_SOFT), ref_enqueued(REF_WEAK),
|
||||
ref_enqueued(REF_FINAL), ref_enqueued(REF_PHANTOM));
|
||||
}
|
||||
|
||||
#define TIME_FORMAT "%.1lfms"
|
||||
|
||||
void ReferenceProcessorPhaseTimes::print_all_references(uint base_indent, bool print_total) const {
|
||||
|
@ -46,7 +46,6 @@ public:
|
||||
FinalRefPhase3,
|
||||
PhantomRefPhase2,
|
||||
PhantomRefPhase3,
|
||||
RefEnqueue,
|
||||
RefParPhaseMax
|
||||
};
|
||||
|
||||
@ -133,7 +132,6 @@ public:
|
||||
// Reset all fields. If not reset at next cycle, an assertion will fail.
|
||||
void reset();
|
||||
|
||||
void print_enqueue_phase(uint base_indent = 0, bool print_total = true) const;
|
||||
void print_all_references(uint base_indent = 0, bool print_total = true) const;
|
||||
};
|
||||
|
||||
@ -203,13 +201,4 @@ public:
|
||||
~RefProcPhaseTimesTracker();
|
||||
};
|
||||
|
||||
// Updates enqueue time related information.
|
||||
// - Enqueueing time, enqueued reference count and stats for each working thread if MT processed.
|
||||
class RefProcEnqueueTimeTracker : public RefProcPhaseTimeBaseTracker {
|
||||
public:
|
||||
RefProcEnqueueTimeTracker(ReferenceProcessorPhaseTimes* phase_times,
|
||||
ReferenceProcessorStats& stats);
|
||||
~RefProcEnqueueTimeTracker();
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP
|
||||
|
@ -141,7 +141,6 @@ public class TestGCLogMessages {
|
||||
new LogMessageWithLevel("Resize TLABs", Level.DEBUG),
|
||||
// Reference Processing
|
||||
new LogMessageWithLevel("Reference Processing", Level.DEBUG),
|
||||
new LogMessageWithLevel("Reference Enqueuing", Level.DEBUG),
|
||||
// VM internal reference processing
|
||||
new LogMessageWithLevel("Weak Processing", Level.DEBUG),
|
||||
|
||||
|
@ -93,9 +93,6 @@ public class TestPrintReferences {
|
||||
gcLogTimeRegex + indent(8) + "Discovered: " + countRegex + "\n" +
|
||||
gcLogTimeRegex + indent(8) + "Cleared: " + countRegex + "\n";
|
||||
String softRefDetailRegex = gcLogTimeRegex + indent(8) + phase1 + ": " + timeRegex + "\n" + refDetailRegex;
|
||||
String enqueueRegex = gcLogTimeRegex + indent(4) + "Reference Enqueuing: " + timeRegex + "\n";
|
||||
String enqueueDetailRegex = gcLogTimeRegex + indent(6) + "Reference Counts: Soft: " + countRegex +
|
||||
" Weak: " + countRegex + " Final: " + countRegex + " Phantom: " + countRegex + "\n";
|
||||
|
||||
output.shouldMatch(/* Total Reference processing time */
|
||||
totalRegex +
|
||||
@ -106,11 +103,7 @@ public class TestPrintReferences {
|
||||
/* FinalReference processing */
|
||||
finalRefRegex + balanceRegex + refDetailRegex +
|
||||
/* PhantomReference processing */
|
||||
phantomRefRegex + balanceRegex + refDetailRegex +
|
||||
/* Total Enqueuing time */
|
||||
enqueueRegex +
|
||||
/* Enqueued Stats */
|
||||
enqueueDetailRegex
|
||||
phantomRefRegex + balanceRegex + refDetailRegex
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user