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