tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ProfilerHelpers.cpp (7998B)


      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 #include "ProfilerHelpers.h"
      8 
      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"
     18 #include "mozilla/dom/Event.h"
     19 #include "nsReadableUtils.h"
     20 
     21 namespace mozilla::dom::indexedDB {
     22 
     23 namespace {
     24 static const char kQuote = '\"';
     25 static const char kOpenBracket = '[';
     26 static const char kCloseBracket = ']';
     27 static const char kOpenParen = '(';
     28 static const char kCloseParen = ')';
     29 
     30 void LoggingHelper(bool aUseProfiler, const char* aFmt, va_list args) {
     31  MOZ_ASSERT(IndexedDatabaseManager::GetLoggingMode() !=
     32             IndexedDatabaseManager::Logging_Disabled);
     33  MOZ_ASSERT(aFmt);
     34 
     35  mozilla::LogModule* logModule = IndexedDatabaseManager::GetLoggingModule();
     36  MOZ_ASSERT(logModule);
     37 
     38  static const mozilla::LogLevel logLevel = LogLevel::Warning;
     39 
     40  if (MOZ_LOG_TEST(logModule, logLevel) ||
     41      (aUseProfiler && profiler_thread_is_being_profiled_for_markers())) {
     42    nsAutoCString message;
     43 
     44    message.AppendVprintf(aFmt, args);
     45 
     46    MOZ_LOG(logModule, logLevel, ("%s", message.get()));
     47 
     48    if (aUseProfiler) {
     49      PROFILER_MARKER_UNTYPED(message, DOM);
     50    }
     51  }
     52 }
     53 }  // namespace
     54 
     55 template <bool CheckLoggingMode>
     56 LoggingIdString<CheckLoggingMode>::LoggingIdString() {
     57  using mozilla::ipc::BackgroundChildImpl;
     58 
     59  if (!CheckLoggingMode || IndexedDatabaseManager::GetLoggingMode() !=
     60                               IndexedDatabaseManager::Logging_Disabled) {
     61    const BackgroundChildImpl::ThreadLocal* threadLocal =
     62        BackgroundChildImpl::GetThreadLocalForCurrentThread();
     63    if (threadLocal) {
     64      const auto& idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
     65      if (idbThreadLocal) {
     66        Assign(idbThreadLocal->IdString());
     67      }
     68    }
     69  }
     70 }
     71 
     72 template <bool CheckLoggingMode>
     73 LoggingIdString<CheckLoggingMode>::LoggingIdString(const nsID& aID) {
     74  static_assert(NSID_LENGTH > 1, "NSID_LENGTH is set incorrectly!");
     75  static_assert(NSID_LENGTH <= kStorageSize,
     76                "nsID string won't fit in our storage!");
     77  // Capacity() excludes the null terminator; NSID_LENGTH includes it.
     78  MOZ_ASSERT(Capacity() + 1 == NSID_LENGTH);
     79 
     80  if (!CheckLoggingMode || IndexedDatabaseManager::GetLoggingMode() !=
     81                               IndexedDatabaseManager::Logging_Disabled) {
     82    // NSID_LENGTH counts the null terminator, SetLength() does not.
     83    SetLength(NSID_LENGTH - 1);
     84 
     85    aID.ToProvidedString(
     86        *reinterpret_cast<char(*)[NSID_LENGTH]>(BeginWriting()));
     87  }
     88 }
     89 
     90 template class LoggingIdString<false>;
     91 template class LoggingIdString<true>;
     92 
     93 LoggingString::LoggingString(IDBDatabase* aDatabase) : nsAutoCString(kQuote) {
     94  MOZ_ASSERT(aDatabase);
     95 
     96  AppendUTF16toUTF8(aDatabase->Name(), *this);
     97  Append(kQuote);
     98 }
     99 
    100 LoggingString::LoggingString(const IDBTransaction& aTransaction)
    101    : nsAutoCString(kOpenBracket) {
    102  constexpr auto kCommaSpace = ", "_ns;
    103 
    104  StringJoinAppend(*this, kCommaSpace, aTransaction.ObjectStoreNamesInternal(),
    105                   [](nsACString& dest, const auto& store) {
    106                     dest.Append(kQuote);
    107                     AppendUTF16toUTF8(store, dest);
    108                     dest.Append(kQuote);
    109                   });
    110 
    111  Append(kCloseBracket);
    112  Append(kCommaSpace);
    113 
    114  switch (aTransaction.GetMode()) {
    115    case IDBTransaction::Mode::ReadOnly:
    116      AppendLiteral("\"readonly\"");
    117      break;
    118    case IDBTransaction::Mode::ReadWrite:
    119      AppendLiteral("\"readwrite\"");
    120      break;
    121    case IDBTransaction::Mode::ReadWriteFlush:
    122      AppendLiteral("\"readwriteflush\"");
    123      break;
    124    case IDBTransaction::Mode::Cleanup:
    125      AppendLiteral("\"cleanup\"");
    126      break;
    127    case IDBTransaction::Mode::VersionChange:
    128      AppendLiteral("\"versionchange\"");
    129      break;
    130    default:
    131      MOZ_CRASH("Unknown mode!");
    132  };
    133 }
    134 
    135 LoggingString::LoggingString(IDBObjectStore* aObjectStore)
    136    : nsAutoCString(kQuote) {
    137  MOZ_ASSERT(aObjectStore);
    138 
    139  AppendUTF16toUTF8(aObjectStore->Name(), *this);
    140  Append(kQuote);
    141 }
    142 
    143 LoggingString::LoggingString(IDBIndex* aIndex) : nsAutoCString(kQuote) {
    144  MOZ_ASSERT(aIndex);
    145 
    146  AppendUTF16toUTF8(aIndex->Name(), *this);
    147  Append(kQuote);
    148 }
    149 
    150 LoggingString::LoggingString(IDBKeyRange* aKeyRange) {
    151  if (aKeyRange) {
    152    if (aKeyRange->IsOnly()) {
    153      Assign(LoggingString(aKeyRange->Lower()));
    154    } else {
    155      if (aKeyRange->LowerOpen()) {
    156        Assign(kOpenParen);
    157      } else {
    158        Assign(kOpenBracket);
    159      }
    160 
    161      Append(LoggingString(aKeyRange->Lower()));
    162      AppendLiteral(", ");
    163      Append(LoggingString(aKeyRange->Upper()));
    164 
    165      if (aKeyRange->UpperOpen()) {
    166        Append(kCloseParen);
    167      } else {
    168        Append(kCloseBracket);
    169      }
    170    }
    171  } else {
    172    AssignLiteral("<undefined>");
    173  }
    174 }
    175 
    176 LoggingString::LoggingString(const Key& aKey) {
    177  if (aKey.IsUnset()) {
    178    AssignLiteral("<undefined>");
    179  } else if (aKey.IsFloat()) {
    180    AppendPrintf("%g", aKey.ToFloat());
    181  } else if (aKey.IsDate()) {
    182    AppendPrintf("<Date %g>", aKey.ToDateMsec());
    183  } else if (aKey.IsString()) {
    184    AppendPrintf("\"%s\"", NS_ConvertUTF16toUTF8(aKey.ToString()).get());
    185  } else if (aKey.IsBinary()) {
    186    AssignLiteral("[object ArrayBuffer]");
    187  } else {
    188    MOZ_ASSERT(aKey.IsArray());
    189    AssignLiteral("[...]");
    190  }
    191 }
    192 
    193 LoggingString::LoggingString(const IDBCursorDirection aDirection) {
    194  switch (aDirection) {
    195    case IDBCursorDirection::Next:
    196      AssignLiteral("\"next\"");
    197      break;
    198    case IDBCursorDirection::Nextunique:
    199      AssignLiteral("\"nextunique\"");
    200      break;
    201    case IDBCursorDirection::Prev:
    202      AssignLiteral("\"prev\"");
    203      break;
    204    case IDBCursorDirection::Prevunique:
    205      AssignLiteral("\"prevunique\"");
    206      break;
    207    default:
    208      MOZ_CRASH("Unknown direction!");
    209  };
    210 }
    211 
    212 LoggingString::LoggingString(const Optional<uint64_t>& aVersion) {
    213  if (aVersion.WasPassed()) {
    214    AppendInt(aVersion.Value());
    215  } else {
    216    AssignLiteral("<undefined>");
    217  }
    218 }
    219 
    220 LoggingString::LoggingString(const Optional<uint32_t>& aLimit) {
    221  if (aLimit.WasPassed()) {
    222    AppendInt(aLimit.Value());
    223  } else {
    224    AssignLiteral("<undefined>");
    225  }
    226 }
    227 
    228 LoggingString::LoggingString(IDBObjectStore* aObjectStore, const Key& aKey) {
    229  MOZ_ASSERT(aObjectStore);
    230 
    231  if (!aObjectStore->HasValidKeyPath()) {
    232    Append(LoggingString(aKey));
    233  }
    234 }
    235 
    236 LoggingString::LoggingString(Event* aEvent, const char16_t* aDefault)
    237    : nsAutoCString(kQuote) {
    238  MOZ_ASSERT(aDefault);
    239 
    240  nsAutoString eventType;
    241 
    242  if (aEvent) {
    243    aEvent->GetType(eventType);
    244  } else {
    245    eventType = nsDependentString(aDefault);
    246  }
    247 
    248  AppendUTF16toUTF8(eventType, *this);
    249  Append(kQuote);
    250 }
    251 
    252 void LoggingHelper(const char* aDetailedFmt, const char* aConciseFmt, ...) {
    253  const IndexedDatabaseManager::LoggingMode mode =
    254      IndexedDatabaseManager::GetLoggingMode();
    255 
    256  if (mode != IndexedDatabaseManager::Logging_Disabled) {
    257    const char* fmt;
    258    if (mode == IndexedDatabaseManager::Logging_Concise ||
    259        mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks) {
    260      fmt = aConciseFmt;
    261    } else {
    262      MOZ_ASSERT(mode == IndexedDatabaseManager::Logging_Detailed ||
    263                 mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks);
    264      fmt = aDetailedFmt;
    265    }
    266 
    267    const bool useProfiler =
    268        mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks ||
    269        mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks;
    270 
    271    va_list args;
    272    va_start(args, aConciseFmt);
    273 
    274    LoggingHelper(useProfiler, fmt, args);
    275 
    276    va_end(args);
    277  }
    278 }
    279 
    280 }  // namespace mozilla::dom::indexedDB