Bug 1351732 - Part 2: Replace use of PLArena with ArenaAllocator in xpcom. r=froydnj
authorEric Rahm <erahm@mozilla.com>
Thu, 30 Mar 2017 16:46:58 -0700
changeset 398778 a2c7254cb8293082c7caa0d9419a71eacf5f85d2
parent 398777 b7e322f24106a81673135d9e1dd839609de35688
child 398779 c788438e745ec9663a9e29ae37a3197995669431
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1351732
milestone55.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 1351732 - Part 2: Replace use of PLArena with ArenaAllocator in xpcom. r=froydnj This swaps xpcom's plarena usage to ArenaAllocator. The new ArenaStrdup extensions are used as well. MozReview-Commit-ID: DHDfl6IkGJL
xpcom/build/moz.build
xpcom/components/moz.build
xpcom/components/nsCategoryManager.cpp
xpcom/components/nsCategoryManager.h
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/ds/moz.build
xpcom/ds/nsPersistentProperties.cpp
xpcom/ds/nsPersistentProperties.h
xpcom/threads/TimerThread.cpp
--- a/xpcom/build/moz.build
+++ b/xpcom/build/moz.build
@@ -47,35 +47,30 @@ else:
     SOURCES += ['PoisonIOInterposerStub.cpp']
 
 include('../glue/objs.mozbuild')
 
 UNIFIED_SOURCES += xpcom_gluens_src_cppsrcs
 UNIFIED_SOURCES += xpcom_glue_src_cppsrcs
 
 UNIFIED_SOURCES += [
+    'FileLocation.cpp',
     'IOInterposer.cpp',
     'LateWriteChecks.cpp',
     'MainThreadIOLogger.cpp',
+    'Omnijar.cpp',
     'Services.cpp',
     'XPCOMInit.cpp',
 ]
 
 if CONFIG['OS_ARCH'] != 'WINNT':
     SOURCES += [
         'NSPRInterposer.cpp',
     ]
 
-# FileLocation.cpp and Omnijar.cpp cannot be built in unified mode because they
-# use plarena.h.
-SOURCES += [
-    'FileLocation.cpp',
-    'Omnijar.cpp',
-]
-
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 DEFINES['_IMPL_NS_STRINGAPI'] = True
 DEFINES['OMNIJAR_NAME'] = CONFIG['OMNIJAR_NAME']
 if CONFIG['MOZ_ICU_DATA_ARCHIVE']:
     DEFINES['MOZ_ICU_DATA_ARCHIVE'] = True
--- a/xpcom/components/moz.build
+++ b/xpcom/components/moz.build
@@ -25,28 +25,22 @@ EXPORTS += [
 
 EXPORTS.mozilla += [
     'GenericFactory.h',
     'Module.h',
     'ModuleLoader.h',
     'ModuleUtils.h',
 ]
 
-# nsCategoryManager.cpp and nsComponentManager.cpp cannot be built in
-# unified mode because they use thea PL_ARENA_CONST_ALIGN_MASK macro
-# with plarena.h.
-SOURCES += [
-    'nsCategoryManager.cpp',
-    'nsComponentManager.cpp',
-]
-
 UNIFIED_SOURCES += [
     'GenericFactory.cpp',
     'ManifestParser.cpp',
     'nsCategoryCache.cpp',
+    'nsCategoryManager.cpp',
+    'nsComponentManager.cpp',
     'nsComponentManagerUtils.cpp',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '!..',
     '../base',
--- a/xpcom/components/nsCategoryManager.cpp
+++ b/xpcom/components/nsCategoryManager.cpp
@@ -1,20 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#define PL_ARENA_CONST_ALIGN_MASK 7
-
 #include "nsICategoryManager.h"
 #include "nsCategoryManager.h"
 
-#include "plarena.h"
 #include "prio.h"
 #include "prlock.h"
 #include "nsCOMPtr.h"
 #include "nsTHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsIFactory.h"
 #include "nsIStringEnumerator.h"
 #include "nsSupportsPrimitives.h"
@@ -22,16 +19,17 @@
 #include "nsServiceManagerUtils.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "nsQuickSort.h"
 #include "nsEnumeratorUtils.h"
 #include "nsThreadUtils.h"
+#include "mozilla/ArenaAllocatorExtensions.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Services.h"
 
 #include "ManifestParser.h"
 #include "nsISimpleEnumerator.h"
 
 using namespace mozilla;
 class nsIComponentLoaderManager;
@@ -43,21 +41,16 @@ class nsIComponentLoaderManager;
 
   In other words, the CategoryDatabase is a tree, whose root is a hashtable.
   Internal nodes (or Categories) are hashtables. Leaf nodes are strings.
 
   The leaf strings are allocated in an arena, because we assume they're not
   going to change much ;)
 */
 
-#define NS_CATEGORYMANAGER_ARENA_SIZE (1024 * 8)
-
-// pulled in from nsComponentManager.cpp
-char* ArenaStrdup(const char* aStr, PLArenaPool* aArena);
-
 //
 // BaseStringEnumerator is subclassed by EntryEnumerator and
 // CategoryEnumerator
 //
 class BaseStringEnumerator
   : public nsISimpleEnumerator
   , private nsIUTF8StringEnumerator
 {
@@ -195,29 +188,27 @@ EntryEnumerator::Create(nsTHashtable<Cat
 }
 
 
 //
 // CategoryNode implementations
 //
 
 CategoryNode*
-CategoryNode::Create(PLArenaPool* aArena)
+CategoryNode::Create(CategoryAllocator* aArena)
 {
   return new (aArena) CategoryNode();
 }
 
 CategoryNode::~CategoryNode() = default;
 
 void*
-CategoryNode::operator new(size_t aSize, PLArenaPool* aArena)
+CategoryNode::operator new(size_t aSize, CategoryAllocator* aArena)
 {
-  void* p;
-  PL_ARENA_ALLOCATE(p, aArena, aSize);
-  return p;
+  return aArena->Allocate(aSize, mozilla::fallible);
 }
 
 nsresult
 CategoryNode::GetLeaf(const char* aEntryName,
                       char** aResult)
 {
   MutexAutoLock lock(mLock);
   nsresult rv = NS_ERROR_NOT_AVAILABLE;
@@ -233,42 +224,42 @@ CategoryNode::GetLeaf(const char* aEntry
   return rv;
 }
 
 nsresult
 CategoryNode::AddLeaf(const char* aEntryName,
                       const char* aValue,
                       bool aReplace,
                       char** aResult,
-                      PLArenaPool* aArena)
+                      CategoryAllocator* aArena)
 {
   if (aResult) {
     *aResult = nullptr;
   }
 
   MutexAutoLock lock(mLock);
   CategoryLeaf* leaf = mTable.GetEntry(aEntryName);
 
   if (!leaf) {
-    const char* arenaEntryName = ArenaStrdup(aEntryName, aArena);
+    const char* arenaEntryName = ArenaStrdup(aEntryName, *aArena);
     if (!arenaEntryName) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     leaf = mTable.PutEntry(arenaEntryName);
     if (!leaf) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   if (leaf->value && !aReplace) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  const char* arenaValue = ArenaStrdup(aValue, aArena);
+  const char* arenaValue = ArenaStrdup(aValue, *aArena);
   if (!arenaValue) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (aResult && leaf->value) {
     *aResult = ToNewCString(nsDependentCString(leaf->value));
     if (!*aResult) {
       return NS_ERROR_OUT_OF_MEMORY;
@@ -405,37 +396,35 @@ nsCategoryManager::Create(nsISupports* a
   if (aOuter) {
     return NS_ERROR_NO_AGGREGATION;
   }
 
   return GetSingleton()->QueryInterface(aIID, aResult);
 }
 
 nsCategoryManager::nsCategoryManager()
-  : mLock("nsCategoryManager")
+  : mArena()
+  , mTable()
+  , mLock("nsCategoryManager")
   , mSuppressNotifications(false)
 {
-  PL_INIT_ARENA_POOL(&mArena, "CategoryManagerArena",
-                     NS_CATEGORYMANAGER_ARENA_SIZE);
 }
 
 void
 nsCategoryManager::InitMemoryReporter()
 {
   RegisterWeakMemoryReporter(this);
 }
 
 nsCategoryManager::~nsCategoryManager()
 {
   // the hashtable contains entries that must be deleted before the arena is
   // destroyed, or else you will have PRLocks undestroyed and other Really
   // Bad Stuff (TM)
   mTable.Clear();
-
-  PL_FinishArenaPool(&mArena);
 }
 
 inline CategoryNode*
 nsCategoryManager::get_category(const char* aName)
 {
   CategoryNode* node;
   if (!mTable.Get(aName, &node)) {
     return nullptr;
@@ -457,17 +446,17 @@ nsCategoryManager::CollectReports(nsIHan
   return NS_OK;
 }
 
 size_t
 nsCategoryManager::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf)
 {
   size_t n = aMallocSizeOf(this);
 
-  n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf);
+  n += mArena.SizeOfExcludingThis(aMallocSizeOf);
 
   n += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
   for (auto iter = mTable.ConstIter(); !iter.Done(); iter.Next()) {
     // We don't measure the key string because it's a non-owning pointer.
     n += iter.Data()->SizeOfExcludingThis(aMallocSizeOf);
   }
 
   return n;
@@ -604,17 +593,17 @@ nsCategoryManager::AddCategoryEntry(cons
   {
     MutexAutoLock lock(mLock);
     category = get_category(aCategoryName);
 
     if (!category) {
       // That category doesn't exist yet; let's make it.
       category = CategoryNode::Create(&mArena);
 
-      char* categoryName = ArenaStrdup(aCategoryName, &mArena);
+      char* categoryName = ArenaStrdup(aCategoryName, mArena);
       mTable.Put(categoryName, category);
     }
   }
 
   if (!category) {
     return;
   }
 
--- a/xpcom/components/nsCategoryManager.h
+++ b/xpcom/components/nsCategoryManager.h
@@ -4,26 +4,28 @@
  * 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/. */
 
 
 #ifndef NSCATEGORYMANAGER_H
 #define NSCATEGORYMANAGER_H
 
 #include "prio.h"
-#include "plarena.h"
 #include "nsClassHashtable.h"
 #include "nsICategoryManager.h"
 #include "nsIMemoryReporter.h"
+#include "mozilla/ArenaAllocator.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/Attributes.h"
 
 class nsIMemoryReporter;
 
+typedef mozilla::ArenaAllocator<1024*8, 8> CategoryAllocator;
+
 /* 16d222a6-1dd2-11b2-b693-f38b02c021b2 */
 #define NS_CATEGORYMANAGER_CID \
 { 0x16d222a6, 0x1dd2, 0x11b2, \
   {0xb6, 0x93, 0xf3, 0x8b, 0x02, 0xc0, 0x21, 0xb2} }
 
 /**
  * a "leaf-node", managed by the nsCategoryNode hashtable.
  *
@@ -50,17 +52,17 @@ class CategoryNode
 public:
   nsresult GetLeaf(const char* aEntryName,
                    char** aResult);
 
   nsresult AddLeaf(const char* aEntryName,
                    const char* aValue,
                    bool aReplace,
                    char** aResult,
-                   PLArenaPool* aArena);
+                   CategoryAllocator* aArena);
 
   void DeleteLeaf(const char* aEntryName);
 
   void Clear()
   {
     mozilla::MutexAutoLock lock(mLock);
     mTable.Clear();
   }
@@ -70,26 +72,26 @@ public:
     mozilla::MutexAutoLock lock(mLock);
     uint32_t tCount = mTable.Count();
     return tCount;
   }
 
   nsresult Enumerate(nsISimpleEnumerator** aResult);
 
   // CategoryNode is arena-allocated, with the strings
-  static CategoryNode* Create(PLArenaPool* aArena);
+  static CategoryNode* Create(CategoryAllocator* aArena);
   ~CategoryNode();
   void operator delete(void*) {}
 
   size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 private:
   CategoryNode() : mLock("CategoryLeaf") {}
 
-  void* operator new(size_t aSize, PLArenaPool* aArena);
+  void* operator new(size_t aSize, CategoryAllocator* aArena);
 
   nsTHashtable<CategoryLeaf> mTable;
   mozilla::Mutex mLock;
 };
 
 
 /**
  * The main implementation of nsICategoryManager.
@@ -132,15 +134,15 @@ private:
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
   CategoryNode* get_category(const char* aName);
   void NotifyObservers(const char* aTopic,
                        const char* aCategoryName, // must be a static string
                        const char* aEntryName);
 
-  PLArenaPool mArena;
+  CategoryAllocator mArena;
   nsClassHashtable<nsDepCharHashKey, CategoryNode> mTable;
   mozilla::Mutex mLock;
   bool mSuppressNotifications;
 };
 
 #endif
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -17,23 +17,16 @@
  */
 
 #include <stdlib.h>
 #include "nscore.h"
 #include "nsISupports.h"
 #include "nspr.h"
 #include "nsCRT.h" // for atoll
 
-// Arena used by component manager for storing contractid string, dll
-// location strings and small objects
-// CAUTION: Arena align mask needs to be defined before including plarena.h
-//          currently from nsComponentManager.h
-#define PL_ARENA_CONST_ALIGN_MASK 7
-#define NS_CM_BLOCK_SIZE (1024 * 8)
-
 #include "nsCategoryManager.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManager.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsCategoryManager.h"
 #include "nsCategoryManagerUtils.h"
 #include "xptiprivate.h"
@@ -152,37 +145,16 @@ error:
     *aInstancePtr = 0;
   }
   if (mErrorPtr) {
     *mErrorPtr = rv;
   }
   return rv;
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// Arena helper functions
-////////////////////////////////////////////////////////////////////////////////
-char*
-ArenaStrndup(const char* aStr, uint32_t aLen, PLArenaPool* aArena)
-{
-  void* mem;
-  // Include trailing null in the aLen
-  PL_ARENA_ALLOCATE(mem, aArena, aLen + 1);
-  if (mem) {
-    memcpy(mem, aStr, aLen + 1);
-  }
-  return static_cast<char*>(mem);
-}
-
-char*
-ArenaStrdup(const char* aStr, PLArenaPool* aArena)
-{
-  return ArenaStrndup(aStr, strlen(aStr), aArena);
-}
-
 // GetService and a few other functions need to exit their mutex mid-function
 // without reentering it later in the block. This class supports that
 // style of early-exit that MutexAutoUnlock doesn't.
 
 namespace {
 
 class MOZ_STACK_CLASS MutexLock
 {
@@ -328,19 +300,16 @@ nsComponentManagerImpl::InitializeModule
   sModuleLocations = new nsTArray<ComponentLocation>;
 }
 
 nsresult
 nsComponentManagerImpl::Init()
 {
   MOZ_ASSERT(NOT_INITIALIZED == mStatus);
 
-  // Initialize our arena
-  PL_INIT_ARENA_POOL(&mArena, "ComponentManagerArena", NS_CM_BLOCK_SIZE);
-
   nsCOMPtr<nsIFile> greDir =
     GetLocationFromDirectoryService(NS_GRE_DIR);
   nsCOMPtr<nsIFile> appDir =
     GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR);
 
   InitializeStaticModules();
 
   nsCategoryManager::GetSingleton()->SuppressNotifications(true);
@@ -709,24 +678,22 @@ nsComponentManagerImpl::ManifestComponen
   KnownModule* km;
 
   km = mKnownModules.Get(hash);
   if (!km) {
     km = new KnownModule(fl);
     mKnownModules.Put(hash, km);
   }
 
-  void* place;
-
-  PL_ARENA_ALLOCATE(place, &mArena, sizeof(nsCID));
+  void* place = mArena.Allocate(sizeof(nsCID));
   nsID* permanentCID = static_cast<nsID*>(place);
   *permanentCID = cid;
 
-  PL_ARENA_ALLOCATE(place, &mArena, sizeof(mozilla::Module::CIDEntry));
-  auto* e = new (place) mozilla::Module::CIDEntry();
+  place = mArena.Allocate(sizeof(mozilla::Module::CIDEntry));
+  auto* e = new (KnownNotNull, place) mozilla::Module::CIDEntry();
   e->cid = permanentCID;
 
   f = new nsFactoryEntry(e, km);
   mFactories.Put(cid, f);
 }
 
 void
 nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& aCx,
@@ -851,19 +818,16 @@ nsresult nsComponentManagerImpl::Shutdow
   mFactories.Clear(); // XXX release the objects, don't just clear
   mLoaderMap.Clear();
   mKnownModules.Clear();
   mKnownStaticModules.Clear();
 
   delete sStaticModules;
   delete sModuleLocations;
 
-  // delete arena for strings and small objects
-  PL_FinishArenaPool(&mArena);
-
   mStatus = SHUTDOWN_COMPLETE;
 
   MOZ_LOG(nsComponentManagerLog, LogLevel::Debug,
          ("nsComponentManager: Shutdown complete."));
 
   return NS_OK;
 }
 
@@ -1768,17 +1732,17 @@ nsComponentManagerImpl::SizeOfIncludingT
   n += sStaticModules->ShallowSizeOfIncludingThis(aMallocSizeOf);
   if (sModuleLocations) {
     n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf);
   }
 
   n += mKnownStaticModules.ShallowSizeOfExcludingThis(aMallocSizeOf);
   n += mKnownModules.ShallowSizeOfExcludingThis(aMallocSizeOf);
 
-  n += PL_SizeOfArenaPoolExcludingPool(&mArena, aMallocSizeOf);
+  n += mArena.SizeOfExcludingThis(aMallocSizeOf);
 
   n += mPendingServices.ShallowSizeOfExcludingThis(aMallocSizeOf);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mLoaderMap's keys and values
   // - mMon
   // - sStaticModules' entries
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -10,31 +10,31 @@
 #include "nsXPCOM.h"
 
 #include "xpcom-private.h"
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIMemoryReporter.h"
 #include "nsIServiceManager.h"
 #include "nsIFile.h"
+#include "mozilla/ArenaAllocator.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Module.h"
 #include "mozilla/ModuleLoader.h"
 #include "mozilla/Mutex.h"
 #include "nsXULAppAPI.h"
 #include "nsIFactory.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "PLDHashTable.h"
 #include "prtime.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
-#include "plarena.h"
 #include "nsCOMArray.h"
 #include "nsDataHashtable.h"
 #include "nsInterfaceHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 
 #include "mozilla/Omnijar.h"
 #include "mozilla/Attributes.h"
@@ -305,17 +305,17 @@ public:
   enum
   {
     NOT_INITIALIZED,
     NORMAL,
     SHUTDOWN_IN_PROGRESS,
     SHUTDOWN_COMPLETE
   } mStatus;
 
-  PLArenaPool   mArena;
+  mozilla::ArenaAllocator<1024*8, 8> mArena;
 
   struct PendingServiceInfo
   {
     const nsCID* cid;
     PRThread* thread;
   };
 
   inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID,
--- a/xpcom/ds/moz.build
+++ b/xpcom/ds/moz.build
@@ -98,34 +98,29 @@ UNIFIED_SOURCES += [
     'nsCOMArray.cpp',
     'nsCRT.cpp',
     'nsDeque.cpp',
     'nsEnumeratorUtils.cpp',
     'nsHashPropertyBag.cpp',
     'nsINIParserImpl.cpp',
     'nsObserverList.cpp',
     'nsObserverService.cpp',
+    'nsPersistentProperties.cpp',
     'nsProperties.cpp',
     'nsQuickSort.cpp',
     'nsStaticNameTable.cpp',
     'nsStringEnumerator.cpp',
     'nsSupportsPrimitives.cpp',
     'nsTArray.cpp',
     'nsTObserverArray.cpp',
     'nsVariant.cpp',
     'PLDHashTable.cpp',
     'Tokenizer.cpp',
 ]
 
-# This file cannot be built in unified mode because it uses the
-# PL_ARENA_CONST_ALIGN_MASK macro with plarena.h.
-SOURCES += [
-    'nsPersistentProperties.cpp',
-]
-
 EXTRA_COMPONENTS += [
     'nsINIProcessor.js',
     'nsINIProcessor.manifest',
 ]
 
 LOCAL_INCLUDES += [
     '../io',
 ]
--- a/xpcom/ds/nsPersistentProperties.cpp
+++ b/xpcom/ds/nsPersistentProperties.cpp
@@ -6,55 +6,30 @@
 
 #include "nsArrayEnumerator.h"
 #include "nsID.h"
 #include "nsCOMArray.h"
 #include "nsUnicharInputStream.h"
 #include "nsPrintfCString.h"
 #include "nsAutoPtr.h"
 
-#define PL_ARENA_CONST_ALIGN_MASK 3
 #include "nsPersistentProperties.h"
 #include "nsIProperties.h"
 
+#include "mozilla/ArenaAllocatorExtensions.h"
+
+using mozilla::ArenaStrdup;
+
 struct PropertyTableEntry : public PLDHashEntryHdr
 {
   // both of these are arena-allocated
   const char* mKey;
   const char16_t* mValue;
 };
 
-static char16_t*
-ArenaStrdup(const nsAFlatString& aString, PLArenaPool* aArena)
-{
-  void* mem;
-  // add one to include the null terminator
-  int32_t len = (aString.Length() + 1) * sizeof(char16_t);
-  PL_ARENA_ALLOCATE(mem, aArena, len);
-  NS_ASSERTION(mem, "Couldn't allocate space!\n");
-  if (mem) {
-    memcpy(mem, aString.get(), len);
-  }
-  return static_cast<char16_t*>(mem);
-}
-
-static char*
-ArenaStrdup(const nsAFlatCString& aString, PLArenaPool* aArena)
-{
-  void* mem;
-  // add one to include the null terminator
-  int32_t len = (aString.Length() + 1) * sizeof(char);
-  PL_ARENA_ALLOCATE(mem, aArena, len);
-  NS_ASSERTION(mem, "Couldn't allocate space!\n");
-  if (mem) {
-    memcpy(mem, aString.get(), len);
-  }
-  return static_cast<char*>(mem);
-}
-
 static const struct PLDHashTableOps property_HashTableOps = {
   PLDHashTable::HashStringKey,
   PLDHashTable::MatchStringKey,
   PLDHashTable::MoveEntryStub,
   PLDHashTable::ClearEntryStub,
   nullptr,
 };
 
@@ -456,23 +431,22 @@ nsPropertiesParser::ParseBuffer(const ch
   }
 
   return NS_OK;
 }
 
 nsPersistentProperties::nsPersistentProperties()
   : mIn(nullptr)
   , mTable(&property_HashTableOps, sizeof(PropertyTableEntry), 16)
+  , mArena()
 {
-  PL_INIT_ARENA_POOL(&mArena, "PersistentPropertyArena", 2048);
 }
 
 nsPersistentProperties::~nsPersistentProperties()
 {
-  PL_FinishArenaPool(&mArena);
 }
 
 nsresult
 nsPersistentProperties::Create(nsISupports* aOuter, REFNSIID aIID,
                                void** aResult)
 {
   if (aOuter) {
     return NS_ERROR_NO_AGGREGATION;
@@ -528,18 +502,18 @@ nsPersistentProperties::SetStringPropert
   if (entry->mKey) {
     aOldValue = entry->mValue;
     NS_WARNING(nsPrintfCString("the property %s already exists",
                                flatKey.get()).get());
   } else {
     aOldValue.Truncate();
   }
 
-  entry->mKey = ArenaStrdup(flatKey, &mArena);
-  entry->mValue = ArenaStrdup(PromiseFlatString(aNewValue), &mArena);
+  entry->mKey = ArenaStrdup(flatKey, mArena);
+  entry->mValue = ArenaStrdup(aNewValue, mArena);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPersistentProperties::Save(nsIOutputStream* aOut, const nsACString& aHeader)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
--- a/xpcom/ds/nsPersistentProperties.h
+++ b/xpcom/ds/nsPersistentProperties.h
@@ -4,19 +4,19 @@
  * 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/. */
 
 #ifndef nsPersistentProperties_h___
 #define nsPersistentProperties_h___
 
 #include "nsIPersistentProperties2.h"
 #include "PLDHashTable.h"
-#include "plarena.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
+#include "mozilla/ArenaAllocator.h"
 #include "mozilla/Attributes.h"
 
 class nsIUnicharInputStream;
 
 class nsPersistentProperties final : public nsIPersistentProperties
 {
 public:
   nsPersistentProperties();
@@ -30,17 +30,17 @@ public:
 
 private:
   ~nsPersistentProperties();
 
 protected:
   nsCOMPtr<nsIUnicharInputStream> mIn;
 
   PLDHashTable mTable;
-  PLArenaPool mArena;
+  mozilla::ArenaAllocator<2048,4> mArena;
 };
 
 class nsPropertyElement final : public nsIPropertyElement
 {
 public:
   nsPropertyElement()
   {
   }
--- a/xpcom/threads/TimerThread.cpp
+++ b/xpcom/threads/TimerThread.cpp
@@ -3,23 +3,23 @@
 /* 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/. */
 
 #include "nsTimerImpl.h"
 #include "TimerThread.h"
 
 #include "nsThreadUtils.h"
-#include "plarena.h"
 #include "pratom.h"
 
 #include "nsIObserverService.h"
 #include "nsIServiceManager.h"
 #include "mozilla/Services.h"
 #include "mozilla/ChaosMode.h"
+#include "mozilla/ArenaAllocator.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/BinarySearch.h"
 
 #include <math.h>
 
 using namespace mozilla;
 #ifdef MOZ_TASK_TRACER
 #include "GeckoTaskTracerImpl.h"
@@ -88,46 +88,45 @@ namespace {
 
 // TimerEventAllocator is a thread-safe allocator used only for nsTimerEvents.
 // It's needed to avoid contention over the default allocator lock when
 // firing timer events (see bug 733277).  The thread-safety is required because
 // nsTimerEvent objects are allocated on the timer thread, and freed on another
 // thread.  Because TimerEventAllocator has its own lock, contention over that
 // lock is limited to the allocation and deallocation of nsTimerEvent objects.
 //
-// Because this allocator is layered over PLArenaPool, it never shrinks -- even
+// Because this is layered over ArenaAllocator, it never shrinks -- even
 // "freed" nsTimerEvents aren't truly freed, they're just put onto a free-list
 // for later recycling.  So the amount of memory consumed will always be equal
 // to the high-water mark consumption.  But nsTimerEvents are small and it's
 // unusual to have more than a few hundred of them, so this shouldn't be a
 // problem in practice.
 
 class TimerEventAllocator
 {
 private:
   struct FreeEntry
   {
     FreeEntry* mNext;
   };
 
-  PLArenaPool mPool;
+  ArenaAllocator<4096> mPool;
   FreeEntry* mFirstFree;
   mozilla::Monitor mMonitor;
 
 public:
   TimerEventAllocator()
-    : mFirstFree(nullptr)
+    : mPool()
+    , mFirstFree(nullptr)
     , mMonitor("TimerEventAllocator")
   {
-    PL_InitArenaPool(&mPool, "TimerEventPool", 4096, /* align = */ 0);
   }
 
   ~TimerEventAllocator()
   {
-    PL_FinishArenaPool(&mPool);
   }
 
   void* Alloc(size_t aSize);
   void Free(void* aPtr);
 };
 
 } // namespace
 
@@ -216,20 +215,17 @@ TimerEventAllocator::Alloc(size_t aSize)
 
   mozilla::MonitorAutoLock lock(mMonitor);
 
   void* p;
   if (mFirstFree) {
     p = mFirstFree;
     mFirstFree = mFirstFree->mNext;
   } else {
-    PL_ARENA_ALLOCATE(p, &mPool, aSize);
-    if (!p) {
-      return nullptr;
-    }
+    p = mPool.Allocate(aSize, fallible);
   }
 
   return p;
 }
 
 void
 TimerEventAllocator::Free(void* aPtr)
 {