Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 */ |