Bug 1690340 - Part 4: Insert the "Page Source" before the "Extensions for Developers...
[gecko.git] / js / public / TraceLoggerAPI.h
blobb26c9118b6f2a58549a620e4ed054015d1289d6a
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* SpiderMonkey TraceLogger APIs. */
8 #ifndef js_TraceLoggerAPI_h
9 #define js_TraceLoggerAPI_h
11 #include "jstypes.h"
13 namespace mozilla {
14 class JSONWriteFunc;
15 class TimeStamp;
16 }; // namespace mozilla
18 namespace JS {
20 // Used to lock any tracelogger activities, and consequently, will also block
21 // any further JS execution when a thread hits an atomic tracelogger activity
22 // such as payload creation.
23 class AutoTraceLoggerLockGuard {
24 public:
25 AutoTraceLoggerLockGuard();
26 ~AutoTraceLoggerLockGuard();
29 // An implementation type must be defined in order to gather data using the
30 // TraceLoggerCollectorBuffer. Each implementation must define the type that is
31 // being collected in the buffer, along with a static method that is used to
32 // actually write into the buffer from the tracelogger.
33 struct TraceLoggerDictionaryImpl {
34 using ImplType = char;
35 static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
36 size_t bufferSize);
39 struct TraceLoggerIdImpl {
40 using ImplType = uint32_t;
41 static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
42 size_t bufferSize);
45 struct TraceLoggerLineNoImpl {
46 using ImplType = int32_t;
47 static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
48 size_t bufferSize);
51 struct TraceLoggerColNoImpl {
52 using ImplType = int32_t;
53 static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
54 size_t bufferSize);
57 struct TraceLoggerTimeStampImpl {
58 using ImplType = mozilla::TimeStamp;
59 static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
60 size_t bufferSize);
63 struct TraceLoggerDurationImpl {
64 using ImplType = double;
65 static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
66 size_t bufferSize);
69 // Buffer that is used to retrieve tracelogger data in fixed size chunks so that
70 // allocation of a large array is not necessary. The TraceLoggerCollectorBuffer
71 // class will manage an internal state which points to the next data index being
72 // collected. Each call to NextChunk will also clobber the internal buffer used
73 // to store the data.
74 template <class T>
75 class TraceLoggerCollectorBuffer {
76 using ImplType = typename T::ImplType;
78 public:
79 class Iterator {
80 public:
81 Iterator(ImplType* buffer, size_t index)
82 : iteratorIndex(index), buf(buffer) {}
84 Iterator operator++() {
85 iteratorIndex++;
86 return *this;
89 bool operator!=(const Iterator& other) const {
90 return iteratorIndex != other.iteratorIndex;
93 ImplType operator*() const { return buf[iteratorIndex]; }
95 private:
96 size_t iteratorIndex;
97 ImplType* buf;
100 explicit TraceLoggerCollectorBuffer(AutoTraceLoggerLockGuard& lockGuard,
101 JSContext* cx = nullptr,
102 size_t length = 4096)
103 : cx_(cx), length_(length), dataIndex_(0), bufferIndex_(0) {
104 buffer_ = js_pod_malloc<ImplType>(length);
107 ~TraceLoggerCollectorBuffer() { js_free(buffer_); }
109 Iterator begin() const { return Iterator(buffer_, 0); }
111 Iterator end() const { return Iterator(buffer_, bufferIndex_); }
113 ImplType* internalBuffer() const { return buffer_; }
115 bool NextChunk() {
116 bufferIndex_ = T::NextChunk(cx_, &dataIndex_, buffer_, length_);
117 return (bufferIndex_ != 0) ? true : false;
120 private:
121 JSContext* cx_;
122 size_t length_;
123 size_t dataIndex_;
124 size_t bufferIndex_;
125 ImplType* buffer_;
128 #ifdef JS_TRACE_LOGGING
130 // Initialize the trace logger. This must be called before using any of the
131 // other trace logging functions.
132 extern JS_PUBLIC_API bool InitTraceLogger();
134 // Return whether the trace logger is supported in this browser session.
135 extern JS_PUBLIC_API bool TraceLoggerSupported();
137 // Begin trace logging events. This will activate some of the
138 // textId's for various events and set the global option
139 // JSJITCOMPILER_ENABLE_TRACELOGGER to true.
140 // This does nothing except return if the trace logger is already active.
141 extern JS_PUBLIC_API void StartTraceLogger(JSContext* cx);
143 // Stop trace logging events. All textId's will be set to false, and the
144 // global JSJITCOMPILER_ENABLE_TRACELOGGER will be set to false.
145 // This does nothing except return if the trace logger is not active.
146 extern JS_PUBLIC_API void StopTraceLogger(JSContext* cx);
148 // Clear and free any event data that was recorded by the trace logger.
149 extern JS_PUBLIC_API void ResetTraceLogger(void);
151 // Spew trace logger statistics.
152 extern JS_PUBLIC_API void SpewTraceLoggerThread(JSContext* cx);
154 // Spew trace logger statistics.
155 extern JS_PUBLIC_API void SpewTraceLoggerForCurrentProcess();
157 #else
158 // Define empty inline functions for when trace logging compilation is not
159 // enabled. TraceLogging.cpp will not be built in that case so we need to
160 // provide something for any routines that reference these.
161 inline bool InitTraceLogger() { return true; }
162 inline bool TraceLoggerSupported() { return false; }
163 inline void StartTraceLogger(JSContext* cx) {}
164 inline void StopTraceLogger(JSContext* cx) {}
165 inline void ResetTraceLogger(void) {}
166 inline void SpewTraceLoggerThread(JSContext* cx) {}
167 inline void SpewTraceLoggerForCurrentProcess() {}
168 inline size_t TraceLoggerDictionaryImpl::NextChunk(JSContext* cx,
169 size_t* dataIndex,
170 ImplType buffer[],
171 size_t bufferSize) {
172 return 0;
174 inline size_t TraceLoggerIdImpl::NextChunk(JSContext* cx, size_t* dataIndex,
175 ImplType buffer[],
176 size_t bufferSize) {
177 return 0;
179 inline size_t TraceLoggerTimeStampImpl::NextChunk(JSContext* cx,
180 size_t* dataIndex,
181 ImplType buffer[],
182 size_t bufferSize) {
183 return 0;
185 inline size_t TraceLoggerDurationImpl::NextChunk(JSContext* cx,
186 size_t* dataIndex,
187 ImplType buffer[],
188 size_t bufferSize) {
189 return 0;
191 inline size_t TraceLoggerLineNoImpl::NextChunk(JSContext* cx, size_t* dataIndex,
192 ImplType buffer[],
193 size_t bufferSize) {
194 return 0;
196 inline size_t TraceLoggerColNoImpl::NextChunk(JSContext* cx, size_t* dataIndex,
197 ImplType buffer[],
198 size_t bufferSize) {
199 return 0;
201 inline AutoTraceLoggerLockGuard::AutoTraceLoggerLockGuard() {}
202 inline AutoTraceLoggerLockGuard::~AutoTraceLoggerLockGuard() {}
203 #endif
204 using TraceLoggerDictionaryBuffer =
205 TraceLoggerCollectorBuffer<JS::TraceLoggerDictionaryImpl>;
206 using TraceLoggerIdBuffer = TraceLoggerCollectorBuffer<JS::TraceLoggerIdImpl>;
207 using TraceLoggerTimeStampBuffer =
208 TraceLoggerCollectorBuffer<JS::TraceLoggerTimeStampImpl>;
209 using TraceLoggerDurationBuffer =
210 TraceLoggerCollectorBuffer<JS::TraceLoggerDurationImpl>;
211 using TraceLoggerLineNoBuffer =
212 TraceLoggerCollectorBuffer<JS::TraceLoggerLineNoImpl>;
213 using TraceLoggerColNoBuffer =
214 TraceLoggerCollectorBuffer<JS::TraceLoggerColNoImpl>;
215 }; // namespace JS
217 #endif /* js_TraceLoggerAPI_h */