summaryrefslogtreecommitdiffstats
path: root/js/public/TraceLoggerAPI.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /js/public/TraceLoggerAPI.h
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--js/public/TraceLoggerAPI.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/js/public/TraceLoggerAPI.h b/js/public/TraceLoggerAPI.h
new file mode 100644
index 0000000000..b26c9118b6
--- /dev/null
+++ b/js/public/TraceLoggerAPI.h
@@ -0,0 +1,217 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* SpiderMonkey TraceLogger APIs. */
+
+#ifndef js_TraceLoggerAPI_h
+#define js_TraceLoggerAPI_h
+
+#include "jstypes.h"
+
+namespace mozilla {
+class JSONWriteFunc;
+class TimeStamp;
+}; // namespace mozilla
+
+namespace JS {
+
+// Used to lock any tracelogger activities, and consequently, will also block
+// any further JS execution when a thread hits an atomic tracelogger activity
+// such as payload creation.
+class AutoTraceLoggerLockGuard {
+ public:
+ AutoTraceLoggerLockGuard();
+ ~AutoTraceLoggerLockGuard();
+};
+
+// An implementation type must be defined in order to gather data using the
+// TraceLoggerCollectorBuffer. Each implementation must define the type that is
+// being collected in the buffer, along with a static method that is used to
+// actually write into the buffer from the tracelogger.
+struct TraceLoggerDictionaryImpl {
+ using ImplType = char;
+ static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
+ size_t bufferSize);
+};
+
+struct TraceLoggerIdImpl {
+ using ImplType = uint32_t;
+ static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
+ size_t bufferSize);
+};
+
+struct TraceLoggerLineNoImpl {
+ using ImplType = int32_t;
+ static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
+ size_t bufferSize);
+};
+
+struct TraceLoggerColNoImpl {
+ using ImplType = int32_t;
+ static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
+ size_t bufferSize);
+};
+
+struct TraceLoggerTimeStampImpl {
+ using ImplType = mozilla::TimeStamp;
+ static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
+ size_t bufferSize);
+};
+
+struct TraceLoggerDurationImpl {
+ using ImplType = double;
+ static size_t NextChunk(JSContext* cx, size_t* dataIndex, ImplType buffer[],
+ size_t bufferSize);
+};
+
+// Buffer that is used to retrieve tracelogger data in fixed size chunks so that
+// allocation of a large array is not necessary. The TraceLoggerCollectorBuffer
+// class will manage an internal state which points to the next data index being
+// collected. Each call to NextChunk will also clobber the internal buffer used
+// to store the data.
+template <class T>
+class TraceLoggerCollectorBuffer {
+ using ImplType = typename T::ImplType;
+
+ public:
+ class Iterator {
+ public:
+ Iterator(ImplType* buffer, size_t index)
+ : iteratorIndex(index), buf(buffer) {}
+
+ Iterator operator++() {
+ iteratorIndex++;
+ return *this;
+ }
+
+ bool operator!=(const Iterator& other) const {
+ return iteratorIndex != other.iteratorIndex;
+ }
+
+ ImplType operator*() const { return buf[iteratorIndex]; }
+
+ private:
+ size_t iteratorIndex;
+ ImplType* buf;
+ };
+
+ explicit TraceLoggerCollectorBuffer(AutoTraceLoggerLockGuard& lockGuard,
+ JSContext* cx = nullptr,
+ size_t length = 4096)
+ : cx_(cx), length_(length), dataIndex_(0), bufferIndex_(0) {
+ buffer_ = js_pod_malloc<ImplType>(length);
+ }
+
+ ~TraceLoggerCollectorBuffer() { js_free(buffer_); }
+
+ Iterator begin() const { return Iterator(buffer_, 0); }
+
+ Iterator end() const { return Iterator(buffer_, bufferIndex_); }
+
+ ImplType* internalBuffer() const { return buffer_; }
+
+ bool NextChunk() {
+ bufferIndex_ = T::NextChunk(cx_, &dataIndex_, buffer_, length_);
+ return (bufferIndex_ != 0) ? true : false;
+ }
+
+ private:
+ JSContext* cx_;
+ size_t length_;
+ size_t dataIndex_;
+ size_t bufferIndex_;
+ ImplType* buffer_;
+};
+
+#ifdef JS_TRACE_LOGGING
+
+// Initialize the trace logger. This must be called before using any of the
+// other trace logging functions.
+extern JS_PUBLIC_API bool InitTraceLogger();
+
+// Return whether the trace logger is supported in this browser session.
+extern JS_PUBLIC_API bool TraceLoggerSupported();
+
+// Begin trace logging events. This will activate some of the
+// textId's for various events and set the global option
+// JSJITCOMPILER_ENABLE_TRACELOGGER to true.
+// This does nothing except return if the trace logger is already active.
+extern JS_PUBLIC_API void StartTraceLogger(JSContext* cx);
+
+// Stop trace logging events. All textId's will be set to false, and the
+// global JSJITCOMPILER_ENABLE_TRACELOGGER will be set to false.
+// This does nothing except return if the trace logger is not active.
+extern JS_PUBLIC_API void StopTraceLogger(JSContext* cx);
+
+// Clear and free any event data that was recorded by the trace logger.
+extern JS_PUBLIC_API void ResetTraceLogger(void);
+
+// Spew trace logger statistics.
+extern JS_PUBLIC_API void SpewTraceLoggerThread(JSContext* cx);
+
+// Spew trace logger statistics.
+extern JS_PUBLIC_API void SpewTraceLoggerForCurrentProcess();
+
+#else
+// Define empty inline functions for when trace logging compilation is not
+// enabled. TraceLogging.cpp will not be built in that case so we need to
+// provide something for any routines that reference these.
+inline bool InitTraceLogger() { return true; }
+inline bool TraceLoggerSupported() { return false; }
+inline void StartTraceLogger(JSContext* cx) {}
+inline void StopTraceLogger(JSContext* cx) {}
+inline void ResetTraceLogger(void) {}
+inline void SpewTraceLoggerThread(JSContext* cx) {}
+inline void SpewTraceLoggerForCurrentProcess() {}
+inline size_t TraceLoggerDictionaryImpl::NextChunk(JSContext* cx,
+ size_t* dataIndex,
+ ImplType buffer[],
+ size_t bufferSize) {
+ return 0;
+}
+inline size_t TraceLoggerIdImpl::NextChunk(JSContext* cx, size_t* dataIndex,
+ ImplType buffer[],
+ size_t bufferSize) {
+ return 0;
+}
+inline size_t TraceLoggerTimeStampImpl::NextChunk(JSContext* cx,
+ size_t* dataIndex,
+ ImplType buffer[],
+ size_t bufferSize) {
+ return 0;
+}
+inline size_t TraceLoggerDurationImpl::NextChunk(JSContext* cx,
+ size_t* dataIndex,
+ ImplType buffer[],
+ size_t bufferSize) {
+ return 0;
+}
+inline size_t TraceLoggerLineNoImpl::NextChunk(JSContext* cx, size_t* dataIndex,
+ ImplType buffer[],
+ size_t bufferSize) {
+ return 0;
+}
+inline size_t TraceLoggerColNoImpl::NextChunk(JSContext* cx, size_t* dataIndex,
+ ImplType buffer[],
+ size_t bufferSize) {
+ return 0;
+}
+inline AutoTraceLoggerLockGuard::AutoTraceLoggerLockGuard() {}
+inline AutoTraceLoggerLockGuard::~AutoTraceLoggerLockGuard() {}
+#endif
+using TraceLoggerDictionaryBuffer =
+ TraceLoggerCollectorBuffer<JS::TraceLoggerDictionaryImpl>;
+using TraceLoggerIdBuffer = TraceLoggerCollectorBuffer<JS::TraceLoggerIdImpl>;
+using TraceLoggerTimeStampBuffer =
+ TraceLoggerCollectorBuffer<JS::TraceLoggerTimeStampImpl>;
+using TraceLoggerDurationBuffer =
+ TraceLoggerCollectorBuffer<JS::TraceLoggerDurationImpl>;
+using TraceLoggerLineNoBuffer =
+ TraceLoggerCollectorBuffer<JS::TraceLoggerLineNoImpl>;
+using TraceLoggerColNoBuffer =
+ TraceLoggerCollectorBuffer<JS::TraceLoggerColNoImpl>;
+}; // namespace JS
+
+#endif /* js_TraceLoggerAPI_h */