js/src/gc/Statistics.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:b8f82d92cff5
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef gc_Statistics_h
8 #define gc_Statistics_h
9
10 #include "mozilla/DebugOnly.h"
11 #include "mozilla/PodOperations.h"
12
13 #include "jsalloc.h"
14 #include "jspubtd.h"
15
16 #include "js/GCAPI.h"
17 #include "js/Vector.h"
18
19 struct JSCompartment;
20
21 namespace js {
22 namespace gcstats {
23
24 enum Phase {
25 PHASE_GC_BEGIN,
26 PHASE_WAIT_BACKGROUND_THREAD,
27 PHASE_MARK_DISCARD_CODE,
28 PHASE_PURGE,
29 PHASE_MARK,
30 PHASE_MARK_ROOTS,
31 PHASE_MARK_DELAYED,
32 PHASE_SWEEP,
33 PHASE_SWEEP_MARK,
34 PHASE_SWEEP_MARK_TYPES,
35 PHASE_SWEEP_MARK_INCOMING_BLACK,
36 PHASE_SWEEP_MARK_WEAK,
37 PHASE_SWEEP_MARK_INCOMING_GRAY,
38 PHASE_SWEEP_MARK_GRAY,
39 PHASE_SWEEP_MARK_GRAY_WEAK,
40 PHASE_FINALIZE_START,
41 PHASE_SWEEP_ATOMS,
42 PHASE_SWEEP_COMPARTMENTS,
43 PHASE_SWEEP_DISCARD_CODE,
44 PHASE_SWEEP_TABLES,
45 PHASE_SWEEP_TABLES_WRAPPER,
46 PHASE_SWEEP_TABLES_BASE_SHAPE,
47 PHASE_SWEEP_TABLES_INITIAL_SHAPE,
48 PHASE_SWEEP_TABLES_TYPE_OBJECT,
49 PHASE_SWEEP_TABLES_BREAKPOINT,
50 PHASE_SWEEP_TABLES_REGEXP,
51 PHASE_DISCARD_ANALYSIS,
52 PHASE_DISCARD_TI,
53 PHASE_FREE_TI_ARENA,
54 PHASE_SWEEP_TYPES,
55 PHASE_SWEEP_OBJECT,
56 PHASE_SWEEP_STRING,
57 PHASE_SWEEP_SCRIPT,
58 PHASE_SWEEP_SHAPE,
59 PHASE_SWEEP_JITCODE,
60 PHASE_FINALIZE_END,
61 PHASE_DESTROY,
62 PHASE_GC_END,
63
64 PHASE_LIMIT
65 };
66
67 enum Stat {
68 STAT_NEW_CHUNK,
69 STAT_DESTROY_CHUNK,
70 STAT_MINOR_GC,
71
72 STAT_LIMIT
73 };
74
75 class StatisticsSerializer;
76
77 struct Statistics {
78 Statistics(JSRuntime *rt);
79 ~Statistics();
80
81 void beginPhase(Phase phase);
82 void endPhase(Phase phase);
83
84 void beginSlice(int collectedCount, int zoneCount, int compartmentCount, JS::gcreason::Reason reason);
85 void endSlice();
86
87 void reset(const char *reason) { slices.back().resetReason = reason; }
88 void nonincremental(const char *reason) { nonincrementalReason = reason; }
89
90 void count(Stat s) {
91 JS_ASSERT(s < STAT_LIMIT);
92 counts[s]++;
93 }
94
95 int64_t beginSCC();
96 void endSCC(unsigned scc, int64_t start);
97
98 jschar *formatMessage();
99 jschar *formatJSON(uint64_t timestamp);
100
101 private:
102 JSRuntime *runtime;
103
104 int64_t startupTime;
105
106 FILE *fp;
107 bool fullFormat;
108
109 /*
110 * GCs can't really nest, but a second GC can be triggered from within the
111 * JSGC_END callback.
112 */
113 int gcDepth;
114
115 int collectedCount;
116 int zoneCount;
117 int compartmentCount;
118 const char *nonincrementalReason;
119
120 struct SliceData {
121 SliceData(JS::gcreason::Reason reason, int64_t start, size_t startFaults)
122 : reason(reason), resetReason(nullptr), start(start), startFaults(startFaults)
123 {
124 mozilla::PodArrayZero(phaseTimes);
125 }
126
127 JS::gcreason::Reason reason;
128 const char *resetReason;
129 int64_t start, end;
130 size_t startFaults, endFaults;
131 int64_t phaseTimes[PHASE_LIMIT];
132
133 int64_t duration() const { return end - start; }
134 };
135
136 Vector<SliceData, 8, SystemAllocPolicy> slices;
137
138 /* Most recent time when the given phase started. */
139 int64_t phaseStartTimes[PHASE_LIMIT];
140
141 /* Total time in a given phase for this GC. */
142 int64_t phaseTimes[PHASE_LIMIT];
143
144 /* Total time in a given phase over all GCs. */
145 int64_t phaseTotals[PHASE_LIMIT];
146
147 /* Number of events of this type for this GC. */
148 unsigned int counts[STAT_LIMIT];
149
150 /* Allocated space before the GC started. */
151 size_t preBytes;
152
153 #ifdef DEBUG
154 /* Phases that are currently on stack. */
155 static const size_t MAX_NESTING = 8;
156 Phase phaseNesting[MAX_NESTING];
157 #endif
158 mozilla::DebugOnly<size_t> phaseNestingDepth;
159
160 /* Sweep times for SCCs of compartments. */
161 Vector<int64_t, 0, SystemAllocPolicy> sccTimes;
162
163 void beginGC();
164 void endGC();
165
166 void gcDuration(int64_t *total, int64_t *maxPause);
167 void sccDurations(int64_t *total, int64_t *maxPause);
168 void printStats();
169 bool formatData(StatisticsSerializer &ss, uint64_t timestamp);
170
171 double computeMMU(int64_t resolution);
172 };
173
174 struct AutoGCSlice
175 {
176 AutoGCSlice(Statistics &stats, int collectedCount, int zoneCount, int compartmentCount,
177 JS::gcreason::Reason reason
178 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
179 : stats(stats)
180 {
181 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
182 stats.beginSlice(collectedCount, zoneCount, compartmentCount, reason);
183 }
184 ~AutoGCSlice() { stats.endSlice(); }
185
186 Statistics &stats;
187 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
188 };
189
190 struct AutoPhase
191 {
192 AutoPhase(Statistics &stats, Phase phase
193 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
194 : stats(stats), phase(phase)
195 {
196 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
197 stats.beginPhase(phase);
198 }
199 ~AutoPhase() {
200 stats.endPhase(phase);
201 }
202
203 Statistics &stats;
204 Phase phase;
205 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
206 };
207
208 struct MaybeAutoPhase
209 {
210 MaybeAutoPhase(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
211 : stats(nullptr)
212 {
213 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
214 }
215 void construct(Statistics &statsArg, Phase phaseArg)
216 {
217 JS_ASSERT(!stats);
218 stats = &statsArg;
219 phase = phaseArg;
220 stats->beginPhase(phase);
221 }
222 ~MaybeAutoPhase() {
223 if (stats)
224 stats->endPhase(phase);
225 }
226
227 Statistics *stats;
228 Phase phase;
229 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
230 };
231
232 struct AutoSCC
233 {
234 AutoSCC(Statistics &stats, unsigned scc
235 MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
236 : stats(stats), scc(scc)
237 {
238 MOZ_GUARD_OBJECT_NOTIFIER_INIT;
239 start = stats.beginSCC();
240 }
241 ~AutoSCC() {
242 stats.endSCC(scc, start);
243 }
244
245 Statistics &stats;
246 unsigned scc;
247 int64_t start;
248 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
249 };
250
251 const char *ExplainReason(JS::gcreason::Reason reason);
252
253 } /* namespace gcstats */
254 } /* namespace js */
255
256 #endif /* gc_Statistics_h */

mercurial