--- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2015-03-03 17:05:48.307761754 +0100 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 2015-03-03 17:05:48.195761759 +0100 @@ -5648,12 +5648,14 @@ // reported parallel time. } + G1GCPhaseTimes* phase_times = g1_policy()->phase_times(); + double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0; - g1_policy()->phase_times()->record_par_time(par_time_ms); + phase_times->record_par_time(par_time_ms); double code_root_fixup_time_ms = (os::elapsedTime() - end_par_time_sec) * 1000.0; - g1_policy()->phase_times()->record_code_root_fixup_time(code_root_fixup_time_ms); + phase_times->record_code_root_fixup_time(code_root_fixup_time_ms); set_par_threads(0); @@ -5665,9 +5667,14 @@ process_discovered_references(n_workers); if (G1StringDedup::is_enabled()) { + double fixup_start = os::elapsedTime(); + G1STWIsAliveClosure is_alive(this); G1KeepAliveClosure keep_alive(this); - G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive); + G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive, true, phase_times); + + double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0; + phase_times->record_string_dedup_fixup_time(fixup_time_ms); } _allocator->release_gc_alloc_regions(n_workers, evacuation_info); --- old/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp 2015-03-03 17:05:48.559761743 +0100 +++ new/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp 2015-03-03 17:05:48.455761748 +0100 @@ -125,6 +125,10 @@ template void WorkerDataArray::verify() { + if (!_enabled) { + return; + } + for (uint i = 0; i < _length; i++) { assert(_data[i] != WorkerDataArray::uninitialized(), err_msg("Invalid data for worker %u in '%s'", i, _title)); @@ -312,11 +316,15 @@ G1GCPhaseTimesTracker::G1GCPhaseTimesTracker(G1GCPhaseTimes* phase_times, G1GCPhaseTimes::GCPhases phase, uint worker_id) : _phase_times(phase_times), _phase(phase), _worker_id(worker_id) { - _start_time = os::elapsedTime(); + if (_phase_times != NULL) { + _start_time = os::elapsedTime(); + } } G1GCPhaseTimesTracker::~G1GCPhaseTimesTracker() { - _phase_times->record_time_secs(_phase, _worker_id, os::elapsedTime() - _start_time); + if (_phase_times != NULL) { + _phase_times->record_time_secs(_phase, _worker_id, os::elapsedTime() - _start_time); + } } void G1GCPhasePrinter::print_single_length(G1GCPhaseTimes::GCPhases phase_id, WorkerDataArray* phase) { --- old/src/share/vm/gc_implementation/g1/g1StringDedup.cpp 2015-03-03 17:05:48.739761736 +0100 +++ new/src/share/vm/gc_implementation/g1/g1StringDedup.cpp 2015-03-03 17:05:48.635761740 +0100 @@ -106,7 +106,7 @@ void G1StringDedup::oops_do(OopClosure* keep_alive) { assert(is_enabled(), "String deduplication not enabled"); - unlink_or_oops_do(NULL, keep_alive); + unlink_or_oops_do(NULL, keep_alive, true /* allow_resize_and_rehash */); } void G1StringDedup::unlink(BoolObjectClosure* is_alive) { @@ -123,43 +123,39 @@ class G1StringDedupUnlinkOrOopsDoTask : public AbstractGangTask { private: G1StringDedupUnlinkOrOopsDoClosure _cl; + G1GCPhaseTimes* _phase_times; public: G1StringDedupUnlinkOrOopsDoTask(BoolObjectClosure* is_alive, OopClosure* keep_alive, - bool allow_resize_and_rehash) : + bool allow_resize_and_rehash, + G1GCPhaseTimes* phase_times) : AbstractGangTask("G1StringDedupUnlinkOrOopsDoTask"), - _cl(is_alive, keep_alive, allow_resize_and_rehash) { - } + _cl(is_alive, keep_alive, allow_resize_and_rehash), _phase_times(phase_times) { } virtual void work(uint worker_id) { - double queue_fixup_start = os::elapsedTime(); - G1StringDedupQueue::unlink_or_oops_do(&_cl); - - double table_fixup_start = os::elapsedTime(); - G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id); - - double queue_fixup_time_sec = table_fixup_start - queue_fixup_start; - double table_fixup_time_sec = os::elapsedTime() - table_fixup_start; - G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); - g1p->phase_times()->record_time_secs(G1GCPhaseTimes::StringDedupQueueFixup, worker_id, queue_fixup_time_sec); - g1p->phase_times()->record_time_secs(G1GCPhaseTimes::StringDedupTableFixup, worker_id, table_fixup_time_sec); + { + G1GCPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupQueueFixup, worker_id); + G1StringDedupQueue::unlink_or_oops_do(&_cl); + } + { + G1GCPhaseTimesTracker x(_phase_times, G1GCPhaseTimes::StringDedupTableFixup, worker_id); + G1StringDedupTable::unlink_or_oops_do(&_cl, worker_id); + } } }; -void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, bool allow_resize_and_rehash) { +void G1StringDedup::unlink_or_oops_do(BoolObjectClosure* is_alive, + OopClosure* keep_alive, + bool allow_resize_and_rehash, + G1GCPhaseTimes* phase_times) { assert(is_enabled(), "String deduplication not enabled"); - G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy(); - double fixup_start = os::elapsedTime(); - G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash); + G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash, phase_times); G1CollectedHeap* g1h = G1CollectedHeap::heap(); g1h->set_par_threads(); g1h->workers()->run_task(&task); g1h->set_par_threads(0); - - double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0; - g1p->phase_times()->record_string_dedup_fixup_time(fixup_time_ms); } void G1StringDedup::threads_do(ThreadClosure* tc) { --- old/src/share/vm/gc_implementation/g1/g1StringDedup.hpp 2015-03-03 17:05:48.919761728 +0100 +++ new/src/share/vm/gc_implementation/g1/g1StringDedup.hpp 2015-03-03 17:05:48.819761733 +0100 @@ -91,6 +91,7 @@ class ThreadClosure; class outputStream; class G1StringDedupTable; +class G1GCPhaseTimes; // // Main interface for interacting with string deduplication. @@ -131,7 +132,7 @@ static void oops_do(OopClosure* keep_alive); static void unlink(BoolObjectClosure* is_alive); static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, - bool allow_resize_and_rehash = true); + bool allow_resize_and_rehash, G1GCPhaseTimes* phase_times = NULL); static void threads_do(ThreadClosure* tc); static void print_worker_threads_on(outputStream* st);