summaryrefslogtreecommitdiffstats
path: root/dom/indexedDB/ProfilerHelpers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/indexedDB/ProfilerHelpers.cpp')
-rw-r--r--dom/indexedDB/ProfilerHelpers.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/dom/indexedDB/ProfilerHelpers.cpp b/dom/indexedDB/ProfilerHelpers.cpp
new file mode 100644
index 0000000000..2d5ebfc2e2
--- /dev/null
+++ b/dom/indexedDB/ProfilerHelpers.cpp
@@ -0,0 +1,281 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "ProfilerHelpers.h"
+
+#include "BackgroundChildImpl.h"
+#include "GeckoProfiler.h"
+#include "IDBDatabase.h"
+#include "IDBIndex.h"
+#include "IDBKeyRange.h"
+#include "IDBObjectStore.h"
+#include "IDBTransaction.h"
+#include "Key.h"
+#include "ThreadLocal.h"
+
+#include "mozilla/dom/Event.h"
+#include "nsReadableUtils.h"
+
+namespace mozilla::dom::indexedDB {
+
+namespace {
+static const char kQuote = '\"';
+static const char kOpenBracket = '[';
+static const char kCloseBracket = ']';
+static const char kOpenParen = '(';
+static const char kCloseParen = ')';
+
+void LoggingHelper(bool aUseProfiler, const char* aFmt, va_list args) {
+ MOZ_ASSERT(IndexedDatabaseManager::GetLoggingMode() !=
+ IndexedDatabaseManager::Logging_Disabled);
+ MOZ_ASSERT(aFmt);
+
+ mozilla::LogModule* logModule = IndexedDatabaseManager::GetLoggingModule();
+ MOZ_ASSERT(logModule);
+
+ static const mozilla::LogLevel logLevel = LogLevel::Warning;
+
+ if (MOZ_LOG_TEST(logModule, logLevel) ||
+ (aUseProfiler && profiler_thread_is_being_profiled_for_markers())) {
+ nsAutoCString message;
+
+ message.AppendVprintf(aFmt, args);
+
+ MOZ_LOG(logModule, logLevel, ("%s", message.get()));
+
+ if (aUseProfiler) {
+ PROFILER_MARKER_UNTYPED(message, DOM);
+ }
+ }
+}
+} // namespace
+
+template <bool CheckLoggingMode>
+LoggingIdString<CheckLoggingMode>::LoggingIdString() {
+ using mozilla::ipc::BackgroundChildImpl;
+
+ if (!CheckLoggingMode || IndexedDatabaseManager::GetLoggingMode() !=
+ IndexedDatabaseManager::Logging_Disabled) {
+ const BackgroundChildImpl::ThreadLocal* threadLocal =
+ BackgroundChildImpl::GetThreadLocalForCurrentThread();
+ if (threadLocal) {
+ const auto& idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
+ if (idbThreadLocal) {
+ Assign(idbThreadLocal->IdString());
+ }
+ }
+ }
+}
+
+template <bool CheckLoggingMode>
+LoggingIdString<CheckLoggingMode>::LoggingIdString(const nsID& aID) {
+ static_assert(NSID_LENGTH > 1, "NSID_LENGTH is set incorrectly!");
+ static_assert(NSID_LENGTH <= kStorageSize,
+ "nsID string won't fit in our storage!");
+ // Capacity() excludes the null terminator; NSID_LENGTH includes it.
+ MOZ_ASSERT(Capacity() + 1 == NSID_LENGTH);
+
+ if (!CheckLoggingMode || IndexedDatabaseManager::GetLoggingMode() !=
+ IndexedDatabaseManager::Logging_Disabled) {
+ // NSID_LENGTH counts the null terminator, SetLength() does not.
+ SetLength(NSID_LENGTH - 1);
+
+ aID.ToProvidedString(
+ *reinterpret_cast<char(*)[NSID_LENGTH]>(BeginWriting()));
+ }
+}
+
+template class LoggingIdString<false>;
+template class LoggingIdString<true>;
+
+LoggingString::LoggingString(IDBDatabase* aDatabase) : nsAutoCString(kQuote) {
+ MOZ_ASSERT(aDatabase);
+
+ AppendUTF16toUTF8(aDatabase->Name(), *this);
+ Append(kQuote);
+}
+
+LoggingString::LoggingString(const IDBTransaction& aTransaction)
+ : nsAutoCString(kOpenBracket) {
+ constexpr auto kCommaSpace = ", "_ns;
+
+ StringJoinAppend(*this, kCommaSpace, aTransaction.ObjectStoreNamesInternal(),
+ [](nsACString& dest, const auto& store) {
+ dest.Append(kQuote);
+ AppendUTF16toUTF8(store, dest);
+ dest.Append(kQuote);
+ });
+
+ Append(kCloseBracket);
+ Append(kCommaSpace);
+
+ switch (aTransaction.GetMode()) {
+ case IDBTransaction::Mode::ReadOnly:
+ AppendLiteral("\"readonly\"");
+ break;
+ case IDBTransaction::Mode::ReadWrite:
+ AppendLiteral("\"readwrite\"");
+ break;
+ case IDBTransaction::Mode::ReadWriteFlush:
+ AppendLiteral("\"readwriteflush\"");
+ break;
+ case IDBTransaction::Mode::Cleanup:
+ AppendLiteral("\"cleanup\"");
+ break;
+ case IDBTransaction::Mode::VersionChange:
+ AppendLiteral("\"versionchange\"");
+ break;
+ default:
+ MOZ_CRASH("Unknown mode!");
+ };
+}
+
+LoggingString::LoggingString(IDBObjectStore* aObjectStore)
+ : nsAutoCString(kQuote) {
+ MOZ_ASSERT(aObjectStore);
+
+ AppendUTF16toUTF8(aObjectStore->Name(), *this);
+ Append(kQuote);
+}
+
+LoggingString::LoggingString(IDBIndex* aIndex) : nsAutoCString(kQuote) {
+ MOZ_ASSERT(aIndex);
+
+ AppendUTF16toUTF8(aIndex->Name(), *this);
+ Append(kQuote);
+}
+
+LoggingString::LoggingString(IDBKeyRange* aKeyRange) {
+ if (aKeyRange) {
+ if (aKeyRange->IsOnly()) {
+ Assign(LoggingString(aKeyRange->Lower()));
+ } else {
+ if (aKeyRange->LowerOpen()) {
+ Assign(kOpenParen);
+ } else {
+ Assign(kOpenBracket);
+ }
+
+ Append(LoggingString(aKeyRange->Lower()));
+ AppendLiteral(", ");
+ Append(LoggingString(aKeyRange->Upper()));
+
+ if (aKeyRange->UpperOpen()) {
+ Append(kCloseParen);
+ } else {
+ Append(kCloseBracket);
+ }
+ }
+ } else {
+ AssignLiteral("<undefined>");
+ }
+}
+
+LoggingString::LoggingString(const Key& aKey) {
+ if (aKey.IsUnset()) {
+ AssignLiteral("<undefined>");
+ } else if (aKey.IsFloat()) {
+ AppendPrintf("%g", aKey.ToFloat());
+ } else if (aKey.IsDate()) {
+ AppendPrintf("<Date %g>", aKey.ToDateMsec());
+ } else if (aKey.IsString()) {
+ AppendPrintf("\"%s\"", NS_ConvertUTF16toUTF8(aKey.ToString()).get());
+ } else if (aKey.IsBinary()) {
+ AssignLiteral("[object ArrayBuffer]");
+ } else {
+ MOZ_ASSERT(aKey.IsArray());
+ AssignLiteral("[...]");
+ }
+}
+
+LoggingString::LoggingString(const IDBCursorDirection aDirection) {
+ switch (aDirection) {
+ case IDBCursorDirection::Next:
+ AssignLiteral("\"next\"");
+ break;
+ case IDBCursorDirection::Nextunique:
+ AssignLiteral("\"nextunique\"");
+ break;
+ case IDBCursorDirection::Prev:
+ AssignLiteral("\"prev\"");
+ break;
+ case IDBCursorDirection::Prevunique:
+ AssignLiteral("\"prevunique\"");
+ break;
+ default:
+ MOZ_CRASH("Unknown direction!");
+ };
+}
+
+LoggingString::LoggingString(const Optional<uint64_t>& aVersion) {
+ if (aVersion.WasPassed()) {
+ AppendInt(aVersion.Value());
+ } else {
+ AssignLiteral("<undefined>");
+ }
+}
+
+LoggingString::LoggingString(const Optional<uint32_t>& aLimit) {
+ if (aLimit.WasPassed()) {
+ AppendInt(aLimit.Value());
+ } else {
+ AssignLiteral("<undefined>");
+ }
+}
+
+LoggingString::LoggingString(IDBObjectStore* aObjectStore, const Key& aKey) {
+ MOZ_ASSERT(aObjectStore);
+
+ if (!aObjectStore->HasValidKeyPath()) {
+ Append(LoggingString(aKey));
+ }
+}
+
+LoggingString::LoggingString(Event* aEvent, const char16_t* aDefault)
+ : nsAutoCString(kQuote) {
+ MOZ_ASSERT(aDefault);
+
+ nsAutoString eventType;
+
+ if (aEvent) {
+ aEvent->GetType(eventType);
+ } else {
+ eventType = nsDependentString(aDefault);
+ }
+
+ AppendUTF16toUTF8(eventType, *this);
+ Append(kQuote);
+}
+
+void LoggingHelper(const char* aDetailedFmt, const char* aConciseFmt, ...) {
+ const IndexedDatabaseManager::LoggingMode mode =
+ IndexedDatabaseManager::GetLoggingMode();
+
+ if (mode != IndexedDatabaseManager::Logging_Disabled) {
+ const char* fmt;
+ if (mode == IndexedDatabaseManager::Logging_Concise ||
+ mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks) {
+ fmt = aConciseFmt;
+ } else {
+ MOZ_ASSERT(mode == IndexedDatabaseManager::Logging_Detailed ||
+ mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks);
+ fmt = aDetailedFmt;
+ }
+
+ const bool useProfiler =
+ mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks ||
+ mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks;
+
+ va_list args;
+ va_start(args, aConciseFmt);
+
+ LoggingHelper(useProfiler, fmt, args);
+
+ va_end(args);
+ }
+}
+
+} // namespace mozilla::dom::indexedDB