1/*
2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_GC_SHARED_WEAKPROCESSORPHASETIMES_HPP
26#define SHARE_GC_SHARED_WEAKPROCESSORPHASETIMES_HPP
27
28#include "gc/shared/weakProcessorPhases.hpp"
29#include "memory/allocation.hpp"
30#include "utilities/globalDefinitions.hpp"
31#include "utilities/ticks.hpp"
32
33template<typename T> class WorkerDataArray;
34
35class WeakProcessorPhaseTimes : public CHeapObj<mtGC> {
36 enum {
37 DeadItems,
38 TotalItems
39 };
40 uint _max_threads;
41 uint _active_workers;
42
43 // Total time for weak processor.
44 double _total_time_sec;
45
46 // Total time for each serially processed phase. Entries for phases
47 // processed by multiple threads are unused, as are entries for
48 // unexecuted phases.
49 double _phase_times_sec[WeakProcessorPhases::phase_count];
50 size_t _phase_dead_items[WeakProcessorPhases::phase_count];
51 size_t _phase_total_items[WeakProcessorPhases::phase_count];
52
53 // Per-worker times and linked items, if multiple threads used and the phase was executed.
54 WorkerDataArray<double>* _worker_data[WeakProcessorPhases::oop_storage_phase_count];
55 WorkerDataArray<size_t>* _worker_dead_items[WeakProcessorPhases::oop_storage_phase_count];
56 WorkerDataArray<size_t>* _worker_total_items[WeakProcessorPhases::oop_storage_phase_count];
57
58 WorkerDataArray<double>* worker_data(WeakProcessorPhase phase) const;
59
60 void log_st_phase(WeakProcessorPhase phase, uint indent) const;
61 void log_mt_phase_summary(WeakProcessorPhase phase, uint indent) const;
62 template <typename T>
63 void log_mt_phase_details(WorkerDataArray<T>* data, uint indent) const;
64
65public:
66 WeakProcessorPhaseTimes(uint max_threads);
67 ~WeakProcessorPhaseTimes();
68
69 uint max_threads() const;
70 uint active_workers() const;
71 void set_active_workers(uint n);
72
73 double total_time_sec() const;
74 double phase_time_sec(WeakProcessorPhase phase) const;
75 double worker_time_sec(uint worker_id, WeakProcessorPhase phase) const;
76
77 void record_total_time_sec(double time_sec);
78 void record_phase_time_sec(WeakProcessorPhase phase, double time_sec);
79 void record_phase_items(WeakProcessorPhase phase, size_t num_dead, size_t num_total);
80 void record_worker_time_sec(uint worker_id, WeakProcessorPhase phase, double time_sec);
81 void record_worker_items(uint worker_id, WeakProcessorPhase phase, size_t num_dead, size_t num_total);
82
83 void reset();
84
85 void log_print(uint indent = 0) const;
86 void log_print_phases(uint indent = 0) const;
87};
88
89// Record total weak processor time and worker count in times.
90// Does nothing if times is NULL.
91class WeakProcessorTimeTracker : StackObj {
92 WeakProcessorPhaseTimes* _times;
93 Ticks _start_time;
94
95public:
96 WeakProcessorTimeTracker(WeakProcessorPhaseTimes* times);
97 ~WeakProcessorTimeTracker();
98};
99
100// Record phase time contribution for the current thread in phase times.
101// Does nothing if phase times is NULL.
102class WeakProcessorPhaseTimeTracker : StackObj {
103private:
104 WeakProcessorPhaseTimes* _times;
105 WeakProcessorPhase _phase;
106 uint _worker_id;
107 Ticks _start_time;
108
109public:
110 // For tracking serial phase times.
111 // Precondition: WeakProcessorPhases::is_serial(phase)
112 WeakProcessorPhaseTimeTracker(WeakProcessorPhaseTimes* times,
113 WeakProcessorPhase phase);
114
115 // For tracking possibly parallel phase times (even if processed by
116 // only one thread).
117 // Precondition: WeakProcessorPhases::is_oop_storage(phase)
118 // Precondition: worker_id < times->max_threads().
119 WeakProcessorPhaseTimeTracker(WeakProcessorPhaseTimes* times,
120 WeakProcessorPhase phase,
121 uint worker_id);
122
123 ~WeakProcessorPhaseTimeTracker();
124};
125
126#endif // SHARE_GC_SHARED_WEAKPROCESSORPHASETIMES_HPP
127