ProfilerHelpers.h 9.9 KB

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