Bug 959150 part 1 - Represent nodes as void* in the portable part of the parser. r=smaug.
☠☠ backed out by e420695e2079 ☠ ☠
authorHenri Sivonen <hsivonen@hsivonen.fi>
Wed, 05 Mar 2014 21:38:49 +0200
changeset 183102 261e2d244c547a157286b06c08bf3352432f2e5d
parent 183101 25bbf68caed4ff7bbd5fb66f952d5333928fe79e
child 183103 603b63c33e9a380a02dec528ce35264e50c3fd2a
push id5439
push userffxbld
push dateMon, 17 Mar 2014 23:08:15 +0000
treeherdermozilla-aurora@c0befb3c8038 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs959150
milestone30.0a1
Bug 959150 part 1 - Represent nodes as void* in the portable part of the parser. r=smaug.
parser/html/moz.build
parser/html/nsAHtml5TreeBuilderState.h
parser/html/nsHtml5AttributeName.cpp
parser/html/nsHtml5AttributeName.h
parser/html/nsHtml5ElementName.cpp
parser/html/nsHtml5ElementName.h
parser/html/nsHtml5HtmlAttributes.cpp
parser/html/nsHtml5HtmlAttributes.h
parser/html/nsHtml5MetaScanner.cpp
parser/html/nsHtml5MetaScanner.h
parser/html/nsHtml5Portability.h
parser/html/nsHtml5StackNode.cpp
parser/html/nsHtml5StackNode.h
parser/html/nsHtml5StateSnapshot.cpp
parser/html/nsHtml5StateSnapshot.h
parser/html/nsHtml5Tokenizer.cpp
parser/html/nsHtml5Tokenizer.h
parser/html/nsHtml5TreeBuilder.cpp
parser/html/nsHtml5TreeBuilder.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
parser/html/nsHtml5TreeBuilderHSupplement.h
parser/html/nsHtml5TreeOperation.h
parser/html/nsHtml5UTF16Buffer.cpp
parser/html/nsHtml5UTF16Buffer.h
parser/html/nsIContentHandle.h
--- a/parser/html/moz.build
+++ b/parser/html/moz.build
@@ -39,16 +39,17 @@ EXPORTS += [
     'nsHtml5StringParser.h',
     'nsHtml5SVGLoadDispatcher.h',
     'nsHtml5TreeOperation.h',
     'nsHtml5TreeOpExecutor.h',
     'nsHtml5TreeOpStage.h',
     'nsHtml5UTF16Buffer.h',
     'nsHtml5UTF16BufferHSupplement.h',
     'nsHtml5ViewSourceUtils.h',
+    'nsIContentHandle.h',
     'nsParserUtils.h',
 ]
 
 UNIFIED_SOURCES += [
     'nsHtml5Atom.cpp',
     'nsHtml5Atoms.cpp',
     'nsHtml5AtomTable.cpp',
     'nsHtml5AttributeName.cpp',
--- a/parser/html/nsAHtml5TreeBuilderState.h
+++ b/parser/html/nsAHtml5TreeBuilderState.h
@@ -1,15 +1,17 @@
 /* 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 nsAHtml5TreeBuilderState_h
 #define nsAHtml5TreeBuilderState_h
 
+#include "nsIContentHandle.h"
+
 /**
  * Interface for exposing the internal state of the HTML5 tree builder.
  * For more documentation, please see
  * http://hg.mozilla.org/projects/htmlparser/file/tip/src/nu/validator/htmlparser/impl/StateSnapshot.java
  */
 class nsAHtml5TreeBuilderState {
   public:
   
@@ -20,21 +22,21 @@ class nsAHtml5TreeBuilderState {
     virtual jArray<int32_t,int32_t> getTemplateModeStack() = 0;
 
     virtual int32_t getStackLength() = 0;
 
     virtual int32_t getListOfActiveFormattingElementsLength() = 0;
 
     virtual int32_t getTemplateModeStackLength() = 0;
 
-    virtual nsIContent** getFormPointer() = 0;
+    virtual nsIContentHandle* getFormPointer() = 0;
     
-    virtual nsIContent** getHeadPointer() = 0;
+    virtual nsIContentHandle* getHeadPointer() = 0;
 
-    virtual nsIContent** getDeepTreeSurrogateParent() = 0;
+    virtual nsIContentHandle* getDeepTreeSurrogateParent() = 0;
 
     virtual int32_t getMode() = 0;
 
     virtual int32_t getOriginalMode() = 0;
 
     virtual bool isFramesetOk() = 0;
 
     virtual bool isNeedToDropLF() = 0;
--- a/parser/html/nsHtml5AttributeName.cpp
+++ b/parser/html/nsHtml5AttributeName.cpp
@@ -27,24 +27,25 @@
 
 #define nsHtml5AttributeName_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5AttributeName.h
+++ b/parser/html/nsHtml5AttributeName.h
@@ -28,24 +28,25 @@
 #ifndef nsHtml5AttributeName_h
 #define nsHtml5AttributeName_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5ElementName.cpp
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -27,24 +27,25 @@
 
 #define nsHtml5ElementName_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5ElementName.h
+++ b/parser/html/nsHtml5ElementName.h
@@ -28,24 +28,25 @@
 #ifndef nsHtml5ElementName_h
 #define nsHtml5ElementName_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5HtmlAttributes.cpp
+++ b/parser/html/nsHtml5HtmlAttributes.cpp
@@ -28,24 +28,25 @@
 
 #define nsHtml5HtmlAttributes_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5HtmlAttributes.h
+++ b/parser/html/nsHtml5HtmlAttributes.h
@@ -29,24 +29,25 @@
 #ifndef nsHtml5HtmlAttributes_h
 #define nsHtml5HtmlAttributes_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
--- a/parser/html/nsHtml5MetaScanner.cpp
+++ b/parser/html/nsHtml5MetaScanner.cpp
@@ -28,24 +28,25 @@
 
 #define nsHtml5MetaScanner_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
--- a/parser/html/nsHtml5MetaScanner.h
+++ b/parser/html/nsHtml5MetaScanner.h
@@ -29,24 +29,25 @@
 #ifndef nsHtml5MetaScanner_h
 #define nsHtml5MetaScanner_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
--- a/parser/html/nsHtml5Portability.h
+++ b/parser/html/nsHtml5Portability.h
@@ -28,24 +28,25 @@
 #ifndef nsHtml5Portability_h
 #define nsHtml5Portability_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
--- a/parser/html/nsHtml5StackNode.cpp
+++ b/parser/html/nsHtml5StackNode.cpp
@@ -28,24 +28,25 @@
 
 #define nsHtml5StackNode_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5UTF16Buffer.h"
@@ -80,84 +81,84 @@ nsHtml5StackNode::isFosterParenting()
 
 bool 
 nsHtml5StackNode::isHtmlIntegrationPoint()
 {
   return (flags & NS_HTML5ELEMENT_NAME_HTML_INTEGRATION_POINT);
 }
 
 
-nsHtml5StackNode::nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContent** node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes)
+nsHtml5StackNode::nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContentHandle* node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes)
   : flags(flags),
     name(name),
     popName(popName),
     ns(ns),
     node(node),
     attributes(attributes),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
 }
 
 
-nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node)
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node)
   : flags(elementName->getFlags()),
     name(elementName->name),
     popName(elementName->name),
     ns(kNameSpaceID_XHTML),
     node(node),
     attributes(nullptr),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
   MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
 }
 
 
-nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsHtml5HtmlAttributes* attributes)
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsHtml5HtmlAttributes* attributes)
   : flags(elementName->getFlags()),
     name(elementName->name),
     popName(elementName->name),
     ns(kNameSpaceID_XHTML),
     node(node),
     attributes(attributes),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
   MOZ_ASSERT(!elementName->isCustom(), "Don't use this constructor for custom elements.");
 }
 
 
-nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName)
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName)
   : flags(elementName->getFlags()),
     name(elementName->name),
     popName(popName),
     ns(kNameSpaceID_XHTML),
     node(node),
     attributes(nullptr),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
 }
 
 
-nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContent** node)
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContentHandle* node)
   : flags(prepareSvgFlags(elementName->getFlags())),
     name(elementName->name),
     popName(popName),
     ns(kNameSpaceID_SVG),
     node(node),
     attributes(nullptr),
     refcount(1)
 {
   MOZ_COUNT_CTOR(nsHtml5StackNode);
 }
 
 
-nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName, bool markAsIntegrationPoint)
+nsHtml5StackNode::nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName, bool markAsIntegrationPoint)
   : flags(prepareMathFlags(elementName->getFlags(), markAsIntegrationPoint)),
     name(elementName->name),
     popName(popName),
     ns(kNameSpaceID_MathML),
     node(node),
     attributes(nullptr),
     refcount(1)
 {
--- a/parser/html/nsHtml5StackNode.h
+++ b/parser/html/nsHtml5StackNode.h
@@ -29,24 +29,25 @@
 #ifndef nsHtml5StackNode_h
 #define nsHtml5StackNode_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
@@ -58,37 +59,37 @@ class nsHtml5Portability;
 
 class nsHtml5StackNode
 {
   public:
     int32_t flags;
     nsIAtom* name;
     nsIAtom* popName;
     int32_t ns;
-    nsIContent** node;
+    nsIContentHandle* node;
     nsHtml5HtmlAttributes* attributes;
   private:
     int32_t refcount;
   public:
     inline int32_t getFlags()
     {
       return flags;
     }
 
     int32_t getGroup();
     bool isScoping();
     bool isSpecial();
     bool isFosterParenting();
     bool isHtmlIntegrationPoint();
-    nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContent** node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes);
-    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node);
-    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsHtml5HtmlAttributes* attributes);
-    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName);
-    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContent** node);
-    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContent** node, nsIAtom* popName, bool markAsIntegrationPoint);
+    nsHtml5StackNode(int32_t flags, int32_t ns, nsIAtom* name, nsIContentHandle* node, nsIAtom* popName, nsHtml5HtmlAttributes* attributes);
+    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node);
+    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsHtml5HtmlAttributes* attributes);
+    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName);
+    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIAtom* popName, nsIContentHandle* node);
+    nsHtml5StackNode(nsHtml5ElementName* elementName, nsIContentHandle* node, nsIAtom* popName, bool markAsIntegrationPoint);
   private:
     static int32_t prepareSvgFlags(int32_t flags);
     static int32_t prepareMathFlags(int32_t flags, bool markAsIntegrationPoint);
   public:
     ~nsHtml5StackNode();
     void dropAttributes();
     void retain();
     void release();
--- a/parser/html/nsHtml5StateSnapshot.cpp
+++ b/parser/html/nsHtml5StateSnapshot.cpp
@@ -27,39 +27,40 @@
 
 #define nsHtml5StateSnapshot_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
 #include "nsHtml5Portability.h"
 
 #include "nsHtml5StateSnapshot.h"
 
 
-nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContent** formPointer, nsIContent** headPointer, nsIContent** deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks)
+nsHtml5StateSnapshot::nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContentHandle* formPointer, nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks)
   : stack(stack),
     listOfActiveFormattingElements(listOfActiveFormattingElements),
     templateModeStack(templateModeStack),
     formPointer(formPointer),
     headPointer(headPointer),
     deepTreeSurrogateParent(deepTreeSurrogateParent),
     mode(mode),
     originalMode(originalMode),
@@ -83,29 +84,29 @@ nsHtml5StateSnapshot::getTemplateModeSta
 }
 
 jArray<nsHtml5StackNode*,int32_t> 
 nsHtml5StateSnapshot::getListOfActiveFormattingElements()
 {
   return listOfActiveFormattingElements;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5StateSnapshot::getFormPointer()
 {
   return formPointer;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5StateSnapshot::getHeadPointer()
 {
   return headPointer;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5StateSnapshot::getDeepTreeSurrogateParent()
 {
   return deepTreeSurrogateParent;
 }
 
 int32_t 
 nsHtml5StateSnapshot::getMode()
 {
--- a/parser/html/nsHtml5StateSnapshot.h
+++ b/parser/html/nsHtml5StateSnapshot.h
@@ -28,24 +28,25 @@
 #ifndef nsHtml5StateSnapshot_h
 #define nsHtml5StateSnapshot_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
@@ -55,32 +56,32 @@ class nsHtml5Portability;
 
 
 class nsHtml5StateSnapshot : public nsAHtml5TreeBuilderState
 {
   private:
     autoJArray<nsHtml5StackNode*,int32_t> stack;
     autoJArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements;
     autoJArray<int32_t,int32_t> templateModeStack;
-    nsIContent** formPointer;
-    nsIContent** headPointer;
-    nsIContent** deepTreeSurrogateParent;
+    nsIContentHandle* formPointer;
+    nsIContentHandle* headPointer;
+    nsIContentHandle* deepTreeSurrogateParent;
     int32_t mode;
     int32_t originalMode;
     bool framesetOk;
     bool needToDropLF;
     bool quirks;
   public:
-    nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContent** formPointer, nsIContent** headPointer, nsIContent** deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks);
+    nsHtml5StateSnapshot(jArray<nsHtml5StackNode*,int32_t> stack, jArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements, jArray<int32_t,int32_t> templateModeStack, nsIContentHandle* formPointer, nsIContentHandle* headPointer, nsIContentHandle* deepTreeSurrogateParent, int32_t mode, int32_t originalMode, bool framesetOk, bool needToDropLF, bool quirks);
     jArray<nsHtml5StackNode*,int32_t> getStack();
     jArray<int32_t,int32_t> getTemplateModeStack();
     jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements();
-    nsIContent** getFormPointer();
-    nsIContent** getHeadPointer();
-    nsIContent** getDeepTreeSurrogateParent();
+    nsIContentHandle* getFormPointer();
+    nsIContentHandle* getHeadPointer();
+    nsIContentHandle* getDeepTreeSurrogateParent();
     int32_t getMode();
     int32_t getOriginalMode();
     bool isFramesetOk();
     bool isNeedToDropLF();
     bool isQuirks();
     int32_t getListOfActiveFormattingElementsLength();
     int32_t getStackLength();
     int32_t getTemplateModeStackLength();
--- a/parser/html/nsHtml5Tokenizer.cpp
+++ b/parser/html/nsHtml5Tokenizer.cpp
@@ -29,17 +29,17 @@
  */
 
 #define nsHtml5Tokenizer_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5NamedCharactersAccel.h"
 #include "nsHtml5Atoms.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Macros.h"
--- a/parser/html/nsHtml5Tokenizer.h
+++ b/parser/html/nsHtml5Tokenizer.h
@@ -30,17 +30,17 @@
 
 #ifndef nsHtml5Tokenizer_h
 #define nsHtml5Tokenizer_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5NamedCharacters.h"
 #include "nsHtml5NamedCharactersAccel.h"
 #include "nsHtml5Atoms.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Macros.h"
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -31,33 +31,34 @@
 #define nsHtml5TreeBuilder_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsITimer.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5Parser.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5PendingNotification.h"
 #include "nsHtml5StateSnapshot.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsHtml5StreamParser.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Highlighter.h"
 #include "nsHtml5PlainTextUtils.h"
 #include "nsHtml5ViewSourceUtils.h"
 #include "mozilla/Likely.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5UTF16Buffer.h"
@@ -84,17 +85,17 @@ nsHtml5TreeBuilder::startTokenization(ns
   formPointer = nullptr;
   headPointer = nullptr;
   deepTreeSurrogateParent = nullptr;
   start(fragment);
   charBufferLen = 0;
   charBuffer = jArray<char16_t,int32_t>::newJArray(1024);
   framesetOk = true;
   if (fragment) {
-    nsIContent** elt;
+    nsIContentHandle* elt;
     if (contextNode) {
       elt = contextNode;
     } else {
       elt = createHtmlElementSetAsRoot(tokenizer->emptyAttributes());
     }
     nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt);
     currentPtr++;
     stack[currentPtr] = node;
@@ -114,17 +115,17 @@ nsHtml5TreeBuilder::startTokenization(ns
     } else {
       tokenizer->setStateAndEndTagExpectation(NS_HTML5TOKENIZER_DATA, contextName);
     }
     contextName = nullptr;
     contextNode = nullptr;
   } else {
     mode = NS_HTML5TREE_BUILDER_INITIAL;
     if (tokenizer->isViewingXmlSource()) {
-      nsIContent** elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes());
+      nsIContentHandle* elt = createElement(kNameSpaceID_SVG, nsHtml5Atoms::svg, tokenizer->emptyAttributes());
       nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_SVG, nsHtml5Atoms::svg, elt);
       currentPtr++;
       stack[currentPtr] = node;
     }
   }
 }
 
 void 
@@ -3578,17 +3579,17 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag
         furthestBlockPos--;
         continue;
       }
       if (nodePos == furthestBlockPos) {
         bookmark = nodeListPos + 1;
       }
       MOZ_ASSERT(node == listOfActiveFormattingElements[nodeListPos]);
       MOZ_ASSERT(node == stack[nodePos]);
-      nsIContent** clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr));
+      nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, node->name, node->attributes->cloneAttributes(nullptr));
       nsHtml5StackNode* newNode = new nsHtml5StackNode(node->getFlags(), node->ns, node->name, clone, node->popName, node->attributes);
       node->dropAttributes();
       stack[nodePos] = newNode;
       newNode->retain();
       listOfActiveFormattingElements[nodeListPos] = newNode;
       node->release();
       node->release();
       node = newNode;
@@ -3599,17 +3600,17 @@ nsHtml5TreeBuilder::adoptionAgencyEndTag
     if (commonAncestor->isFosterParenting()) {
 
       detachFromParent(lastNode->node);
       insertIntoFosterParent(lastNode->node);
     } else {
       detachFromParent(lastNode->node);
       appendElement(lastNode->node, commonAncestor->node);
     }
-    nsIContent** clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr));
+    nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, formattingElt->name, formattingElt->attributes->cloneAttributes(nullptr));
     nsHtml5StackNode* formattingClone = new nsHtml5StackNode(formattingElt->getFlags(), formattingElt->ns, formattingElt->name, clone, formattingElt->popName, formattingElt->attributes);
     formattingElt->dropAttributes();
     appendChildrenToNewParent(furthestBlock->node, clone);
     appendElement(clone, furthestBlock->node);
     removeFromListOfActiveFormattingElements(formattingEltListPos);
     insertIntoListOfActiveFormattingElements(formattingClone, bookmark);
     MOZ_ASSERT(formattingEltStackPos < furthestBlockPos);
     removeFromStack(formattingEltStackPos);
@@ -3760,34 +3761,34 @@ nsHtml5TreeBuilder::reconstructTheActive
     }
     if (isInStack(listOfActiveFormattingElements[entryPos])) {
       break;
     }
   }
   while (entryPos < listPtr) {
     entryPos++;
     nsHtml5StackNode* entry = listOfActiveFormattingElements[entryPos];
-    nsIContent** clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
+    nsIContentHandle* clone = createElement(kNameSpaceID_XHTML, entry->name, entry->attributes->cloneAttributes(nullptr));
     nsHtml5StackNode* entryClone = new nsHtml5StackNode(entry->getFlags(), entry->ns, entry->name, clone, entry->popName, entry->attributes);
     entry->dropAttributes();
     nsHtml5StackNode* currentNode = stack[currentPtr];
     if (currentNode->isFosterParenting()) {
       insertIntoFosterParent(clone);
     } else {
       appendElement(clone, currentNode->node);
     }
     push(entryClone);
     listOfActiveFormattingElements[entryPos] = entryClone;
     entry->release();
     entryClone->retain();
   }
 }
 
 void 
-nsHtml5TreeBuilder::insertIntoFosterParent(nsIContent** child)
+nsHtml5TreeBuilder::insertIntoFosterParent(nsIContentHandle* child)
 {
   int32_t tablePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TABLE);
   int32_t templatePos = findLastOrRoot(NS_HTML5TREE_BUILDER_TEMPLATE);
   if (templatePos >= tablePos) {
     appendElement(child, stack[templatePos]->node);
     return;
   }
   nsHtml5StackNode* node = stack[tablePos];
@@ -3839,31 +3840,31 @@ nsHtml5TreeBuilder::popOnEof()
   markMalformedIfScript(node->node);
   elementPopped(node->ns, node->popName, node->node);
   node->release();
 }
 
 void 
 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes)
 {
-  nsIContent** elt = createHtmlElementSetAsRoot(attributes);
+  nsIContentHandle* elt = createHtmlElementSetAsRoot(attributes);
   nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HTML, elt);
   push(node);
 }
 
 void 
 nsHtml5TreeBuilder::appendHtmlElementToDocumentAndPush()
 {
   appendHtmlElementToDocumentAndPush(tokenizer->emptyAttributes());
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::head, attributes);
   appendElement(elt, stack[currentPtr]->node);
   headPointer = elt;
   nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_HEAD, elt);
   push(node);
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement(nsHtml5HtmlAttributes* attributes)
@@ -3875,17 +3876,17 @@ void
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushBodyElement()
 {
   appendToCurrentNodeAndPushBodyElement(tokenizer->emptyAttributes());
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
   if (!isTemplateContents()) {
     formPointer = elt;
   }
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
@@ -3893,63 +3894,63 @@ nsHtml5TreeBuilder::appendToCurrentNodeA
   }
   nsHtml5StackNode* node = new nsHtml5StackNode(nsHtml5ElementName::ELT_FORM, elt);
   push(node);
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, attributes->cloneAttributes(nullptr));
   push(node);
   append(node);
   node->retain();
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes);
   appendElement(elt, stack[currentPtr]->node);
   if (nsHtml5ElementName::ELT_TEMPLATE == elementName) {
     elt = getDocumentFragmentForTemplate(elt);
   }
   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
   push(node);
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
   nsIAtom* popName = elementName->name;
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, popName, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt, popName);
   push(node);
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
   nsIAtom* popName = elementName->name;
-  nsIContent** elt = createElement(kNameSpaceID_MathML, popName, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   bool markAsHtmlIntegrationPoint = false;
@@ -3969,120 +3970,120 @@ nsHtml5TreeBuilder::annotationXmlEncodin
   }
   return nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("application/xhtml+xml", encoding) || nsHtml5Portability::lowerCaseLiteralEqualsIgnoreAsciiCaseString("text/html", encoding);
 }
 
 void 
 nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
   nsIAtom* popName = elementName->camelCaseName;
-  nsIContent** elt = createElement(kNameSpaceID_SVG, popName, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, popName, elt);
   push(node);
 }
 
 void 
-nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContent** form)
+nsHtml5TreeBuilder::appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, elementName->name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   nsHtml5StackNode* node = new nsHtml5StackNode(elementName, elt);
   push(node);
 }
 
 void 
-nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form)
+nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   elementPushed(kNameSpaceID_XHTML, name, elt);
   elementPopped(kNameSpaceID_XHTML, name, elt);
 }
 
 void 
 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
   nsIAtom* popName = elementName->name;
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, popName, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, popName, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   elementPushed(kNameSpaceID_XHTML, popName, elt);
   elementPopped(kNameSpaceID_XHTML, popName, elt);
 }
 
 void 
 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
   nsIAtom* popName = elementName->camelCaseName;
-  nsIContent** elt = createElement(kNameSpaceID_SVG, popName, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_SVG, popName, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   elementPushed(kNameSpaceID_SVG, popName, elt);
   elementPopped(kNameSpaceID_SVG, popName, elt);
 }
 
 void 
 nsHtml5TreeBuilder::appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes)
 {
   nsIAtom* popName = elementName->name;
-  nsIContent** elt = createElement(kNameSpaceID_MathML, popName, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_MathML, popName, attributes);
   nsHtml5StackNode* current = stack[currentPtr];
   if (current->isFosterParenting()) {
 
     insertIntoFosterParent(elt);
   } else {
     appendElement(elt, current->node);
   }
   elementPushed(kNameSpaceID_MathML, popName, elt);
   elementPopped(kNameSpaceID_MathML, popName, elt);
 }
 
 void 
-nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form)
+nsHtml5TreeBuilder::appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, name, attributes, !form || fragment || isTemplateContents() ? nullptr : form);
   nsHtml5StackNode* current = stack[currentPtr];
   appendElement(elt, current->node);
   elementPushed(kNameSpaceID_XHTML, name, elt);
   elementPopped(kNameSpaceID_XHTML, name, elt);
 }
 
 void 
 nsHtml5TreeBuilder::appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes)
 {
-  nsIContent** elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
+  nsIContentHandle* elt = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::form, attributes);
   formPointer = elt;
   nsHtml5StackNode* current = stack[currentPtr];
   appendElement(elt, current->node);
   elementPushed(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
   elementPopped(kNameSpaceID_XHTML, nsHtml5Atoms::form, elt);
 }
 
 void 
@@ -4102,26 +4103,26 @@ nsHtml5TreeBuilder::isInForeignButNotHtm
 {
   if (currentPtr < 0) {
     return false;
   }
   return !isSpecialParentInForeign(stack[currentPtr]);
 }
 
 void 
-nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, int32_t ns, nsIContent** node, bool quirks)
+nsHtml5TreeBuilder::setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks)
 {
   this->contextName = context;
   this->contextNamespace = ns;
   this->contextNode = node;
   this->fragment = (!!contextName);
   this->quirks = quirks;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5TreeBuilder::currentNode()
 {
   return stack[currentPtr]->node;
 }
 
 bool 
 nsHtml5TreeBuilder::isScriptingEnabled()
 {
@@ -4320,29 +4321,29 @@ nsHtml5TreeBuilder::findInArray(nsHtml5S
   for (int32_t i = listPtr; i >= 0; i--) {
     if (node == arr[i]) {
       return i;
     }
   }
   return -1;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5TreeBuilder::getFormPointer()
 {
   return formPointer;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5TreeBuilder::getHeadPointer()
 {
   return headPointer;
 }
 
-nsIContent** 
+nsIContentHandle* 
 nsHtml5TreeBuilder::getDeepTreeSurrogateParent()
 {
   return deepTreeSurrogateParent;
 }
 
 jArray<nsHtml5StackNode*,int32_t> 
 nsHtml5TreeBuilder::getListOfActiveFormattingElements()
 {
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -32,33 +32,34 @@
 #define nsHtml5TreeBuilder_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsITimer.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5DocumentMode.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsHtml5Parser.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5PendingNotification.h"
 #include "nsHtml5StateSnapshot.h"
 #include "nsHtml5StackNode.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsHtml5StreamParser.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Highlighter.h"
 #include "nsHtml5PlainTextUtils.h"
 #include "nsHtml5ViewSourceUtils.h"
 #include "mozilla/Likely.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
 class nsHtml5HtmlAttributes;
@@ -78,26 +79,26 @@ class nsHtml5TreeBuilder : public nsAHtm
   protected:
     nsHtml5Tokenizer* tokenizer;
   private:
     bool scriptingEnabled;
     bool needToDropLF;
     bool fragment;
     nsIAtom* contextName;
     int32_t contextNamespace;
-    nsIContent** contextNode;
+    nsIContentHandle* contextNode;
     autoJArray<int32_t,int32_t> templateModeStack;
     int32_t templateModePtr;
     autoJArray<nsHtml5StackNode*,int32_t> stack;
     int32_t currentPtr;
     autoJArray<nsHtml5StackNode*,int32_t> listOfActiveFormattingElements;
     int32_t listPtr;
-    nsIContent** formPointer;
-    nsIContent** headPointer;
-    nsIContent** deepTreeSurrogateParent;
+    nsIContentHandle* formPointer;
+    nsIContentHandle* headPointer;
+    nsIContentHandle* deepTreeSurrogateParent;
   protected:
     autoJArray<char16_t,int32_t> charBuffer;
     int32_t charBufferLen;
   private:
     bool quirks;
     bool isSrcdocDocument;
   public:
     void startTokenization(nsHtml5Tokenizer* self);
@@ -169,17 +170,17 @@ class nsHtml5TreeBuilder : public nsAHtm
     int32_t findInListOfActiveFormattingElementsContainsBetweenEndAndLastMarker(nsIAtom* name);
     void maybeForgetEarlierDuplicateFormattingElement(nsIAtom* name, nsHtml5HtmlAttributes* attributes);
     int32_t findLastOrRoot(nsIAtom* name);
     int32_t findLastOrRoot(int32_t group);
     bool addAttributesToBody(nsHtml5HtmlAttributes* attributes);
     void addAttributesToHtml(nsHtml5HtmlAttributes* attributes);
     void pushHeadPointerOntoStack();
     void reconstructTheActiveFormattingElements();
-    void insertIntoFosterParent(nsIContent** child);
+    void insertIntoFosterParent(nsIContentHandle* child);
     bool isInStack(nsHtml5StackNode* node);
     void popTemplateMode();
     void pop();
     void silentPop();
     void popOnEof();
     void appendHtmlElementToDocumentAndPush(nsHtml5HtmlAttributes* attributes);
     void appendHtmlElementToDocumentAndPush();
     void appendToCurrentNodeAndPushHeadElement(nsHtml5HtmlAttributes* attributes);
@@ -187,76 +188,76 @@ class nsHtml5TreeBuilder : public nsAHtm
     void appendToCurrentNodeAndPushBodyElement();
     void appendToCurrentNodeAndPushFormElementMayFoster(nsHtml5HtmlAttributes* attributes);
     void appendToCurrentNodeAndPushFormattingElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
     void appendToCurrentNodeAndPushElement(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
     void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
     void appendToCurrentNodeAndPushElementMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
     bool annotationXmlEncodingPermitsHtml(nsHtml5HtmlAttributes* attributes);
     void appendToCurrentNodeAndPushElementMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
-    void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContent** form);
-    void appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form);
+    void appendToCurrentNodeAndPushElementMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
+    void appendVoidElementToCurrentMayFoster(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
     void appendVoidElementToCurrentMayFoster(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
     void appendVoidElementToCurrentMayFosterSVG(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
     void appendVoidElementToCurrentMayFosterMathML(nsHtml5ElementName* elementName, nsHtml5HtmlAttributes* attributes);
-    void appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form);
+    void appendVoidElementToCurrent(nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
     void appendVoidFormToCurrent(nsHtml5HtmlAttributes* attributes);
   protected:
     void accumulateCharacters(const char16_t* buf, int32_t start, int32_t length);
     void requestSuspension();
-    nsIContent** createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
-    nsIContent** createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContent** form);
-    nsIContent** createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
-    void detachFromParent(nsIContent** element);
-    bool hasChildren(nsIContent** element);
-    void appendElement(nsIContent** child, nsIContent** newParent);
-    void appendChildrenToNewParent(nsIContent** oldParent, nsIContent** newParent);
-    void insertFosterParentedChild(nsIContent** child, nsIContent** table, nsIContent** stackParent);
-    void insertFosterParentedCharacters(char16_t* buf, int32_t start, int32_t length, nsIContent** table, nsIContent** stackParent);
-    void appendCharacters(nsIContent** parent, char16_t* buf, int32_t start, int32_t length);
-    void appendIsindexPrompt(nsIContent** parent);
-    void appendComment(nsIContent** parent, char16_t* buf, int32_t start, int32_t length);
+    nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes);
+    nsIContentHandle* createElement(int32_t ns, nsIAtom* name, nsHtml5HtmlAttributes* attributes, nsIContentHandle* form);
+    nsIContentHandle* createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* attributes);
+    void detachFromParent(nsIContentHandle* element);
+    bool hasChildren(nsIContentHandle* element);
+    void appendElement(nsIContentHandle* child, nsIContentHandle* newParent);
+    void appendChildrenToNewParent(nsIContentHandle* oldParent, nsIContentHandle* newParent);
+    void insertFosterParentedChild(nsIContentHandle* child, nsIContentHandle* table, nsIContentHandle* stackParent);
+    void insertFosterParentedCharacters(char16_t* buf, int32_t start, int32_t length, nsIContentHandle* table, nsIContentHandle* stackParent);
+    void appendCharacters(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
+    void appendIsindexPrompt(nsIContentHandle* parent);
+    void appendComment(nsIContentHandle* parent, char16_t* buf, int32_t start, int32_t length);
     void appendCommentToDocument(char16_t* buf, int32_t start, int32_t length);
-    void addAttributesToElement(nsIContent** element, nsHtml5HtmlAttributes* attributes);
-    void markMalformedIfScript(nsIContent** elt);
+    void addAttributesToElement(nsIContentHandle* element, nsHtml5HtmlAttributes* attributes);
+    void markMalformedIfScript(nsIContentHandle* elt);
     void start(bool fragmentMode);
     void end();
     void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier);
-    void elementPushed(int32_t ns, nsIAtom* name, nsIContent** node);
-    void elementPopped(int32_t ns, nsIAtom* name, nsIContent** node);
+    void elementPushed(int32_t ns, nsIAtom* name, nsIContentHandle* node);
+    void elementPopped(int32_t ns, nsIAtom* name, nsIContentHandle* node);
   public:
     inline bool cdataSectionAllowed()
     {
       return isInForeign();
     }
 
   private:
     bool isInForeign();
     bool isInForeignButNotHtmlOrMathTextIntegrationPoint();
   public:
-    void setFragmentContext(nsIAtom* context, int32_t ns, nsIContent** node, bool quirks);
+    void setFragmentContext(nsIAtom* context, int32_t ns, nsIContentHandle* node, bool quirks);
   protected:
-    nsIContent** currentNode();
+    nsIContentHandle* currentNode();
   public:
     bool isScriptingEnabled();
     void setScriptingEnabled(bool scriptingEnabled);
     void setIsSrcdocDocument(bool isSrcdocDocument);
     void flushCharacters();
   private:
     bool charBufferContainsNonWhitespace();
   public:
     nsAHtml5TreeBuilderState* newSnapshot();
     bool snapshotMatches(nsAHtml5TreeBuilderState* snapshot);
     void loadState(nsAHtml5TreeBuilderState* snapshot, nsHtml5AtomTable* interner);
   private:
     int32_t findInArray(nsHtml5StackNode* node, jArray<nsHtml5StackNode*,int32_t> arr);
   public:
-    nsIContent** getFormPointer();
-    nsIContent** getHeadPointer();
-    nsIContent** getDeepTreeSurrogateParent();
+    nsIContentHandle* getFormPointer();
+    nsIContentHandle* getHeadPointer();
+    nsIContentHandle* getDeepTreeSurrogateParent();
     jArray<nsHtml5StackNode*,int32_t> getListOfActiveFormattingElements();
     jArray<nsHtml5StackNode*,int32_t> getStack();
     jArray<int32_t,int32_t> getTemplateModeStack();
     int32_t getMode();
     int32_t getOriginalMode();
     bool isFramesetOk();
     bool isNeedToDropLF();
     bool isQuirks();
--- a/parser/html/nsHtml5TreeBuilderCppSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderCppSupplement.h
@@ -36,27 +36,27 @@ nsHtml5TreeBuilder::nsHtml5TreeBuilder(n
 
 nsHtml5TreeBuilder::~nsHtml5TreeBuilder()
 {
   MOZ_COUNT_DTOR(nsHtml5TreeBuilder);
   NS_ASSERTION(!mActive, "nsHtml5TreeBuilder deleted without ever calling end() on it!");
   mOpQueue.Clear();
 }
 
-nsIContent**
+nsIContentHandle*
 nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes)
 {
   NS_PRECONDITION(aAttributes, "Got null attributes.");
   NS_PRECONDITION(aName, "Got null name.");
   NS_PRECONDITION(aNamespace == kNameSpaceID_XHTML || 
                   aNamespace == kNameSpaceID_SVG || 
                   aNamespace == kNameSpaceID_MathML,
                   "Bogus namespace.");
 
-  nsIContent** content = AllocateContentHandle();
+  nsIContentHandle* content = AllocateContentHandle();
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(aNamespace,
                aName,
                aAttributes,
                content,
                !!mSpeculativeLoadStage);
   // mSpeculativeLoadStage is non-null only in the off-the-main-thread
@@ -204,126 +204,126 @@ nsHtml5TreeBuilder::createElement(int32_
     }
   }
 
   // End wall of code for speculative loading
   
   return content;
 }
 
-nsIContent**
-nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContent** aFormElement)
+nsIContentHandle*
+nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName, nsHtml5HtmlAttributes* aAttributes, nsIContentHandle* aFormElement)
 {
-  nsIContent** content = createElement(aNamespace, aName, aAttributes);
+  nsIContentHandle* content = createElement(aNamespace, aName, aAttributes);
   if (aFormElement) {
     nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
     NS_ASSERTION(treeOp, "Tree op allocation failed.");
     treeOp->Init(eTreeOpSetFormElement, content, aFormElement);
   }
   return content;
 }
 
-nsIContent**
+nsIContentHandle*
 nsHtml5TreeBuilder::createHtmlElementSetAsRoot(nsHtml5HtmlAttributes* aAttributes)
 {
-  nsIContent** content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes);
+  nsIContentHandle* content = createElement(kNameSpaceID_XHTML, nsHtml5Atoms::html, aAttributes);
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppendToDocument, content);
   return content;
 }
 
 void
-nsHtml5TreeBuilder::detachFromParent(nsIContent** aElement)
+nsHtml5TreeBuilder::detachFromParent(nsIContentHandle* aElement)
 {
   NS_PRECONDITION(aElement, "Null element");
 
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpDetach, aElement);
 }
 
 void
-nsHtml5TreeBuilder::appendElement(nsIContent** aChild, nsIContent** aParent)
+nsHtml5TreeBuilder::appendElement(nsIContentHandle* aChild, nsIContentHandle* aParent)
 {
   NS_PRECONDITION(aChild, "Null child");
   NS_PRECONDITION(aParent, "Null parent");
   if (deepTreeSurrogateParent) {
     return;
   }
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppend, aChild, aParent);
 }
 
 void
-nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContent** aOldParent, nsIContent** aNewParent)
+nsHtml5TreeBuilder::appendChildrenToNewParent(nsIContentHandle* aOldParent, nsIContentHandle* aNewParent)
 {
   NS_PRECONDITION(aOldParent, "Null old parent");
   NS_PRECONDITION(aNewParent, "Null new parent");
 
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppendChildrenToNewParent, aOldParent, aNewParent);
 }
 
 void
-nsHtml5TreeBuilder::insertFosterParentedCharacters(char16_t* aBuffer, int32_t aStart, int32_t aLength, nsIContent** aTable, nsIContent** aStackParent)
+nsHtml5TreeBuilder::insertFosterParentedCharacters(char16_t* aBuffer, int32_t aStart, int32_t aLength, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
 {
   NS_PRECONDITION(aBuffer, "Null buffer");
   NS_PRECONDITION(aTable, "Null table");
   NS_PRECONDITION(aStackParent, "Null stack parent");
 
   char16_t* bufferCopy = new char16_t[aLength];
   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpFosterParentText, bufferCopy, aLength, aStackParent, aTable);
 }
 
 void
-nsHtml5TreeBuilder::insertFosterParentedChild(nsIContent** aChild, nsIContent** aTable, nsIContent** aStackParent)
+nsHtml5TreeBuilder::insertFosterParentedChild(nsIContentHandle* aChild, nsIContentHandle* aTable, nsIContentHandle* aStackParent)
 {
   NS_PRECONDITION(aChild, "Null child");
   NS_PRECONDITION(aTable, "Null table");
   NS_PRECONDITION(aStackParent, "Null stack parent");
 
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpFosterParent, aChild, aStackParent, aTable);
 }
 
 void
-nsHtml5TreeBuilder::appendCharacters(nsIContent** aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
+nsHtml5TreeBuilder::appendCharacters(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
 {
   NS_PRECONDITION(aBuffer, "Null buffer");
   NS_PRECONDITION(aParent, "Null parent");
 
   char16_t* bufferCopy = new char16_t[aLength];
   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppendText, bufferCopy, aLength,
       deepTreeSurrogateParent ? deepTreeSurrogateParent : aParent);
 }
 
 void
-nsHtml5TreeBuilder::appendIsindexPrompt(nsIContent** aParent)
+nsHtml5TreeBuilder::appendIsindexPrompt(nsIContentHandle* aParent)
 {
   NS_PRECONDITION(aParent, "Null parent");
 
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppendIsindexPrompt, aParent);
 }
 
 void
-nsHtml5TreeBuilder::appendComment(nsIContent** aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
+nsHtml5TreeBuilder::appendComment(nsIContentHandle* aParent, char16_t* aBuffer, int32_t aStart, int32_t aLength)
 {
   NS_PRECONDITION(aBuffer, "Null buffer");
   NS_PRECONDITION(aParent, "Null parent");
   if (deepTreeSurrogateParent) {
     return;
   }
 
   char16_t* bufferCopy = new char16_t[aLength];
@@ -343,31 +343,31 @@ nsHtml5TreeBuilder::appendCommentToDocum
   memcpy(bufferCopy, aBuffer, aLength * sizeof(char16_t));
   
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpAppendCommentToDocument, bufferCopy, aLength);
 }
 
 void
-nsHtml5TreeBuilder::addAttributesToElement(nsIContent** aElement, nsHtml5HtmlAttributes* aAttributes)
+nsHtml5TreeBuilder::addAttributesToElement(nsIContentHandle* aElement, nsHtml5HtmlAttributes* aAttributes)
 {
   NS_PRECONDITION(aElement, "Null element");
   NS_PRECONDITION(aAttributes, "Null attributes");
 
   if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
     return;
   }
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(aElement, aAttributes);
 }
 
 void
-nsHtml5TreeBuilder::markMalformedIfScript(nsIContent** aElement)
+nsHtml5TreeBuilder::markMalformedIfScript(nsIContentHandle* aElement)
 {
   NS_PRECONDITION(aElement, "Null element");
 
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(eTreeOpMarkMalformedIfScript, aElement);
 }
 
@@ -398,17 +398,17 @@ nsHtml5TreeBuilder::appendDoctypeToDocum
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(aName, *aPublicId, *aSystemId);
   // nsXMLContentSink can flush here, but what's the point?
   // It can also interrupt here, but we can't.
 }
 
 void
-nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsIAtom* aName, nsIContent** aElement)
+nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
 {
   NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
   NS_ASSERTION(aName, "Element doesn't have local name!");
   NS_ASSERTION(aElement, "No element!");
   /*
    * The frame constructor uses recursive algorithms, so it can't deal with
    * arbitrarily deep trees. This is especially a problem on Windows where
    * the permitted depth of the runtime stack is rather small.
@@ -462,17 +462,17 @@ nsHtml5TreeBuilder::elementPushed(int32_
       aName == nsHtml5Atoms::video ||
       aName == nsHtml5Atoms::menuitem) {
     mOpQueue.AppendElement()->Init(eTreeOpDoneCreatingElement, aElement);
     return;
   }
 }
 
 void
-nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContent** aElement)
+nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContentHandle* aElement)
 {
   NS_ASSERTION(aNamespace == kNameSpaceID_XHTML || aNamespace == kNameSpaceID_SVG || aNamespace == kNameSpaceID_MathML, "Element isn't HTML, SVG or MathML!");
   NS_ASSERTION(aName, "Element doesn't have local name!");
   NS_ASSERTION(aElement, "No element!");
   if (deepTreeSurrogateParent && currentPtr <= MAX_REFLOW_DEPTH) {
     deepTreeSurrogateParent = nullptr;
   }
   if (aNamespace == kNameSpaceID_MathML) {
@@ -563,17 +563,17 @@ nsHtml5TreeBuilder::accumulateCharacters
     jArray<char16_t,int32_t> newBuf = jArray<char16_t,int32_t>::newJArray(newAllocLength);
     memcpy(newBuf, charBuffer, sizeof(char16_t) * charBufferLen);
     charBuffer = newBuf;
   }
   memcpy(charBuffer + charBufferLen, aBuf + aStart, sizeof(char16_t) * aLength);
   charBufferLen = newFillLen;
 }
 
-nsIContent**
+nsIContentHandle*
 nsHtml5TreeBuilder::AllocateContentHandle()
 {
   if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
     mOldHandles.AppendElement(mHandles.forget());
     mHandles = new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH];
     mHandlesUsed = 0;
   }
 #ifdef DEBUG
@@ -746,38 +746,38 @@ nsHtml5TreeBuilder::StartPlainTextBody()
 void
 nsHtml5TreeBuilder::documentMode(nsHtml5DocumentMode m)
 {
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
   treeOp->Init(m);
 }
 
-nsIContent**
-nsHtml5TreeBuilder::getDocumentFragmentForTemplate(nsIContent** aTemplate)
+nsIContentHandle*
+nsHtml5TreeBuilder::getDocumentFragmentForTemplate(nsIContentHandle* aTemplate)
 {
   nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
   NS_ASSERTION(treeOp, "Tree op allocation failed.");
-  nsIContent** fragHandle = AllocateContentHandle();
+  nsIContentHandle* fragHandle = AllocateContentHandle();
   treeOp->Init(eTreeOpGetDocumentFragmentForTemplate, aTemplate, fragHandle);
   return fragHandle;
 }
 
-nsIContent**
-nsHtml5TreeBuilder::getFormPointerForContext(nsIContent** aContext)
+nsIContentHandle*
+nsHtml5TreeBuilder::getFormPointerForContext(nsIContentHandle* aContext)
 {
   if (!aContext) {
     return nullptr;
   }
 
   MOZ_ASSERT(NS_IsMainThread());
 
   // aContext must always be a handle to an element that already exists
   // in the document. It must never be an empty handle.
-  nsIContent* contextNode = *aContext;
+  nsIContent* contextNode = *(static_cast<nsIContent**>(aContext));
   nsIContent* currentAncestor = contextNode;
 
   // We traverse the ancestors of the context node to find the nearest
   // form pointer. This traversal is why aContext must not be an emtpy handle.
   nsIContent* nearestForm = nullptr;
   while (currentAncestor) {
     if (currentAncestor->IsHTML(nsGkAtoms::form)) {
       nearestForm = currentAncestor;
@@ -785,18 +785,18 @@ nsHtml5TreeBuilder::getFormPointerForCon
     }
     currentAncestor = currentAncestor->GetParent();
   }
 
   if (!nearestForm) {
     return nullptr;
   }
 
-  nsIContent** formPointer = AllocateContentHandle();
-  *formPointer = nearestForm;
+  nsIContentHandle* formPointer = AllocateContentHandle();
+  *(static_cast<nsIContent**>(formPointer)) = nearestForm;
   return formPointer;
 }
 
 // Error reporting
 
 void
 nsHtml5TreeBuilder::EnableViewSource(nsHtml5Highlighter* aHighlighter)
 {
--- a/parser/html/nsHtml5TreeBuilderHSupplement.h
+++ b/parser/html/nsHtml5TreeBuilderHSupplement.h
@@ -21,19 +21,19 @@
 #endif
 
     // DocumentModeHandler
     /**
      * Tree builder uses this to report quirkiness of the document
      */
     void documentMode(nsHtml5DocumentMode m);
 
-    nsIContent** getDocumentFragmentForTemplate(nsIContent** aTemplate);
+    nsIContentHandle* getDocumentFragmentForTemplate(nsIContentHandle* aTemplate);
 
-    nsIContent** getFormPointerForContext(nsIContent** aContext);
+    nsIContentHandle* getFormPointerForContext(nsIContentHandle* aContext);
 
     /**
      * Using nsIContent** instead of nsIContent* is the parser deals with DOM
      * nodes in a way that works off the main thread. Non-main-thread code
      * can't refcount or otherwise touch nsIContent objects in any way.
      * Yet, the off-the-main-thread code needs to have a way to hold onto a
      * particular node and repeatedly operate on the same node.
      *
@@ -44,21 +44,21 @@
      * nsIContent** immediately and a tree op is enqueued for later allocating
      * an actual nsIContent object and writing a pointer to it into the memory
      * location pointed to by the nsIContent**.
      *
      * Since tree ops are in a queue, the node creating tree op will always
      * run before tree ops that try to further operate on the node that the
      * nsIContent** is a handle to.
      *
-     * On-the-main-thread parts of the parser use the same mechanism in order
-     * to avoid having to have duplicate code paths for on-the-main-thread and
-     * off-the-main-thread tree builder instances.)
+     * On-the-main-thread parts of the parser use nsIContent* instead of
+     * nsIContent**. Since both cases share the same parser core, the parser
+     * core casts both to nsIContentHandle*.
      */
-    nsIContent** AllocateContentHandle();
+    nsIContentHandle* AllocateContentHandle();
     
     void accumulateCharactersForced(const char16_t* aBuf, int32_t aStart, int32_t aLength)
     {
       accumulateCharacters(aBuf, aStart, aLength);
     }
 
   public:
 
--- a/parser/html/nsHtml5TreeOperation.h
+++ b/parser/html/nsHtml5TreeOperation.h
@@ -93,34 +93,34 @@ class nsHtml5TreeOperation {
     ~nsHtml5TreeOperation();
 
     inline void Init(eHtml5TreeOperation aOpCode) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       mOpCode = aOpCode;
     }
 
-    inline void Init(eHtml5TreeOperation aOpCode, nsIContent** aNode) {
+    inline void Init(eHtml5TreeOperation aOpCode, nsIContentHandle* aNode) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       mOpCode = aOpCode;
-      mOne.node = aNode;
+      mOne.node = static_cast<nsIContent**>(aNode);
     }
 
     inline void Init(eHtml5TreeOperation aOpCode, 
-                     nsIContent** aNode,
-                     nsIContent** aParent) {
+                     nsIContentHandle* aNode,
+                     nsIContentHandle* aParent) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
       mOpCode = aOpCode;
-      mOne.node = aNode;
-      mTwo.node = aParent;
+      mOne.node = static_cast<nsIContent**>(aNode);
+      mTwo.node = static_cast<nsIContent**>(aParent);
     }
     
     inline void Init(eHtml5TreeOperation aOpCode, 
                      const nsACString& aString,
                      int32_t aInt32) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
 
@@ -141,147 +141,147 @@ class nsHtml5TreeOperation {
                      const nsACString& aString,
                      int32_t aInt32,
                      int32_t aLineNumber) {
       Init(aOpCode, aString, aInt32);
       mTwo.integer = aLineNumber;
     }
 
     inline void Init(eHtml5TreeOperation aOpCode,
-                     nsIContent** aNode,
-                     nsIContent** aParent, 
-                     nsIContent** aTable) {
+                     nsIContentHandle* aNode,
+                     nsIContentHandle* aParent,
+                     nsIContentHandle* aTable) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       NS_PRECONDITION(aParent, "Initialized tree op with null parent.");
       NS_PRECONDITION(aTable, "Initialized tree op with null table.");
       mOpCode = aOpCode;
-      mOne.node = aNode;
-      mTwo.node = aParent;
-      mThree.node = aTable;
+      mOne.node = static_cast<nsIContent**>(aNode);
+      mTwo.node = static_cast<nsIContent**>(aParent);
+      mThree.node = static_cast<nsIContent**>(aTable);
     }
 
     inline void Init(nsHtml5DocumentMode aMode) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       mOpCode = eTreeOpDocumentMode;
       mOne.mode = aMode;
     }
     
-    inline void InitScript(nsIContent** aNode) {
+    inline void InitScript(nsIContentHandle* aNode) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       mOpCode = eTreeOpRunScript;
-      mOne.node = aNode;
+      mOne.node = static_cast<nsIContent**>(aNode);
       mTwo.state = nullptr;
     }
     
     inline void Init(int32_t aNamespace, 
                      nsIAtom* aName, 
                      nsHtml5HtmlAttributes* aAttributes,
-                     nsIContent** aTarget,
+                     nsIContentHandle* aTarget,
                      bool aFromNetwork) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aName, "Initialized tree op with null name.");
       NS_PRECONDITION(aTarget, "Initialized tree op with null target node.");
       mOpCode = aFromNetwork ?
                 eTreeOpCreateElementNetwork :
                 eTreeOpCreateElementNotNetwork;
       mFour.integer = aNamespace;
-      mOne.node = aTarget;
+      mOne.node = static_cast<nsIContent**>(aTarget);
       mTwo.atom = aName;
       if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
         mThree.attributes = nullptr;
       } else {
         mThree.attributes = aAttributes;
       }
     }
 
     inline void Init(eHtml5TreeOperation aOpCode, 
                      char16_t* aBuffer, 
                      int32_t aLength, 
-                     nsIContent** aStackParent,
-                     nsIContent** aTable) {
+                     nsIContentHandle* aStackParent,
+                     nsIContentHandle* aTable) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
       mOpCode = aOpCode;
-      mOne.node = aStackParent;
+      mOne.node = static_cast<nsIContent**>(aStackParent);
       mTwo.unicharPtr = aBuffer;
-      mThree.node = aTable;
+      mThree.node = static_cast<nsIContent**>(aTable);
       mFour.integer = aLength;
     }
 
     inline void Init(eHtml5TreeOperation aOpCode, 
                      char16_t* aBuffer, 
                      int32_t aLength, 
-                     nsIContent** aParent) {
+                     nsIContentHandle* aParent) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
       mOpCode = aOpCode;
-      mOne.node = aParent;
+      mOne.node = static_cast<nsIContent**>(aParent);
       mTwo.unicharPtr = aBuffer;
       mFour.integer = aLength;
     }
 
     inline void Init(eHtml5TreeOperation aOpCode, 
                      char16_t* aBuffer, 
                      int32_t aLength) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aBuffer, "Initialized tree op with null buffer.");
       mOpCode = aOpCode;
       mTwo.unicharPtr = aBuffer;
       mFour.integer = aLength;
     }
     
-    inline void Init(nsIContent** aElement,
+    inline void Init(nsIContentHandle* aElement,
                      nsHtml5HtmlAttributes* aAttributes) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aElement, "Initialized tree op with null element.");
       mOpCode = eTreeOpAddAttributes;
-      mOne.node = aElement;
+      mOne.node = static_cast<nsIContent**>(aElement);
       mTwo.attributes = aAttributes;
     }
     
     inline void Init(nsIAtom* aName, 
                      const nsAString& aPublicId, 
                      const nsAString& aSystemId) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       mOpCode = eTreeOpAppendDoctypeToDocument;
       mOne.atom = aName;
       mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
     }
     
-    inline void Init(nsIContent** aElement,
+    inline void Init(nsIContentHandle* aElement,
                      const char* aMsgId,
                      nsIAtom* aAtom,
                      nsIAtom* aOtherAtom) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       mOpCode = eTreeOpAddError;
-      mOne.node = aElement;
+      mOne.node = static_cast<nsIContent**>(aElement);
       mTwo.charPtr = (char*)aMsgId;
       mThree.atom = aAtom;
       mFour.atom = aOtherAtom;
     }
 
-    inline void Init(nsIContent** aElement,
+    inline void Init(nsIContentHandle* aElement,
                      const char* aMsgId,
                      nsIAtom* aAtom) {
       Init(aElement, aMsgId, aAtom, nullptr);
     }
 
-    inline void Init(nsIContent** aElement,
+    inline void Init(nsIContentHandle* aElement,
                      const char* aMsgId) {
       Init(aElement, aMsgId, nullptr, nullptr);
     }
 
     inline void Init(const char* aMsgId,
                      bool aError,
                      int32_t aLineNumber) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
@@ -297,46 +297,46 @@ class nsHtml5TreeOperation {
         "Op code must be uninitialized when initializing.");
 
       char16_t* str = NS_StringCloneData(aString);
       mOpCode = aOpCode;
       mOne.unicharPtr = str;
     }
     
     inline void Init(eHtml5TreeOperation aOpCode,
-                     nsIContent** aNode,
+                     nsIContentHandle* aNode,
                      int32_t aInt) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       mOpCode = aOpCode;
-      mOne.node = aNode;
+      mOne.node = static_cast<nsIContent**>(aNode);
       mFour.integer = aInt;
     }
 
-    inline void InitAddClass(nsIContent** aNode, const char16_t* aClass) {
+    inline void InitAddClass(nsIContentHandle* aNode, const char16_t* aClass) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       NS_PRECONDITION(aClass, "Initialized tree op with null string.");
       // aClass must be a literal string that does not need freeing
       mOpCode = eTreeOpAddClass;
-      mOne.node = aNode;
+      mOne.node = static_cast<nsIContent**>(aNode);
       mTwo.unicharPtr = (char16_t*)aClass;
     }
 
-    inline void InitAddLineNumberId(nsIContent** aNode,
+    inline void InitAddLineNumberId(nsIContentHandle* aNode,
                                     const int32_t aLineNumber) {
       NS_PRECONDITION(mOpCode == eTreeOpUninitialized,
         "Op code must be uninitialized when initializing.");
       NS_PRECONDITION(aNode, "Initialized tree op with null node.");
       NS_PRECONDITION(aLineNumber > 0, "Initialized tree op with line number.");
       // aClass must be a literal string that does not need freeing
       mOpCode = eTreeOpAddLineNumberId;
-      mOne.node = aNode;
+      mOne.node = static_cast<nsIContent**>(aNode);
       mFour.integer = aLineNumber;
     }
 
     inline bool IsRunScript() {
       return mOpCode == eTreeOpRunScript;
     }
     
     inline void SetSnapshot(nsAHtml5TreeBuilderState* aSnapshot, int32_t aLine) {
--- a/parser/html/nsHtml5UTF16Buffer.cpp
+++ b/parser/html/nsHtml5UTF16Buffer.cpp
@@ -27,24 +27,25 @@
 
 #define nsHtml5UTF16Buffer_cpp__
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 #include "nsHtml5Tokenizer.h"
 #include "nsHtml5TreeBuilder.h"
 #include "nsHtml5MetaScanner.h"
 #include "nsHtml5AttributeName.h"
 #include "nsHtml5ElementName.h"
 #include "nsHtml5HtmlAttributes.h"
 #include "nsHtml5StackNode.h"
--- a/parser/html/nsHtml5UTF16Buffer.h
+++ b/parser/html/nsHtml5UTF16Buffer.h
@@ -28,24 +28,25 @@
 #ifndef nsHtml5UTF16Buffer_h
 #define nsHtml5UTF16Buffer_h
 
 #include "nsIAtom.h"
 #include "nsHtml5AtomTable.h"
 #include "nsString.h"
 #include "nsNameSpaceManager.h"
 #include "nsIContent.h"
-#include "nsISupportsImpl.h"
+#include "nsTraceRefcnt.h"
 #include "jArray.h"
 #include "nsHtml5ArrayCopy.h"
 #include "nsAHtml5TreeBuilderState.h"
 #include "nsHtml5Atoms.h"
 #include "nsHtml5ByteReadable.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsHtml5Macros.h"
+#include "nsIContentHandle.h"
 
 class nsHtml5StreamParser;
 
 class nsHtml5Tokenizer;
 class nsHtml5TreeBuilder;
 class nsHtml5MetaScanner;
 class nsHtml5AttributeName;
 class nsHtml5ElementName;
new file mode 100644
--- /dev/null
+++ b/parser/html/nsIContentHandle.h
@@ -0,0 +1,5 @@
+/* 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/. */
+
+typedef void nsIContentHandle;