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"
13 #include "IDBKeyRange.h"
14 #include "IDBObjectStore.h"
15 #include "IDBTransaction.h"
17 #include "ThreadLocal.h"
19 #include "mozilla/dom/Event.h"
20 #include "nsReadableUtils.h"
22 namespace mozilla::dom::indexedDB
{
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
);
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()));
50 PROFILER_MARKER_UNTYPED(message
, DOM
);
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();
65 const auto& idbThreadLocal
= threadLocal
->mIndexedDBThreadLocal
;
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);
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);
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
) {
108 AppendUTF16toUTF8(store
, dest
);
112 Append(kCloseBracket
);
115 switch (aTransaction
.GetMode()) {
116 case IDBTransaction::Mode::ReadOnly
:
117 AppendLiteral("\"readonly\"");
119 case IDBTransaction::Mode::ReadWrite
:
120 AppendLiteral("\"readwrite\"");
122 case IDBTransaction::Mode::ReadWriteFlush
:
123 AppendLiteral("\"readwriteflush\"");
125 case IDBTransaction::Mode::Cleanup
:
126 AppendLiteral("\"cleanup\"");
128 case IDBTransaction::Mode::VersionChange
:
129 AppendLiteral("\"versionchange\"");
132 MOZ_CRASH("Unknown mode!");
136 LoggingString::LoggingString(IDBObjectStore
* aObjectStore
)
137 : nsAutoCString(kQuote
) {
138 MOZ_ASSERT(aObjectStore
);
140 AppendUTF16toUTF8(aObjectStore
->Name(), *this);
144 LoggingString::LoggingString(IDBIndex
* aIndex
) : nsAutoCString(kQuote
) {
147 AppendUTF16toUTF8(aIndex
->Name(), *this);
151 LoggingString::LoggingString(IDBKeyRange
* aKeyRange
) {
153 if (aKeyRange
->IsOnly()) {
154 Assign(LoggingString(aKeyRange
->Lower()));
156 if (aKeyRange
->LowerOpen()) {
159 Assign(kOpenBracket
);
162 Append(LoggingString(aKeyRange
->Lower()));
164 Append(LoggingString(aKeyRange
->Upper()));
166 if (aKeyRange
->UpperOpen()) {
169 Append(kCloseBracket
);
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]");
189 MOZ_ASSERT(aKey
.IsArray());
190 AssignLiteral("[...]");
194 LoggingString::LoggingString(const IDBCursorDirection aDirection
) {
195 switch (aDirection
) {
196 case IDBCursorDirection::Next
:
197 AssignLiteral("\"next\"");
199 case IDBCursorDirection::Nextunique
:
200 AssignLiteral("\"nextunique\"");
202 case IDBCursorDirection::Prev
:
203 AssignLiteral("\"prev\"");
205 case IDBCursorDirection::Prevunique
:
206 AssignLiteral("\"prevunique\"");
209 MOZ_CRASH("Unknown direction!");
213 LoggingString::LoggingString(const Optional
<uint64_t>& aVersion
) {
214 if (aVersion
.WasPassed()) {
215 AppendInt(aVersion
.Value());
217 AssignLiteral("<undefined>");
221 LoggingString::LoggingString(const Optional
<uint32_t>& aLimit
) {
222 if (aLimit
.WasPassed()) {
223 AppendInt(aLimit
.Value());
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
;
244 aEvent
->GetType(eventType
);
246 eventType
= nsDependentString(aDefault
);
249 AppendUTF16toUTF8(eventType
, *this);
253 void LoggingHelper(const char* aDetailedFmt
, const char* aConciseFmt
, ...) {
254 const IndexedDatabaseManager::LoggingMode mode
=
255 IndexedDatabaseManager::GetLoggingMode();
257 if (mode
!= IndexedDatabaseManager::Logging_Disabled
) {
259 if (mode
== IndexedDatabaseManager::Logging_Concise
||
260 mode
== IndexedDatabaseManager::Logging_ConciseProfilerMarks
) {
263 MOZ_ASSERT(mode
== IndexedDatabaseManager::Logging_Detailed
||
264 mode
== IndexedDatabaseManager::Logging_DetailedProfilerMarks
);
268 const bool useProfiler
=
269 mode
== IndexedDatabaseManager::Logging_ConciseProfilerMarks
||
270 mode
== IndexedDatabaseManager::Logging_DetailedProfilerMarks
;
273 va_start(args
, aConciseFmt
);
275 LoggingHelper(useProfiler
, fmt
, args
);
281 } // namespace mozilla::dom::indexedDB