Line data Source code
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/. */
6 :
7 : #ifndef mozilla_dom_indexeddb_profilerhelpers_h__
8 : #define mozilla_dom_indexeddb_profilerhelpers_h__
9 :
10 : // This file is not exported and is only meant to be included in IndexedDB
11 : // source files.
12 :
13 : #include "BackgroundChildImpl.h"
14 : #include "GeckoProfiler.h"
15 : #include "IDBCursor.h"
16 : #include "IDBDatabase.h"
17 : #include "IDBIndex.h"
18 : #include "IDBKeyRange.h"
19 : #include "IDBObjectStore.h"
20 : #include "IDBTransaction.h"
21 : #include "IndexedDatabaseManager.h"
22 : #include "Key.h"
23 : #include "mozilla/Assertions.h"
24 : #include "mozilla/Attributes.h"
25 : #include "mozilla/dom/BindingDeclarations.h"
26 : #include "nsDebug.h"
27 : #include "nsID.h"
28 : #include "nsIDOMEvent.h"
29 : #include "nsString.h"
30 : #include "mozilla/Logging.h"
31 :
32 : // Include this last to avoid path problems on Windows.
33 : #include "ActorsChild.h"
34 :
35 : namespace mozilla {
36 : namespace dom {
37 : namespace indexedDB {
38 :
39 0 : class MOZ_STACK_CLASS LoggingIdString final
40 : : public nsAutoCString
41 : {
42 : public:
43 0 : LoggingIdString()
44 0 : {
45 : using mozilla::ipc::BackgroundChildImpl;
46 :
47 0 : if (IndexedDatabaseManager::GetLoggingMode() !=
48 : IndexedDatabaseManager::Logging_Disabled) {
49 : const BackgroundChildImpl::ThreadLocal* threadLocal =
50 0 : BackgroundChildImpl::GetThreadLocalForCurrentThread();
51 0 : if (threadLocal) {
52 0 : const ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
53 0 : if (idbThreadLocal) {
54 0 : Assign(idbThreadLocal->IdString());
55 : }
56 : }
57 : }
58 0 : }
59 :
60 : explicit
61 0 : LoggingIdString(const nsID& aID)
62 0 : {
63 : static_assert(NSID_LENGTH > 1, "NSID_LENGTH is set incorrectly!");
64 : static_assert(NSID_LENGTH <= kDefaultStorageSize,
65 : "nID string won't fit in our storage!");
66 0 : MOZ_ASSERT(Capacity() > NSID_LENGTH);
67 :
68 0 : if (IndexedDatabaseManager::GetLoggingMode() !=
69 : IndexedDatabaseManager::Logging_Disabled) {
70 : // NSID_LENGTH counts the null terminator, SetLength() does not.
71 0 : SetLength(NSID_LENGTH - 1);
72 :
73 : aID.ToProvidedString(
74 0 : *reinterpret_cast<char(*)[NSID_LENGTH]>(BeginWriting()));
75 : }
76 0 : }
77 : };
78 :
79 0 : class MOZ_STACK_CLASS LoggingString final
80 : : public nsAutoCString
81 : {
82 : static const char kQuote = '\"';
83 : static const char kOpenBracket = '[';
84 : static const char kCloseBracket = ']';
85 : static const char kOpenParen = '(';
86 : static const char kCloseParen = ')';
87 :
88 : public:
89 : explicit
90 0 : LoggingString(IDBDatabase* aDatabase)
91 0 : : nsAutoCString(kQuote)
92 : {
93 0 : MOZ_ASSERT(aDatabase);
94 :
95 0 : AppendUTF16toUTF8(aDatabase->Name(), *this);
96 0 : Append(kQuote);
97 0 : }
98 :
99 : explicit
100 0 : LoggingString(IDBTransaction* aTransaction)
101 0 : : nsAutoCString(kOpenBracket)
102 : {
103 0 : MOZ_ASSERT(aTransaction);
104 :
105 0 : NS_NAMED_LITERAL_CSTRING(kCommaSpace, ", ");
106 :
107 0 : const nsTArray<nsString>& stores = aTransaction->ObjectStoreNamesInternal();
108 :
109 0 : for (uint32_t count = stores.Length(), index = 0; index < count; index++) {
110 0 : Append(kQuote);
111 0 : AppendUTF16toUTF8(stores[index], *this);
112 0 : Append(kQuote);
113 :
114 0 : if (index != count - 1) {
115 0 : Append(kCommaSpace);
116 : }
117 : }
118 :
119 0 : Append(kCloseBracket);
120 0 : Append(kCommaSpace);
121 :
122 0 : switch (aTransaction->GetMode()) {
123 : case IDBTransaction::READ_ONLY:
124 0 : AppendLiteral("\"readonly\"");
125 0 : break;
126 : case IDBTransaction::READ_WRITE:
127 0 : AppendLiteral("\"readwrite\"");
128 0 : break;
129 : case IDBTransaction::READ_WRITE_FLUSH:
130 0 : AppendLiteral("\"readwriteflush\"");
131 0 : break;
132 : case IDBTransaction::CLEANUP:
133 0 : AppendLiteral("\"cleanup\"");
134 0 : break;
135 : case IDBTransaction::VERSION_CHANGE:
136 0 : AppendLiteral("\"versionchange\"");
137 0 : break;
138 : default:
139 0 : MOZ_CRASH("Unknown mode!");
140 : };
141 0 : }
142 :
143 : explicit
144 0 : LoggingString(IDBObjectStore* aObjectStore)
145 0 : : nsAutoCString(kQuote)
146 : {
147 0 : MOZ_ASSERT(aObjectStore);
148 :
149 0 : AppendUTF16toUTF8(aObjectStore->Name(), *this);
150 0 : Append(kQuote);
151 0 : }
152 :
153 : explicit
154 0 : LoggingString(IDBIndex* aIndex)
155 0 : : nsAutoCString(kQuote)
156 : {
157 0 : MOZ_ASSERT(aIndex);
158 :
159 0 : AppendUTF16toUTF8(aIndex->Name(), *this);
160 0 : Append(kQuote);
161 0 : }
162 :
163 : explicit
164 0 : LoggingString(IDBKeyRange* aKeyRange)
165 0 : {
166 0 : if (aKeyRange) {
167 0 : if (aKeyRange->IsOnly()) {
168 0 : Assign(LoggingString(aKeyRange->Lower()));
169 : } else {
170 0 : if (aKeyRange->LowerOpen()) {
171 0 : Assign(kOpenParen);
172 : } else {
173 0 : Assign(kOpenBracket);
174 : }
175 :
176 0 : Append(LoggingString(aKeyRange->Lower()));
177 0 : AppendLiteral(", ");
178 0 : Append(LoggingString(aKeyRange->Upper()));
179 :
180 0 : if (aKeyRange->UpperOpen()) {
181 0 : Append(kCloseParen);
182 : } else {
183 0 : Append(kCloseBracket);
184 : }
185 : }
186 : } else {
187 0 : AssignLiteral("<undefined>");
188 : }
189 0 : }
190 :
191 : explicit
192 0 : LoggingString(const Key& aKey)
193 0 : {
194 0 : if (aKey.IsUnset()) {
195 0 : AssignLiteral("<undefined>");
196 0 : } else if (aKey.IsFloat()) {
197 0 : AppendPrintf("%g", aKey.ToFloat());
198 0 : } else if (aKey.IsDate()) {
199 0 : AppendPrintf("<Date %g>", aKey.ToDateMsec());
200 0 : } else if (aKey.IsString()) {
201 0 : nsAutoString str;
202 0 : aKey.ToString(str);
203 0 : AppendPrintf("\"%s\"", NS_ConvertUTF16toUTF8(str).get());
204 0 : } else if (aKey.IsBinary()) {
205 0 : AssignLiteral("[object ArrayBuffer]");
206 : } else {
207 0 : MOZ_ASSERT(aKey.IsArray());
208 0 : AssignLiteral("[...]");
209 : }
210 0 : }
211 :
212 : explicit
213 0 : LoggingString(const IDBCursor::Direction aDirection)
214 0 : {
215 0 : switch (aDirection) {
216 : case IDBCursor::NEXT:
217 0 : AssignLiteral("\"next\"");
218 0 : break;
219 : case IDBCursor::NEXT_UNIQUE:
220 0 : AssignLiteral("\"nextunique\"");
221 0 : break;
222 : case IDBCursor::PREV:
223 0 : AssignLiteral("\"prev\"");
224 0 : break;
225 : case IDBCursor::PREV_UNIQUE:
226 0 : AssignLiteral("\"prevunique\"");
227 0 : break;
228 : default:
229 0 : MOZ_CRASH("Unknown direction!");
230 : };
231 0 : }
232 :
233 : explicit
234 0 : LoggingString(const Optional<uint64_t>& aVersion)
235 0 : {
236 0 : if (aVersion.WasPassed()) {
237 0 : AppendInt(aVersion.Value());
238 : } else {
239 0 : AssignLiteral("<undefined>");
240 : }
241 0 : }
242 :
243 : explicit
244 0 : LoggingString(const Optional<uint32_t>& aLimit)
245 0 : {
246 0 : if (aLimit.WasPassed()) {
247 0 : AppendInt(aLimit.Value());
248 : } else {
249 0 : AssignLiteral("<undefined>");
250 : }
251 0 : }
252 :
253 0 : LoggingString(IDBObjectStore* aObjectStore, const Key& aKey)
254 0 : {
255 0 : MOZ_ASSERT(aObjectStore);
256 :
257 0 : if (!aObjectStore->HasValidKeyPath()) {
258 0 : Append(LoggingString(aKey));
259 : }
260 0 : }
261 :
262 0 : LoggingString(nsIDOMEvent* aEvent, const char16_t* aDefault)
263 0 : : nsAutoCString(kQuote)
264 : {
265 0 : MOZ_ASSERT(aDefault);
266 :
267 0 : nsString eventType;
268 :
269 0 : if (aEvent) {
270 0 : MOZ_ALWAYS_SUCCEEDS(aEvent->GetType(eventType));
271 : } else {
272 0 : eventType = nsDependentString(aDefault);
273 : }
274 :
275 0 : AppendUTF16toUTF8(eventType, *this);
276 0 : Append(kQuote);
277 0 : }
278 : };
279 :
280 : inline void MOZ_FORMAT_PRINTF(2, 3)
281 0 : LoggingHelper(bool aUseProfiler, const char* aFmt, ...)
282 : {
283 0 : MOZ_ASSERT(IndexedDatabaseManager::GetLoggingMode() !=
284 : IndexedDatabaseManager::Logging_Disabled);
285 0 : MOZ_ASSERT(aFmt);
286 :
287 0 : mozilla::LogModule* logModule = IndexedDatabaseManager::GetLoggingModule();
288 0 : MOZ_ASSERT(logModule);
289 :
290 : static const mozilla::LogLevel logLevel = LogLevel::Warning;
291 :
292 0 : if (MOZ_LOG_TEST(logModule, logLevel) ||
293 0 : (aUseProfiler && profiler_is_active())) {
294 0 : nsAutoCString message;
295 :
296 : {
297 : va_list args;
298 0 : va_start(args, aFmt);
299 :
300 0 : message.AppendPrintf(aFmt, args);
301 :
302 0 : va_end(args);
303 : }
304 :
305 0 : MOZ_LOG(logModule, logLevel, ("%s", message.get()));
306 :
307 0 : if (aUseProfiler) {
308 0 : profiler_add_marker(message.get());
309 : }
310 : }
311 0 : }
312 :
313 : } // namespace indexedDB
314 : } // namespace dom
315 : } // namespace mozilla
316 :
317 : #define IDB_LOG_MARK(_detailedFmt, _conciseFmt, ...) \
318 : do { \
319 : using namespace mozilla::dom::indexedDB; \
320 : \
321 : const IndexedDatabaseManager::LoggingMode mode = \
322 : IndexedDatabaseManager::GetLoggingMode(); \
323 : \
324 : if (mode != IndexedDatabaseManager::Logging_Disabled) { \
325 : const char* _fmt; \
326 : if (mode == IndexedDatabaseManager::Logging_Concise || \
327 : mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks) { \
328 : _fmt = _conciseFmt; \
329 : } else { \
330 : MOZ_ASSERT( \
331 : mode == IndexedDatabaseManager::Logging_Detailed || \
332 : mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks); \
333 : _fmt = _detailedFmt; \
334 : } \
335 : \
336 : const bool _useProfiler = \
337 : mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks || \
338 : mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks; \
339 : \
340 : LoggingHelper(_useProfiler, _fmt, ##__VA_ARGS__); \
341 : } \
342 : } while (0)
343 :
344 : #define IDB_LOG_ID_STRING(...) \
345 : mozilla::dom::indexedDB::LoggingIdString(__VA_ARGS__).get()
346 :
347 : #define IDB_LOG_STRINGIFY(...) \
348 : mozilla::dom::indexedDB::LoggingString(__VA_ARGS__).get()
349 :
350 : #endif // mozilla_dom_indexeddb_profilerhelpers_h__
|