/* * 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