--- /dev/null 2017-06-09 15:42:47.034680681 -0700 +++ new/src/share/vm/gc/shared/referenceProcessorPhaseTimes.hpp 2017-06-09 16:48:19.872192878 -0700 @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP +#define SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP + +#include "gc/shared/referenceProcessorStats.hpp" +#include "gc/shared/workerDataArray.inline.hpp" + +class DiscoveredList; +class GCTimer; + +class ReferenceProcessorPhaseTimes : public CHeapObj { +public: + // For phases that have parallel work. + enum RefProcPhases { + RefPhase1, + RefPhase2, + RefPhase3, + RefEnqueue, + RefPhaseMax + }; + +private: + // Records per thread information of each phase. + WorkerDataArray* _worker_time_sec[RefPhaseMax]; + // Records elapsed time of each phase. + double _phase_time_ms[RefPhaseMax]; + double _balance_queues_time_ms; + bool _processing_is_mt; + const uint _max_gc_threads; + +public: + ReferenceProcessorPhaseTimes(uint max_gc_threads, bool processing_is_mt); + + static double uninitialized() { return -1.0; } + + WorkerDataArray* worker_time_sec(RefProcPhases phase) const; + double phase_time_ms(RefProcPhases phase) const; + void set_phase_time_ms(RefProcPhases phase, double time); + double balance_queues_time_ms() const { return _balance_queues_time_ms; } + void set_balance_queues_time_ms(double time_ms) { _balance_queues_time_ms = time_ms; } + bool processing_is_mt() const { return _processing_is_mt; } + void set_processing_is_mt(bool processing_is_mt) { _processing_is_mt = processing_is_mt; } + uint max_gc_threads() const { return _max_gc_threads; } + + void reset(); +}; + +// Updates working time of each worker thread. +class RefProcWorkerTimeTracker : public StackObj { +protected: + WorkerDataArray* _worker_time; + double _start_time; + uint _worker_id; + +public: + RefProcWorkerTimeTracker(WorkerDataArray* worker_time, uint worker_id); + ~RefProcWorkerTimeTracker(); +}; + +class RefProcPhaseTimeBaseTracker : public StackObj { +protected: + const char* _title; + ReferenceProcessorPhaseTimes* _phase_times; + Ticks _start_ticks; + Ticks _end_ticks; + GCTimer* _gc_timer; + + Ticks end_ticks(); + double elapsed_time(); + ReferenceProcessorPhaseTimes* phase_times() const { return _phase_times; } + // Print phase elapsed time with each worker information if MT processed. + void print_phase(ReferenceProcessorPhaseTimes::RefProcPhases phase, uint indent); + +public: + RefProcPhaseTimeBaseTracker(const char* title, + ReferenceProcessorPhaseTimes* phase_times, + GCTimer* gc_timer); + ~RefProcPhaseTimeBaseTracker(); +}; + +// Updates queue balance time at ReferenceProcessorPhaseTimes and +// save it into GCTimer. +class RefProcBalanceQueuesTimeTracker : public RefProcPhaseTimeBaseTracker { +public: + RefProcBalanceQueuesTimeTracker(ReferenceProcessorPhaseTimes* phase_times, + GCTimer* gc_timer); + ~RefProcBalanceQueuesTimeTracker(); +}; + +// Updates phase time at ReferenceProcessorPhaseTimes and save it into GCTimer. +class RefProcPhaseTimeTracker : public RefProcPhaseTimeBaseTracker { + ReferenceProcessorPhaseTimes::RefProcPhases _phase; + +public: + RefProcPhaseTimeTracker(ReferenceProcessorPhaseTimes::RefProcPhases phase, + ReferenceProcessorPhaseTimes* phase_times, + GCTimer* gc_timer); + ~RefProcPhaseTimeTracker(); +}; + +// Prints phase time log. +// - Each phase processing time, cleared/discovered reference counts and stats for each working threads if MT processed. +// From destructor, ReferenceProcessorPhaseTimes will be reset for next time use. +class RefProcPhaseTimesLogger : public RefProcPhaseTimeBaseTracker { + DiscoveredList* _lists; + size_t _ref_discovered; + +public: + RefProcPhaseTimesLogger(const char* title, + ReferenceProcessorPhaseTimes* phase_times, + DiscoveredList lists[], + GCTimer* gc_timer); + ~RefProcPhaseTimesLogger(); +}; + +// Prints enqueue time log. +// - Enqueueing time, enqueued reference count and stats for each working thread if MT processed. +class RefProcEnqueueTimeLogger : public RefProcPhaseTimeBaseTracker { + ReferenceProcessorStats& _stats; + +public: + RefProcEnqueueTimeLogger(ReferenceProcessorPhaseTimes* phase_times, + ReferenceProcessorStats& stats, + GCTimer* gc_timer); + ~RefProcEnqueueTimeLogger(); +}; + +#endif // SHARE_VM_GC_SHARED_REFERENCEPROCESSORPHASETIMES_HPP