Bug 1563023 - Part 6: Simplify iterations over all client types; r=asuth
authorJan Varga <jan.varga@gmail.com>
Fri, 23 Aug 2019 04:48:36 +0000
changeset 553304 b70ad16ea2aedd286a84fe0935a18176a59c61a3
parent 553303 b62dd021e1700bed1e51dfcaa5ecc5dcfe1dc399
child 553305 f41a0d88947089263d3a636ee31d278e6117c5ae
push id2165
push userffxbld-merge
push dateMon, 14 Oct 2019 16:30:58 +0000
treeherdermozilla-release@0eae18af659f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1563023
milestone70.0a1
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
Bug 1563023 - Part 6: Simplify iterations over all client types; r=asuth This patch converts index based client type loops to iterator based client type loops. This way the static cast is avoided and the loops are simpler and more readable. Differential Revision: https://phabricator.services.mozilla.com/D38629
dom/quota/ActorsParent.cpp
dom/quota/Client.h
dom/quota/QuotaManager.h
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -42,17 +42,16 @@
 #include "mozilla/dom/simpledb/ActorsParent.h"
 #include "mozilla/dom/StorageActivityService.h"
 #include "mozilla/dom/StorageDBUpdater.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/net/MozURL.h"
-#include "mozilla/IntegerRange.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPrefs_dom.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TextUtils.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TypeTraits.h"
@@ -625,20 +624,23 @@ class OriginInfo final {
   GroupInfo* GetGroupInfo() const { return mGroupInfo; }
 
   const nsCString& Origin() const { return mOrigin; }
 
   int64_t LockedUsage() const {
     AssertCurrentThreadOwnsQuotaMutex();
 
 #ifdef DEBUG
+    QuotaManager* quotaManager = QuotaManager::Get();
+    MOZ_ASSERT(quotaManager);
+
     uint64_t usage = 0;
-    for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
-      AssertNoOverflow(usage, mClientUsages[index].valueOr(0));
-      usage += mClientUsages[index].valueOr(0);
+    for (Client::Type type : quotaManager->AllClientTypes()) {
+      AssertNoOverflow(usage, mClientUsages[type].valueOr(0));
+      usage += mClientUsages[type].valueOr(0);
     }
     MOZ_ASSERT(mUsage == usage);
 #endif
 
     return mUsage;
   }
 
   int64_t LockedAccessTime() const {
@@ -3504,16 +3506,21 @@ nsresult QuotaManager::Init(const nsAStr
   mClients.AppendElement(cache::CreateQuotaClient());
   mClients.AppendElement(simpledb::CreateQuotaClient());
   if (NextGenLocalStorageEnabled()) {
     mClients.AppendElement(localstorage::CreateQuotaClient());
   } else {
     mClients.SetLength(Client::TypeMax());
   }
 
+  mAllClientTypes = {Client::Type::IDB, Client::Type::DOMCACHE,
+                     Client::Type::SDB, Client::Type::LS};
+  mAllClientTypesExceptLS = {Client::Type::IDB, Client::Type::DOMCACHE,
+                             Client::Type::SDB};
+
   return NS_OK;
 }
 
 void QuotaManager::Shutdown() {
   AssertIsOnOwningThread();
 
   // Setting this flag prevents the service from being recreated and prevents
   // further storagess from being created.
@@ -3525,18 +3532,18 @@ void QuotaManager::Shutdown() {
 
   // Kick off the shutdown timer.
   MOZ_ALWAYS_SUCCEEDS(mShutdownTimer->InitWithNamedFuncCallback(
       &ShutdownTimerCallback, this, DEFAULT_SHUTDOWN_TIMER_MS,
       nsITimer::TYPE_ONE_SHOT, "QuotaManager::ShutdownTimerCallback"));
 
   // Each client will spin the event loop while we wait on all the threads
   // to close. Our timer may fire during that loop.
-  for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
-    mClients[index]->ShutdownWorkThreads();
+  for (Client::Type type : AllClientTypes()) {
+    mClients[type]->ShutdownWorkThreads();
   }
 
   // Cancel the timer regardless of whether it actually fired.
   if (NS_FAILED(mShutdownTimer->Cancel())) {
     NS_WARNING("Failed to cancel shutdown timer!");
   }
 
   // NB: It's very important that runnable is destroyed on this thread
@@ -5794,22 +5801,22 @@ void QuotaManager::OpenDirectoryInternal
       nsAutoPtr<nsTHashtable<nsCStringHashKey>>& origin = origins[clientType];
       if (!origin) {
         origin = new nsTHashtable<nsCStringHashKey>();
       }
       origin->PutEntry(originScope.GetOrigin());
     }
   }
 
-  for (uint32_t index : IntegerRange(uint32_t(Client::TypeMax()))) {
-    if (origins[index]) {
-      for (auto iter = origins[index]->Iter(); !iter.Done(); iter.Next()) {
-        MOZ_ASSERT(mClients[index]);
-
-        mClients[index]->AbortOperations(iter.Get()->GetKey());
+  for (Client::Type type : AllClientTypes()) {
+    if (origins[type]) {
+      for (auto iter = origins[type]->Iter(); !iter.Done(); iter.Next()) {
+        MOZ_ASSERT(mClients[type]);
+
+        mClients[type]->AbortOperations(iter.Get()->GetKey());
       }
     }
   }
 }
 
 nsresult QuotaManager::EnsureOriginIsInitialized(
     PersistenceType aPersistenceType, const nsACString& aSuffix,
     const nsACString& aGroup, const nsACString& aOrigin, nsIFile** aDirectory) {
@@ -6030,18 +6037,18 @@ nsresult QuotaManager::AboutToClearOrigi
     const Nullable<PersistenceType>& aPersistenceType,
     const OriginScope& aOriginScope,
     const Nullable<Client::Type>& aClientType) {
   AssertIsOnIOThread();
 
   nsresult rv;
 
   if (aClientType.IsNull()) {
-    for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
-      rv = mClients[index]->AboutToClearOrigins(aPersistenceType, aOriginScope);
+    for (Client::Type type : AllClientTypes()) {
+      rv = mClients[type]->AboutToClearOrigins(aPersistenceType, aOriginScope);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
     }
   } else {
     rv = mClients[aClientType.Value()]->AboutToClearOrigins(aPersistenceType,
                                                             aOriginScope);
     if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -6057,18 +6064,18 @@ void QuotaManager::OriginClearCompleted(
     const Nullable<Client::Type>& aClientType) {
   AssertIsOnIOThread();
 
   if (aClientType.IsNull()) {
     if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
       mInitializedOrigins.RemoveElement(aOrigin);
     }
 
-    for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
-      mClients[index]->OnOriginClearCompleted(aPersistenceType, aOrigin);
+    for (Client::Type type : AllClientTypes()) {
+      mClients[type]->OnOriginClearCompleted(aPersistenceType, aOrigin);
     }
   } else {
     mClients[aClientType.Value()]->OnOriginClearCompleted(aPersistenceType,
                                                           aOrigin);
   }
 }
 
 void QuotaManager::ResetOrClearCompleted() {
@@ -6083,16 +6090,24 @@ void QuotaManager::ResetOrClearCompleted
 
 Client* QuotaManager::GetClient(Client::Type aClientType) {
   MOZ_ASSERT(aClientType >= Client::IDB);
   MOZ_ASSERT(aClientType < Client::TypeMax());
 
   return mClients.ElementAt(aClientType);
 }
 
+const AutoTArray<Client::Type, Client::TYPE_MAX>&
+QuotaManager::AllClientTypes() {
+  if (CachedNextGenLocalStorageEnabled()) {
+    return mAllClientTypes;
+  }
+  return mAllClientTypesExceptLS;
+}
+
 uint64_t QuotaManager::GetGroupLimit() const {
   MOZ_ASSERT(mTemporaryStorageInitialized);
 
   // To avoid one group evicting all the rest, limit the amount any one group
   // can use to 20%. To prevent individual sites from using exorbitant amounts
   // of storage where there is a lot of free space, cap the group limit to 2GB.
   uint64_t x = std::min<uint64_t>(mTemporaryStorageLimit * .20, 2 GB);
 
@@ -6764,20 +6779,23 @@ OriginInfo::OriginInfo(GroupInfo* aGroup
       mPersisted(aPersisted),
       mDirectoryExists(aDirectoryExists) {
   MOZ_ASSERT(aGroupInfo);
   MOZ_ASSERT(aClientUsages.Length() == Client::TypeMax());
   MOZ_ASSERT_IF(aPersisted,
                 aGroupInfo->mPersistenceType == PERSISTENCE_TYPE_DEFAULT);
 
 #ifdef DEBUG
+  QuotaManager* quotaManager = QuotaManager::Get();
+  MOZ_ASSERT(quotaManager);
+
   uint64_t usage = 0;
-  for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
-    AssertNoOverflow(usage, aClientUsages[index].valueOr(0));
-    usage += aClientUsages[index].valueOr(0);
+  for (Client::Type type : quotaManager->AllClientTypes()) {
+    AssertNoOverflow(usage, aClientUsages[type].valueOr(0));
+    usage += aClientUsages[type].valueOr(0);
   }
   MOZ_ASSERT(aUsage == usage);
 #endif
 
   MOZ_COUNT_CTOR(OriginInfo);
 }
 
 void OriginInfo::LockedDecreaseUsage(Client::Type aClientType, int64_t aSize) {
--- a/dom/quota/Client.h
+++ b/dom/quota/Client.h
@@ -31,17 +31,17 @@ class OriginScope;
 class QuotaManager;
 class UsageInfo;
 
 // An abstract interface for quota manager clients.
 // Each storage API must provide an implementation of this interface in order
 // to participate in centralized quota and storage handling.
 class Client {
  public:
-  typedef mozilla::Atomic<bool> AtomicBool;
+  typedef Atomic<bool> AtomicBool;
 
   enum Type {
     IDB = 0,
     // APPCACHE,
     DOMCACHE,
     SDB,
     LS,
     TYPE_MAX
--- a/dom/quota/QuotaManager.h
+++ b/dom/quota/QuotaManager.h
@@ -363,16 +363,18 @@ class QuotaManager final : public Backgr
 
   nsIThread* IOThread() {
     NS_ASSERTION(mIOThread, "This should never be null!");
     return mIOThread;
   }
 
   Client* GetClient(Client::Type aClientType);
 
+  const AutoTArray<Client::Type, Client::TYPE_MAX>& AllClientTypes();
+
   const nsString& GetBasePath() const { return mBasePath; }
 
   const nsString& GetStoragePath() const { return mStoragePath; }
 
   const nsString& GetStoragePath(PersistenceType aPersistenceType) const {
     if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
       return mPermanentStoragePath;
     }
@@ -516,18 +518,18 @@ class QuotaManager final : public Backgr
   void DeleteFilesForOrigin(PersistenceType aPersistenceType,
                             const nsACString& aOrigin);
 
   void FinalizeOriginEviction(nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
 
   void ReleaseIOThreadObjects() {
     AssertIsOnIOThread();
 
-    for (uint32_t index = 0; index < uint32_t(Client::TypeMax()); index++) {
-      mClients[index]->ReleaseIOThreadObjects();
+    for (Client::Type type : AllClientTypes()) {
+      mClients[type]->ReleaseIOThreadObjects();
     }
   }
 
   DirectoryLockTable& GetDirectoryLockTable(PersistenceType aPersistenceType);
 
   bool IsSanitizedOriginValid(const nsACString& aSanitizedOrigin);
 
   static void ShutdownTimerCallback(nsITimer* aTimer, void* aClosure);
@@ -560,16 +562,19 @@ class QuotaManager final : public Backgr
   // sanitized origin strings. This hash table isn't protected by any mutex but
   // it is only ever touched on the IO thread.
   nsDataHashtable<nsCStringHashKey, bool> mValidOrigins;
 
   // This array is populated at initialization time and then never modified, so
   // it can be iterated on any thread.
   AutoTArray<RefPtr<Client>, Client::TYPE_MAX> mClients;
 
+  AutoTArray<Client::Type, Client::TYPE_MAX> mAllClientTypes;
+  AutoTArray<Client::Type, Client::TYPE_MAX> mAllClientTypesExceptLS;
+
   nsString mBasePath;
   nsString mIndexedDBPath;
   nsString mStoragePath;
   nsString mPermanentStoragePath;
   nsString mTemporaryStoragePath;
   nsString mDefaultStoragePath;
 
   uint64_t mTemporaryStorageLimit;