js/src/gc/Statistics.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial