Merge autoland to mozilla-central. a=merge
[gecko.git] / dom / indexedDB / ProfilerHelpers.cpp
blob2d5ebfc2e226333c67ad970f13d5d831a155debf
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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/. */
7 #include "ProfilerHelpers.h"
9 #include "BackgroundChildImpl.h"
10 #include "GeckoProfiler.h"
11 #include "IDBDatabase.h"
12 #include "IDBIndex.h"
13 #include "IDBKeyRange.h"
14 #include "IDBObjectStore.h"
15 #include "IDBTransaction.h"
16 #include "Key.h"
17 #include "ThreadLocal.h"
19 #include "mozilla/dom/Event.h"
20 #include "nsReadableUtils.h"
22 namespace mozilla::dom::indexedDB {
24 namespace {
25 static const char kQuote = '\"';
26 static const char kOpenBracket = '[';
27 static const char kCloseBracket = ']';
28 static const char kOpenParen = '(';
29 static const char kCloseParen = ')';
31 void LoggingHelper(bool aUseProfiler, const char* aFmt, va_list args) {
32 MOZ_ASSERT(IndexedDatabaseManager::GetLoggingMode() !=
33 IndexedDatabaseManager::Logging_Disabled);
34 MOZ_ASSERT(aFmt);
36 mozilla::LogModule* logModule = IndexedDatabaseManager::GetLoggingModule();
37 MOZ_ASSERT(logModule);
39 static const mozilla::LogLevel logLevel = LogLevel::Warning;
41 if (MOZ_LOG_TEST(logModule, logLevel) ||
42 (aUseProfiler && profiler_thread_is_being_profiled_for_markers())) {
43 nsAutoCString message;
45 message.AppendVprintf(aFmt, args);
47 MOZ_LOG(logModule, logLevel, ("%s", message.get()));
49 if (aUseProfiler) {
50 PROFILER_MARKER_UNTYPED(message, DOM);
54 } // namespace
56 template <bool CheckLoggingMode>
57 LoggingIdString<CheckLoggingMode>::LoggingIdString() {
58 using mozilla::ipc::BackgroundChildImpl;
60 if (!CheckLoggingMode || IndexedDatabaseManager::GetLoggingMode() !=
61 IndexedDatabaseManager::Logging_Disabled) {
62 const BackgroundChildImpl::ThreadLocal* threadLocal =
63 BackgroundChildImpl::GetThreadLocalForCurrentThread();
64 if (threadLocal) {
65 const auto& idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
66 if (idbThreadLocal) {
67 Assign(idbThreadLocal->IdString());
73 template <bool CheckLoggingMode>
74 LoggingIdString<CheckLoggingMode>::LoggingIdString(const nsID& aID) {
75 static_assert(NSID_LENGTH > 1, "NSID_LENGTH is set incorrectly!");
76 static_assert(NSID_LENGTH <= kStorageSize,
77 "nsID string won't fit in our storage!");
78 // Capacity() excludes the null terminator; NSID_LENGTH includes it.
79 MOZ_ASSERT(Capacity() + 1 == NSID_LENGTH);
81 if (!CheckLoggingMode || IndexedDatabaseManager::GetLoggingMode() !=
82 IndexedDatabaseManager::Logging_Disabled) {
83 // NSID_LENGTH counts the null terminator, SetLength() does not.
84 SetLength(NSID_LENGTH - 1);
86 aID.ToProvidedString(
87 *reinterpret_cast<char(*)[NSID_LENGTH]>(BeginWriting()));
91 template class LoggingIdString<false>;
92 template class LoggingIdString<true>;
94 LoggingString::LoggingString(IDBDatabase* aDatabase) : nsAutoCString(kQuote) {
95 MOZ_ASSERT(aDatabase);
97 AppendUTF16toUTF8(aDatabase->Name(), *this);
98 Append(kQuote);
101 LoggingString::LoggingString(const IDBTransaction& aTransaction)
102 : nsAutoCString(kOpenBracket) {
103 constexpr auto kCommaSpace = ", "_ns;
105 StringJoinAppend(*this, kCommaSpace, aTransaction.ObjectStoreNamesInternal(),
106 [](nsACString& dest, const auto& store) {
107 dest.Append(kQuote);
108 AppendUTF16toUTF8(store, dest);
109 dest.Append(kQuote);
112 Append(kCloseBracket);
113 Append(kCommaSpace);
115 switch (aTransaction.GetMode()) {
116 case IDBTransaction::Mode::ReadOnly:
117 AppendLiteral("\"readonly\"");
118 break;
119 case IDBTransaction::Mode::ReadWrite:
120 AppendLiteral("\"readwrite\"");
121 break;
122 case IDBTransaction::Mode::ReadWriteFlush:
123 AppendLiteral("\"readwriteflush\"");
124 break;
125 case IDBTransaction::Mode::Cleanup:
126 AppendLiteral("\"cleanup\"");
127 break;
128 case IDBTransaction::Mode::VersionChange:
129 AppendLiteral("\"versionchange\"");
130 break;
131 default:
132 MOZ_CRASH("Unknown mode!");
136 LoggingString::LoggingString(IDBObjectStore* aObjectStore)
137 : nsAutoCString(kQuote) {
138 MOZ_ASSERT(aObjectStore);
140 AppendUTF16toUTF8(aObjectStore->Name(), *this);
141 Append(kQuote);
144 LoggingString::LoggingString(IDBIndex* aIndex) : nsAutoCString(kQuote) {
145 MOZ_ASSERT(aIndex);
147 AppendUTF16toUTF8(aIndex->Name(), *this);
148 Append(kQuote);
151 LoggingString::LoggingString(IDBKeyRange* aKeyRange) {
152 if (aKeyRange) {
153 if (aKeyRange->IsOnly()) {
154 Assign(LoggingString(aKeyRange->Lower()));
155 } else {
156 if (aKeyRange->LowerOpen()) {
157 Assign(kOpenParen);
158 } else {
159 Assign(kOpenBracket);
162 Append(LoggingString(aKeyRange->Lower()));
163 AppendLiteral(", ");
164 Append(LoggingString(aKeyRange->Upper()));
166 if (aKeyRange->UpperOpen()) {
167 Append(kCloseParen);
168 } else {
169 Append(kCloseBracket);
172 } else {
173 AssignLiteral("<undefined>");
177 LoggingString::LoggingString(const Key& aKey) {
178 if (aKey.IsUnset()) {
179 AssignLiteral("<undefined>");
180 } else if (aKey.IsFloat()) {
181 AppendPrintf("%g", aKey.ToFloat());
182 } else if (aKey.IsDate()) {
183 AppendPrintf("<Date %g>", aKey.ToDateMsec());
184 } else if (aKey.IsString()) {
185 AppendPrintf("\"%s\"", NS_ConvertUTF16toUTF8(aKey.ToString()).get());
186 } else if (aKey.IsBinary()) {
187 AssignLiteral("[object ArrayBuffer]");
188 } else {
189 MOZ_ASSERT(aKey.IsArray());
190 AssignLiteral("[...]");
194 LoggingString::LoggingString(const IDBCursorDirection aDirection) {
195 switch (aDirection) {
196 case IDBCursorDirection::Next:
197 AssignLiteral("\"next\"");
198 break;
199 case IDBCursorDirection::Nextunique:
200 AssignLiteral("\"nextunique\"");
201 break;
202 case IDBCursorDirection::Prev:
203 AssignLiteral("\"prev\"");
204 break;
205 case IDBCursorDirection::Prevunique:
206 AssignLiteral("\"prevunique\"");
207 break;
208 default:
209 MOZ_CRASH("Unknown direction!");
213 LoggingString::LoggingString(const Optional<uint64_t>& aVersion) {
214 if (aVersion.WasPassed()) {
215 AppendInt(aVersion.Value());
216 } else {
217 AssignLiteral("<undefined>");
221 LoggingString::LoggingString(const Optional<uint32_t>& aLimit) {
222 if (aLimit.WasPassed()) {
223 AppendInt(aLimit.Value());
224 } else {
225 AssignLiteral("<undefined>");
229 LoggingString::LoggingString(IDBObjectStore* aObjectStore, const Key& aKey) {
230 MOZ_ASSERT(aObjectStore);
232 if (!aObjectStore->HasValidKeyPath()) {
233 Append(LoggingString(aKey));
237 LoggingString::LoggingString(Event* aEvent, const char16_t* aDefault)
238 : nsAutoCString(kQuote) {
239 MOZ_ASSERT(aDefault);
241 nsAutoString eventType;
243 if (aEvent) {
244 aEvent->GetType(eventType);
245 } else {
246 eventType = nsDependentString(aDefault);
249 AppendUTF16toUTF8(eventType, *this);
250 Append(kQuote);
253 void LoggingHelper(const char* aDetailedFmt, const char* aConciseFmt, ...) {
254 const IndexedDatabaseManager::LoggingMode mode =
255 IndexedDatabaseManager::GetLoggingMode();
257 if (mode != IndexedDatabaseManager::Logging_Disabled) {
258 const char* fmt;
259 if (mode == IndexedDatabaseManager::Logging_Concise ||
260 mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks) {
261 fmt = aConciseFmt;
262 } else {
263 MOZ_ASSERT(mode == IndexedDatabaseManager::Logging_Detailed ||
264 mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks);
265 fmt = aDetailedFmt;
268 const bool useProfiler =
269 mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks ||
270 mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks;
272 va_list args;
273 va_start(args, aConciseFmt);
275 LoggingHelper(useProfiler, fmt, args);
277 va_end(args);
281 } // namespace mozilla::dom::indexedDB