Line data Source code
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 TraceLoggingTypes_h
8 : #define TraceLoggingTypes_h
9 :
10 : #include "jsalloc.h"
11 : #include "jsstr.h"
12 :
13 : // Tree items, meaning they have a start and stop and form a nested tree.
14 : #define TRACELOGGER_TREE_ITEMS(_) \
15 : _(AnnotateScripts) \
16 : _(Baseline) \
17 : _(BaselineCompilation) \
18 : _(Engine) \
19 : _(GC) \
20 : _(GCAllocation) \
21 : _(GCSweeping) \
22 : _(Interpreter) \
23 : _(InlinedScripts) \
24 : _(IonAnalysis) \
25 : _(IonCompilation) \
26 : _(IonCompilationPaused) \
27 : _(IonLinking) \
28 : _(IonMonkey) \
29 : _(IrregexpCompile) \
30 : _(IrregexpExecute) \
31 : _(MinorGC) \
32 : _(Frontend) \
33 : _(ParsingFull) \
34 : _(ParsingSyntax) \
35 : _(BytecodeEmission) \
36 : _(BytecodeFoldConstants) \
37 : _(BytecodeNameFunctions) \
38 : _(DecodeScript) \
39 : _(DecodeFunction) \
40 : _(EncodeScript) \
41 : _(EncodeFunction) \
42 : _(Scripts) \
43 : _(VM) \
44 : _(CompressSource) \
45 : _(WasmCompilation) \
46 : _(Call) \
47 : \
48 : /* Specific passes during ion compilation */ \
49 : _(PruneUnusedBranches) \
50 : _(FoldTests) \
51 : _(FoldEmptyBlocks) \
52 : _(SplitCriticalEdges) \
53 : _(RenumberBlocks) \
54 : _(ScalarReplacement) \
55 : _(DominatorTree) \
56 : _(PhiAnalysis) \
57 : _(MakeLoopsContiguous) \
58 : _(ApplyTypes) \
59 : _(EagerSimdUnbox) \
60 : _(AliasAnalysis) \
61 : _(GVN) \
62 : _(LICM) \
63 : _(Sincos) \
64 : _(RangeAnalysis) \
65 : _(LoopUnrolling) \
66 : _(Sink) \
67 : _(RemoveUnnecessaryBitops) \
68 : _(FoldLinearArithConstants) \
69 : _(EffectiveAddressAnalysis) \
70 : _(AlignmentMaskAnalysis) \
71 : _(EliminateDeadCode) \
72 : _(ReorderInstructions) \
73 : _(EdgeCaseAnalysis) \
74 : _(EliminateRedundantChecks) \
75 : _(AddKeepAliveInstructions) \
76 : _(GenerateLIR) \
77 : _(RegisterAllocation) \
78 : _(GenerateCode) \
79 : _(IonBuilderRestartLoop) \
80 : _(VMSpecific)
81 :
82 : // Log items, with timestamp only.
83 : #define TRACELOGGER_LOG_ITEMS(_) \
84 : _(Bailout) \
85 : _(Invalidation) \
86 : _(Disable) \
87 : _(Enable) \
88 : _(Stop)
89 :
90 : // Predefined IDs for common operations. These IDs can be used
91 : // without using TraceLogCreateTextId, because there are already created.
92 : enum TraceLoggerTextId {
93 : TraceLogger_Error = 0,
94 : TraceLogger_Internal,
95 : #define DEFINE_TEXT_ID(textId) TraceLogger_ ## textId,
96 : TRACELOGGER_TREE_ITEMS(DEFINE_TEXT_ID)
97 : TraceLogger_LastTreeItem,
98 : TRACELOGGER_LOG_ITEMS(DEFINE_TEXT_ID)
99 : #undef DEFINE_TEXT_ID
100 : TraceLogger_Last
101 : };
102 :
103 : inline const char*
104 195 : TLTextIdString(TraceLoggerTextId id)
105 : {
106 195 : switch (id) {
107 : case TraceLogger_Error:
108 0 : return "TraceLogger failed to process text";
109 : case TraceLogger_Internal:
110 0 : return "TraceLogger overhead";
111 : #define NAME(textId) case TraceLogger_ ## textId: return #textId;
112 3 : TRACELOGGER_TREE_ITEMS(NAME)
113 3 : TRACELOGGER_LOG_ITEMS(NAME)
114 : #undef NAME
115 : default:
116 0 : MOZ_CRASH();
117 : }
118 : }
119 :
120 : uint32_t
121 : TLStringToTextId(JSLinearString* str);
122 :
123 : // Return whether a given item id can be enabled/disabled.
124 : inline bool
125 213 : TLTextIdIsTogglable(uint32_t id)
126 : {
127 213 : if (id == TraceLogger_Error)
128 0 : return false;
129 213 : if (id == TraceLogger_Internal)
130 3 : return false;
131 210 : if (id == TraceLogger_Stop)
132 3 : return false;
133 : // Actually never used. But added here so it doesn't show as toggle
134 207 : if (id == TraceLogger_LastTreeItem)
135 3 : return false;
136 204 : if (id == TraceLogger_Last)
137 0 : return false;
138 : // Cannot toggle the logging of one engine on/off, because at the stop
139 : // event it is sometimes unknown which engine was running.
140 204 : if (id == TraceLogger_IonMonkey || id == TraceLogger_Baseline || id == TraceLogger_Interpreter)
141 9 : return false;
142 195 : return true;
143 : }
144 :
145 : inline bool
146 134937 : TLTextIdIsTreeEvent(uint32_t id)
147 : {
148 : // Everything between TraceLogger_Error and TraceLogger_LastTreeItem are tree events and
149 : // atm also every custom event.
150 134937 : return (id > TraceLogger_Error && id < TraceLogger_LastTreeItem) ||
151 134937 : id >= TraceLogger_Last;
152 : }
153 :
154 : template <class T>
155 : class ContinuousSpace {
156 : T* data_;
157 : uint32_t size_;
158 : uint32_t capacity_;
159 :
160 : // The maximum number of bytes of RAM a continuous space structure can take.
161 : static const uint32_t LIMIT = 200 * 1024 * 1024;
162 :
163 : public:
164 22 : ContinuousSpace ()
165 22 : : data_(nullptr)
166 22 : { }
167 :
168 22 : bool init() {
169 22 : capacity_ = 64;
170 22 : size_ = 0;
171 22 : data_ = (T*) js_malloc(capacity_ * sizeof(T));
172 22 : if (!data_)
173 0 : return false;
174 :
175 22 : return true;
176 : }
177 :
178 0 : ~ContinuousSpace()
179 : {
180 0 : js_free(data_);
181 0 : data_ = nullptr;
182 0 : }
183 :
184 0 : static uint32_t maxSize() {
185 0 : return LIMIT / sizeof(T);
186 : }
187 :
188 0 : T* data() {
189 0 : return data_;
190 : }
191 :
192 : uint32_t capacity() const {
193 : return capacity_;
194 : }
195 :
196 0 : uint32_t size() const {
197 0 : return size_;
198 : }
199 :
200 0 : bool empty() const {
201 0 : return size_ == 0;
202 : }
203 :
204 0 : uint32_t lastEntryId() const {
205 0 : MOZ_ASSERT(!empty());
206 0 : return size_ - 1;
207 : }
208 :
209 0 : T& lastEntry() {
210 0 : return data()[lastEntryId()];
211 : }
212 :
213 22 : bool hasSpaceForAdd(uint32_t count = 1) {
214 22 : if (size_ + count <= capacity_)
215 22 : return true;
216 0 : return false;
217 : }
218 :
219 22 : bool ensureSpaceBeforeAdd(uint32_t count = 1) {
220 22 : MOZ_ASSERT(data_);
221 22 : if (hasSpaceForAdd(count))
222 22 : return true;
223 :
224 : // Limit the size of a continuous buffer.
225 0 : if (size_ + count > maxSize())
226 0 : return false;
227 :
228 0 : uint32_t nCapacity = capacity_ * 2;
229 0 : nCapacity = (nCapacity < maxSize()) ? nCapacity : maxSize();
230 :
231 0 : T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
232 0 : if (!entries)
233 0 : return false;
234 :
235 0 : data_ = entries;
236 0 : capacity_ = nCapacity;
237 :
238 0 : return true;
239 : }
240 :
241 0 : T& operator[](size_t i) {
242 0 : MOZ_ASSERT(i < size_);
243 0 : return data()[i];
244 : }
245 :
246 : void push(T& data) {
247 : MOZ_ASSERT(size_ < capacity_);
248 : data()[size_++] = data;
249 : }
250 :
251 0 : T& pushUninitialized() {
252 0 : MOZ_ASSERT(size_ < capacity_);
253 0 : return data()[size_++];
254 : }
255 :
256 0 : void pop() {
257 0 : MOZ_ASSERT(!empty());
258 0 : size_--;
259 0 : }
260 :
261 0 : void clear() {
262 0 : size_ = 0;
263 0 : }
264 :
265 0 : size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
266 0 : return mallocSizeOf(data_);
267 : }
268 : };
269 :
270 : // The layout of the event log in memory and in the log file.
271 : // Readable by JS using TypedArrays.
272 : struct EventEntry {
273 : uint64_t time;
274 : uint32_t textId;
275 : EventEntry(uint64_t time, uint32_t textId)
276 : : time(time), textId(textId)
277 : { }
278 : };
279 :
280 : #endif /* TraceLoggingTypes_h */
|