Bug 1477579: Part 1 - Use literal strings for statically registered contract ID keys. r=froydnj
authorKris Maglione <maglione.k@gmail.com>
Sun, 22 Jul 2018 10:54:56 -0700
changeset 427915 71f70ce6f9314111dc05fe8dceaac43edfda6659
parent 427914 79d837085ea4b48d74f9df1fc38b4e53d1186823
child 427916 a431ef7d271b44d602ae7c403a91ae909789b2f0
push id105582
push usermaglione.k@gmail.com
push dateTue, 24 Jul 2018 02:11:27 +0000
treeherdermozilla-inbound@7d93ec719958 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1477579
milestone63.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 1477579: Part 1 - Use literal strings for statically registered contract ID keys. r=froydnj Most of our components are static, and registered using literal C strings. For those components, we currently use a nsDependentCString as a key when creating a hash entry, which leads to an unnecessary duplication. Using literal CStrings instead avoids the duplication. MozReview-Commit-ID: 5DOUF8ZQMlh
xpcom/components/nsComponentManager.cpp
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -52,16 +52,20 @@
 
 #include <new>     // for placement new
 
 #include "mozilla/Omnijar.h"
 
 #include "mozilla/Logging.h"
 #include "LogModulePrefWatcher.h"
 
+#ifdef MOZ_MEMORY
+#include "mozmemory.h"
+#endif
+
 using namespace mozilla;
 
 static LazyLogModule nsComponentManagerLog("nsComponentManager");
 
 #if 0
  #define SHOW_DENIED_ON_SHUTDOWN
  #define SHOW_CI_ON_EXISTING_SERVICE
 #endif
@@ -463,16 +467,52 @@ ProcessSelectorMatches(Module::ProcessSe
   if (aSelector & Module::CONTENT_PROCESS_ONLY) {
     return type == GeckoProcessType_Content;
   }
   return true;
 }
 
 static const int kModuleVersionWithSelector = 51;
 
+template<typename T>
+static void
+AssertNotMallocAllocated(T* aPtr)
+{
+#if defined(DEBUG) && defined(MOZ_MEMORY)
+  jemalloc_ptr_info_t info;
+  jemalloc_ptr_info((void*)aPtr, &info);
+  MOZ_ASSERT(info.tag == TagUnknown);
+#endif
+}
+
+template<typename T>
+static void
+AssertNotStackAllocated(T* aPtr)
+{
+  // The main thread's stack should be allocated at the top of our address
+  // space. Anything stack allocated should be above us on the stack, and
+  // therefore above our first argument pointer.
+  // Only this is apparently not the case on Windows.
+#ifndef XP_WIN
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(uintptr_t(aPtr) < uintptr_t(&aPtr));
+#endif
+}
+
+static inline nsCString
+AsLiteralCString(const char* aStr)
+{
+  AssertNotMallocAllocated(aStr);
+  AssertNotStackAllocated(aStr);
+
+  nsCString str;
+  str.AssignLiteral(aStr, strlen(aStr));
+  return str;
+}
+
 void
 nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
                                        FileLocation* aFile)
 {
   mLock.AssertNotCurrentThreadOwns();
 
   if (aModule->mVersion >= kModuleVersionWithSelector &&
       !ProcessSelectorMatches(aModule->selector))
@@ -578,17 +618,17 @@ nsComponentManagerImpl::RegisterContract
     SafeMutexAutoUnlock unlock(mLock);
     LogMessage("Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
                aEntry->contractid,
                idstr);
 
     return;
   }
 
-  mContractIDs.Put(nsDependentCString(aEntry->contractid), f);
+  mContractIDs.Put(AsLiteralCString(aEntry->contractid), f);
 }
 
 static void
 CutExtension(nsCString& aPath)
 {
   int32_t dotPos = aPath.RFindChar('.');
   if (kNotFound == dotPos) {
     aPath.Truncate();