Bug 959150 part 3 - Move the parts of nsHtml5TreeOpExecutor that the static methods in nsHtml5TreeOperation need to access into a new superclass. r=smaug.
☠☠ backed out by e420695e2079 ☠ ☠
authorHenri Sivonen <hsivonen@hsivonen.fi>
Wed, 05 Mar 2014 21:38:49 +0200
changeset 189298 8d0ae8bffb08bc71bde1b7639f3b3b8959051def
parent 189297 603b63c33e9a380a02dec528ce35264e50c3fd2a
child 189299 14441e5285826c348ac560bad0d240b2f64f14a4
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs959150
milestone30.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 959150 part 3 - Move the parts of nsHtml5TreeOpExecutor that the static methods in nsHtml5TreeOperation need to access into a new superclass. r=smaug.
parser/html/moz.build
parser/html/nsHtml5DocumentBuilder.cpp
parser/html/nsHtml5DocumentBuilder.h
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
parser/html/nsHtml5TreeOperation.cpp
parser/html/nsHtml5TreeOperation.h
--- a/parser/html/moz.build
+++ b/parser/html/moz.build
@@ -16,16 +16,17 @@ EXPORTS += [
     'nsAHtml5TreeBuilderState.h',
     'nsAHtml5TreeOpSink.h',
     'nsHtml5ArrayCopy.h',
     'nsHtml5AtomList.h',
     'nsHtml5Atoms.h',
     'nsHtml5AtomTable.h',
     'nsHtml5ByteReadable.h',
     'nsHtml5DependentUTF16Buffer.h',
+    'nsHtml5DocumentBuilder.h',
     'nsHtml5DocumentMode.h',
     'nsHtml5HtmlAttributes.h',
     'nsHtml5Macros.h',
     'nsHtml5MetaScanner.h',
     'nsHtml5MetaScannerHSupplement.h',
     'nsHtml5Module.h',
     'nsHtml5NamedCharacters.h',
     'nsHtml5NamedCharactersAccel.h',
@@ -49,16 +50,17 @@ EXPORTS += [
 ]
 
 UNIFIED_SOURCES += [
     'nsHtml5Atom.cpp',
     'nsHtml5Atoms.cpp',
     'nsHtml5AtomTable.cpp',
     'nsHtml5AttributeName.cpp',
     'nsHtml5DependentUTF16Buffer.cpp',
+    'nsHtml5DocumentBuilder.cpp',
     'nsHtml5ElementName.cpp',
     'nsHtml5Highlighter.cpp',
     'nsHtml5HtmlAttributes.cpp',
     'nsHtml5MetaScanner.cpp',
     'nsHtml5Module.cpp',
     'nsHtml5NamedCharacters.cpp',
     'nsHtml5NamedCharactersAccel.cpp',
     'nsHtml5OwningUTF16Buffer.cpp',
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5DocumentBuilder.cpp
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* 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 "nsHtml5DocumentBuilder.h"
+
+#include "nsScriptLoader.h"
+#include "mozilla/css/Loader.h"
+#include "nsIDocShell.h"
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsHtml5DocumentBuilder, nsContentSink,
+                                     mOwnedElements)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHtml5DocumentBuilder)
+NS_INTERFACE_MAP_END_INHERITING(nsContentSink)
+
+NS_IMPL_ADDREF_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
+NS_IMPL_RELEASE_INHERITED(nsHtml5DocumentBuilder, nsContentSink)
+
+void
+nsHtml5DocumentBuilder::DropHeldElements()
+{
+  mScriptLoader = nullptr;
+  mDocument = nullptr;
+  mNodeInfoManager = nullptr;
+  mCSSLoader = nullptr;
+  mDocumentURI = nullptr;
+  mDocShell = nullptr;
+  mOwnedElements.Clear();
+}
+
new file mode 100644
--- /dev/null
+++ b/parser/html/nsHtml5DocumentBuilder.h
@@ -0,0 +1,121 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
+/* 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/. */
+
+#ifndef nsHtml5DocumentBuilder_h
+#define nsHtml5DocumentBuilder_h
+
+#include "nsHtml5PendingNotification.h"
+
+typedef nsIContent* nsIContentPtr;
+
+enum eHtml5FlushState {
+  eNotFlushing = 0,  // not flushing
+  eInFlush = 1,      // the Flush() method is on the call stack
+  eInDocUpdate = 2,  // inside an update batch on the document
+  eNotifying = 3     // flushing pending append notifications
+};
+
+class nsHtml5DocumentBuilder : public nsContentSink
+{
+public:
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5DocumentBuilder,
+                                           nsContentSink)
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  inline void HoldElement(nsIContent* aContent) {
+    mOwnedElements.AppendElement(aContent);
+  }
+
+  inline bool HaveNotified(nsIContent* aNode) {
+    NS_PRECONDITION(aNode, "HaveNotified called with null argument.");
+    const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
+    const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
+    for (;;) {
+      nsIContent* parent = aNode->GetParent();
+      if (!parent) {
+        return true;
+      }
+      for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
+        if (iter->Contains(parent)) {
+          return iter->HaveNotifiedIndex(parent->IndexOf(aNode));
+        }
+      }
+      aNode = parent;
+    }
+  }
+
+  void PostPendingAppendNotification(nsIContent* aParent, nsIContent* aChild) {
+    bool newParent = true;
+    const nsIContentPtr* first = mElementsSeenInThisAppendBatch.Elements();
+    const nsIContentPtr* last = first + mElementsSeenInThisAppendBatch.Length() - 1;
+    for (const nsIContentPtr* iter = last; iter >= first; --iter) {
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+      sAppendBatchSlotsExamined++;
+#endif
+      if (*iter == aParent) {
+        newParent = false;
+        break;
+      }
+    }
+    if (aChild->IsElement()) {
+      mElementsSeenInThisAppendBatch.AppendElement(aChild);
+    }
+    mElementsSeenInThisAppendBatch.AppendElement(aParent);
+    if (newParent) {
+      mPendingNotifications.AppendElement(aParent);
+    }
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+    sAppendBatchExaminations++;
+#endif
+  }
+
+  void FlushPendingAppendNotifications() {
+    NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update");
+    mFlushState = eNotifying;
+    const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
+    const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
+    for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
+      iter->Fire();
+    }
+    mPendingNotifications.Clear();
+#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
+    if (mElementsSeenInThisAppendBatch.Length() > sAppendBatchMaxSize) {
+      sAppendBatchMaxSize = mElementsSeenInThisAppendBatch.Length();
+    }
+#endif
+    mElementsSeenInThisAppendBatch.Clear();
+    NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync");
+    mFlushState = eInDocUpdate;
+  }
+
+  void DropHeldElements();
+
+  // Getters and setters for fields from nsContentSink
+  nsIDocument* GetDocument() {
+    return mDocument;
+  }
+  nsNodeInfoManager* GetNodeInfoManager() {
+    return mNodeInfoManager;
+  }
+
+  virtual bool BelongsToStringParser() = 0;
+
+protected:
+  inline void SetAppendBatchCapacity(uint32_t aCapacity)
+  {
+    mElementsSeenInThisAppendBatch.SetCapacity(aCapacity);
+  }
+
+private:
+  nsTArray<nsHtml5PendingNotification> mPendingNotifications;
+  nsTArray<nsCOMPtr<nsIContent> >      mOwnedElements;
+  nsTArray<nsIContentPtr>              mElementsSeenInThisAppendBatch;
+protected:
+  eHtml5FlushState                     mFlushState;
+};
+
+#endif // nsHtml5DocumentBuilder_h
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -30,23 +30,20 @@
 #include "GeckoProfiler.h"
 #include "nsIScriptError.h"
 #include "nsIScriptContext.h"
 #include "mozilla/Preferences.h"
 #include "nsIHTMLDocument.h"
 
 using namespace mozilla;
 
-NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsHtml5TreeOpExecutor, nsContentSink,
-                                     mOwnedElements)
-
 NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHtml5TreeOpExecutor)
   NS_INTERFACE_TABLE_INHERITED1(nsHtml5TreeOpExecutor, 
                                 nsIContentSink)
-NS_INTERFACE_TABLE_TAIL_INHERITING(nsContentSink)
+NS_INTERFACE_TABLE_TAIL_INHERITING(nsHtml5DocumentBuilder)
 
 NS_IMPL_ADDREF_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
 
 NS_IMPL_RELEASE_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
 
 class nsHtml5ExecutorReflusher : public nsRunnable
 {
   private:
@@ -504,17 +501,17 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
     mFlushState = eInFlush;
 
     nsIContent* scriptElement = nullptr;
     
     BeginDocUpdate();
 
     uint32_t numberOfOpsToFlush = mOpQueue.Length();
 
-    mElementsSeenInThisAppendBatch.SetCapacity(numberOfOpsToFlush * 2);
+    SetAppendBatchCapacity(numberOfOpsToFlush * 2);
 
     const nsHtml5TreeOperation* first = mOpQueue.Elements();
     const nsHtml5TreeOperation* last = first + numberOfOpsToFlush - 1;
     for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(first);;) {
       if (MOZ_UNLIKELY(!mParser)) {
         // The previous tree op caused a call to nsIParser::Terminate().
         break;
       }
@@ -608,17 +605,17 @@ nsHtml5TreeOpExecutor::FlushDocumentWrit
 #endif
   
   nsIContent* scriptElement = nullptr;
   
   BeginDocUpdate();
 
   uint32_t numberOfOpsToFlush = mOpQueue.Length();
 
-  mElementsSeenInThisAppendBatch.SetCapacity(numberOfOpsToFlush * 2);
+  SetAppendBatchCapacity(numberOfOpsToFlush * 2);
 
   const nsHtml5TreeOperation* start = mOpQueue.Elements();
   const nsHtml5TreeOperation* end = start + numberOfOpsToFlush;
   for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(start);
        iter < end;
        ++iter) {
     if (MOZ_UNLIKELY(!mParser)) {
       // The previous tree op caused a call to nsIParser::Terminate().
@@ -894,28 +891,16 @@ nsHtml5TreeOpExecutor::Reset()
   mStarted = false;
   mFlushState = eNotFlushing;
   mRunFlushLoopOnStack = false;
   MOZ_ASSERT(!mReadingFromStage);
   MOZ_ASSERT(NS_SUCCEEDED(mBroken));
 }
 
 void
-nsHtml5TreeOpExecutor::DropHeldElements()
-{
-  mScriptLoader = nullptr;
-  mDocument = nullptr;
-  mNodeInfoManager = nullptr;
-  mCSSLoader = nullptr;
-  mDocumentURI = nullptr;
-  mDocShell = nullptr;
-  mOwnedElements.Clear();
-}
-
-void
 nsHtml5TreeOpExecutor::MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue)
 {
   NS_PRECONDITION(mFlushState == eNotFlushing, "mOpQueue modified during tree op execution.");
   if (mOpQueue.IsEmpty()) {
     mOpQueue.SwapElements(aOpQueue);
     return;
   }
   mOpQueue.MoveElementsFrom(aOpQueue);
--- a/parser/html/nsHtml5TreeOpExecutor.h
+++ b/parser/html/nsHtml5TreeOpExecutor.h
@@ -1,61 +1,50 @@
 /* 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/. */
 
 #ifndef nsHtml5TreeOpExecutor_h
 #define nsHtml5TreeOpExecutor_h
 
 #include "nsIAtom.h"
-#include "nsNameSpaceManager.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5SpeculativeLoad.h"
-#include "nsHtml5PendingNotification.h"
 #include "nsTArray.h"
 #include "nsContentSink.h"
 #include "nsNodeInfoManager.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsIScriptElement.h"
 #include "nsIParser.h"
 #include "nsAHtml5TreeOpSink.h"
 #include "nsHtml5TreeOpStage.h"
 #include "nsIURI.h"
 #include "nsTHashtable.h"
 #include "nsHashKeys.h"
 #include "mozilla/LinkedList.h"
+#include "nsHtml5DocumentBuilder.h"
 
 class nsHtml5Parser;
 class nsHtml5TreeBuilder;
 class nsHtml5Tokenizer;
 class nsHtml5StreamParser;
 
-typedef nsIContent* nsIContentPtr;
-
-enum eHtml5FlushState {
-  eNotFlushing = 0,  // not flushing
-  eInFlush = 1,      // the Flush() method is on the call stack
-  eInDocUpdate = 2,  // inside an update batch on the document
-  eNotifying = 3     // flushing pending append notifications
-};
-
-class nsHtml5TreeOpExecutor : public nsContentSink,
+class nsHtml5TreeOpExecutor : public nsHtml5DocumentBuilder,
                               public nsIContentSink,
                               public nsAHtml5TreeOpSink,
                               public mozilla::LinkedListElement<nsHtml5TreeOpExecutor>
 {
   friend class nsHtml5FlushLoopGuard;
 
   public:
     NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
     NS_DECL_ISUPPORTS_INHERITED
-    NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHtml5TreeOpExecutor, nsContentSink)
 
   private:
     static bool        sExternalViewSource;
 #ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
     static uint32_t    sAppendBatchMaxSize;
     static uint32_t    sAppendBatchSlotsExamined;
     static uint32_t    sAppendBatchExaminations;
     static uint32_t    sLongestTimeOffTheEventLoop;
@@ -64,20 +53,17 @@ class nsHtml5TreeOpExecutor : public nsC
 
     /**
      * Whether EOF needs to be suppressed
      */
     bool                                 mSuppressEOF;
     
     bool                                 mReadingFromStage;
     nsTArray<nsHtml5TreeOperation>       mOpQueue;
-    nsTArray<nsIContentPtr>              mElementsSeenInThisAppendBatch;
-    nsTArray<nsHtml5PendingNotification> mPendingNotifications;
     nsHtml5StreamParser*                 mStreamParser;
-    nsTArray<nsCOMPtr<nsIContent> >      mOwnedElements;
     
     /**
      * URLs already preloaded/preloading.
      */
     nsTHashtable<nsCStringHashKey> mPreloadedURLs;
 
     nsCOMPtr<nsIURI> mSpeculationBaseURI;
 
@@ -85,18 +71,16 @@ class nsHtml5TreeOpExecutor : public nsC
 
     /**
      * Whether the parser has started
      */
     bool                          mStarted;
 
     nsHtml5TreeOpStage            mStage;
 
-    eHtml5FlushState              mFlushState;
-
     bool                          mRunFlushLoopOnStack;
 
     bool                          mCallContinueInterruptedParsingIfEnabled;
 
     /**
      * Non-NS_OK if this parser should refuse to process any more input.
      * For example, the parser needs to be marked as broken if it drops some
      * input due to a memory allocation failure. In such a case, the whole
@@ -175,23 +159,17 @@ class nsHtml5TreeOpExecutor : public nsC
     virtual nsresult FlushTags();
     virtual void ContinueInterruptedParsingAsync();
  
     /**
      * Sets up style sheet load / parse
      */
     void UpdateStyleSheet(nsIContent* aElement);
 
-    // Getters and setters for fields from nsContentSink
-    nsIDocument* GetDocument() {
-      return mDocument;
-    }
-    nsNodeInfoManager* GetNodeInfoManager() {
-      return mNodeInfoManager;
-    }
+    // XXX Does anyone need this?
     nsIDocShell* GetDocShell() {
       return mDocShell;
     }
 
     bool IsScriptExecuting() {
       return IsScriptExecutingImpl();
     }
     
@@ -242,78 +220,17 @@ class nsHtml5TreeOpExecutor : public nsC
       NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync");
       if (mFlushState == eInDocUpdate) {
         FlushPendingAppendNotifications();
         mFlushState = eInFlush;
         mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
       }
     }
 
-    void PostPendingAppendNotification(nsIContent* aParent, nsIContent* aChild) {
-      bool newParent = true;
-      const nsIContentPtr* first = mElementsSeenInThisAppendBatch.Elements();
-      const nsIContentPtr* last = first + mElementsSeenInThisAppendBatch.Length() - 1;
-      for (const nsIContentPtr* iter = last; iter >= first; --iter) {
-#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
-        sAppendBatchSlotsExamined++;
-#endif
-        if (*iter == aParent) {
-          newParent = false;
-          break;
-        }
-      }
-      if (aChild->IsElement()) {
-        mElementsSeenInThisAppendBatch.AppendElement(aChild);
-      }
-      mElementsSeenInThisAppendBatch.AppendElement(aParent);
-      if (newParent) {
-        mPendingNotifications.AppendElement(aParent);
-      }
-#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
-      sAppendBatchExaminations++;
-#endif
-    }
-
-    void FlushPendingAppendNotifications() {
-      NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update");
-      mFlushState = eNotifying;
-      const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
-      const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
-      for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
-        iter->Fire();
-      }
-      mPendingNotifications.Clear();
-#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
-      if (mElementsSeenInThisAppendBatch.Length() > sAppendBatchMaxSize) {
-        sAppendBatchMaxSize = mElementsSeenInThisAppendBatch.Length();
-      }
-#endif
-      mElementsSeenInThisAppendBatch.Clear();
-      NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync");
-      mFlushState = eInDocUpdate;
-    }
     
-    inline bool HaveNotified(nsIContent* aNode) {
-      NS_PRECONDITION(aNode, "HaveNotified called with null argument.");
-      const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
-      const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
-      for (;;) {
-        nsIContent* parent = aNode->GetParent();
-        if (!parent) {
-          return true;
-        }
-        for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
-          if (iter->Contains(parent)) {
-            return iter->HaveNotifiedIndex(parent->IndexOf(aNode));
-          }
-        }
-        aNode = parent;
-      }
-    }
-
     void StartLayout();
     
     void SetDocumentMode(nsHtml5DocumentMode m);
 
     nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
                   nsISupports* aContainer, nsIChannel* aChannel);
 
     void FlushSpeculativeLoads();
@@ -353,22 +270,16 @@ class nsHtml5TreeOpExecutor : public nsC
       return mRunFlushLoopOnStack;
     }
 #endif
     
     void RunScript(nsIContent* aScriptElement);
     
     void Reset();
     
-    inline void HoldElement(nsIContent* aContent) {
-      mOwnedElements.AppendElement(aContent);
-    }
-
-    void DropHeldElements();
-
     /**
      * Flush the operations from the tree operations from the argument
      * queue unconditionally. (This is for the main thread case.)
      */
     virtual void MoveOpsFrom(nsTArray<nsHtml5TreeOperation>& aOpQueue);
     
     nsHtml5TreeOpStage* GetStage() {
       return &mStage;
--- a/parser/html/nsHtml5TreeOperation.cpp
+++ b/parser/html/nsHtml5TreeOperation.cpp
@@ -115,17 +115,17 @@ nsHtml5TreeOperation::~nsHtml5TreeOperat
       break;
   }
 }
 
 nsresult
 nsHtml5TreeOperation::AppendTextToTextNode(const char16_t* aBuffer,
                                            uint32_t aLength,
                                            nsIContent* aTextNode,
-                                           nsHtml5TreeOpExecutor* aBuilder)
+                                           nsHtml5DocumentBuilder* aBuilder)
 {
   NS_PRECONDITION(aTextNode, "Got null text node.");
 
   if (aBuilder->HaveNotified(aTextNode)) {
     // This text node has already been notified on, so it's necessary to
     // notify on the append
     nsresult rv = NS_OK;
     uint32_t oldLength = aTextNode->TextLength();
@@ -147,17 +147,17 @@ nsHtml5TreeOperation::AppendTextToTextNo
   return aTextNode->AppendText(aBuffer, aLength, false);
 }
 
 
 nsresult
 nsHtml5TreeOperation::AppendText(const char16_t* aBuffer,
                                  uint32_t aLength,
                                  nsIContent* aParent,
-                                 nsHtml5TreeOpExecutor* aBuilder)
+                                 nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIContent* lastChild = aParent->GetLastChild();
   if (lastChild && lastChild->IsNodeOfType(nsINode::eTEXT)) {
     nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
                                  aBuilder->GetDocument());
     return AppendTextToTextNode(aBuffer, 
                                 aLength, 
@@ -171,17 +171,17 @@ nsHtml5TreeOperation::AppendText(const c
   NS_ENSURE_SUCCESS(rv, rv);
 
   return Append(text, aParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::Append(nsIContent* aNode,
                              nsIContent* aParent,
-                             nsHtml5TreeOpExecutor* aBuilder)
+                             nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIDocument* executorDoc = aBuilder->GetDocument();
   NS_ASSERTION(executorDoc, "Null doc on executor");
   nsIDocument* parentDoc = aParent->OwnerDoc();
   NS_ASSERTION(parentDoc, "Null owner doc on old node.");
 
   if (MOZ_LIKELY(executorDoc == parentDoc)) {
@@ -202,17 +202,17 @@ nsHtml5TreeOperation::Append(nsIContent*
     nsNodeUtils::ContentAppended(aParent, aNode, childCount);
   }
   parentDoc->EndUpdate(UPDATE_CONTENT_MODEL);
   return rv;
 }
 
 nsresult
 nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
-                                       nsHtml5TreeOpExecutor* aBuilder)
+                                       nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   aBuilder->FlushPendingAppendNotifications();
   nsIDocument* doc = aBuilder->GetDocument();
   uint32_t childCount = doc->GetChildCount();
   rv = doc->AppendChildTo(aNode, false);
   NS_ENSURE_SUCCESS(rv, rv);
   nsNodeUtils::ContentInserted(doc, aNode, childCount);
@@ -240,33 +240,33 @@ IsElementOrTemplateContent(nsINode* aNod
         return true;
       }
     }
   }
   return false;
 }
 
 void
-nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5TreeOpExecutor* aBuilder)
+nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder)
 {
   aBuilder->FlushPendingAppendNotifications();
   nsCOMPtr<nsINode> parent = aNode->GetParentNode();
   if (parent) {
     nsHtml5OtherDocUpdate update(parent->OwnerDoc(),
         aBuilder->GetDocument());
     int32_t pos = parent->IndexOf(aNode);
     NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
     parent->RemoveChildAt(pos, true);
   }
 }
 
 nsresult
 nsHtml5TreeOperation::AppendChildrenToNewParent(nsIContent* aNode,
                                                 nsIContent* aParent,
-                                                nsHtml5TreeOpExecutor* aBuilder)
+                                                nsHtml5DocumentBuilder* aBuilder)
 {
   aBuilder->FlushPendingAppendNotifications();
 
   nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
                                aBuilder->GetDocument());
 
   uint32_t childCount = aParent->GetChildCount();
   bool didAppend = false;
@@ -283,17 +283,17 @@ nsHtml5TreeOperation::AppendChildrenToNe
   }
   return NS_OK;
 }
 
 nsresult
 nsHtml5TreeOperation::FosterParent(nsIContent* aNode,
                                    nsIContent* aParent,
                                    nsIContent* aTable,
-                                   nsHtml5TreeOpExecutor* aBuilder)
+                                   nsHtml5DocumentBuilder* aBuilder)
 {
   nsIContent* foster = aTable->GetParent();
 
   if (IsElementOrTemplateContent(foster)) {
     aBuilder->FlushPendingAppendNotifications();
 
     nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
                                  aBuilder->GetDocument());
@@ -306,17 +306,17 @@ nsHtml5TreeOperation::FosterParent(nsICo
   }
 
   return Append(aNode, aParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
                                     nsHtml5HtmlAttributes* aAttributes,
-                                    nsHtml5TreeOpExecutor* aBuilder)
+                                    nsHtml5DocumentBuilder* aBuilder)
 {
   dom::Element* node = aNode->AsElement();
   nsHtml5OtherDocUpdate update(node->OwnerDoc(),
                                aBuilder->GetDocument());
 
   int32_t len = aAttributes->getLength();
   for (int32_t i = len; i > 0;) {
     --i;
@@ -340,17 +340,17 @@ nsHtml5TreeOperation::AddAttributes(nsIC
 }
 
 
 nsIContent*
 nsHtml5TreeOperation::CreateElement(int32_t aNs,
                                     nsIAtom* aName,
                                     nsHtml5HtmlAttributes* aAttributes,
                                     bool aFromNetwork,
-                                    nsHtml5TreeOpExecutor* aBuilder)
+                                    nsHtml5DocumentBuilder* aBuilder)
 {
   bool isKeygen = (aName == nsHtml5Atoms::keygen && aNs == kNameSpaceID_XHTML);
   if (MOZ_UNLIKELY(isKeygen)) {
     aName = nsHtml5Atoms::select;
   }
 
   nsCOMPtr<dom::Element> newContent;
   nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->
@@ -485,17 +485,17 @@ nsHtml5TreeOperation::SetFormElement(nsI
     nsRefPtr<dom::HTMLImageElement> imageElement =
       static_cast<dom::HTMLImageElement*>(domImageElement.get());
     MOZ_ASSERT(imageElement);
     imageElement->SetForm(formElement);
   }
 }
 
 nsresult
-nsHtml5TreeOperation::AppendIsindexPrompt(nsIContent* parent, nsHtml5TreeOpExecutor* aBuilder)
+nsHtml5TreeOperation::AppendIsindexPrompt(nsIContent* parent, nsHtml5DocumentBuilder* aBuilder)
 {
   nsXPIDLString prompt;
   nsresult rv =
       nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
                                          "IsIndexPromptWithSpace", prompt);
   uint32_t len = prompt.Length();
   if (NS_FAILED(rv)) {
     return rv;
@@ -507,17 +507,17 @@ nsHtml5TreeOperation::AppendIsindexPromp
   return AppendText(prompt.BeginReading(), len, parent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::FosterParentText(nsIContent* aStackParent,
                                        char16_t* aBuffer,
                                        uint32_t aLength,
                                        nsIContent* aTable,
-                                       nsHtml5TreeOpExecutor* aBuilder)
+                                       nsHtml5DocumentBuilder* aBuilder)
 {
   nsresult rv = NS_OK;
   nsIContent* foster = aTable->GetParent();
 
   if (IsElementOrTemplateContent(foster)) {
     aBuilder->FlushPendingAppendNotifications();
 
     nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
@@ -547,46 +547,46 @@ nsHtml5TreeOperation::FosterParentText(n
 
   return AppendText(aBuffer, aLength, aStackParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AppendComment(nsIContent* aParent,
                                     char16_t* aBuffer,
                                     int32_t aLength,
-                                    nsHtml5TreeOpExecutor* aBuilder)
+                                    nsHtml5DocumentBuilder* aBuilder)
 {
   nsRefPtr<dom::Comment> comment =
     new dom::Comment(aBuilder->GetNodeInfoManager());
   NS_ASSERTION(comment, "Infallible malloc failed?");
   nsresult rv = comment->SetText(aBuffer, aLength, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return Append(comment, aParent, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AppendCommentToDocument(char16_t* aBuffer,
                                               int32_t aLength,
-                                              nsHtml5TreeOpExecutor* aBuilder)
+                                              nsHtml5DocumentBuilder* aBuilder)
 {
   nsRefPtr<dom::Comment> comment =
     new dom::Comment(aBuilder->GetNodeInfoManager());
   NS_ASSERTION(comment, "Infallible malloc failed?");
   nsresult rv = comment->SetText(aBuffer, aLength, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return AppendToDocument(comment, aBuilder);
 }
 
 nsresult
 nsHtml5TreeOperation::AppendDoctypeToDocument(nsIAtom* aName,
                                               const nsAString& aPublicId,
                                               const nsAString& aSystemId,
-                                              nsHtml5TreeOpExecutor* aBuilder)
+                                              nsHtml5DocumentBuilder* aBuilder)
 {
   // Adapted from nsXMLContentSink
   // Create a new doctype node
   nsCOMPtr<nsIDOMDocumentType> docType;
   nsAutoString voidString;
   voidString.SetIsVoid(true);
   NS_NewDOMDocumentType(getter_AddRefs(docType),
                         aBuilder->GetNodeInfoManager(),
@@ -613,17 +613,17 @@ nsHtml5TreeOperation::PreventScriptExecu
 {
   nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aNode);
   MOZ_ASSERT(sele);
   sele->PreventExecution();
 }
 
 void
 nsHtml5TreeOperation::DoneAddingChildren(nsIContent* aNode,
-                                         nsHtml5TreeOpExecutor* aBuilder)
+                                         nsHtml5DocumentBuilder* aBuilder)
 {
   aNode->DoneAddingChildren(aBuilder->HaveNotified(aNode));
 }
 
 void
 nsHtml5TreeOperation::DoneCreatingElement(nsIContent* aNode)
 {
   aNode->DoneCreatingElement();
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -7,16 +7,17 @@
 
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsXPCOMStrings.h"
 
 class nsIContent;
 class nsHtml5TreeOpExecutor;
 class nsHtml5StateSnapshot;
+class nsHtml5DocumentBuilder;
 
 enum eHtml5TreeOperation {
 #ifdef DEBUG
   eTreeOpUninitialized,
 #endif
   // main HTML5 ops
   eTreeOpAppend,
   eTreeOpDetach,
@@ -108,82 +109,82 @@ class nsHtml5TreeOperation {
       nsAutoString str;
       aAtom->ToString(str);
       return do_GetAtom(str);
     }
 
     static nsresult AppendTextToTextNode(const char16_t* aBuffer,
                                          uint32_t aLength,
                                          nsIContent* aTextNode,
-                                         nsHtml5TreeOpExecutor* aBuilder);
+                                         nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendText(const char16_t* aBuffer,
                                uint32_t aLength,
                                nsIContent* aParent,
-                               nsHtml5TreeOpExecutor* aBuilder);
+                               nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult Append(nsIContent* aNode,
                            nsIContent* aParent,
-                           nsHtml5TreeOpExecutor* aBuilder);
+                           nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendToDocument(nsIContent* aNode,
-                                     nsHtml5TreeOpExecutor* aBuilder);
+                                     nsHtml5DocumentBuilder* aBuilder);
 
-    static void Detach(nsIContent* aNode, nsHtml5TreeOpExecutor* aBuilder);
+    static void Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendChildrenToNewParent(nsIContent* aNode,
                                               nsIContent* aParent,
-                                              nsHtml5TreeOpExecutor* aBuilder);
+                                              nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult FosterParent(nsIContent* aNode,
                                  nsIContent* aParent,
                                  nsIContent* aTable,
-                                 nsHtml5TreeOpExecutor* aBuilder);
+                                 nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AddAttributes(nsIContent* aNode,
                                   nsHtml5HtmlAttributes* aAttributes,
-                                  nsHtml5TreeOpExecutor* aBuilder);
+                                  nsHtml5DocumentBuilder* aBuilder);
 
     static nsIContent* CreateElement(int32_t aNs,
                                      nsIAtom* aName,
                                      nsHtml5HtmlAttributes* aAttributes,
                                      bool aFromNetwork,
-                                     nsHtml5TreeOpExecutor* aBuilder);
+                                     nsHtml5DocumentBuilder* aBuilder);
 
     static void SetFormElement(nsIContent* aNode, nsIContent* aParent);
 
     static nsresult AppendIsindexPrompt(nsIContent* parent,
-                                        nsHtml5TreeOpExecutor* aBuilder);
+                                        nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult FosterParentText(nsIContent* aStackParent,
                                      char16_t* aBuffer,
                                      uint32_t aLength,
                                      nsIContent* aTable,
-                                     nsHtml5TreeOpExecutor* aBuilder);
+                                     nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendComment(nsIContent* aParent,
                                   char16_t* aBuffer,
                                   int32_t aLength,
-                                  nsHtml5TreeOpExecutor* aBuilder);
+                                  nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendCommentToDocument(char16_t* aBuffer,
                                            int32_t aLength,
-                                           nsHtml5TreeOpExecutor* aBuilder);
+                                           nsHtml5DocumentBuilder* aBuilder);
 
     static nsresult AppendDoctypeToDocument(nsIAtom* aName,
                                             const nsAString& aPublicId,
                                             const nsAString& aSystemId,
-                                            nsHtml5TreeOpExecutor* aBuilder);
+                                            nsHtml5DocumentBuilder* aBuilder);
 
     static nsIContent* GetDocumentFragmentForTemplate(nsIContent* aNode);
 
     static void PreventScriptExecution(nsIContent* aNode);
 
     static void DoneAddingChildren(nsIContent* aNode,
-                                   nsHtml5TreeOpExecutor* aBuilder);
+                                   nsHtml5DocumentBuilder* aBuilder);
 
     static void DoneCreatingElement(nsIContent* aNode);
 
     nsHtml5TreeOperation();
 
     ~nsHtml5TreeOperation();
 
     inline void Init(eHtml5TreeOperation aOpCode) {
@@ -436,17 +437,18 @@ class nsHtml5TreeOperation {
     inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine) {
       NS_ASSERTION(IsRunScript(), 
         "Setting a snapshot for a tree operation other than eTreeOpRunScript!");
       NS_PRECONDITION(aSnapshot, "Initialized tree op with null snapshot.");
       mTwo.state = aSnapshot;
       mFour.integer = aLine;
     }
 
-    nsresult Perform(nsHtml5TreeOpExecutor* aBuilder, nsIContent** aScriptElement);
+    nsresult Perform(nsHtml5TreeOpExecutor* aBuilder,
+                     nsIContent** aScriptElement);
 
   private:
     // possible optimization:
     // Make the queue take items the size of pointer and make the op code
     // decide how many operands it dequeues after it.
     eHtml5TreeOperation mOpCode;
     union {
       nsIContent**                    node;