Backed out 8 changesets (bug 1497007) for causing build bustages in /builds/worker/workspace/build/src/dom/indexedDB/IDBTransaction.cpp CLOSED TREE
authorshindli <shindli@mozilla.com>
Fri, 08 Nov 2019 16:28:53 +0200
changeset 501299 e58433e75e955fcc154b0ed647a352fa308ccb1e
parent 501298 682483b64a30714b3adf47feb2586bdacdc1800b
child 501300 6fb4aa1b817d5995c11f0507b6273b373fedb02e
push id114168
push userdluca@mozilla.com
push dateSun, 10 Nov 2019 03:08:55 +0000
treeherdermozilla-inbound@33f64c1ef3e4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1497007
milestone72.0a1
backs out15de0d72f1c42745a24dd32550f4c8dd1884ce2f
7056932f64222b6787681ee2117a214ba7c96e08
7304fae8c4364b150f04e6e3d9a5d34cf27345ac
be22a95de04b3917bb18ae9b7f995dea4d02cd79
98ac48b5f1ef0fb93b87cda238d5cd5b1e7970ae
562d3cda9fa39ede2a172913876e4600aae78c0f
3f96e71be2e3063fb4c2013e6ad62b06fab71cd1
3d9e86698c9fbe0fc6cf56faa32c7380913dc97d
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 8 changesets (bug 1497007) for causing build bustages in /builds/worker/workspace/build/src/dom/indexedDB/IDBTransaction.cpp CLOSED TREE Backed out changeset 15de0d72f1c4 (bug 1497007) Backed out changeset 7056932f6422 (bug 1497007) Backed out changeset 7304fae8c436 (bug 1497007) Backed out changeset be22a95de04b (bug 1497007) Backed out changeset 98ac48b5f1ef (bug 1497007) Backed out changeset 562d3cda9fa3 (bug 1497007) Backed out changeset 3f96e71be2e3 (bug 1497007) Backed out changeset 3d9e86698c9f (bug 1497007)
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBIndex.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBTransaction.cpp
dom/indexedDB/IDBTransaction.h
--- a/dom/indexedDB/IDBDatabase.cpp
+++ b/dom/indexedDB/IDBDatabase.cpp
@@ -727,18 +727,16 @@ void IDBDatabase::AbortTransactions(bool
                                   const bool aShouldWarn) {
       MOZ_ASSERT(aDatabase);
       aDatabase->AssertIsOnOwningThread();
 
       nsTHashtable<nsPtrHashKey<IDBTransaction>>& transactionTable =
           aDatabase->mTransactions;
 
       if (!transactionTable.Count()) {
-        // Return early as an optimization, the remainder is a no-op in this
-        // case.
         return;
       }
 
       StrongTransactionArray transactionsToAbort;
       transactionsToAbort.SetCapacity(transactionTable.Count());
 
       for (auto iter = transactionTable.Iter(); !iter.Done(); iter.Next()) {
         IDBTransaction* transaction = iter.Get()->GetKey();
@@ -751,36 +749,47 @@ void IDBDatabase::AbortTransactions(bool
         // been successfully committed yet so we will warn the user.
         if (!transaction->IsDone()) {
           transactionsToAbort.AppendElement(transaction);
         }
       }
       MOZ_ASSERT(transactionsToAbort.Length() <= transactionTable.Count());
 
       if (transactionsToAbort.IsEmpty()) {
-        // Return early as an optimization, the remainder is a no-op in this
-        // case.
         return;
       }
 
       // We want to abort transactions as soon as possible so we iterate the
       // transactions once and abort them all first, collecting the transactions
       // that need to have a warning issued along the way. Those that need a
       // warning will be a subset of those that are aborted, so we don't need
       // additional strong references here.
       WeakTransactionArray transactionsThatNeedWarning;
 
       for (RefPtr<IDBTransaction>& transaction : transactionsToAbort) {
         MOZ_ASSERT(transaction);
         MOZ_ASSERT(!transaction->IsDone());
 
-        // We warn for any transactions that could have written data, but
-        // ignore read-only transactions.
-        if (aShouldWarn && transaction->IsWriteAllowed()) {
-          transactionsThatNeedWarning.AppendElement(transaction);
+        if (aShouldWarn) {
+          switch (transaction->GetMode()) {
+            // We ignore transactions that could not have written any data.
+            case IDBTransaction::READ_ONLY:
+              break;
+
+            // We warn for any transactions that could have written data.
+            case IDBTransaction::READ_WRITE:
+            case IDBTransaction::READ_WRITE_FLUSH:
+            case IDBTransaction::CLEANUP:
+            case IDBTransaction::VERSION_CHANGE:
+              transactionsThatNeedWarning.AppendElement(transaction);
+              break;
+
+            default:
+              MOZ_CRASH("Unknown mode!");
+          }
         }
 
         transaction->Abort(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR);
       }
 
       static const char kWarningMessage[] =
           "IndexedDBTransactionAbortNavigation";
 
--- a/dom/indexedDB/IDBIndex.cpp
+++ b/dom/indexedDB/IDBIndex.cpp
@@ -83,26 +83,34 @@ void IDBIndex::AssertIsOnOwningThread() 
 }
 
 #endif  // DEBUG
 
 void IDBIndex::RefreshMetadata(bool aMayDelete) {
   AssertIsOnOwningThread();
   MOZ_ASSERT_IF(mDeletedMetadata, mMetadata == mDeletedMetadata);
 
-  const auto& indexes = mObjectStore->Spec().indexes();
-  const auto foundIt = std::find_if(
-      indexes.cbegin(), indexes.cend(),
-      [id = Id()](const auto& metadata) { return metadata.id() == id; });
-  const bool found = foundIt != indexes.cend();
+  const nsTArray<IndexMetadata>& indexes = mObjectStore->Spec().indexes();
+
+  bool found = false;
+
+  for (uint32_t count = indexes.Length(), index = 0; index < count; index++) {
+    const IndexMetadata& metadata = indexes[index];
+
+    if (metadata.id() == Id()) {
+      mMetadata = &metadata;
+
+      found = true;
+      break;
+    }
+  }
 
   MOZ_ASSERT_IF(!aMayDelete && !mDeletedMetadata, found);
 
   if (found) {
-    mMetadata = &*foundIt;
     MOZ_ASSERT(mMetadata != mDeletedMetadata);
     mDeletedMetadata = nullptr;
   } else {
     NoteDeletion();
   }
 }
 
 void IDBIndex::NoteDeletion() {
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -2348,30 +2348,37 @@ void IDBObjectStore::RefreshSpec(bool aM
   AssertIsOnOwningThread();
   MOZ_ASSERT_IF(mDeletedSpec, mSpec == mDeletedSpec);
 
   const DatabaseSpec* dbSpec = mTransaction->Database()->Spec();
   MOZ_ASSERT(dbSpec);
 
   const nsTArray<ObjectStoreSpec>& objectStores = dbSpec->objectStores();
 
-  const auto foundIt = std::find_if(objectStores.cbegin(), objectStores.cend(),
-                                    [id = Id()](const auto& objSpec) {
-                                      return objSpec.metadata().id() == id;
-                                    });
-  const bool found = foundIt != objectStores.cend();
-  if (found) {
-    mSpec = &*foundIt;
-
-    for (auto& index : mIndexes) {
-      index->RefreshMetadata(aMayDelete);
-    }
-
-    for (auto& index : mDeletedIndexes) {
-      index->RefreshMetadata(false);
+  bool found = false;
+
+  for (uint32_t objCount = objectStores.Length(), objIndex = 0;
+       objIndex < objCount; objIndex++) {
+    const ObjectStoreSpec& objSpec = objectStores[objIndex];
+
+    if (objSpec.metadata().id() == Id()) {
+      mSpec = &objSpec;
+
+      for (uint32_t idxCount = mIndexes.Length(), idxIndex = 0;
+           idxIndex < idxCount; idxIndex++) {
+        mIndexes[idxIndex]->RefreshMetadata(aMayDelete);
+      }
+
+      for (uint32_t idxCount = mDeletedIndexes.Length(), idxIndex = 0;
+           idxIndex < idxCount; idxIndex++) {
+        mDeletedIndexes[idxIndex]->RefreshMetadata(false);
+      }
+
+      found = true;
+      break;
     }
   }
 
   MOZ_ASSERT_IF(!aMayDelete && !mDeletedSpec, found);
 
   if (found) {
     MOZ_ASSERT(mSpec != mDeletedSpec);
     mDeletedSpec = nullptr;
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -26,205 +26,171 @@
 #include "nsServiceManagerUtils.h"
 #include "nsTHashtable.h"
 #include "ProfilerHelpers.h"
 #include "ReportInternalError.h"
 
 // Include this last to avoid path problems on Windows.
 #include "ActorsChild.h"
 
-namespace {
-using namespace mozilla::dom::indexedDB;
-using namespace mozilla::ipc;
-
-// TODO: Move this to xpcom/ds.
-template <typename T, typename Range, typename Transformation>
-nsTHashtable<T> TransformToHashtable(const Range& aRange,
-                                     const Transformation& aTransformation) {
-  // TODO: Determining the size of the range is not syntactically necessary (and
-  // requires random access iterators if expressed this way). It is a
-  // performance optimization. We could resort to std::distance to support any
-  // iterator category, but this would lead to a double iteration of the range
-  // in case of non-random-access iterators. It is hard to determine in general
-  // if double iteration or reallocation is worse.
-  auto res = nsTHashtable<T>(aRange.cend() - aRange.cbegin());
-  // TOOD: std::transform could be used if nsTHashtable had an insert_iterator,
-  // and this would also allow a more generic version not depending on
-  // nsTHashtable at all.
-  for (const auto& item : aRange) {
-    res.PutEntry(aTransformation(item));
-  }
-  return res;
-}
-
-ThreadLocal* GetIndexedDBThreadLocal() {
-  BackgroundChildImpl::ThreadLocal* const threadLocal =
-      BackgroundChildImpl::GetThreadLocalForCurrentThread();
-  MOZ_ASSERT(threadLocal);
-
-  ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
-  MOZ_ASSERT(idbThreadLocal);
-
-  return idbThreadLocal;
-}
-}  // namespace
-
 namespace mozilla {
 namespace dom {
 
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::ipc;
 
-bool IDBTransaction::HasTransactionChild() const {
-  return (mMode == VERSION_CHANGE
-              ? static_cast<void*>(
-                    mBackgroundActor.mVersionChangeBackgroundActor)
-              : mBackgroundActor.mNormalBackgroundActor) != nullptr;
-}
-
-template <typename Func>
-auto IDBTransaction::DoWithTransactionChild(const Func& aFunc) const {
-  MOZ_ASSERT(HasTransactionChild());
-  return mMode == VERSION_CHANGE
-             ? aFunc(*mBackgroundActor.mVersionChangeBackgroundActor)
-             : aFunc(*mBackgroundActor.mNormalBackgroundActor);
-}
-
-IDBTransaction::IDBTransaction(IDBDatabase* const aDatabase,
+IDBTransaction::IDBTransaction(IDBDatabase* aDatabase,
                                const nsTArray<nsString>& aObjectStoreNames,
-                               const Mode aMode, nsString aFilename,
-                               const uint32_t aLineNo, const uint32_t aColumn)
+                               Mode aMode)
     : DOMEventTargetHelper(aDatabase),
       mDatabase(aDatabase),
       mObjectStoreNames(aObjectStoreNames),
-      mLoggingSerialNumber(GetIndexedDBThreadLocal()->NextTransactionSN(aMode)),
+      mLoggingSerialNumber(0),
       mNextObjectStoreId(0),
       mNextIndexId(0),
       mAbortCode(NS_OK),
       mPendingRequestCount(0),
-      mFilename(std::move(aFilename)),
-      mLineNo(aLineNo),
-      mColumn(aColumn),
+      mLineNo(0),
+      mColumn(0),
       mReadyState(IDBTransaction::INITIAL),
       mMode(aMode),
       mCreating(false),
       mRegistered(false),
       mAbortedByScript(false),
       mNotedActiveTransaction(false)
 #ifdef DEBUG
       ,
       mSentCommitOrAbort(false),
       mFiredCompleteOrAbort(false)
 #endif
 {
   MOZ_ASSERT(aDatabase);
   aDatabase->AssertIsOnOwningThread();
 
-  // This also nulls mBackgroundActor.mVersionChangeBackgroundActor, so this is
-  // valid also for mMode == VERSION_CHANGE.
   mBackgroundActor.mNormalBackgroundActor = nullptr;
 
+  BackgroundChildImpl::ThreadLocal* threadLocal =
+      BackgroundChildImpl::GetThreadLocalForCurrentThread();
+  MOZ_ASSERT(threadLocal);
+
+  ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
+  MOZ_ASSERT(idbThreadLocal);
+
+  const_cast<int64_t&>(mLoggingSerialNumber) =
+      idbThreadLocal->NextTransactionSN(aMode);
+
 #ifdef DEBUG
   if (!aObjectStoreNames.IsEmpty()) {
+    nsTArray<nsString> sortedNames(aObjectStoreNames);
+    sortedNames.Sort();
+
+    const uint32_t count = sortedNames.Length();
+    MOZ_ASSERT(count == aObjectStoreNames.Length());
+
     // Make sure the array is properly sorted.
-    MOZ_ASSERT(
-        std::is_sorted(aObjectStoreNames.cbegin(), aObjectStoreNames.cend()));
+    for (uint32_t index = 0; index < count; index++) {
+      MOZ_ASSERT(aObjectStoreNames[index] == sortedNames[index]);
+    }
 
     // Make sure there are no duplicates in our objectStore names.
-    MOZ_ASSERT(aObjectStoreNames.cend() ==
-               std::adjacent_find(aObjectStoreNames.cbegin(),
-                                  aObjectStoreNames.cend()));
+    for (uint32_t index = 0; index < count - 1; index++) {
+      MOZ_ASSERT(sortedNames[index] != sortedNames[index + 1]);
+    }
   }
 #endif
 
   mozilla::HoldJSObjects(this);
 }
 
 IDBTransaction::~IDBTransaction() {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!mPendingRequestCount);
   MOZ_ASSERT(!mCreating);
   MOZ_ASSERT(!mNotedActiveTransaction);
   MOZ_ASSERT(mSentCommitOrAbort);
-  MOZ_ASSERT_IF(HasTransactionChild(), mFiredCompleteOrAbort);
+  MOZ_ASSERT_IF(
+      mMode == VERSION_CHANGE && mBackgroundActor.mVersionChangeBackgroundActor,
+      mFiredCompleteOrAbort);
+  MOZ_ASSERT_IF(
+      mMode != VERSION_CHANGE && mBackgroundActor.mNormalBackgroundActor,
+      mFiredCompleteOrAbort);
 
   if (mRegistered) {
     mDatabase->UnregisterTransaction(this);
 #ifdef DEBUG
     mRegistered = false;
 #endif
   }
 
-  if (HasTransactionChild()) {
-    if (mMode == VERSION_CHANGE) {
-      mBackgroundActor.mVersionChangeBackgroundActor->SendDeleteMeInternal(
-          /* aFailedConstructor */ false);
-    } else {
-      mBackgroundActor.mNormalBackgroundActor->SendDeleteMeInternal();
+  if (mMode == VERSION_CHANGE) {
+    if (auto* actor = mBackgroundActor.mVersionChangeBackgroundActor) {
+      actor->SendDeleteMeInternal(/* aFailedConstructor */ false);
+
+      MOZ_ASSERT(!mBackgroundActor.mVersionChangeBackgroundActor,
+                 "SendDeleteMeInternal should have cleared!");
     }
+  } else if (auto* actor = mBackgroundActor.mNormalBackgroundActor) {
+    actor->SendDeleteMeInternal();
+
+    MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor,
+               "SendDeleteMeInternal should have cleared!");
   }
-  MOZ_ASSERT(!HasTransactionChild(),
-             "SendDeleteMeInternal should have cleared!");
 
   ReleaseWrapper(this);
   mozilla::DropJSObjects(this);
 }
 
 // static
 already_AddRefed<IDBTransaction> IDBTransaction::CreateVersionChange(
-    IDBDatabase* const aDatabase,
-    BackgroundVersionChangeTransactionChild* const aActor,
-    IDBOpenDBRequest* const aOpenRequest, const int64_t aNextObjectStoreId,
-    const int64_t aNextIndexId) {
+    IDBDatabase* aDatabase, BackgroundVersionChangeTransactionChild* aActor,
+    IDBOpenDBRequest* aOpenRequest, int64_t aNextObjectStoreId,
+    int64_t aNextIndexId) {
   MOZ_ASSERT(aDatabase);
   aDatabase->AssertIsOnOwningThread();
   MOZ_ASSERT(aActor);
   MOZ_ASSERT(aOpenRequest);
   MOZ_ASSERT(aNextObjectStoreId > 0);
   MOZ_ASSERT(aNextIndexId > 0);
 
   nsTArray<nsString> emptyObjectStoreNames;
 
-  nsString filename;
-  uint32_t lineNo, column;
-  aOpenRequest->GetCallerLocation(filename, &lineNo, &column);
   RefPtr<IDBTransaction> transaction =
-      new IDBTransaction(aDatabase, emptyObjectStoreNames, VERSION_CHANGE,
-                         std::move(filename), lineNo, column);
+      new IDBTransaction(aDatabase, emptyObjectStoreNames, VERSION_CHANGE);
+  aOpenRequest->GetCallerLocation(transaction->mFilename, &transaction->mLineNo,
+                                  &transaction->mColumn);
 
   transaction->NoteActiveTransaction();
 
   transaction->mBackgroundActor.mVersionChangeBackgroundActor = aActor;
   transaction->mNextObjectStoreId = aNextObjectStoreId;
   transaction->mNextIndexId = aNextIndexId;
 
   aDatabase->RegisterTransaction(transaction);
   transaction->mRegistered = true;
 
   return transaction.forget();
 }
 
 // static
 already_AddRefed<IDBTransaction> IDBTransaction::Create(
-    JSContext* const aCx, IDBDatabase* const aDatabase,
-    const nsTArray<nsString>& aObjectStoreNames, const Mode aMode) {
+    JSContext* aCx, IDBDatabase* aDatabase,
+    const nsTArray<nsString>& aObjectStoreNames, Mode aMode) {
   MOZ_ASSERT(aDatabase);
   aDatabase->AssertIsOnOwningThread();
   MOZ_ASSERT(!aObjectStoreNames.IsEmpty());
   MOZ_ASSERT(aMode == READ_ONLY || aMode == READ_WRITE ||
              aMode == READ_WRITE_FLUSH || aMode == CLEANUP);
 
-  nsString filename;
-  uint32_t lineNo, column;
-  IDBRequest::CaptureCaller(aCx, filename, &lineNo, &column);
-  RefPtr<IDBTransaction> transaction = new IDBTransaction(
-      aDatabase, aObjectStoreNames, aMode, std::move(filename), lineNo, column);
+  RefPtr<IDBTransaction> transaction =
+      new IDBTransaction(aDatabase, aObjectStoreNames, aMode);
+  IDBRequest::CaptureCaller(aCx, transaction->mFilename, &transaction->mLineNo,
+                            &transaction->mColumn);
 
   if (!NS_IsMainThread()) {
-    WorkerPrivate* const workerPrivate = GetCurrentThreadWorkerPrivate();
+    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(workerPrivate);
 
     workerPrivate->AssertIsOnWorkerThread();
 
     RefPtr<StrongWorkerRef> workerRef = StrongWorkerRef::Create(
         workerPrivate, "IDBTransaction", [transaction]() {
           transaction->AssertIsOnOwningThread();
           if (!transaction->IsCommittingOrDone()) {
@@ -257,102 +223,127 @@ already_AddRefed<IDBTransaction> IDBTran
 }
 
 // static
 IDBTransaction* IDBTransaction::GetCurrent() {
   using namespace mozilla::ipc;
 
   MOZ_ASSERT(BackgroundChild::GetForCurrentThread());
 
-  return GetIndexedDBThreadLocal()->GetCurrentTransaction();
+  BackgroundChildImpl::ThreadLocal* threadLocal =
+      BackgroundChildImpl::GetThreadLocalForCurrentThread();
+  MOZ_ASSERT(threadLocal);
+
+  ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal;
+  MOZ_ASSERT(idbThreadLocal);
+
+  return idbThreadLocal->GetCurrentTransaction();
 }
 
 #ifdef DEBUG
 
 void IDBTransaction::AssertIsOnOwningThread() const {
   MOZ_ASSERT(mDatabase);
   mDatabase->AssertIsOnOwningThread();
 }
 
 #endif  // DEBUG
 
 void IDBTransaction::SetBackgroundActor(
-    indexedDB::BackgroundTransactionChild* const aBackgroundActor) {
+    indexedDB::BackgroundTransactionChild* aBackgroundActor) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aBackgroundActor);
   MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor);
   MOZ_ASSERT(mMode != VERSION_CHANGE);
 
   NoteActiveTransaction();
 
   mBackgroundActor.mNormalBackgroundActor = aBackgroundActor;
 }
 
 BackgroundRequestChild* IDBTransaction::StartRequest(
-    IDBRequest* const aRequest, const RequestParams& aParams) {
+    IDBRequest* aRequest, const RequestParams& aParams) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aRequest);
   MOZ_ASSERT(aParams.type() != RequestParams::T__None);
 
-  BackgroundRequestChild* const actor = new BackgroundRequestChild(aRequest);
+  BackgroundRequestChild* actor = new BackgroundRequestChild(aRequest);
+
+  if (mMode == VERSION_CHANGE) {
+    MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
 
-  DoWithTransactionChild([actor, &aParams](auto& transactionChild) {
-    transactionChild.SendPBackgroundIDBRequestConstructor(actor, aParams);
-  });
+    mBackgroundActor.mVersionChangeBackgroundActor
+        ->SendPBackgroundIDBRequestConstructor(actor, aParams);
+  } else {
+    MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
+
+    mBackgroundActor.mNormalBackgroundActor
+        ->SendPBackgroundIDBRequestConstructor(actor, aParams);
+  }
 
   MOZ_ASSERT(actor->GetActorEventTarget(),
              "The event target shall be inherited from its manager actor.");
 
   // Balanced in BackgroundRequestChild::Recv__delete__().
   OnNewRequest();
 
   return actor;
 }
 
-void IDBTransaction::OpenCursor(BackgroundCursorChild* const aBackgroundActor,
+void IDBTransaction::OpenCursor(BackgroundCursorChild* aBackgroundActor,
                                 const OpenCursorParams& aParams) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aBackgroundActor);
   MOZ_ASSERT(aParams.type() != OpenCursorParams::T__None);
 
-  DoWithTransactionChild([aBackgroundActor, &aParams](auto& actor) {
-    actor.SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
-  });
+  if (mMode == VERSION_CHANGE) {
+    MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
+
+    mBackgroundActor.mVersionChangeBackgroundActor
+        ->SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
+  } else {
+    MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
+
+    mBackgroundActor.mNormalBackgroundActor
+        ->SendPBackgroundIDBCursorConstructor(aBackgroundActor, aParams);
+  }
 
   MOZ_ASSERT(aBackgroundActor->GetActorEventTarget(),
              "The event target shall be inherited from its manager actor.");
 
   // Balanced in BackgroundCursorChild::RecvResponse().
   OnNewRequest();
 }
 
-void IDBTransaction::RefreshSpec(const bool aMayDelete) {
+void IDBTransaction::RefreshSpec(bool aMayDelete) {
   AssertIsOnOwningThread();
 
-  for (auto& objectStore : mObjectStores) {
-    objectStore->RefreshSpec(aMayDelete);
+  for (uint32_t count = mObjectStores.Length(), index = 0; index < count;
+       index++) {
+    mObjectStores[index]->RefreshSpec(aMayDelete);
   }
 
-  for (auto& objectStore : mDeletedObjectStores) {
-    objectStore->RefreshSpec(false);
+  for (uint32_t count = mDeletedObjectStores.Length(), index = 0; index < count;
+       index++) {
+    mDeletedObjectStores[index]->RefreshSpec(false);
   }
 }
 
 void IDBTransaction::OnNewRequest() {
   AssertIsOnOwningThread();
 
   if (!mPendingRequestCount) {
     MOZ_ASSERT(INITIAL == mReadyState);
     mReadyState = LOADING;
   }
 
   ++mPendingRequestCount;
 }
 
-void IDBTransaction::OnRequestFinished(const bool aRequestCompletedSuccessfully) {
+void IDBTransaction::OnRequestFinished(bool aRequestCompletedSuccessfully) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mPendingRequestCount);
 
   --mPendingRequestCount;
 
   if (!mPendingRequestCount) {
     mReadyState = COMMITTING;
 
@@ -386,39 +377,50 @@ void IDBTransaction::SendCommit() {
   // Don't do this in the macro because we always need to increment the serial
   // number to keep in sync with the parent.
   const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
 
   IDB_LOG_MARK_CHILD_TRANSACTION_REQUEST(
       "All requests complete, committing transaction", "IDBTransaction commit",
       LoggingSerialNumber(), requestSerialNumber);
 
-  DoWithTransactionChild([](auto& actor) { actor.SendCommit(); });
+  if (mMode == VERSION_CHANGE) {
+    MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
+    mBackgroundActor.mVersionChangeBackgroundActor->SendCommit();
+  } else {
+    MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
+    mBackgroundActor.mNormalBackgroundActor->SendCommit();
+  }
 
 #ifdef DEBUG
   mSentCommitOrAbort = true;
 #endif
 }
 
-void IDBTransaction::SendAbort(const nsresult aResultCode) {
+void IDBTransaction::SendAbort(nsresult aResultCode) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aResultCode));
   MOZ_ASSERT(IsCommittingOrDone());
   MOZ_ASSERT(!mSentCommitOrAbort);
 
   // Don't do this in the macro because we always need to increment the serial
   // number to keep in sync with the parent.
   const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber();
 
   IDB_LOG_MARK_CHILD_TRANSACTION_REQUEST(
       "Aborting transaction with result 0x%x", "IDBTransaction abort (0x%x)",
       LoggingSerialNumber(), requestSerialNumber, aResultCode);
 
-  DoWithTransactionChild(
-      [aResultCode](auto& actor) { actor.SendAbort(aResultCode); });
+  if (mMode == VERSION_CHANGE) {
+    MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
+    mBackgroundActor.mVersionChangeBackgroundActor->SendAbort(aResultCode);
+  } else {
+    MOZ_ASSERT(mBackgroundActor.mNormalBackgroundActor);
+    mBackgroundActor.mNormalBackgroundActor->SendAbort(aResultCode);
+  }
 
 #ifdef DEBUG
   mSentCommitOrAbort = true;
 #endif
 }
 
 void IDBTransaction::NoteActiveTransaction() {
   AssertIsOnOwningThread();
@@ -453,19 +455,18 @@ bool IDBTransaction::IsOpen() const {
   if (mReadyState == IDBTransaction::LOADING &&
       (mCreating || GetCurrent() == this)) {
     return true;
   }
 
   return false;
 }
 
-void IDBTransaction::GetCallerLocation(nsAString& aFilename,
-                                       uint32_t* const aLineNo,
-                                       uint32_t* const aColumn) const {
+void IDBTransaction::GetCallerLocation(nsAString& aFilename, uint32_t* aLineNo,
+                                       uint32_t* aColumn) const {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aLineNo);
   MOZ_ASSERT(aColumn);
 
   aFilename = mFilename;
   *aLineNo = mLineNo;
   *aColumn = mColumn;
 }
@@ -474,224 +475,226 @@ already_AddRefed<IDBObjectStore> IDBTran
     const ObjectStoreSpec& aSpec) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aSpec.metadata().id());
   MOZ_ASSERT(VERSION_CHANGE == mMode);
   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
   MOZ_ASSERT(IsOpen());
 
 #ifdef DEBUG
-  // TODO: Use #ifdef and local variable as a workaround for Bug 1583449.
-  const bool objectStoreNameDoesNotYetExist =
-      std::all_of(mObjectStores.cbegin(), mObjectStores.cend(),
-                  [& name = aSpec.metadata().name()](const auto& objectStore) {
-                    return objectStore->Name() != name;
-                  });
-  MOZ_ASSERT(objectStoreNameDoesNotYetExist);
+  {
+    const nsString& name = aSpec.metadata().name();
+
+    for (uint32_t count = mObjectStores.Length(), index = 0; index < count;
+         index++) {
+      MOZ_ASSERT(mObjectStores[index]->Name() != name);
+    }
+  }
 #endif
 
   MOZ_ALWAYS_TRUE(
       mBackgroundActor.mVersionChangeBackgroundActor->SendCreateObjectStore(
           aSpec.metadata()));
 
   RefPtr<IDBObjectStore> objectStore = IDBObjectStore::Create(this, aSpec);
   MOZ_ASSERT(objectStore);
 
   mObjectStores.AppendElement(objectStore);
 
   return objectStore.forget();
 }
 
-void IDBTransaction::DeleteObjectStore(const int64_t aObjectStoreId) {
+void IDBTransaction::DeleteObjectStore(int64_t aObjectStoreId) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aObjectStoreId);
   MOZ_ASSERT(VERSION_CHANGE == mMode);
   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
   MOZ_ASSERT(IsOpen());
 
   MOZ_ALWAYS_TRUE(
       mBackgroundActor.mVersionChangeBackgroundActor->SendDeleteObjectStore(
           aObjectStoreId));
 
-  const auto foundIt =
-      std::find_if(mObjectStores.begin(), mObjectStores.end(),
-                   [aObjectStoreId](const auto& objectStore) {
-                     return objectStore->Id() == aObjectStoreId;
-                   });
-  if (foundIt != mObjectStores.end()) {
-    auto& objectStore = *foundIt;
-    objectStore->NoteDeletion();
+  for (uint32_t count = mObjectStores.Length(), index = 0; index < count;
+       index++) {
+    RefPtr<IDBObjectStore>& objectStore = mObjectStores[index];
+
+    if (objectStore->Id() == aObjectStoreId) {
+      objectStore->NoteDeletion();
 
-    RefPtr<IDBObjectStore>* deletedObjectStore =
-        mDeletedObjectStores.AppendElement();
-    deletedObjectStore->swap(objectStore);
+      RefPtr<IDBObjectStore>* deletedObjectStore =
+          mDeletedObjectStores.AppendElement();
+      deletedObjectStore->swap(mObjectStores[index]);
 
-    mObjectStores.RemoveElementAt(foundIt);
+      mObjectStores.RemoveElementAt(index);
+      break;
+    }
   }
 }
 
-void IDBTransaction::RenameObjectStore(const int64_t aObjectStoreId,
+void IDBTransaction::RenameObjectStore(int64_t aObjectStoreId,
                                        const nsAString& aName) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aObjectStoreId);
   MOZ_ASSERT(VERSION_CHANGE == mMode);
   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
   MOZ_ASSERT(IsOpen());
 
   MOZ_ALWAYS_TRUE(
       mBackgroundActor.mVersionChangeBackgroundActor->SendRenameObjectStore(
           aObjectStoreId, nsString(aName)));
 }
 
-void IDBTransaction::CreateIndex(IDBObjectStore* const aObjectStore,
+void IDBTransaction::CreateIndex(IDBObjectStore* aObjectStore,
                                  const indexedDB::IndexMetadata& aMetadata) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aObjectStore);
   MOZ_ASSERT(aMetadata.id());
   MOZ_ASSERT(VERSION_CHANGE == mMode);
   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
   MOZ_ASSERT(IsOpen());
 
   MOZ_ALWAYS_TRUE(
       mBackgroundActor.mVersionChangeBackgroundActor->SendCreateIndex(
           aObjectStore->Id(), aMetadata));
 }
 
-void IDBTransaction::DeleteIndex(IDBObjectStore* const aObjectStore,
-                                 const int64_t aIndexId) {
+void IDBTransaction::DeleteIndex(IDBObjectStore* aObjectStore,
+                                 int64_t aIndexId) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aObjectStore);
   MOZ_ASSERT(aIndexId);
   MOZ_ASSERT(VERSION_CHANGE == mMode);
   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
   MOZ_ASSERT(IsOpen());
 
   MOZ_ALWAYS_TRUE(
       mBackgroundActor.mVersionChangeBackgroundActor->SendDeleteIndex(
           aObjectStore->Id(), aIndexId));
 }
 
-void IDBTransaction::RenameIndex(IDBObjectStore* const aObjectStore,
-                                 const int64_t aIndexId,
+void IDBTransaction::RenameIndex(IDBObjectStore* aObjectStore, int64_t aIndexId,
                                  const nsAString& aName) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aObjectStore);
   MOZ_ASSERT(aIndexId);
   MOZ_ASSERT(VERSION_CHANGE == mMode);
   MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor);
   MOZ_ASSERT(IsOpen());
 
   MOZ_ALWAYS_TRUE(
       mBackgroundActor.mVersionChangeBackgroundActor->SendRenameIndex(
           aObjectStore->Id(), aIndexId, nsString(aName)));
 }
 
-void IDBTransaction::AbortInternal(const nsresult aAbortCode,
+void IDBTransaction::AbortInternal(nsresult aAbortCode,
                                    already_AddRefed<DOMException> aError) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aAbortCode));
   MOZ_ASSERT(!IsCommittingOrDone());
 
   RefPtr<DOMException> error = aError;
 
   const bool isVersionChange = mMode == VERSION_CHANGE;
-  const bool needToSendAbort = mReadyState == INITIAL;
+  const bool isInvalidated = mDatabase->IsInvalidated();
+  bool needToSendAbort = mReadyState == INITIAL;
 
   mAbortCode = aAbortCode;
   mReadyState = DONE;
   mError = error.forget();
 
   if (isVersionChange) {
     // If a version change transaction is aborted, we must revert the world
     // back to its previous state unless we're being invalidated after the
     // transaction already completed.
-    if (!mDatabase->IsInvalidated()) {
+    if (!isInvalidated) {
       mDatabase->RevertToPreviousState();
     }
 
     // We do the reversion only for the mObjectStores/mDeletedObjectStores but
     // not for the mIndexes/mDeletedIndexes of each IDBObjectStore because it's
     // time-consuming(O(m*n)) and mIndexes/mDeletedIndexes won't be used anymore
     // in IDBObjectStore::(Create|Delete)Index() and IDBObjectStore::Index() in
     // which all the executions are returned earlier by !transaction->IsOpen().
 
     const nsTArray<ObjectStoreSpec>& specArray =
         mDatabase->Spec()->objectStores();
 
     if (specArray.IsEmpty()) {
-      // This case is specially handled as a performance optimization, it is
-      // equivalent to the else block.
       mObjectStores.Clear();
+      mDeletedObjectStores.Clear();
     } else {
-      const auto validIds = TransformToHashtable<nsUint64HashKey>(
-          specArray, [](const auto& spec) {
-            const int64_t objectStoreId = spec.metadata().id();
-            MOZ_ASSERT(objectStoreId);
-            return static_cast<uint64_t>(objectStoreId);
-          });
+      nsTHashtable<nsUint64HashKey> validIds(specArray.Length());
 
-      mObjectStores.RemoveElementsAt(
-          std::remove_if(mObjectStores.begin(), mObjectStores.end(),
-                         [&validIds](const auto& objectStore) {
-                           return !validIds.Contains(
-                               uint64_t(objectStore->Id()));
-                         }),
-          mObjectStores.end());
+      for (uint32_t specCount = specArray.Length(), specIndex = 0;
+           specIndex < specCount; specIndex++) {
+        const int64_t objectStoreId = specArray[specIndex].metadata().id();
+        MOZ_ASSERT(objectStoreId);
 
-      // TODO: if nsTArray had an insert iterator, we could use the following
-      // instead:
-      // std::copy_if(std::make_move_iterator(mDeletedObjectStores.begin()),
-      //              std::make_move_iterator(mDeletedObjectStores.end()),
-      //              std::back_inserter(mObjectStores),
-      //              [&validIds](const auto& deletedObjectStore) {
-      //                const int64_t objectStoreId = deletedObjectStore->Id();
-      //                MOZ_ASSERT(objectStoreId);
-      //                return validIds.Contains(uint64_t(objectStoreId));
-      //              });
-      for (auto& deletedObjectStore : mDeletedObjectStores) {
-        const int64_t objectStoreId = deletedObjectStore->Id();
+        validIds.PutEntry(uint64_t(objectStoreId));
+      }
+
+      for (uint32_t objCount = mObjectStores.Length(), objIndex = 0;
+           objIndex < objCount;
+           /* incremented conditionally */) {
+        const int64_t objectStoreId = mObjectStores[objIndex]->Id();
         MOZ_ASSERT(objectStoreId);
 
         if (validIds.Contains(uint64_t(objectStoreId))) {
-          RefPtr<IDBObjectStore>* objectStore = mObjectStores.AppendElement();
-          objectStore->swap(deletedObjectStore);
+          objIndex++;
+        } else {
+          mObjectStores.RemoveElementAt(objIndex);
+          objCount--;
         }
       }
+
+      if (!mDeletedObjectStores.IsEmpty()) {
+        for (uint32_t objCount = mDeletedObjectStores.Length(), objIndex = 0;
+             objIndex < objCount; objIndex++) {
+          const int64_t objectStoreId = mDeletedObjectStores[objIndex]->Id();
+          MOZ_ASSERT(objectStoreId);
+
+          if (validIds.Contains(uint64_t(objectStoreId))) {
+            RefPtr<IDBObjectStore>* objectStore = mObjectStores.AppendElement();
+            objectStore->swap(mDeletedObjectStores[objIndex]);
+          }
+        }
+        mDeletedObjectStores.Clear();
+      }
     }
-    mDeletedObjectStores.Clear();
   }
 
   // Fire the abort event if there are no outstanding requests. Otherwise the
   // abort event will be fired when all outstanding requests finish.
   if (needToSendAbort) {
     SendAbort(aAbortCode);
   }
 
   if (isVersionChange) {
     mDatabase->Close();
   }
 }
 
-void IDBTransaction::Abort(IDBRequest* const aRequest) {
+void IDBTransaction::Abort(IDBRequest* aRequest) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aRequest);
 
   if (IsCommittingOrDone()) {
     // Already started (and maybe finished) the commit or abort so there is
     // nothing to do here.
     return;
   }
 
   ErrorResult rv;
   RefPtr<DOMException> error = aRequest->GetError(rv);
 
   AbortInternal(aRequest->GetErrorCode(), error.forget());
 }
 
-void IDBTransaction::Abort(const nsresult aErrorCode) {
+void IDBTransaction::Abort(nsresult aErrorCode) {
   AssertIsOnOwningThread();
 
   if (IsCommittingOrDone()) {
     // Already started (and maybe finished) the commit or abort so there is
     // nothing to do here.
     return;
   }
 
@@ -708,28 +711,28 @@ void IDBTransaction::Abort(ErrorResult& 
   }
 
   AbortInternal(NS_ERROR_DOM_INDEXEDDB_ABORT_ERR, nullptr);
 
   MOZ_ASSERT(!mAbortedByScript);
   mAbortedByScript = true;
 }
 
-void IDBTransaction::FireCompleteOrAbortEvents(const nsresult aResult) {
+void IDBTransaction::FireCompleteOrAbortEvents(nsresult aResult) {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!mFiredCompleteOrAbort);
 
   mReadyState = DONE;
 
 #ifdef DEBUG
   mFiredCompleteOrAbort = true;
 #endif
 
   // Make sure we drop the WorkerRef when this function completes.
-  const auto scopeExit = MakeScopeExit([&] { mWorkerRef = nullptr; });
+  auto scopeExit = MakeScopeExit([&] { mWorkerRef = nullptr; });
 
   RefPtr<Event> event;
   if (NS_SUCCEEDED(aResult)) {
     event = CreateGenericEvent(this, nsDependentString(kCompleteEventType),
                                eDoesNotBubble, eNotCancelable);
     MOZ_ASSERT(event);
 
     // If we hit this assertion, it probably means transaction object on the
@@ -850,17 +853,17 @@ DOMException* IDBTransaction::GetError()
   AssertIsOnOwningThread();
 
   return mError;
 }
 
 already_AddRefed<DOMStringList> IDBTransaction::ObjectStoreNames() const {
   AssertIsOnOwningThread();
 
-  if (mMode == VERSION_CHANGE) {
+  if (mMode == IDBTransaction::VERSION_CHANGE) {
     return mDatabase->ObjectStoreNames();
   }
 
   RefPtr<DOMStringList> list = new DOMStringList();
   list->StringArray() = mObjectStoreNames;
   return list.forget();
 }
 
@@ -875,41 +878,46 @@ already_AddRefed<IDBObjectStore> IDBTran
 
   const ObjectStoreSpec* spec = nullptr;
 
   if (IDBTransaction::VERSION_CHANGE == mMode ||
       mObjectStoreNames.Contains(aName)) {
     const nsTArray<ObjectStoreSpec>& objectStores =
         mDatabase->Spec()->objectStores();
 
-    const auto foundIt =
-        std::find_if(objectStores.cbegin(), objectStores.cend(),
-                     [&aName](const auto& objectStore) {
-                       return objectStore.metadata().name() == aName;
-                     });
-    if (foundIt != objectStores.cend()) {
-      spec = &*foundIt;
+    for (uint32_t count = objectStores.Length(), index = 0; index < count;
+         index++) {
+      const ObjectStoreSpec& objectStore = objectStores[index];
+      if (objectStore.metadata().name() == aName) {
+        spec = &objectStore;
+        break;
+      }
     }
   }
 
   if (!spec) {
     aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR);
     return nullptr;
   }
 
+  const int64_t desiredId = spec->metadata().id();
+
   RefPtr<IDBObjectStore> objectStore;
 
-  const auto foundIt = std::find_if(
-      mObjectStores.cbegin(), mObjectStores.cend(),
-      [desiredId = spec->metadata().id()](const auto& existingObjectStore) {
-        return existingObjectStore->Id() == desiredId;
-      });
-  if (foundIt != mObjectStores.cend()) {
-    objectStore = *foundIt;
-  } else {
+  for (uint32_t count = mObjectStores.Length(), index = 0; index < count;
+       index++) {
+    RefPtr<IDBObjectStore>& existingObjectStore = mObjectStores[index];
+
+    if (existingObjectStore->Id() == desiredId) {
+      objectStore = existingObjectStore;
+      break;
+    }
+  }
+
+  if (!objectStore) {
     objectStore = IDBObjectStore::Create(this, *spec);
     MOZ_ASSERT(objectStore);
 
     mObjectStores.AppendElement(objectStore);
   }
 
   return objectStore.forget();
 }
@@ -934,21 +942,21 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBTransaction,
                                                 DOMEventTargetHelper)
   // Don't unlink mDatabase!
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mObjectStores)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDeletedObjectStores)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-JSObject* IDBTransaction::WrapObject(JSContext* const aCx,
+JSObject* IDBTransaction::WrapObject(JSContext* aCx,
                                      JS::Handle<JSObject*> aGivenProto) {
   AssertIsOnOwningThread();
 
-  return IDBTransaction_Binding::Wrap(aCx, this, std::move(aGivenProto));
+  return IDBTransaction_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void IDBTransaction::GetEventTargetParent(EventChainPreVisitor& aVisitor) {
   AssertIsOnOwningThread();
 
   aVisitor.mCanHandle = true;
   aVisitor.SetParentTarget(mDatabase, false);
 }
--- a/dom/indexedDB/IDBTransaction.h
+++ b/dom/indexedDB/IDBTransaction.h
@@ -57,20 +57,19 @@ class IDBTransaction final : public DOME
 
     // Only needed for IPC serialization helper, should never be used in code.
     MODE_INVALID
   };
 
   enum ReadyState { INITIAL = 0, LOADING, COMMITTING, DONE };
 
  private:
-  // TODO: Only non-const because of Bug 1575173.
   RefPtr<IDBDatabase> mDatabase;
   RefPtr<DOMException> mError;
-  const nsTArray<nsString> mObjectStoreNames;
+  nsTArray<nsString> mObjectStoreNames;
   nsTArray<RefPtr<IDBObjectStore>> mObjectStores;
   nsTArray<RefPtr<IDBObjectStore>> mDeletedObjectStores;
   RefPtr<StrongWorkerRef> mWorkerRef;
   nsTArray<IDBCursor*> mCursors;
 
   // Tagged with mMode. If mMode is VERSION_CHANGE then mBackgroundActor will be
   // a BackgroundVersionChangeTransactionChild. Otherwise it will be a
   // BackgroundTransactionChild.
@@ -81,39 +80,28 @@ class IDBTransaction final : public DOME
   } mBackgroundActor;
 
   const int64_t mLoggingSerialNumber;
 
   // Only used for VERSION_CHANGE transactions.
   int64_t mNextObjectStoreId;
   int64_t mNextIndexId;
 
-  nsresult mAbortCode;  ///< The result that caused the transaction to be
-                        ///< aborted, or NS_OK if not aborted.
-                        ///< NS_ERROR_DOM_INDEXEDDB_ABORT_ERR indicates that the
-                        ///< user explicitly requested aborting. Should be
-                        ///< renamed to mResult or so, because it is actually
-                        ///< used to check if the transaction has been aborted.
-  uint32_t mPendingRequestCount;  ///< Counted via OnNewRequest and
-                                  ///< OnRequestFinished, so that the
-                                  ///< transaction can auto-commit when the last
-                                  ///< pending request finished.
+  nsresult mAbortCode;
+  uint32_t mPendingRequestCount;
 
-  const nsString mFilename;
-  const uint32_t mLineNo;
-  const uint32_t mColumn;
+  nsString mFilename;
+  uint32_t mLineNo;
+  uint32_t mColumn;
 
   ReadyState mReadyState;
-  const Mode mMode;
+  Mode mMode;
 
-  bool mCreating;    ///< Set between successful creation until the transaction
-                     ///< has run on the event-loop.
-  bool mRegistered;  ///< Whether mDatabase->RegisterTransaction() has been
-                     ///< called (which may not be the case if construction was
-                     ///< incomplete).
+  bool mCreating;
+  bool mRegistered;
   bool mAbortedByScript;
   bool mNotedActiveTransaction;
 
 #ifdef DEBUG
   bool mSentCommitOrAbort;
   bool mFiredCompleteOrAbort;
 #endif
 
@@ -202,17 +190,18 @@ class IDBTransaction final : public DOME
     return mMode;
   }
 
   IDBDatabase* Database() const {
     AssertIsOnOwningThread();
     return mDatabase;
   }
 
-  // Only for use by ProfilerHelpers.h
+  IDBDatabase* Db() const { return Database(); }
+
   const nsTArray<nsString>& ObjectStoreNamesInternal() const {
     AssertIsOnOwningThread();
     return mObjectStoreNames;
   }
 
   already_AddRefed<IDBObjectStore> CreateObjectStore(
       const indexedDB::ObjectStoreSpec& aSpec);
 
@@ -235,16 +224,31 @@ class IDBTransaction final : public DOME
   int64_t LoggingSerialNumber() const {
     AssertIsOnOwningThread();
 
     return mLoggingSerialNumber;
   }
 
   nsIGlobalObject* GetParentObject() const;
 
+  IDBTransactionMode GetMode(ErrorResult& aRv) const;
+
+  DOMException* GetError() const;
+
+  already_AddRefed<IDBObjectStore> ObjectStore(const nsAString& aName,
+                                               ErrorResult& aRv);
+
+  void Abort(ErrorResult& aRv);
+
+  IMPL_EVENT_HANDLER(abort)
+  IMPL_EVENT_HANDLER(complete)
+  IMPL_EVENT_HANDLER(error)
+
+  already_AddRefed<DOMStringList> ObjectStoreNames() const;
+
   void FireCompleteOrAbortEvents(nsresult aResult);
 
   // Only for VERSION_CHANGE transactions.
   int64_t NextObjectStoreId();
 
   // Only for VERSION_CHANGE transactions.
   int64_t NextIndexId();
 
@@ -252,63 +256,39 @@ class IDBTransaction final : public DOME
   void RegisterCursor(IDBCursor* aCursor);
   void UnregisterCursor(IDBCursor* aCursor);
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIRUNNABLE
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBTransaction, DOMEventTargetHelper)
 
   // nsWrapperCache
-  JSObject* WrapObject(JSContext* aCx,
-                       JS::Handle<JSObject*> aGivenProto) override;
-
-  // Methods bound via WebIDL.
-  IDBDatabase* Db() const { return Database(); }
-
-  IDBTransactionMode GetMode(ErrorResult& aRv) const;
-
-  DOMException* GetError() const;
-
-  already_AddRefed<IDBObjectStore> ObjectStore(const nsAString& aName,
-                                               ErrorResult& aRv);
-
-  void Abort(ErrorResult& aRv);
-
-  IMPL_EVENT_HANDLER(abort)
-  IMPL_EVENT_HANDLER(complete)
-  IMPL_EVENT_HANDLER(error)
-
-  already_AddRefed<DOMStringList> ObjectStoreNames() const;
+  virtual JSObject* WrapObject(JSContext* aCx,
+                               JS::Handle<JSObject*> aGivenProto) override;
 
   // EventTarget
   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
 
  private:
   IDBTransaction(IDBDatabase* aDatabase,
-                 const nsTArray<nsString>& aObjectStoreNames, Mode aMode,
-                 nsString aFilename, uint32_t aLineNo, uint32_t aColumn);
+                 const nsTArray<nsString>& aObjectStoreNames, Mode aMode);
   ~IDBTransaction();
 
   void AbortInternal(nsresult aAbortCode,
                      already_AddRefed<DOMException> aError);
 
   void SendCommit();
 
   void SendAbort(nsresult aResultCode);
 
   void NoteActiveTransaction();
 
   void MaybeNoteInactiveTransaction();
 
   void OnNewRequest();
 
   void OnRequestFinished(bool aRequestCompletedSuccessfully);
-
-  template <typename Func>
-  auto DoWithTransactionChild(const Func& aFunc) const;
-
-  bool HasTransactionChild() const;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_idbtransaction_h__