Bug 729519 - Allocate nsFrameList::sEmptyList from the .rodata segment, not the heap. r=bzbarsky
authorMats Palmgren <matspal@gmail.com>
Mon, 01 Apr 2013 17:26:02 +0200
changeset 133282 c320c5821f98d0665df06588f4279906d97fc75b
parent 133281 ba8a10a35c183a8760a848d0129da3289ac32d44
child 133283 489955a7d7597d36c6d884eecbc9b245146e0205
push idunknown
push userunknown
push dateunknown
reviewersbzbarsky
bugs729519
milestone22.0a1
Bug 729519 - Allocate nsFrameList::sEmptyList from the .rodata segment, not the heap. r=bzbarsky
layout/build/nsLayoutStatics.cpp
layout/generic/nsFrameList.cpp
layout/generic/nsFrameList.h
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -47,17 +47,16 @@
 #include "nsTextFrameTextRunCache.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsTextFragment.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsCrossSiteListenerProxy.h"
 #include "nsHTMLDNSPrefetch.h"
 #include "nsHtml5Module.h"
 #include "nsFocusManager.h"
-#include "nsFrameList.h"
 #include "nsListControlFrame.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "SVGElementFactory.h"
 #include "nsSVGUtils.h"
 #include "nsMathMLAtoms.h"
 #include "nsMathMLOperators.h"
 #include "Navigator.h"
 #include "nsDOMStorageBaseDB.h"
@@ -250,18 +249,16 @@ nsLayoutStatics::Initialize()
   nsContentSink::InitializeStatics();
   nsHtml5Module::InitializeStatics();
   nsLayoutUtils::Initialize();
   nsIPresShell::InitializeStatics();
   nsRefreshDriver::InitializeStatics();
 
   nsCORSListenerProxy::Startup();
 
-  nsFrameList::Init();
-
   NS_SealStaticAtomTable();
 
   nsWindowMemoryReporter::Init();
 
   SVGElementFactory::Init();
   nsSVGUtils::Init();
 
   InitProcessPriorityManager();
@@ -368,18 +365,16 @@ nsLayoutStatics::Shutdown()
   nsTreeSanitizer::ReleaseStatics();
 
   nsHtml5Module::ReleaseStatics();
 
   nsRegion::ShutdownStatic();
 
   NS_ShutdownEventTargetChainItemRecyclePool();
 
-  nsFrameList::Shutdown();
-
   HTMLInputElement::DestroyUploadLastDir();
 
   nsLayoutUtils::Shutdown();
 
   nsHyphenationManager::Shutdown();
   nsEditorSpellCheck::ShutDown();
   nsDOMMutationObserver::Shutdown();
 
--- a/layout/generic/nsFrameList.cpp
+++ b/layout/generic/nsFrameList.cpp
@@ -9,40 +9,37 @@
 
 #ifdef IBMBIDI
 #include "nsCOMPtr.h"
 #include "nsGkAtoms.h"
 #include "nsILineIterator.h"
 #include "nsBidiPresUtils.h"
 #endif // IBMBIDI
 
-const nsFrameList* nsFrameList::sEmptyList;
-
-/* static */
-void
-nsFrameList::Init()
-{
-  NS_PRECONDITION(!sEmptyList, "Shouldn't be allocated");
-
-  sEmptyList = new nsFrameList();
+namespace mozilla {
+namespace layout {
+namespace detail {
+const AlignedFrameListBytes gEmptyFrameListBytes = { 0 };
+}
+}
 }
 
 void
 nsFrameList::Destroy()
 {
-  NS_PRECONDITION(this != sEmptyList, "Shouldn't Destroy() sEmptyList");
+  NS_PRECONDITION(this != &EmptyList(), "Shouldn't Destroy() sEmptyList");
 
   DestroyFrames();
   delete this;
 }
 
 void
 nsFrameList::DestroyFrom(nsIFrame* aDestructRoot)
 {
-  NS_PRECONDITION(this != sEmptyList, "Shouldn't Destroy() sEmptyList");
+  NS_PRECONDITION(this != &EmptyList(), "Shouldn't Destroy() this list");
 
   DestroyFramesFrom(aDestructRoot);
   delete this;
 }
 
 void
 nsFrameList::DestroyFrames()
 {
--- a/layout/generic/nsFrameList.h
+++ b/layout/generic/nsFrameList.h
@@ -286,19 +286,17 @@ public:
    */
   nsIFrame* GetNextVisualFor(nsIFrame* aFrame) const;
 #endif // IBMBIDI
 
 #ifdef DEBUG
   void List(FILE* out) const;
 #endif
 
-  static void Init();
-  static void Shutdown() { delete sEmptyList; }
-  static const nsFrameList& EmptyList() { return *sEmptyList; }
+  static inline const nsFrameList& EmptyList();
 
   class Enumerator;
 
   /**
    * A class representing a slice of a frame list.
    */
   class Slice {
     friend class Enumerator;
@@ -459,24 +457,40 @@ public:
 
 private:
 #ifdef DEBUG_FRAME_LIST
   void VerifyList() const;
 #else
   void VerifyList() const {}
 #endif
 
-  static const nsFrameList* sEmptyList;
-
 protected:
   /**
    * Disconnect aFrame from its siblings.  This must only be called if aFrame
    * is NOT the first or last sibling, because otherwise its nsFrameList will
    * have a stale mFirst/LastChild pointer.  This precondition is asserted.
    * This function is O(1).
    */
   static void UnhookFrameFromSiblings(nsIFrame* aFrame);
 
   nsIFrame* mFirstChild;
   nsIFrame* mLastChild;
 };
 
+namespace mozilla {
+namespace layout {
+namespace detail {
+union AlignedFrameListBytes {
+  void* ptr;
+  char bytes[sizeof(nsFrameList)];
+};
+extern const AlignedFrameListBytes gEmptyFrameListBytes;
+}
+}
+}
+
+/* static */ inline const nsFrameList&
+nsFrameList::EmptyList()
+{
+  return *reinterpret_cast<const nsFrameList*>(&mozilla::layout::detail::gEmptyFrameListBytes);
+}
+
 #endif /* nsFrameList_h___ */