Bug 1347461 - Part 2: Always initialize all DataStorage classes in the content process at initialization time; r=keeler
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 15 Mar 2017 22:20:24 -0400
changeset 560300 4947199c855f546bf4199c090e705c73b149143d
parent 560299 0fa8897bf56a8773c8fb501380260f8945912583
child 560301 38f9f8c344da0b8d093a0072f149fff87f246676
push id53365
push userjichen@mozilla.com
push dateTue, 11 Apr 2017 08:35:12 +0000
reviewerskeeler
bugs1347461
milestone55.0a1
Bug 1347461 - Part 2: Always initialize all DataStorage classes in the content process at initialization time; r=keeler
dom/ipc/ContentParent.cpp
security/manager/ssl/DataStorage.cpp
security/manager/ssl/DataStorageList.h
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2231,19 +2231,16 @@ ContentParent::InitInternal(ProcessPrior
       dom::GfxInfoFeatureStatus gfxFeatureStatus;
       gfxFeatureStatus.feature() = i;
       gfxFeatureStatus.status() = status;
       gfxFeatureStatus.failureId() = failureId;
       xpcomInit.gfxFeatureStatus().AppendElement(gfxFeatureStatus);
     }
   }
 
-  // Ensure the SSS is initialized before we try to use its storage.
-  nsCOMPtr<nsISiteSecurityService> sss = do_GetService("@mozilla.org/ssservice;1");
-
   DataStorage::GetAllChildProcessData(xpcomInit.dataStorage());
 
   // Must send screen info before send initialData
   ScreenManager& screenManager = ScreenManager::GetSingleton();
   screenManager.CopyScreensToRemote(this);
 
   Unused << SendSetXPCOMProcessAttributes(xpcomInit, initialData, lnfCache);
 
--- a/security/manager/ssl/DataStorage.cpp
+++ b/security/manager/ssl/DataStorage.cpp
@@ -186,18 +186,43 @@ DataStorage::GetAllChildProcessData(
 
 // static
 void
 DataStorage::SetCachedStorageEntries(
   const InfallibleTArray<mozilla::dom::DataStorageEntry>& aEntries)
 {
   MOZ_ASSERT(XRE_IsContentProcess());
 
-  for (auto& entry : aEntries) {
-    RefPtr<DataStorage> storage = DataStorage::GetFromRawFileName(entry.filename());
+  // Make sure to initialize all DataStorage classes.
+  // For each one, we look through the list of our entries and if we find
+  // a matching DataStorage object, we initialize it.
+  //
+  // Note that this is an O(n^2) operation, but the n here is very small
+  // (currently 3).  There is a comment in the DataStorageList.h header
+  // about updating the algorithm here to something more fancy if the list
+  // of DataStorage items grows some day.
+  nsTArray<dom::DataStorageEntry> entries;
+#define DATA_STORAGE(_)                              \
+  {                                                  \
+    dom::DataStorageEntry entry;                     \
+    entry.filename() = NS_LITERAL_STRING(#_ ".txt"); \
+    for (auto& e : aEntries) {                       \
+      if (entry.filename().Equals(e.filename())) {   \
+        entry.items() = Move(e.items());             \
+        break;                                       \
+      }                                              \
+    }                                                \
+    entries.AppendElement(Move(entry));              \
+  }
+#include "mozilla/DataStorageList.h"
+#undef DATA_STORAGE
+
+  for (auto& entry : entries) {
+    RefPtr<DataStorage> storage =
+      DataStorage::GetFromRawFileName(entry.filename());
     bool dataWillPersist = false;
     storage->Init(dataWillPersist, &entry.items());
   }
 }
 
 size_t
 DataStorage::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
 {
--- a/security/manager/ssl/DataStorageList.h
+++ b/security/manager/ssl/DataStorageList.h
@@ -2,12 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // This is the list of well-known PSM DataStorage classes that Gecko uses.
 // These are key value data stores that are backed by a simple text-based
 // storage in the profile directory.
+//
+// Please note that it is crucial for performance reasons for the number of
+// these classes to remain low.  If you need to add to this list, you may
+// need to update the algorithm in DataStorage::SetCachedStorageEntries()
+// to something faster.
 
 DATA_STORAGE(AlternateServices)
 DATA_STORAGE(SecurityPreloadState)
 DATA_STORAGE(SiteSecurityServiceState)