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 "builtin/String.h"
11
12 #include "js/AllocPolicy.h"
13
14 // Tree items, meaning they have a start and stop and form a nested tree.
15 #define TRACELOGGER_TREE_ITEMS(_) \
16 _(AnnotateScripts) \
17 _(Baseline) \
18 _(BaselineCompilation) \
19 _(Engine) \
20 _(GC) \
21 _(GCAllocation) \
22 _(GCSweeping) \
23 _(Interpreter) \
24 _(InlinedScripts) \
25 _(IonAnalysis) \
26 _(IonCompilation) \
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) TraceLogger_LastTreeItem,
97 TRACELOGGER_LOG_ITEMS(DEFINE_TEXT_ID)
98 #undef DEFINE_TEXT_ID
99 TraceLogger_Last
100 };
101
TLTextIdString(TraceLoggerTextId id)102 inline const char* TLTextIdString(TraceLoggerTextId id) {
103 switch (id) {
104 case TraceLogger_Error:
105 return "TraceLogger failed to process text";
106 case TraceLogger_Internal:
107 return "TraceLogger overhead";
108 #define NAME(textId) \
109 case TraceLogger_##textId: \
110 return #textId;
111 TRACELOGGER_TREE_ITEMS(NAME)
112 TRACELOGGER_LOG_ITEMS(NAME)
113 #undef NAME
114 default:
115 MOZ_CRASH();
116 }
117 }
118
119 uint32_t TLStringToTextId(JSLinearString* str);
120
121 // Return whether a given item id can be enabled/disabled.
TLTextIdIsTogglable(uint32_t id)122 inline bool TLTextIdIsTogglable(uint32_t id) {
123 if (id == TraceLogger_Error) return false;
124 if (id == TraceLogger_Internal) return false;
125 if (id == TraceLogger_Stop) return false;
126 // Actually never used. But added here so it doesn't show as toggle
127 if (id == TraceLogger_LastTreeItem) return false;
128 if (id == TraceLogger_Last) return false;
129 // Cannot toggle the logging of one engine on/off, because at the stop
130 // event it is sometimes unknown which engine was running.
131 if (id == TraceLogger_IonMonkey || id == TraceLogger_Baseline ||
132 id == TraceLogger_Interpreter)
133 return false;
134 return true;
135 }
136
TLTextIdIsTreeEvent(uint32_t id)137 inline bool TLTextIdIsTreeEvent(uint32_t id) {
138 // Everything between TraceLogger_Error and TraceLogger_LastTreeItem are tree
139 // events and atm also every custom event.
140 return (id > TraceLogger_Error && id < TraceLogger_LastTreeItem) ||
141 id >= TraceLogger_Last;
142 }
143
144 template <class T>
145 class ContinuousSpace {
146 T* data_;
147 uint32_t size_;
148 uint32_t capacity_;
149
150 // The maximum number of bytes of RAM a continuous space structure can take.
151 static const uint32_t LIMIT = 200 * 1024 * 1024;
152
153 public:
ContinuousSpace()154 ContinuousSpace() : data_(nullptr) {}
155
init()156 bool init() {
157 capacity_ = 64;
158 size_ = 0;
159 data_ = (T*)js_malloc(capacity_ * sizeof(T));
160 if (!data_) return false;
161
162 return true;
163 }
164
~ContinuousSpace()165 ~ContinuousSpace() {
166 js_free(data_);
167 data_ = nullptr;
168 }
169
maxSize()170 static uint32_t maxSize() { return LIMIT / sizeof(T); }
171
data()172 T* data() { return data_; }
173
capacity()174 uint32_t capacity() const { return capacity_; }
175
size()176 uint32_t size() const { return size_; }
177
empty()178 bool empty() const { return size_ == 0; }
179
lastEntryId()180 uint32_t lastEntryId() const {
181 MOZ_ASSERT(!empty());
182 return size_ - 1;
183 }
184
lastEntry()185 T& lastEntry() { return data()[lastEntryId()]; }
186
187 bool hasSpaceForAdd(uint32_t count = 1) {
188 if (size_ + count <= capacity_) return true;
189 return false;
190 }
191
192 bool ensureSpaceBeforeAdd(uint32_t count = 1) {
193 MOZ_ASSERT(data_);
194 if (hasSpaceForAdd(count)) return true;
195
196 // Limit the size of a continuous buffer.
197 if (size_ + count > maxSize()) return false;
198
199 uint32_t nCapacity = capacity_ * 2;
200 nCapacity = (nCapacity < maxSize()) ? nCapacity : maxSize();
201
202 T* entries = (T*)js_realloc(data_, nCapacity * sizeof(T));
203 if (!entries) return false;
204
205 data_ = entries;
206 capacity_ = nCapacity;
207
208 return true;
209 }
210
211 T& operator[](size_t i) {
212 MOZ_ASSERT(i < size_);
213 return data()[i];
214 }
215
push(T & data)216 void push(T& data) {
217 MOZ_ASSERT(size_ < capacity_);
218 data()[size_++] = data;
219 }
220
pushUninitialized()221 T& pushUninitialized() {
222 MOZ_ASSERT(size_ < capacity_);
223 return data()[size_++];
224 }
225
pop()226 void pop() {
227 MOZ_ASSERT(!empty());
228 size_--;
229 }
230
clear()231 void clear() { size_ = 0; }
232
sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)233 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const {
234 return mallocSizeOf(data_);
235 }
236 };
237
238 // The layout of the event log in memory and in the log file.
239 // Readable by JS using TypedArrays.
240 struct EventEntry {
241 uint64_t time;
242 uint32_t textId;
EventEntryEventEntry243 EventEntry(uint64_t time, uint32_t textId) : time(time), textId(textId) {}
244 };
245
246 #endif /* TraceLoggingTypes_h */
247