Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 16 Aug 2014 17:42:29 -0400
changeset 200007 94ba78a423050deda23c6382fc3aa004d5e89913
parent 199904 c3eb1b5ad4e4b12e0982a07bdccb2de09799bc52 (current diff)
parent 200006 cafba2a1b359a8205906cad600b363be4d7e4f6d (diff)
child 200008 739c7c889af30eda981406ec7965545a64307103
child 200014 82722ad59732fd355f6bd77d5194ceaa1dab23c3
child 200018 e5a893c6e64c40e5b7648cc80cfb2dce5b27594a
push idunknown
push userunknown
push dateunknown
reviewersmerge
milestone34.0a1
Merge inbound to m-c. a=merge
js/src/assembler/assembler/MacroAssembler.h
js/src/assembler/assembler/MacroAssemblerMIPS.h
js/src/assembler/assembler/MacroAssemblerSparc.h
js/src/assembler/assembler/MacroAssemblerX86.h
js/src/assembler/assembler/MacroAssemblerX86_64.h
js/src/assembler/wtf/Platform.h
js/src/jit/none/BaseMacroAssembler-none.h
security/manager/boot/src/StaticHPKPins.h
--- a/accessible/base/Logging.cpp
+++ b/accessible/base/Logging.cpp
@@ -191,18 +191,20 @@ LogDocLoadGroup(nsIDocument* aDocumentNo
   nsCOMPtr<nsILoadGroup> loadGroup = aDocumentNode->GetDocumentLoadGroup();
   printf("load group: %p", static_cast<void*>(loadGroup));
 }
 
 static void
 LogDocParent(nsIDocument* aDocumentNode)
 {
   nsIDocument* parentDoc = aDocumentNode->GetParentDocument();
-  printf("parent id: %p", static_cast<void*>(parentDoc));
+  printf("parent DOM document: %p", static_cast<void*>(parentDoc));
   if (parentDoc) {
+    printf(", parent acc document: %p",
+           static_cast<void*>(GetExistingDocAccessible(parentDoc)));
     printf("\n    parent ");
     LogDocURI(parentDoc);
     printf("\n");
   }
 }
 
 static void
 LogDocInfo(nsIDocument* aDocumentNode, DocAccessible* aDocument)
--- a/accessible/base/SelectionManager.cpp
+++ b/accessible/base/SelectionManager.cpp
@@ -7,16 +7,17 @@
 
 #include "DocAccessible-inl.h"
 #include "HyperTextAccessible.h"
 #include "HyperTextAccessible-inl.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsEventShell.h"
+#include "nsFrameSelection.h"
 
 #include "nsIAccessibleTypes.h"
 #include "nsIDOMDocument.h"
 #include "nsIPresShell.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -967,32 +967,32 @@ nsAccessibilityService::GetOrCreateAcces
       newAcc = CreateHTMLAccessibleByMarkup(frame, content, aContext);
 
       // Try using frame to do it.
       if (!newAcc)
         newAcc = CreateAccessibleByFrameType(frame, content, aContext);
 
       // If table has strong ARIA role then all table descendants shouldn't
       // expose their native roles.
-      if (!roleMapEntry && newAcc) {
+      if (!roleMapEntry && newAcc && aContext->HasStrongARIARole()) {
         if (frame->AccessibleType() == eHTMLTableRowType) {
           nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
-          if (contextRoleMap && !(contextRoleMap->IsOfType(eTable)))
+          if (!contextRoleMap->IsOfType(eTable))
             roleMapEntry = &aria::gEmptyRoleMap;
 
         } else if (frame->AccessibleType() == eHTMLTableCellType &&
                    aContext->ARIARoleMap() == &aria::gEmptyRoleMap) {
           roleMapEntry = &aria::gEmptyRoleMap;
 
         } else if (content->Tag() == nsGkAtoms::dt ||
                    content->Tag() == nsGkAtoms::li ||
                    content->Tag() == nsGkAtoms::dd ||
                    frame->AccessibleType() == eHTMLLiType) {
           nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
-          if (contextRoleMap && !(contextRoleMap->IsOfType(eList)))
+          if (!contextRoleMap->IsOfType(eList))
             roleMapEntry = &aria::gEmptyRoleMap;
         }
       }
     }
   }
 
   // Accessible XBL types and deck stuff are used in XUL only currently.
   if (!newAcc && content->IsXUL()) {
--- a/accessible/generic/Accessible-inl.h
+++ b/accessible/generic/Accessible-inl.h
@@ -23,16 +23,22 @@ Accessible::Role()
 }
 
 inline bool
 Accessible::IsARIARole(nsIAtom* aARIARole) const
 {
   return mRoleMapEntry && mRoleMapEntry->Is(aARIARole);
 }
 
+inline bool
+Accessible::HasStrongARIARole() const
+{
+  return mRoleMapEntry && mRoleMapEntry->roleRule == kUseMapRole;
+}
+
 inline mozilla::a11y::role
 Accessible::ARIARole()
 {
   if (!mRoleMapEntry || mRoleMapEntry->roleRule != kUseMapRole)
     return mozilla::a11y::roles::NOTHING;
 
   return ARIATransformRole(mRoleMapEntry->role);
 }
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -214,16 +214,17 @@ public:
    */
   mozilla::a11y::role Role();
 
   /**
    * Return true if ARIA role is specified on the element.
    */
   bool HasARIARole() const { return mRoleMapEntry; }
   bool IsARIARole(nsIAtom* aARIARole) const;
+  bool HasStrongARIARole() const;
 
   /**
    * Retrun ARIA role map if any.
    */
   nsRoleMapEntry* ARIARoleMap() const { return mRoleMapEntry; }
 
   /**
    * Return accessible role specified by ARIA (see constants in
--- a/accessible/generic/HyperTextAccessible-inl.h
+++ b/accessible/generic/HyperTextAccessible-inl.h
@@ -9,16 +9,17 @@
 #include "HyperTextAccessible.h"
 
 #include "nsAccUtils.h"
 
 #include "nsIClipboard.h"
 #include "nsIEditor.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPlaintextEditor.h"
+#include "nsFrameSelection.h"
 
 namespace mozilla {
 namespace a11y {
 
 inline bool
 HyperTextAccessible::IsValidOffset(int32_t aOffset)
 {
   index_t offset = ConvertMagicOffset(aOffset);
@@ -138,17 +139,17 @@ HyperTextAccessible::AdjustCaretOffset(u
   return aOffset;
 }
 
 inline bool
 HyperTextAccessible::IsCaretAtEndOfLine() const
 {
   nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
   return frameSelection &&
-    frameSelection->GetHint() == nsFrameSelection::HINTLEFT;
+    frameSelection->GetHint() == CARET_ASSOCIATE_BEFORE;
 }
 
 inline already_AddRefed<nsFrameSelection>
 HyperTextAccessible::FrameSelection() const
 {
   nsIFrame* frame = GetFrame();
   return frame ? frame->GetFrameSelection() : nullptr;
 }
--- a/accessible/generic/HyperTextAccessible.cpp
+++ b/accessible/generic/HyperTextAccessible.cpp
@@ -1264,17 +1264,17 @@ HyperTextAccessible::CaretLineNumber()
     return -1;
 
   nsIContent* caretContent = caretNode->AsContent();
   if (!nsCoreUtils::IsAncestorOf(GetNode(), caretContent))
     return -1;
 
   int32_t returnOffsetUnused;
   uint32_t caretOffset = domSel->FocusOffset();
-  nsFrameSelection::HINT hint = frameSelection->GetHint();
+  CaretAssociationHint hint = frameSelection->GetHint();
   nsIFrame *caretFrame = frameSelection->GetFrameForNodeOffset(caretContent, caretOffset,
                                                                hint, &returnOffsetUnused);
   NS_ENSURE_TRUE(caretFrame, -1);
 
   int32_t lineNumber = 1;
   nsAutoLineIterator lineIterForCaret;
   nsIContent *hyperTextContent = IsContent() ? mContent.get() : nullptr;
   while (caretFrame) {
@@ -1317,26 +1317,22 @@ HyperTextAccessible::CaretLineNumber()
 nsIntRect
 HyperTextAccessible::GetCaretRect(nsIWidget** aWidget)
 {
   *aWidget = nullptr;
 
   nsRefPtr<nsCaret> caret = mDoc->PresShell()->GetCaret();
   NS_ENSURE_TRUE(caret, nsIntRect());
 
-  nsISelection* caretSelection = caret->GetCaretDOMSelection();
-  NS_ENSURE_TRUE(caretSelection, nsIntRect());
-
-  bool isVisible = false;
-  caret->GetCaretVisible(&isVisible);
+  bool isVisible = caret->IsVisible();
   if (!isVisible)
     return nsIntRect();
 
   nsRect rect;
-  nsIFrame* frame = caret->GetGeometry(caretSelection, &rect);
+  nsIFrame* frame = caret->GetGeometry(&rect);
   if (!frame || rect.IsEmpty())
     return nsIntRect();
 
   nsPoint offset;
   // Offset from widget origin to the frame origin, which includes chrome
   // on the widget.
   *aWidget = frame->GetNearestWidget(offset);
   NS_ENSURE_TRUE(*aWidget, nsIntRect());
--- a/accessible/generic/HyperTextAccessible.h
+++ b/accessible/generic/HyperTextAccessible.h
@@ -4,21 +4,32 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11y_HyperTextAccessible_h__
 #define mozilla_a11y_HyperTextAccessible_h__
 
 #include "AccessibleWrap.h"
 #include "nsIAccessibleTypes.h"
 #include "xpcAccessibleHyperText.h"
+#include "nsDirection.h"
+#include "WordMovementType.h"
+#include "nsIFrame.h"
 
-#include "nsFrameSelection.h"
 #include "nsISelectionController.h"
 
+class nsFrameSelection;
+class nsRange;
+class nsIWidget;
+
 namespace mozilla {
+
+namespace dom {
+class Selection;
+}
+
 namespace a11y {
 
 class TextRange;
 
 struct DOMPoint {
   DOMPoint() : node(nullptr), idx(0) { }
   DOMPoint(nsINode* aNode, int32_t aIdx) : node(aNode), idx(aIdx) { }
 
--- a/accessible/jsat/ContentControl.jsm
+++ b/accessible/jsat/ContentControl.jsm
@@ -391,17 +391,17 @@ this.ContentControl.prototype = {
       let acc = aAnchor;
       let rule = aOptions.onScreenOnly ?
         TraversalRules.SimpleOnScreen : TraversalRules.Simple;
       let forcePresentFunc = () => {
         if (aOptions.forcePresent) {
           this._contentScope.get().sendAsyncMessage(
             'AccessFu:Present', Presentation.pivotChanged(
               vc.position, null, Ci.nsIAccessiblePivot.REASON_NONE,
-              vc.startOffset, vc.endOffset));
+              vc.startOffset, vc.endOffset, false));
         }
       };
 
       if (aOptions.noOpIfOnScreen &&
         Utils.isAliveAndVisible(vc.position, true)) {
         forcePresentFunc();
         return;
       }
@@ -411,21 +411,22 @@ this.ContentControl.prototype = {
           this.document.activeElement) || acc;
       }
 
       let moved = false;
       let moveMethod = aOptions.moveMethod || 'moveNext'; // default is moveNext
       let moveFirstOrLast = moveMethod in ['moveFirst', 'moveLast'];
       if (!moveFirstOrLast || acc) {
         // We either need next/previous or there is an anchor we need to use.
-        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true);
+        moved = vc[moveFirstOrLast ? 'moveNext' : moveMethod](rule, acc, true,
+                                                              false);
       }
       if (moveFirstOrLast && !moved) {
         // We move to first/last after no anchor move happened or succeeded.
-        moved = vc[moveMethod](rule);
+        moved = vc[moveMethod](rule, false);
       }
 
       let sentToChild = this.sendToChild(vc, {
         name: 'AccessFu:AutoMove',
         json: {
           moveMethod: aOptions.moveMethod,
           moveToFocused: aOptions.moveToFocused,
           noOpIfOnScreen: true,
--- a/accessible/jsat/EventManager.jsm
+++ b/accessible/jsat/EventManager.jsm
@@ -156,17 +156,18 @@ this.EventManager.prototype = {
         let reason = event.reason;
         let oldAccessible = event.oldAccessible;
 
         if (this.editState.editing) {
           aEvent.accessibleDocument.takeFocus();
         }
         this.present(
           Presentation.pivotChanged(position, oldAccessible, reason,
-                                    pivot.startOffset, pivot.endOffset));
+                                    pivot.startOffset, pivot.endOffset,
+                                    aEvent.isFromUserInput));
 
         break;
       }
       case Events.STATE_CHANGE:
       {
         let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
         let state = Utils.getState(event);
         if (state.contains(States.CHECKED)) {
--- a/accessible/jsat/Presentation.jsm
+++ b/accessible/jsat/Presentation.jsm
@@ -41,18 +41,19 @@ Presenter.prototype = {
   type: 'Base',
 
   /**
    * The virtual cursor's position changed.
    * @param {PivotContext} aContext the context object for the new pivot
    *   position.
    * @param {int} aReason the reason for the pivot change.
    *   See nsIAccessiblePivot.
+   * @param {bool} aIsFromUserInput the pivot change was invoked by the user
    */
-  pivotChanged: function pivotChanged(aContext, aReason) {}, // jshint ignore:line
+  pivotChanged: function pivotChanged(aContext, aReason, aIsFromUserInput) {}, // jshint ignore:line
 
   /**
    * An object's action has been invoked.
    * @param {nsIAccessible} aObject the object that has been invoked.
    * @param {string} aActionName the name of the action.
    */
   actionInvoked: function actionInvoked(aObject, aActionName) {}, // jshint ignore:line
 
@@ -61,17 +62,17 @@ Presenter.prototype = {
    */
   textChanged: function textChanged(aIsInserted, aStartOffset, aLength, aText, // jshint ignore:line
                                     aModifiedText) {}, // jshint ignore:line
 
   /**
    * Text selection has changed. TODO.
    */
   textSelectionChanged: function textSelectionChanged(
-    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser) {}, // jshint ignore:line
+    aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput) {}, // jshint ignore:line
 
   /**
    * Selection has changed. TODO.
    * @param {nsIAccessible} aObject the object that has been selected.
    */
   selectionChanged: function selectionChanged(aObject) {}, // jshint ignore:line
 
   /**
@@ -357,37 +358,37 @@ AndroidPresenter.prototype.textChanged =
         aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
     }
 
     return {type: this.type, details: [eventDetails]};
   };
 
 AndroidPresenter.prototype.textSelectionChanged =
   function AndroidPresenter_textSelectionChanged(aText, aStart, aEnd, aOldStart,
-                                                 aOldEnd, aIsFromUser) {
+                                                 aOldEnd, aIsFromUserInput) {
     let androidEvents = [];
 
-    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUser) {
+    if (Utils.AndroidSdkVersion >= 14 && !aIsFromUserInput) {
       if (!this._braillePresenter) {
         this._braillePresenter = new BraillePresenter();
       }
       let brailleOutput = this._braillePresenter.textSelectionChanged(
-        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser).details;
+        aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUserInput).details;
 
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
         text: [aText],
         fromIndex: aStart,
         toIndex: aEnd,
         itemCount: aText.length,
         brailleOutput: brailleOutput
       });
     }
 
-    if (Utils.AndroidSdkVersion >= 16 && aIsFromUser) {
+    if (Utils.AndroidSdkVersion >= 16 && aIsFromUserInput) {
       let [from, to] = aOldStart < aStart ?
         [aOldStart, aStart] : [aStart, aOldStart];
       androidEvents.push({
         eventType: this.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
         text: [aText],
         fromIndex: from,
         toIndex: to
       });
@@ -464,30 +465,31 @@ B2GPresenter.prototype.PIVOT_CHANGE_HAPT
 /**
  * Pivot move reasons.
  * @type {Array}
  */
 B2GPresenter.prototype.pivotChangedReasons = ['none', 'next', 'prev', 'first',
                                               'last', 'text', 'point'];
 
 B2GPresenter.prototype.pivotChanged =
-  function B2GPresenter_pivotChanged(aContext, aReason) {
+  function B2GPresenter_pivotChanged(aContext, aReason, aIsUserInput) {
     if (!aContext.accessible) {
       return null;
     }
 
     return {
       type: this.type,
       details: {
         eventType: 'vc-change',
         data: UtteranceGenerator.genForContext(aContext),
         options: {
           pattern: this.PIVOT_CHANGE_HAPTIC_PATTERN,
           isKey: aContext.accessible.role === Roles.KEY,
-          reason: this.pivotChangedReasons[aReason]
+          reason: this.pivotChangedReasons[aReason],
+          isUserInput: aIsUserInput
         }
       }
     };
   };
 
 B2GPresenter.prototype.valueChanged =
   function B2GPresenter_valueChanged(aAccessible) {
     return {
@@ -579,39 +581,40 @@ this.Presentation = { // jshint ignore:l
       'b2g': [VisualPresenter, B2GPresenter],
       'browser': [VisualPresenter, B2GPresenter, AndroidPresenter]
     };
     this.presenters = [new P() for (P of presenterMap[Utils.MozBuildApp])]; // jshint ignore:line
     return this.presenters;
   },
 
   pivotChanged: function Presentation_pivotChanged(
-    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset) {
+    aPosition, aOldPosition, aReason, aStartOffset, aEndOffset, aIsUserInput) {
     let context = new PivotContext(
       aPosition, aOldPosition, aStartOffset, aEndOffset);
-    return [p.pivotChanged(context, aReason) for each (p in this.presenters)]; // jshint ignore:line
+    return [p.pivotChanged(context, aReason, aIsUserInput)
+      for each (p in this.presenters)]; // jshint ignore:line
   },
 
   actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
     return [p.actionInvoked(aObject, aActionName) // jshint ignore:line
       for each (p in this.presenters)]; // jshint ignore:line
   },
 
   textChanged: function Presentation_textChanged(aIsInserted, aStartOffset,
                                     aLength, aText,
                                     aModifiedText) {
     return [p.textChanged(aIsInserted, aStartOffset, aLength, aText, // jshint ignore:line
       aModifiedText) for each (p in this.presenters)]; // jshint ignore:line
   },
 
   textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
                                                       aOldStart, aOldEnd,
-                                                      aIsFromUser) {
+                                                      aIsFromUserInput) {
     return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
-      aIsFromUser) for each (p in this.presenters)]; // jshint ignore:line
+      aIsFromUserInput) for each (p in this.presenters)]; // jshint ignore:line
   },
 
   valueChanged: function valueChanged(aAccessible) {
     return [ p.valueChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
   },
 
   tabStateChanged: function Presentation_tabStateChanged(aDocObj, aPageState) {
     return [p.tabStateChanged(aDocObj, aPageState) // jshint ignore:line
--- a/accessible/tests/mochitest/tree/test_table.html
+++ b/accessible/tests/mochitest/tree/test_table.html
@@ -157,16 +157,28 @@
               { CELL: [
                 { TEXT_LEAF: [ ] }
               ] }
             ] }
           ] } ]
         };
       testAccessibleTree("table5", accTree);
 
+      /////////////////////////////////////////////////////////////////////////
+      // log table
+      accTree =
+        { TABLE: [
+          { ROW: [
+            { CELL: [
+              { TEXT_LEAF: [ ] }
+            ] }
+          ] }
+        ] };
+      testAccessibleTree("logtable", accTree);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
@@ -259,10 +271,12 @@
 
   <table id="table5">
     <tbody style="display:block;overflow:auto;">
       <tr>
         <td>bla</td>
       </tr>
     </tbody>
   </table>
+
+  <table id="logtable" role="log"><tr><td>blah</td></tr></table>
 </body>
 </html>
--- a/accessible/windows/msaa/nsWinUtils.cpp
+++ b/accessible/windows/msaa/nsWinUtils.cpp
@@ -11,16 +11,17 @@
 #include "DocAccessible.h"
 #include "nsCoreUtils.h"
 
 #include "mozilla/Preferences.h"
 #include "nsArrayUtils.h"
 #include "nsIArray.h"
 #include "nsIDocument.h"
 #include "nsIDocShellTreeItem.h"
+#include "nsIDOMElement.h"
 #include "nsXULAppAPI.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 // Window property used by ipc related code in identifying accessible
 // tab windows.
 const wchar_t* kPropNameTabContent = L"AccessibleTabWindow";
--- a/accessible/windows/sdn/sdnAccessible.cpp
+++ b/accessible/windows/sdn/sdnAccessible.cpp
@@ -12,16 +12,17 @@
 #include "nsAttrName.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleTypes.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsNameSpaceManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsWinUtils.h"
+#include "nsRange.h"
 
 #include "nsAutoPtr.h"
 
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
--- a/accessible/windows/sdn/sdnTextAccessible.cpp
+++ b/accessible/windows/sdn/sdnTextAccessible.cpp
@@ -10,16 +10,17 @@
 
 #include "nsCoreUtils.h"
 #include "DocAccessible.h"
 
 #include "nsIFrame.h"
 #include "nsFontMetrics.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
+#include "nsRange.h"
 #include "gfxFont.h"
 #include "nsIAccessibleTypes.h"
 #include "mozilla/gfx/2D.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // sdnTextAccessible
--- a/accessible/xpcom/xpcAccessibleTextRange.cpp
+++ b/accessible/xpcom/xpcAccessibleTextRange.cpp
@@ -3,18 +3,18 @@
 /* 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 "xpcAccessibleTextRange.h"
 
 #include "HyperTextAccessible.h"
 #include "TextRange.h"
-
- #include "nsIMutableArray.h"
+#include "nsIMutableArray.h"
+#include "nsComponentManagerUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 // nsISupports and cycle collection
 
 NS_IMPL_CYCLE_COLLECTION(xpcAccessibleTextRange,
                          mRange.mRoot,
--- a/build/sanitizers/lsan_suppressions.txt
+++ b/build/sanitizers/lsan_suppressions.txt
@@ -54,19 +54,16 @@ leak:nsSocketTransport::BuildSocket
 leak:nsServerSocket::OnSocketReady
 
 # Bug 1021350 - Small leak under event_base_once. m1, m4, bc3
 leak:event_base_once
 
 # Bug 1021854 - nsFileStreamBase::DoOpen() leaking fds. bc1, oth
 leak:nsLocalFile::OpenNSPRFileDesc
 
-# Bug 1023585 - Leak of array buffer in JSStructuredCloneWriter::transferOwnership(). m1
-leak:AllocateArrayBufferContents
-
 # Bug 1022010 - Small leak under _render_glyph_outline. bc1
 leak:_render_glyph_outline
 
 # Bug 1023548 - Small leak under SECITEM_AllocItem_Util. bc1, bc3
 leak:SECITEM_AllocItem_Util
 
 # This is a one-time leak, so it is probably okay to ignore. bc1, oth
 leak:GlobalPrinters::InitializeGlobalPrinters
--- a/config/external/nss/nss.def
+++ b/config/external/nss/nss.def
@@ -642,16 +642,17 @@ SSL_GetSRTPCipher
 SSL_HandshakeCallback
 SSL_HandshakeNegotiatedExtension
 SSL_ImplementedCiphers DATA
 SSL_ImportFD
 SSL_NumImplementedCiphers DATA
 SSL_OptionSet
 SSL_OptionSetDefault
 SSL_PeerCertificate
+SSL_PeerCertificateChain
 SSL_PeerStapledOCSPResponses
 SSL_ResetHandshake
 SSL_SetCanFalseStartCallback
 SSL_SetNextProtoNego
 SSL_SetPKCS11PinArg
 SSL_SetSockPeerID
 SSL_SetSRTPCiphers
 SSL_SetStapledOCSPResponses
--- a/configure.in
+++ b/configure.in
@@ -8335,20 +8335,16 @@ dnl ====================================
 if test "$MOZ_DEBUG" -o "$NS_TRACE_MALLOC" -o "$MOZ_DMD"; then
     MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS=
 fi
 
 if test "$MOZ_APP_COMPONENT_INCLUDE"; then
   AC_DEFINE_UNQUOTED(MOZ_APP_COMPONENT_INCLUDE, "$MOZ_APP_COMPONENT_INCLUDE")
 fi
 
-if test "$MOZ_APP_COMPONENT_MODULES"; then
-  AC_DEFINE_UNQUOTED(MOZ_APP_COMPONENT_MODULES, $MOZ_APP_COMPONENT_MODULES)
-fi
-
 dnl ========================================================
 dnl =
 dnl = Maintainer debug option (no --enable equivalent)
 dnl =
 dnl ========================================================
 
 AC_SUBST(AR)
 AC_SUBST(AR_FLAGS)
@@ -8732,17 +8728,16 @@ AC_SUBST(OBJ_SUFFIX)
 AC_SUBST(BIN_SUFFIX)
 AC_SUBST(ASM_SUFFIX)
 AC_SUBST(IMPORT_LIB_SUFFIX)
 AC_SUBST(USE_N32)
 AC_SUBST(CC_VERSION)
 AC_SUBST(CXX_VERSION)
 AC_SUBST(MSMANIFEST_TOOL)
 AC_SUBST(NS_ENABLE_TSF)
-AC_SUBST_LIST(MOZ_APP_EXTRA_LIBS)
 
 AC_SUBST(MOZ_WAVE)
 AC_SUBST(MOZ_VORBIS)
 AC_SUBST(MOZ_TREMOR)
 AC_SUBST(MOZ_OPUS)
 AC_SUBST(MOZ_WEBM)
 AC_SUBST(MOZ_WMF)
 AC_SUBST(MOZ_FFMPEG)
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -7,16 +7,17 @@
  * A base class implementing nsIObjectLoadingContent for use by
  * various content nodes that want to provide plugin/document/image
  * loading functionality (eg <embed>, <object>, <applet>, etc).
  */
 
 // Interface headers
 #include "imgLoader.h"
 #include "nsIContent.h"
+#include "nsIContentInlines.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
 #include "nsIDOMCustomEvent.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIExternalProtocolHandler.h"
 #include "nsIObjectFrame.h"
@@ -77,16 +78,17 @@
 #include "mozilla/BasicEvents.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Telemetry.h"
+#include "mozilla/dom/HTMLObjectElementBinding.h"
 
 #ifdef XP_WIN
 // Thanks so much, Microsoft! :(
 #ifdef CreateEvent
 #undef CreateEvent
 #endif
 #endif // XP_WIN
 
@@ -911,16 +913,177 @@ nsObjectLoadingContent::InstantiatePlugi
                             doc,
                             NS_LITERAL_STRING("PluginInstantiated"));
   NS_DispatchToCurrentThread(ev);
 
   return NS_OK;
 }
 
 void
+nsObjectLoadingContent::GetPluginAttributes(nsTArray<MozPluginParameter>& aAttributes)
+{
+  aAttributes = mCachedAttributes;
+}
+
+void
+nsObjectLoadingContent::GetPluginParameters(nsTArray<MozPluginParameter>& aParameters)
+{
+  aParameters = mCachedParameters;
+}
+
+void
+nsObjectLoadingContent::GetNestedParams(nsTArray<MozPluginParameter>& aParams,
+                                        bool aIgnoreCodebase)
+{
+  nsCOMPtr<nsIDOMElement> domElement =
+    do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
+
+  nsCOMPtr<nsIDOMHTMLCollection> allParams;
+  NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml");
+  domElement->GetElementsByTagNameNS(xhtml_ns,
+        NS_LITERAL_STRING("param"), getter_AddRefs(allParams));
+
+  if (!allParams)
+    return;
+
+  uint32_t numAllParams;
+  allParams->GetLength(&numAllParams);
+  for (uint32_t i = 0; i < numAllParams; i++) {
+    nsCOMPtr<nsIDOMNode> pNode;
+    allParams->Item(i, getter_AddRefs(pNode));
+    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(pNode);
+
+    if (!element)
+      continue;
+
+    nsAutoString name;
+    element->GetAttribute(NS_LITERAL_STRING("name"), name);
+
+    if (name.IsEmpty())
+      continue;
+
+    nsCOMPtr<nsIDOMNode> parent;
+    nsCOMPtr<nsIDOMHTMLObjectElement> domObject;
+    nsCOMPtr<nsIDOMHTMLAppletElement> domApplet;
+    pNode->GetParentNode(getter_AddRefs(parent));
+    while (!(domObject || domApplet) && parent) {
+      domObject = do_QueryInterface(parent);
+      domApplet = do_QueryInterface(parent);
+      nsCOMPtr<nsIDOMNode> temp;
+      parent->GetParentNode(getter_AddRefs(temp));
+      parent = temp;
+    }
+
+    if (domApplet) {
+      parent = do_QueryInterface(domApplet);
+    } else if (domObject) {
+      parent = do_QueryInterface(domObject);
+    } else {
+      continue;
+    }
+
+    nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(domElement);
+    if (parent == domNode) {
+      MozPluginParameter param;
+      element->GetAttribute(NS_LITERAL_STRING("name"), param.mName);
+      element->GetAttribute(NS_LITERAL_STRING("value"), param.mValue);
+
+      param.mName.Trim(" \n\r\t\b", true, true, false);
+      param.mValue.Trim(" \n\r\t\b", true, true, false);
+
+      // ignore codebase param if it was already added in the attributes array.
+      if (aIgnoreCodebase && param.mName.EqualsIgnoreCase("codebase")) {
+        continue;
+      }
+
+      aParams.AppendElement(param);
+    }
+  }
+}
+
+void
+nsObjectLoadingContent::BuildParametersArray()
+{
+  if (mCachedAttributes.Length() || mCachedParameters.Length()) {
+    MOZ_ASSERT(false, "Parameters array should be empty.");
+    return;
+  }
+
+  nsCOMPtr<nsIContent> content =
+    do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
+
+  int32_t start = 0, end = content->GetAttrCount(), step = 1;
+  // HTML attributes are stored in reverse order.
+  if (content->IsHTML() && content->IsInHTMLDocument()) {
+    start = end - 1;
+    end = -1;
+    step = -1;
+  }
+
+  for (int32_t i = start; i != end; i += step) {
+    MozPluginParameter param;
+    const nsAttrName* attrName = content->GetAttrNameAt(i);
+    nsIAtom* atom = attrName->LocalName();
+    content->GetAttr(attrName->NamespaceID(), atom, param.mValue);
+    atom->ToString(param.mName);
+    mCachedAttributes.AppendElement(param);
+  }
+
+  bool isJava = nsPluginHost::IsJavaMIMEType(mContentType.get());
+
+  nsCString codebase;
+  if (isJava) {
+      mBaseURI->GetSpec(codebase);
+  }
+
+  nsAdoptingCString wmodeOverride = Preferences::GetCString("plugins.force.wmode");
+
+  for (uint32_t i = 0; i < mCachedAttributes.Length(); i++) {
+    if (!wmodeOverride.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("wmode")) {
+      CopyASCIItoUTF16(wmodeOverride, mCachedAttributes[i].mValue);
+      wmodeOverride.Truncate();
+    } else if (!codebase.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("codebase")) {
+      CopyASCIItoUTF16(codebase, mCachedAttributes[i].mValue);
+      codebase.Truncate();
+    }
+  }
+
+  if (!wmodeOverride.IsEmpty()) {
+    MozPluginParameter param;
+    param.mName = NS_LITERAL_STRING("wmode");
+    CopyASCIItoUTF16(wmodeOverride, param.mValue);
+    mCachedAttributes.AppendElement(param);
+  }
+
+  if (!codebase.IsEmpty()) {
+    MozPluginParameter param;
+    param.mName = NS_LITERAL_STRING("codebase");
+    CopyASCIItoUTF16(codebase, param.mValue);
+    mCachedAttributes.AppendElement(param);
+  }
+
+  // Some plugins were never written to understand the "data" attribute of the OBJECT tag.
+  // Real and WMP will not play unless they find a "src" attribute, see bug 152334.
+  // Nav 4.x would simply replace the "data" with "src". Because some plugins correctly
+  // look for "data", lets instead copy the "data" attribute and add another entry
+  // to the bottom of the array if there isn't already a "src" specified.
+  if (content->Tag() == nsGkAtoms::object &&
+      !content->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) {
+    MozPluginParameter param;
+    content->GetAttr(kNameSpaceID_None, nsGkAtoms::data, param.mValue);
+    if (!param.mValue.IsEmpty()) {
+      param.mName = NS_LITERAL_STRING("SRC");
+      mCachedAttributes.AppendElement(param);
+    }
+  }
+
+  GetNestedParams(mCachedParameters, isJava);
+}
+
+void
 nsObjectLoadingContent::NotifyOwnerDocumentActivityChanged()
 {
   // XXX(johns): We cannot touch plugins or run arbitrary script from this call,
   //             as nsDocument is in a non-reentrant state.
 
   // If we have a plugin we want to queue an event to stop it unless we are
   // moved into an active document before returning to the event loop.
   if (mInstanceOwner || mInstantiating) {
@@ -1497,69 +1660,25 @@ nsObjectLoadingContent::UpdateObjectPara
   nsAutoString codebaseStr;
   nsCOMPtr<nsIURI> docBaseURI = thisContent->GetBaseURI();
   bool hasCodebase = thisContent->HasAttr(kNameSpaceID_None, nsGkAtoms::codebase);
   if (hasCodebase)
     thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::codebase, codebaseStr);
 
 
   // Java wants the codebase attribute even if it occurs in <param> tags
-  // XXX(johns): This duplicates a chunk of code from nsInstanceOwner, see
-  //             bug 853995
   if (isJava) {
     // Find all <param> tags that are nested beneath us, but not beneath another
     // object/applet tag.
-    nsCOMArray<nsIDOMElement> ourParams;
-    nsCOMPtr<nsIDOMElement> mydomElement = do_QueryInterface(thisContent);
-
-    nsCOMPtr<nsIDOMHTMLCollection> allParams;
-    NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml");
-    mydomElement->GetElementsByTagNameNS(xhtml_ns, NS_LITERAL_STRING("param"),
-                                         getter_AddRefs(allParams));
-    if (allParams) {
-      uint32_t numAllParams;
-      allParams->GetLength(&numAllParams);
-      for (uint32_t i = 0; i < numAllParams; i++) {
-        nsCOMPtr<nsIDOMNode> pnode;
-        allParams->Item(i, getter_AddRefs(pnode));
-        nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(pnode);
-        if (domelement) {
-          nsAutoString name;
-          domelement->GetAttribute(NS_LITERAL_STRING("name"), name);
-          name.Trim(" \n\r\t\b", true, true, false);
-          if (name.EqualsIgnoreCase("codebase")) {
-            // Find the first plugin element parent
-            nsCOMPtr<nsIDOMNode> parent;
-            nsCOMPtr<nsIDOMHTMLObjectElement> domobject;
-            nsCOMPtr<nsIDOMHTMLAppletElement> domapplet;
-            pnode->GetParentNode(getter_AddRefs(parent));
-            while (!(domobject || domapplet) && parent) {
-              domobject = do_QueryInterface(parent);
-              domapplet = do_QueryInterface(parent);
-              nsCOMPtr<nsIDOMNode> temp;
-              parent->GetParentNode(getter_AddRefs(temp));
-              parent = temp;
-            }
-            if (domapplet || domobject) {
-              if (domapplet) {
-                parent = do_QueryInterface(domapplet);
-              }
-              else {
-                parent = do_QueryInterface(domobject);
-              }
-              nsCOMPtr<nsIDOMNode> mydomNode = do_QueryInterface(mydomElement);
-              if (parent == mydomNode) {
-                hasCodebase = true;
-                domelement->GetAttribute(NS_LITERAL_STRING("value"),
-                                         codebaseStr);
-                codebaseStr.Trim(" \n\r\t\b", true, true, false);
-              }
-            }
-          }
-        }
+    nsTArray<MozPluginParameter> params;
+    GetNestedParams(params, false);
+    for (uint32_t i = 0; i < params.Length(); i++) {
+      if (params[i].mName.EqualsIgnoreCase("codebase")) {
+        hasCodebase = true;
+        codebaseStr = params[i].mValue;
       }
     }
   }
 
   if (isJava && hasCodebase && codebaseStr.IsEmpty()) {
     // Java treats codebase="" as "/"
     codebaseStr.Assign('/');
     // XXX(johns): This doesn't cover the case of "https:" which java would
@@ -2116,16 +2235,22 @@ nsObjectLoadingContent::LoadObject(bool 
     rv = NS_ERROR_UNEXPECTED;
     return NS_OK;
   }
 
   ///
   /// Attempt to load new type
   ///
 
+
+  // Cache the current attributes and parameters.
+  if (mType == eType_Plugin || mType == eType_Null) {
+    BuildParametersArray();
+  }
+
   // We don't set mFinalListener until OnStartRequest has been called, to
   // prevent re-entry ugliness with CloseChannel()
   nsCOMPtr<nsIStreamListener> finalListener;
   // If we decide to synchronously spawn a plugin, we do it after firing
   // notifications to avoid re-entry causing notifications to fire out of order.
   bool doSpawnPlugin = false;
   switch (mType) {
     case eType_Image:
@@ -2472,16 +2597,19 @@ nsObjectLoadingContent::UnloadObject(boo
   if (mIsStopping) {
     // The protochain is normally thrown out after a plugin stops, but if we
     // re-enter while stopping a plugin and try to load something new, we need
     // to throw away the old protochain in the nested unload.
     TeardownProtoChain();
     mIsStopping = false;
   }
 
+  mCachedAttributes.Clear();
+  mCachedParameters.Clear();
+
   // This call should be last as it may re-enter
   StopPluginInstance();
 }
 
 void
 nsObjectLoadingContent::NotifyStateChanged(ObjectType aOldType,
                                            EventStates aOldState,
                                            bool aSync,
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -29,16 +29,17 @@ class AutoSetInstantiatingToFalse;
 class nsObjectFrame;
 class nsFrameLoader;
 class nsXULElement;
 class nsPluginInstanceOwner;
 
 namespace mozilla {
 namespace dom {
 template<typename T> class Sequence;
+struct MozPluginParameter;
 }
 }
 
 class nsObjectLoadingContent : public nsImageLoadingContent
                              , public nsIStreamListener
                              , public nsIFrameLoaderOwner
                              , public nsIObjectLoadingContent
                              , public nsIChannelEventSink
@@ -115,16 +116,29 @@ class nsObjectLoadingContent : public ns
     ObjectType Type() const { return mType; }
 
     void SetIsNetworkCreated(bool aNetworkCreated)
     {
       mNetworkCreated = aNetworkCreated;
     }
 
     /**
+     * When the object is loaded, the attributes and all nested <param>
+     * elements are cached as name:value string pairs to be passed as
+     * parameters when instantiating the plugin.
+     *
+     * Note: these cached values can be overriden for different quirk cases.
+     */
+    // Returns the cached attributes array.
+    void GetPluginAttributes(nsTArray<mozilla::dom::MozPluginParameter>& aAttributes);
+
+    // Returns the cached <param> array.
+    void GetPluginParameters(nsTArray<mozilla::dom::MozPluginParameter>& aParameters);
+
+    /**
      * Immediately instantiate a plugin instance. This is a no-op if mType !=
      * eType_Plugin or a plugin is already running.
      *
      * aIsLoading indicates that we are in the loading code, and we can bypass
      * the mIsLoading check.
      */
     nsresult InstantiatePluginInstance(bool aIsLoading = false);
 
@@ -318,16 +332,36 @@ class nsObjectLoadingContent : public ns
       // necessarily happen when changing between object types. E.g., if a PDF
       // handler was installed between the last load of this object and now, we
       // might change from eType_Document -> eType_Plugin without changing
       // ContentType
       eParamContentTypeChanged = 1u << 2
     };
 
     /**
+     * Getter for child <param> elements that are not nested in another plugin
+     * dom element.
+     * This is an internal helper function and should not be used directly for
+     * passing parameters to the plugin instance.
+     *
+     * See GetPluginParameters and GetPluginAttributes, which also handle
+     * quirk-overrides.
+     *
+     * @param aParameters     The array containing pairs of name/value strings
+     *                        from nested <param> objects.
+     * @param aIgnoreCodebase Flag for ignoring the "codebase" param when
+     *                        building the array. This is useful when loading
+     *                        java.
+     */
+    void GetNestedParams(nsTArray<mozilla::dom::MozPluginParameter>& aParameters,
+                         bool aIgnoreCodebase);
+
+    void BuildParametersArray();
+
+    /**
      * Loads fallback content with the specified FallbackType
      *
      * @param aType   FallbackType value for type of fallback we're loading
      * @param aNotify Send notifications and events. If false, caller is
      *                responsible for doing so
      */
     void LoadFallback(FallbackType aType, bool aNotify);
 
@@ -574,11 +608,13 @@ class nsObjectLoadingContent : public ns
 
     // For plugin stand-in types (click-to-play, play preview, ...) tracks
     // whether content js has tried to access the plugin script object.
     bool                        mScriptRequested : 1;
 
     nsWeakFrame                 mPrintFrame;
 
     nsRefPtr<nsPluginInstanceOwner> mInstanceOwner;
+    nsTArray<mozilla::dom::MozPluginParameter> mCachedAttributes;
+    nsTArray<mozilla::dom::MozPluginParameter> mCachedParameters;
 };
 
 #endif
--- a/content/html/content/src/nsTextEditorState.cpp
+++ b/content/html/content/src/nsTextEditorState.cpp
@@ -40,16 +40,17 @@
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsTextNode.h"
 #include "nsIController.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/HTMLInputElement.h"
 #include "nsNumberControlFrame.h"
+#include "nsFrameSelection.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kTextEditorCID, NS_TEXTEDITOR_CID);
 
 class MOZ_STACK_CLASS ValueSetter
 {
@@ -412,20 +413,18 @@ nsTextInputSelectionImpl::GetCaretVisibl
 {
   if (!mPresShellWeak) return NS_ERROR_NOT_INITIALIZED;
   nsresult result;
   nsCOMPtr<nsIPresShell> shell = do_QueryReferent(mPresShellWeak, &result);
   if (shell)
   {
     nsRefPtr<nsCaret> caret = shell->GetCaret();
     if (caret) {
-      nsISelection* domSel = mFrameSelection->
-        GetSelection(nsISelectionController::SELECTION_NORMAL);
-      if (domSel)
-        return caret->GetCaretVisible(_retval);
+      *_retval = caret->IsVisible();
+      return NS_OK;
     }
   }
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsTextInputSelectionImpl::SetCaretVisibilityDuringSelection(bool aVisibility)
 {
@@ -541,32 +540,32 @@ nsTextInputSelectionImpl::CompleteMove(b
 {
   // grab the parent / root DIV for this text widget
   nsIContent* parentDIV = mFrameSelection->GetLimiter();
   if (!parentDIV)
     return NS_ERROR_UNEXPECTED;
 
   // make the caret be either at the very beginning (0) or the very end
   int32_t offset = 0;
-  nsFrameSelection::HINT hint = nsFrameSelection::HINTLEFT;
+  CaretAssociationHint hint = CARET_ASSOCIATE_BEFORE;
   if (aForward)
   {
     offset = parentDIV->GetChildCount();
 
     // Prevent the caret from being placed after the last
     // BR node in the content tree!
 
     if (offset > 0)
     {
       nsIContent *child = parentDIV->GetLastChild();
 
       if (child->Tag() == nsGkAtoms::br)
       {
         --offset;
-        hint = nsFrameSelection::HINTRIGHT; // for Bug 106855
+        hint = CARET_ASSOCIATE_AFTER; // for Bug 106855
       }
     }
   }
 
   mFrameSelection->HandleClick(parentDIV, offset, offset, aExtend,
                                false, hint);
 
   // if we got this far, attempt to scroll no matter what the above result is
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -191,16 +191,28 @@ DOMMediaStream::GetVideoTracks(nsTArray<
   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
     VideoStreamTrack* t = mTracks[i]->AsVideoStreamTrack();
     if (t) {
       aTracks.AppendElement(t);
     }
   }
 }
 
+void
+DOMMediaStream::GetTracks(nsTArray<nsRefPtr<MediaStreamTrack> >& aTracks)
+{
+  aTracks.AppendElements(mTracks);
+}
+
+bool
+DOMMediaStream::HasTrack(const MediaStreamTrack& aTrack) const
+{
+  return mTracks.Contains(&aTrack);
+}
+
 bool
 DOMMediaStream::IsFinished()
 {
   return !mStream || mStream->IsFinished();
 }
 
 void
 DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -76,16 +76,18 @@ public:
   }
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   // WebIDL
   double CurrentTime();
 
   void GetAudioTracks(nsTArray<nsRefPtr<AudioStreamTrack> >& aTracks);
   void GetVideoTracks(nsTArray<nsRefPtr<VideoStreamTrack> >& aTracks);
+  void GetTracks(nsTArray<nsRefPtr<MediaStreamTrack> >& aTracks);
+  bool HasTrack(const MediaStreamTrack& aTrack) const;
 
   MediaStream* GetStream() const { return mStream; }
 
   /**
    * Overridden in DOMLocalMediaStreams to allow getUserMedia to pass
    * data directly to RTCPeerConnection without going through graph queuing.
    * Returns a bool to let us know if direct data will be delivered.
    */
--- a/content/media/fmp4/apple/AppleVTDecoder.cpp
+++ b/content/media/fmp4/apple/AppleVTDecoder.cpp
@@ -293,16 +293,22 @@ AppleVTDecoder::OutputFrame(CVPixelBuffe
                       aFrameRef->duration,
                       buffer,
                       aFrameRef->is_sync_point,
                       aFrameRef->timestamp,
                       visible);
   // Unlock the returned image data.
   CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly);
 
+  if (!data) {
+    NS_ERROR("Couldn't create VideoData for frame");
+    mCallback->Error();
+    return NS_ERROR_FAILURE;
+  }
+
   // Frames come out in DTS order but we need to output them
   // in composition order.
   mReorderQueue.Push(data.forget());
   if (mReorderQueue.Length() > 2) {
     VideoData* readyData = mReorderQueue.Pop();
     mCallback->Output(readyData);
   }
 
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -2140,18 +2140,17 @@ nsFocusManager::SetCaretVisible(nsIPresS
 {
   // When browsing with caret, make sure caret is visible after new focus
   // Return early if there is no caret. This can happen for the testcase
   // for bug 308025 where a window is closed in a blur handler.
   nsRefPtr<nsCaret> caret = aPresShell->GetCaret();
   if (!caret)
     return NS_OK;
 
-  bool caretVisible = false;
-  caret->GetCaretVisible(&caretVisible);
+  bool caretVisible = caret->IsVisible();
   if (!aVisible && !caretVisible)
     return NS_OK;
 
   nsRefPtr<nsFrameSelection> frameSelection;
   if (aContent) {
     NS_ASSERTION(aContent->GetComposedDoc() == aPresShell->GetDocument(),
                  "Wrong document?");
     nsIFrame *focusFrame = aContent->GetPrimaryFrame();
@@ -2171,17 +2170,17 @@ nsFocusManager::SetCaretVisible(nsIPresS
         return NS_ERROR_FAILURE;
       }
       // First, hide the caret to prevent attempting to show it in SetCaretDOMSelection
       selCon->SetCaretEnabled(false);
 
       // Caret must blink on non-editable elements
       caret->SetIgnoreUserModify(true);
       // Tell the caret which selection to use
-      caret->SetCaretDOMSelection(domSelection);
+      caret->SetSelection(domSelection);
 
       // In content, we need to set the caret. The only special case is edit
       // fields, which have a different frame selection from the document.
       // They will take care of making the caret visible themselves.
 
       selCon->SetCaretReadOnly(false);
       selCon->SetCaretEnabled(aVisible);
     }
@@ -2290,19 +2289,18 @@ nsFocusManager::GetSelectionLocation(nsI
             if (nullptr == newCaretFrame)
               break;
             newCaretContent = newCaretFrame->GetContent();
           } while (!newCaretContent || newCaretContent == startContent);
 
           if (newCaretFrame && newCaretContent) {
             // If the caret is exactly at the same position of the new frame,
             // then we can use the newCaretFrame and newCaretContent for our position
-            nsRefPtr<nsCaret> caret = aPresShell->GetCaret();
             nsRect caretRect;
-            nsIFrame *frame = caret->GetGeometry(domSelection, &caretRect);
+            nsIFrame *frame = nsCaret::GetGeometry(domSelection, &caretRect);
             if (frame) {
               nsPoint caretWidgetOffset;
               nsIWidget *widget = frame->GetNearestWidget(caretWidgetOffset);
               caretRect.MoveBy(caretWidgetOffset);
               nsPoint newCaretOffset;
               nsIWidget *newCaretWidget = newCaretFrame->GetNearestWidget(newCaretOffset);
               if (widget == newCaretWidget && caretRect.y == newCaretOffset.y &&
                   caretRect.x == newCaretOffset.x) {
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -34,16 +34,18 @@
 #include "nsIPermissionManager.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptTimeoutHandler.h"
 #include "nsIController.h"
 #include "nsScriptNameSpaceManager.h"
 #include "nsISlowScriptDebug.h"
 #include "nsWindowMemoryReporter.h"
 #include "WindowNamedPropertiesHandler.h"
+#include "nsFrameSelection.h"
+#include "nsISelectionListener.h"
 
 // Helper Classes
 #include "nsJSUtils.h"
 #include "jsapi.h"              // for JSAutoRequest
 #include "js/OldDebugAPI.h"     // for JS_ClearWatchPointsForObject
 #include "jswrapper.h"
 #include "nsReadableUtils.h"
 #include "nsDOMClassInfo.h"
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -113,21 +113,18 @@ ContentEventHandler::Init(WidgetQueryCon
 
   aEvent->mReply.mContentsRoot = mRootContent.get();
 
   bool isCollapsed;
   rv = mSelection->GetIsCollapsed(&isCollapsed);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_NOT_AVAILABLE);
   aEvent->mReply.mHasSelection = !isCollapsed;
 
-  nsRefPtr<nsCaret> caret = mPresShell->GetCaret();
-  NS_ASSERTION(caret, "GetCaret returned null");
-
   nsRect r;
-  nsIFrame* frame = caret->GetGeometry(mSelection, &r);
+  nsIFrame* frame = nsCaret::GetGeometry(mSelection, &r);
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   aEvent->mReply.mFocusedWidget = frame->GetNearestWidget();
 
   return NS_OK;
 }
 
 nsresult
@@ -438,18 +435,18 @@ ContentEventHandler::ExpandToClusterBoun
     return NS_OK;
   }
 
   NS_ASSERTION(*aXPOffset <= aContent->TextLength(),
                "offset is out of range.");
 
   nsRefPtr<nsFrameSelection> fs = mPresShell->FrameSelection();
   int32_t offsetInFrame;
-  nsFrameSelection::HINT hint =
-    aForward ? nsFrameSelection::HINTLEFT : nsFrameSelection::HINTRIGHT;
+  CaretAssociationHint hint =
+    aForward ? CARET_ASSOCIATE_BEFORE : CARET_ASSOCIATE_AFTER;
   nsIFrame* frame = fs->GetFrameForNodeOffset(aContent, int32_t(*aXPOffset),
                                               hint, &offsetInFrame);
   if (!frame) {
     // This content doesn't have any frames, we only can check surrogate pair...
     const nsTextFragment* text = aContent->GetText();
     NS_ENSURE_TRUE(text, NS_ERROR_FAILURE);
     if (NS_IS_LOW_SURROGATE(text->CharAt(*aXPOffset)) &&
         NS_IS_HIGH_SURROGATE(text->CharAt(*aXPOffset - 1))) {
@@ -838,40 +835,38 @@ ContentEventHandler::OnQueryCaretRect(Wi
 {
   nsresult rv = Init(aEvent);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   LineBreakType lineBreakType = GetLineBreakType(aEvent);
 
-  nsRefPtr<nsCaret> caret = mPresShell->GetCaret();
-  NS_ASSERTION(caret, "GetCaret returned null");
-
   // When the selection is collapsed and the queried offset is current caret
   // position, we should return the "real" caret rect.
   bool selectionIsCollapsed;
   rv = mSelection->GetIsCollapsed(&selectionIsCollapsed);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsRect caretRect;
+  nsIFrame* caretFrame = nsCaret::GetGeometry(mSelection, &caretRect);
+
   if (selectionIsCollapsed) {
     uint32_t offset;
     rv = GetFlatTextOffsetOfRange(mRootContent, mFirstSelectedRange, &offset,
                                   lineBreakType);
     NS_ENSURE_SUCCESS(rv, rv);
     if (offset == aEvent->mInput.mOffset) {
-      nsRect rect;
-      nsIFrame* caretFrame = caret->GetGeometry(mSelection, &rect);
       if (!caretFrame) {
         return NS_ERROR_FAILURE;
       }
-      rv = ConvertToRootViewRelativeOffset(caretFrame, rect);
+      rv = ConvertToRootViewRelativeOffset(caretFrame, caretRect);
       NS_ENSURE_SUCCESS(rv, rv);
       aEvent->mReply.mRect =
-        rect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel());
+        caretRect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel());
       aEvent->mReply.mOffset = aEvent->mInput.mOffset;
       aEvent->mSucceeded = true;
       return NS_OK;
     }
   }
 
   // Otherwise, we should set the guessed caret rect.
   nsRefPtr<nsRange> range = new nsRange(mRootContent);
@@ -887,17 +882,17 @@ ContentEventHandler::OnQueryCaretRect(Wi
 
   nsPoint posInFrame;
   rv = frame->GetPointFromOffset(range->StartOffset(), &posInFrame);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRect rect;
   rect.x = posInFrame.x;
   rect.y = posInFrame.y;
-  rect.width = caret->GetCaretRect().width;
+  rect.width = caretRect.width;
   rect.height = frame->GetSize().height;
 
   rv = ConvertToRootViewRelativeOffset(frame, rect);
   NS_ENSURE_SUCCESS(rv, rv);
 
   aEvent->mReply.mRect =
       rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel());
   aEvent->mSucceeded = true;
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -396,20 +396,16 @@ EventDispatcher::Dispatch(nsISupports* a
   PROFILER_LABEL("EventDispatcher", "Dispatch",
     js::ProfileEntry::Category::EVENTS);
 
   NS_ASSERTION(aEvent, "Trying to dispatch without WidgetEvent!");
   NS_ENSURE_TRUE(!aEvent->mFlags.mIsBeingDispatched,
                  NS_ERROR_DOM_INVALID_STATE_ERR);
   NS_ASSERTION(!aTargets || !aEvent->message, "Wrong parameters!");
 
-#ifdef NIGHTLY_BUILD
-  MOZ_RELEASE_ASSERT(!mozilla::ipc::ProcessingUrgentMessages());
-#endif
-
   // If we're dispatching an already created DOMEvent object, make
   // sure it is initialized!
   // If aTargets is non-null, the event isn't going to be dispatched.
   NS_ENSURE_TRUE(aEvent->message || !aDOMEvent || aTargets,
                  NS_ERROR_DOM_INVALID_STATE_ERR);
 
   nsCOMPtr<EventTarget> target = do_QueryInterface(aTarget);
 
--- a/dom/events/test/test_all_synthetic_events.html
+++ b/dom/events/test/test_all_synthetic_events.html
@@ -206,16 +206,20 @@ const kEventConstructors = {
   KeyboardEvent:                             { create: function (aName, aProps) {
                                                          return new KeyboardEvent(aName, aProps);
                                                        },
                                              },
   MediaStreamEvent:                          { create: function (aName, aProps) {
                                                          return new MediaStreamEvent(aName, aProps);
                                                        },
                                              },
+  MediaStreamTrackEvent:                     { create: function (aName, aProps) {
+                                                         return new MediaStreamTrackEvent(aName, aProps);
+                                                       },
+                                             },
   MessageEvent:                              { create: function (aName, aProps) {
                                                          var e = new MessageEvent("messageevent", { bubbles: aProps.bubbles,
                                                              cancelable: aProps.cancelable, data: aProps.data, origin: aProps.origin,
                                                              lastEventId: aProps.lastEventId, source: aProps.source });
                                                          return e;
                                                        },
                                              },
   MouseEvent:                                { create: function (aName, aProps) {
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -17,25 +17,29 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 const PC_CONTRACT = "@mozilla.org/dom/peerconnection;1";
 const PC_OBS_CONTRACT = "@mozilla.org/dom/peerconnectionobserver;1";
 const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
 const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
 const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
 const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
 const PC_IDENTITY_CONTRACT = "@mozilla.org/dom/rtcidentityassertion;1";
 const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
+const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
+const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
 
 const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
 const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
 const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
 const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
 const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
 const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
 const PC_IDENTITY_CID = Components.ID("{1abc7499-3c54-43e0-bd60-686e2703f072}");
 const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
+const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
+const PC_RECEIVER_CID = Components.ID("{d974b814-8fde-411c-8c45-b86791b81030}");
 
 // Global list of PeerConnection objects, so they can be cleaned up when
 // a page is torn down. (Maps inner window ID to an array of PC objects).
 function GlobalPCList() {
   this._list = {};
   this._networkdown = false; // XXX Need to query current state somehow
   this._lifecycleobservers = {};
   Services.obs.addObserver(this, "inner-window-destroyed", true);
@@ -201,22 +205,16 @@ RTCSessionDescription.prototype = {
 
   __init: function(dict) {
     this.type = dict.type;
     this.sdp  = dict.sdp;
   }
 };
 
 function RTCStatsReport(win, dict) {
-  function appendStats(stats, report) {
-    stats.forEach(function(stat) {
-        report[stat.id] = stat;
-      });
-  }
-
   this._win = win;
   this._pcid = dict.pcid;
   this._report = convertToRTCStatsReport(dict);
 }
 RTCStatsReport.prototype = {
   classDescription: "RTCStatsReport",
   classID: PC_STATS_CID,
   contractID: PC_STATS_CONTRACT,
@@ -278,16 +276,18 @@ RTCIdentityAssertion.prototype = {
   __init: function(idp, name) {
     this.idp = idp;
     this.name  = name;
   }
 };
 
 function RTCPeerConnection() {
   this._queue = [];
+  this._senders = [];
+  this._receivers = [];
 
   this._pc = null;
   this._observer = null;
   this._closed = false;
 
   this._onCreateOfferSuccess = null;
   this._onCreateOfferFailure = null;
   this._onCreateAnswerSuccess = null;
@@ -332,16 +332,17 @@ RTCPeerConnection.prototype = {
     this._mustValidateRTCConfiguration(rtcConfig,
         "RTCPeerConnection constructor passed invalid RTCConfiguration");
     if (_globalPCList._networkdown) {
       throw new this._win.DOMError("",
           "Can't create RTCPeerConnections when the network is down");
     }
 
     this.makeGetterSetterEH("onaddstream");
+    this.makeGetterSetterEH("onaddtrack");
     this.makeGetterSetterEH("onicecandidate");
     this.makeGetterSetterEH("onnegotiationneeded");
     this.makeGetterSetterEH("onsignalingstatechange");
     this.makeGetterSetterEH("onremovestream");
     this.makeGetterSetterEH("ondatachannel");
     this.makeGetterSetterEH("oniceconnectionstatechange");
     this.makeGetterSetterEH("onidentityresult");
     this.makeGetterSetterEH("onpeeridentity");
@@ -775,37 +776,48 @@ RTCPeerConnection.prototype = {
 
   _addIceCandidate: function(cand) {
     this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
                                (cand.sdpMLineIndex === null) ? 0 :
                                  cand.sdpMLineIndex + 1);
   },
 
   addStream: function(stream) {
-    if (stream.currentTime === undefined) {
-      throw new this._win.DOMError("", "Invalid stream passed to addStream!");
-    }
-    this._queueOrRun({ func: this._addStream,
-                       args: [stream],
-                       wait: false });
-  },
-
-  _addStream: function(stream) {
-    this._impl.addStream(stream);
+    stream.getTracks().forEach(track => this.addTrack(track, stream));
   },
 
   removeStream: function(stream) {
      // Bug 844295: Not implementing this functionality.
      throw new this._win.DOMError("", "removeStream not yet implemented");
   },
 
   getStreamById: function(id) {
     throw new this._win.DOMError("", "getStreamById not yet implemented");
   },
 
+  addTrack: function(track, stream) {
+    if (stream.currentTime === undefined) {
+      throw new this._win.DOMError("", "invalid stream.");
+    }
+    if (stream.getTracks().indexOf(track) == -1) {
+      throw new this._win.DOMError("", "track is not in stream.");
+    }
+    this._checkClosed();
+    this._impl.addTrack(track, stream);
+    let sender = this._win.RTCRtpSender._create(this._win,
+                                                new RTCRtpSender(this, track));
+    this._senders.push({ sender: sender, stream: stream });
+    return sender;
+  },
+
+  removeTrack: function(sender) {
+     // Bug 844295: Not implementing this functionality.
+     throw new this._win.DOMError("", "removeTrack not yet implemented");
+  },
+
   close: function() {
     if (this._closed) {
       return;
     }
     this.changeIceConnectionState("closed");
     this._queueOrRun({ func: this._close, args: [false], wait: false });
     this._closed = true;
   },
@@ -821,16 +833,46 @@ RTCPeerConnection.prototype = {
     return this._impl.getLocalStreams();
   },
 
   getRemoteStreams: function() {
     this._checkClosed();
     return this._impl.getRemoteStreams();
   },
 
+  getSenders: function() {
+    this._checkClosed();
+    let streams = this._impl.getLocalStreams();
+    let senders = [];
+    // prune senders in case any streams have disappeared down below
+    for (let i = this._senders.length - 1; i >= 0; i--) {
+      if (streams.indexOf(this._senders[i].stream) != -1) {
+        senders.push(this._senders[i].sender);
+      } else {
+        this._senders.splice(i,1);
+      }
+    }
+    return senders;
+  },
+
+  getReceivers: function() {
+    this._checkClosed();
+    let streams = this._impl.getRemoteStreams();
+    let receivers = [];
+    // prune receivers in case any streams have disappeared down below
+    for (let i = this._receivers.length - 1; i >= 0; i--) {
+      if (streams.indexOf(this._receivers[i].stream) != -1) {
+        receivers.push(this._receivers[i].receiver);
+      } else {
+        this._receivers.splice(i,1);
+      }
+    }
+    return receivers;
+  },
+
   get localDescription() {
     this._checkClosed();
     let sdp = this._impl.localDescription;
     if (sdp.length == 0) {
       return null;
     }
 
     sdp = this._localIdp.wrapSdp(sdp);
@@ -1239,16 +1281,27 @@ PeerConnectionObserver.prototype = {
     this._dompc.dispatchEvent(ev);
   },
 
   onRemoveStream: function(stream, type) {
     this.dispatchEvent(new this._dompc._win.MediaStreamEvent("removestream",
                                                              { stream: stream }));
   },
 
+  onAddTrack: function(track) {
+    let ev = new this._dompc._win.MediaStreamTrackEvent("addtrack",
+                                                        { track: track });
+    this._dompc.dispatchEvent(ev);
+  },
+
+  onRemoveTrack: function(track, type) {
+    this.dispatchEvent(new this._dompc._win.MediaStreamTrackEvent("removetrack",
+                                                                  { track: track }));
+  },
+
   foundIceCandidate: function(cand) {
     this.dispatchEvent(new this._dompc._win.RTCPeerConnectionIceEvent("icecandidate",
                                                                       { candidate: cand } ));
   },
 
   notifyDataChannel: function(channel) {
     this.dispatchEvent(new this._dompc._win.RTCDataChannelEvent("datachannel",
                                                                 { channel: channel }));
@@ -1270,18 +1323,42 @@ RTCPeerConnectionStatic.prototype = {
       .getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
   },
 
   registerPeerConnectionLifecycleCallback: function(cb) {
     _globalPCList._registerPeerConnectionLifecycleCallback(this._winID, cb);
   },
 };
 
+function RTCRtpSender(pc, track) {
+  this.pc = pc;
+  this.track = track;
+}
+RTCRtpSender.prototype = {
+  classDescription: "RTCRtpSender",
+  classID: PC_SENDER_CID,
+  contractID: PC_SENDER_CONTRACT,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+};
+
+function RTCRtpReceiver(pc, track) {
+  this.pc = pc;
+  this.track = track;
+}
+RTCRtpReceiver.prototype = {
+  classDescription: "RTCRtpReceiver",
+  classID: PC_RECEIVER_CID,
+  contractID: PC_RECEIVER_CONTRACT,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
+};
+
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
   [GlobalPCList,
    RTCIceCandidate,
    RTCSessionDescription,
    RTCPeerConnection,
    RTCPeerConnectionStatic,
+   RTCRtpReceiver,
+   RTCRtpSender,
    RTCStatsReport,
    RTCIdentityAssertion,
    PeerConnectionObserver]
 );
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -1,17 +1,21 @@
 component {00e0e20d-1494-4776-8e0e-0f0acbea3c79} PeerConnection.js
 component {d1748d4c-7f6a-4dc5-add6-d55b7678537e} PeerConnection.js
 component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
 component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
 component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
 component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
 component {1abc7499-3c54-43e0-bd60-686e2703f072} PeerConnection.js
 component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
+component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
+component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
 
 contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
 contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
 contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
 contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
 contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
 contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
 contract @mozilla.org/dom/rtcidentityassertion;1 {1abc7499-3c54-43e0-bd60-686e2703f072}
 contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}
+contract @mozilla.org/dom/rtpsender;1 {4fff5d46-d827-4cd4-a970-8fd53977440e}
+contract @mozilla.org/dom/rtpreceiver;1 {d974b814-8fde-411c-8c45-b86791b81030}
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -1538,17 +1538,25 @@ PeerConnectionWrapper.prototype = {
    * @param {string} side
    *        The location the stream is coming from ('local' or 'remote')
    */
   attachMedia : function PCW_attachMedia(stream, type, side) {
     info("Got media stream: " + type + " (" + side + ")");
     this.streams.push(stream);
 
     if (side === 'local') {
-      this._pc.addStream(stream);
+      // In order to test both the addStream and addTrack APIs, we do video one
+      // way and audio + audiovideo the other.
+      if (type == "video") {
+        this._pc.addStream(stream);
+      } else {
+        stream.getTracks().forEach(function(track) {
+          this._pc.addTrack(track, stream);
+        }.bind(this));
+      }
     }
 
     var element = createMediaElement(type, this.label + '_' + side);
     this.mediaCheckers.push(new MediaElementChecker(element));
     element.mozSrcObject = stream;
     element.play();
   },
 
--- a/dom/plugins/base/nsNPAPIPluginInstance.cpp
+++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -34,18 +34,20 @@
 #include "nsPluginStreamListenerPeer.h"
 #include "nsSize.h"
 #include "nsNetCID.h"
 #include "nsIContent.h"
 #include "nsVersionComparator.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/unused.h"
 #include "nsILoadContext.h"
+#include "mozilla/dom/HTMLObjectElementBinding.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "ANPBase.h"
 #include <android/log.h>
 #include "android_npapi.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/CondVar.h"
 #include "AndroidBridge.h"
@@ -191,16 +193,19 @@ nsNPAPIPluginInstance::nsNPAPIPluginInst
     mPlugin(nullptr),
     mMIMEType(nullptr),
     mOwner(nullptr),
     mCurrentPluginEvent(nullptr)
 #ifdef MOZ_WIDGET_ANDROID
   , mOnScreen(true)
 #endif
   , mHaveJavaC2PJSObjectQuirk(false)
+  , mCachedParamLength(0)
+  , mCachedParamNames(nullptr)
+  , mCachedParamValues(nullptr)
 {
   mNPP.pdata = nullptr;
   mNPP.ndata = this;
 
   PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
 
 #ifdef MOZ_WIDGET_ANDROID
   sPluginNPPMap[&mNPP] = this;
@@ -214,16 +219,38 @@ nsNPAPIPluginInstance::~nsNPAPIPluginIns
 #ifdef MOZ_WIDGET_ANDROID
   sPluginNPPMap.erase(&mNPP);
 #endif
 
   if (mMIMEType) {
     PR_Free((void *)mMIMEType);
     mMIMEType = nullptr;
   }
+
+  if (!mCachedParamValues || !mCachedParamNames) {
+    return;
+  }
+  MOZ_ASSERT(mCachedParamValues && mCachedParamNames);
+
+  for (uint32_t i = 0; i < mCachedParamLength; i++) {
+    if (mCachedParamNames[i]) {
+      NS_Free(mCachedParamNames[i]);
+      mCachedParamNames[i] = nullptr;
+    }
+    if (mCachedParamValues[i]) {
+      NS_Free(mCachedParamValues[i]);
+      mCachedParamValues[i] = nullptr;
+    }
+  }
+
+  NS_Free(mCachedParamNames);
+  mCachedParamNames = nullptr;
+
+  NS_Free(mCachedParamValues);
+  mCachedParamValues = nullptr;
 }
 
 uint32_t nsNPAPIPluginInstance::gInUnsafePluginCalls = 0;
 
 void
 nsNPAPIPluginInstance::Destroy()
 {
   Stop();
@@ -373,38 +400,16 @@ nsNPAPIPluginInstance::GetTagType(nsPlug
   if (!mOwner) {
     return NS_ERROR_FAILURE;
   }
 
   return mOwner->GetTagType(result);
 }
 
 nsresult
-nsNPAPIPluginInstance::GetAttributes(uint16_t& n, const char*const*& names,
-                                     const char*const*& values)
-{
-  if (!mOwner) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return mOwner->GetAttributes(n, names, values);
-}
-
-nsresult
-nsNPAPIPluginInstance::GetParameters(uint16_t& n, const char*const*& names,
-                                     const char*const*& values)
-{
-  if (!mOwner) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return mOwner->GetParameters(n, names, values);
-}
-
-nsresult
 nsNPAPIPluginInstance::GetMode(int32_t *result)
 {
   if (mOwner)
     return mOwner->GetMode(result);
   else
     return NS_ERROR_FAILURE;
 }
 
@@ -422,109 +427,73 @@ nsNPAPIPluginInstance::FileCachedStreamL
 
 nsresult
 nsNPAPIPluginInstance::Start()
 {
   if (mRunning == RUNNING) {
     return NS_OK;
   }
 
+  if (!mOwner) {
+    MOZ_ASSERT(false, "Should not be calling Start() on unowned plugin.");
+    return NS_ERROR_FAILURE;
+  }
+
   PluginDestructionGuard guard(this);
 
-  uint16_t count = 0;
-  const char* const* names = nullptr;
-  const char* const* values = nullptr;
+  nsTArray<MozPluginParameter> attributes;
+  nsTArray<MozPluginParameter> params;
+
   nsPluginTagType tagtype;
   nsresult rv = GetTagType(&tagtype);
   if (NS_SUCCEEDED(rv)) {
-    // Note: If we failed to get the tag type, we may be a full page plugin, so no arguments
-    rv = GetAttributes(count, names, values);
-    NS_ENSURE_SUCCESS(rv, rv);
+    mOwner->GetAttributes(attributes);
+    mOwner->GetParameters(params);
+  } else {
+    MOZ_ASSERT(false, "Failed to get tag type.");
+  }
+
+  mCachedParamLength = attributes.Length() + 1 + params.Length();
+
+  // We add an extra entry "PARAM" as a separator between the attribute
+  // and param values, but we don't count it if there are no <param> entries.
+  // Legacy behavior quirk.
+  uint32_t quirkParamLength = params.Length() ?
+                                mCachedParamLength : attributes.Length();
+
+  mCachedParamNames = (char**)NS_Alloc(sizeof(char*) * mCachedParamLength);
+  mCachedParamValues = (char**)NS_Alloc(sizeof(char*) * mCachedParamLength);
 
-    // nsPluginTagType_Object or Applet may also have PARAM tags
-    // Note: The arrays handed back by GetParameters() are
-    // crafted specially to be directly behind the arrays from GetAttributes()
-    // with a null entry as a separator. This is for 4.x backwards compatibility!
-    // see bug 111008 for details
-    if (tagtype != nsPluginTagType_Embed) {
-      uint16_t pcount = 0;
-      const char* const* pnames = nullptr;
-      const char* const* pvalues = nullptr;
-      if (NS_SUCCEEDED(GetParameters(pcount, pnames, pvalues))) {
-        // Android expects an empty string as the separator instead of null
-#ifdef MOZ_WIDGET_ANDROID
-        NS_ASSERTION(PL_strcmp(values[count], "") == 0, "attribute/parameter array not setup correctly for Android NPAPI plugins");
-#else
-        NS_ASSERTION(!values[count], "attribute/parameter array not setup correctly for NPAPI plugins");
-#endif
-        if (pcount)
-          count += ++pcount; // if it's all setup correctly, then all we need is to
-                             // change the count (attrs + PARAM/blank + params)
-      }
-    }
+  for (uint32_t i = 0; i < attributes.Length(); i++) {
+    mCachedParamNames[i] = ToNewUTF8String(attributes[i].mName);
+    mCachedParamValues[i] = ToNewUTF8String(attributes[i].mValue);
+  }
+
+  // Android expects and empty string instead of null.
+  mCachedParamNames[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
+  #ifdef MOZ_WIDGET_ANDROID
+    mCachedParamValues[attributes.Length()] = ToNewUTF8String(NS_LITERAL_STRING(""));
+  #else
+    mCachedParamValues[attributes.Length()] = nullptr;
+  #endif
+
+  for (uint32_t i = 0, pos = attributes.Length() + 1; i < params.Length(); i ++) {
+    mCachedParamNames[pos] = ToNewUTF8String(params[i].mName);
+    mCachedParamValues[pos] = ToNewUTF8String(params[i].mValue);
+    pos++;
   }
 
   int32_t       mode;
   const char*   mimetype;
   NPError       error = NPERR_GENERIC_ERROR;
 
   GetMode(&mode);
   GetMIMEType(&mimetype);
 
-  CheckJavaC2PJSObjectQuirk(count, names, values);
-
-  // Some older versions of Flash have a bug in them
-  // that causes the stack to become currupt if we
-  // pass swliveconnect=1 in the NPP_NewProc arrays.
-  // See bug 149336 (UNIX), bug 186287 (Mac)
-  //
-  // The code below disables the attribute unless
-  // the environment variable:
-  // MOZILLA_PLUGIN_DISABLE_FLASH_SWLIVECONNECT_HACK
-  // is set.
-  //
-  // It is okay to disable this attribute because
-  // back in 4.x, scripting required liveconnect to
-  // start Java which was slow. Scripting no longer
-  // requires starting Java and is quick plus controled
-  // from the browser, so Flash now ignores this attribute.
-  //
-  // This code can not be put at the time of creating
-  // the array because we may need to examine the
-  // stream header to determine we want Flash.
-
-  static const char flashMimeType[] = "application/x-shockwave-flash";
-  static const char blockedParam[] = "swliveconnect";
-  if (count && !PL_strcasecmp(mimetype, flashMimeType)) {
-    static int cachedDisableHack = 0;
-    if (!cachedDisableHack) {
-       if (PR_GetEnv("MOZILLA_PLUGIN_DISABLE_FLASH_SWLIVECONNECT_HACK"))
-         cachedDisableHack = -1;
-       else
-         cachedDisableHack = 1;
-    }
-    if (cachedDisableHack > 0) {
-      for (uint16_t i=0; i<count; i++) {
-        if (!PL_strcasecmp(names[i], blockedParam)) {
-          // BIG FAT WARNIG:
-          // I'm ugly casting |const char*| to |char*| and altering it
-          // because I know we do malloc it values in
-          // http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/layout/html/base/src/nsObjectFrame.cpp&rev=1.349&root=/cvsroot#3020
-          // and free it at line #2096, so it couldn't be a const ptr to string literal
-          char *val = (char*) values[i];
-          if (val && *val) {
-            // we cannot just *val=0, it won't be free properly in such case
-            val[0] = '0';
-            val[1] = 0;
-          }
-          break;
-        }
-      }
-    }
-  }
+  CheckJavaC2PJSObjectQuirk(quirkParamLength, mCachedParamNames, mCachedParamValues);
 
   bool oldVal = mInPluginInitCall;
   mInPluginInitCall = true;
 
   // Need this on the stack before calling NPP_New otherwise some callbacks that
   // the plugin may make could fail (NPN_HasProperty, for example).
   NPPAutoPusher autopush(&mNPP);
 
@@ -536,23 +505,23 @@ nsNPAPIPluginInstance::Start()
     return NS_ERROR_FAILURE;
 
   // Mark this instance as running before calling NPP_New because the plugin may
   // call other NPAPI functions, like NPN_GetURLNotify, that assume this is set
   // before returning. If the plugin returns failure, we'll clear it out below.
   mRunning = RUNNING;
 
   nsresult newResult = library->NPP_New((char*)mimetype, &mNPP, (uint16_t)mode,
-                                        count, (char**)names, (char**)values,
-                                        nullptr, &error);
+                                        quirkParamLength, mCachedParamNames,
+                                        mCachedParamValues, nullptr, &error);
   mInPluginInitCall = oldVal;
 
   NPP_PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   ("NPP New called: this=%p, npp=%p, mime=%s, mode=%d, argc=%d, return=%d\n",
-  this, &mNPP, mimetype, mode, count, error));
+  this, &mNPP, mimetype, mode, quirkParamLength, error));
 
   if (NS_FAILED(newResult) || error != NPERR_NO_ERROR) {
     mRunning = DESTROYED;
     nsJSNPRuntime::OnPluginDestroy(&mNPP);
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -300,20 +300,16 @@ public:
     }
   }
 
 protected:
 
   virtual ~nsNPAPIPluginInstance();
 
   nsresult GetTagType(nsPluginTagType *result);
-  nsresult GetAttributes(uint16_t& n, const char*const*& names,
-                         const char*const*& values);
-  nsresult GetParameters(uint16_t& n, const char*const*& names,
-                         const char*const*& values);
   nsresult GetMode(int32_t *result);
 
   // check if this is a Java applet and affected by bug 750480
   void CheckJavaC2PJSObjectQuirk(uint16_t paramCount,
                                  const char* const* names,
                                  const char* const* values);
 
   // The structure used to communicate between the plugin instance and
@@ -393,16 +389,22 @@ private:
 
   nsIntSize mCurrentSize;
 #endif
 
   // is this instance Java and affected by bug 750480?
   bool mHaveJavaC2PJSObjectQuirk;
 
   static uint32_t gInUnsafePluginCalls;
+
+  // The arrays can only be released when the plugin instance is destroyed,
+  // because the plugin, in in-process mode, might keep a reference to them.
+  uint32_t mCachedParamLength;
+  char **mCachedParamNames;
+  char **mCachedParamValues;
 };
 
 // On Android, we need to guard against plugin code leaking entries in the local
 // JNI ref table. See https://bugzilla.mozilla.org/show_bug.cgi?id=780831#c21
 #ifdef MOZ_WIDGET_ANDROID
   #define MAIN_THREAD_JNI_REF_GUARD mozilla::AutoLocalJNIFrame jniFrame
 #else
   #define MAIN_THREAD_JNI_REF_GUARD
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -34,30 +34,33 @@ using mozilla::DefaultXDisplay;
 #include "nsLayoutUtils.h"
 #include "nsIPluginWidget.h"
 #include "nsViewManager.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIAppShell.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIObjectLoadingContent.h"
+#include "nsObjectLoadingContent.h"
 #include "nsAttrName.h"
 #include "nsIFocusManager.h"
 #include "nsFocusManager.h"
 #include "nsIDOMDragEvent.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDocShell.h"
 #include "ImageContainer.h"
 #include "nsIDOMHTMLCollection.h"
 #include "GLContext.h"
 #include "GLSharedHandleHelpers.h"
 #include "nsIContentInlines.h"
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/TextEvents.h"
+#include "mozilla/dom/HTMLObjectElementBinding.h"
+#include "nsFrameSelection.h"
 
 #include "nsContentCID.h"
 #include "nsWidgetsCID.h"
 static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #ifdef XP_WIN
 #include <wtypes.h>
@@ -83,16 +86,17 @@ static nsPluginInstanceOwner* sFullScree
 
 using namespace mozilla::dom;
 
 #include <android/log.h>
 #define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
 #endif
 
 using namespace mozilla;
+using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 // special class for handeling DOM context menu events because for
 // some reason it starves other mouse events if implemented on the
 // same class
 class nsPluginDOMContextMenuListener : public nsIDOMEventListener
 {
   virtual ~nsPluginDOMContextMenuListener();
@@ -275,20 +279,16 @@ nsPluginInstanceOwner::nsPluginInstanceO
   mSentInitialTopLevelWindowEvent = false;
   mColorProfile = nullptr;
   mPluginPortChanged = false;
 #endif
   mContentFocused = false;
   mWidgetVisible = true;
   mPluginWindowVisible = false;
   mPluginDocumentActiveState = true;
-  mNumCachedAttrs = 0;
-  mNumCachedParams = 0;
-  mCachedAttrParamNames = nullptr;
-  mCachedAttrParamValues = nullptr;
   mLastMouseDownButtonType = -1;
 
 #ifdef XP_MACOSX
 #ifndef NP_NO_CARBON
   // We don't support Carbon, but it is still the default model for i386 NPAPI.
   mEventModel = NPEventModelCarbon;
 #else
   mEventModel = NPEventModelCocoa;
@@ -301,49 +301,25 @@ nsPluginInstanceOwner::nsPluginInstanceO
 #ifdef MOZ_WIDGET_ANDROID
   mFullScreen = false;
   mJavaView = nullptr;
 #endif
 }
 
 nsPluginInstanceOwner::~nsPluginInstanceOwner()
 {
-  int32_t cnt;
-
   if (mWaitingForPaint) {
     // We don't care when the event is dispatched as long as it's "soon",
     // since whoever needs it will be waiting for it.
     nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, true);
     NS_DispatchToMainThread(event);
   }
 
   mObjectFrame = nullptr;
 
-  for (cnt = 0; cnt < (mNumCachedAttrs + 1 + mNumCachedParams); cnt++) {
-    if (mCachedAttrParamNames && mCachedAttrParamNames[cnt]) {
-      NS_Free(mCachedAttrParamNames[cnt]);
-      mCachedAttrParamNames[cnt] = nullptr;
-    }
-
-    if (mCachedAttrParamValues && mCachedAttrParamValues[cnt]) {
-      NS_Free(mCachedAttrParamValues[cnt]);
-      mCachedAttrParamValues[cnt] = nullptr;
-    }
-  }
-
-  if (mCachedAttrParamNames) {
-    NS_Free(mCachedAttrParamNames);
-    mCachedAttrParamNames = nullptr;
-  }
-
-  if (mCachedAttrParamValues) {
-    NS_Free(mCachedAttrParamValues);
-    mCachedAttrParamValues = nullptr;
-  }
-
   PLUG_DeletePluginNativeWindow(mPluginWindow);
   mPluginWindow = nullptr;
 
 #ifdef MOZ_WIDGET_ANDROID
   RemovePluginView();
 #endif
 
   if (mInstance) {
@@ -406,48 +382,23 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
     *aMode = NP_FULL;
   } else {
     *aMode = NP_EMBED;
   }
 
   return rv;
 }
 
-NS_IMETHODIMP nsPluginInstanceOwner::GetAttributes(uint16_t& n,
-                                                   const char*const*& names,
-                                                   const char*const*& values)
-{
-  nsresult rv = EnsureCachedAttrParamArrays();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  n = mNumCachedAttrs;
-  names  = (const char **)mCachedAttrParamNames;
-  values = (const char **)mCachedAttrParamValues;
-
-  return rv;
-}
-
-NS_IMETHODIMP nsPluginInstanceOwner::GetAttribute(const char* name, const char* *result)
+void nsPluginInstanceOwner::GetAttributes(nsTArray<MozPluginParameter>& attributes)
 {
-  NS_ENSURE_ARG_POINTER(name);
-  NS_ENSURE_ARG_POINTER(result);
-
-  nsresult rv = EnsureCachedAttrParamArrays();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *result = nullptr;
-
-  for (int i = 0; i < mNumCachedAttrs; i++) {
-    if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) {
-      *result = mCachedAttrParamValues[i];
-      return NS_OK;
-    }
-  }
-
-  return NS_ERROR_FAILURE;
+  nsCOMPtr<nsIObjectLoadingContent> content = do_QueryInterface(mContent);
+  nsObjectLoadingContent *loadingContent =
+    static_cast<nsObjectLoadingContent*>(content.get());
+
+  loadingContent->GetPluginAttributes(attributes);
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::GetDOMElement(nsIDOMElement* *result)
 {
   return CallQueryInterface(mContent, result);
 }
 
 nsresult nsPluginInstanceOwner::GetInstance(nsNPAPIPluginInstance **aInstance)
@@ -784,336 +735,23 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   else if (atom == nsGkAtoms::embed)
     *result = nsPluginTagType_Embed;
   else if (atom == nsGkAtoms::object)
     *result = nsPluginTagType_Object;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsPluginInstanceOwner::GetParameters(uint16_t& n, const char*const*& names, const char*const*& values)
-{
-  nsresult rv = EnsureCachedAttrParamArrays();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  n = mNumCachedParams;
-  if (n) {
-    names  = (const char **)(mCachedAttrParamNames + mNumCachedAttrs + 1);
-    values = (const char **)(mCachedAttrParamValues + mNumCachedAttrs + 1);
-  } else
-    names = values = nullptr;
-
-  return rv;
-}
-
-NS_IMETHODIMP nsPluginInstanceOwner::GetParameter(const char* name, const char* *result)
-{
-  NS_ENSURE_ARG_POINTER(name);
-  NS_ENSURE_ARG_POINTER(result);
-
-  nsresult rv = EnsureCachedAttrParamArrays();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *result = nullptr;
-
-  for (int i = mNumCachedAttrs + 1; i < (mNumCachedParams + 1 + mNumCachedAttrs); i++) {
-    if (0 == PL_strcasecmp(mCachedAttrParamNames[i], name)) {
-      *result = mCachedAttrParamValues[i];
-      return NS_OK;
-    }
-  }
-
-  return NS_ERROR_FAILURE;
-}
-
-
-// Cache the attributes and/or parameters of our tag into a single set
-// of arrays to be compatible with Netscape 4.x. The attributes go first,
-// followed by a PARAM/null and then any PARAM tags. Also, hold the
-// cached array around for the duration of the life of the instance
-// because Netscape 4.x did. See bug 111008.
-nsresult nsPluginInstanceOwner::EnsureCachedAttrParamArrays()
+void nsPluginInstanceOwner::GetParameters(nsTArray<MozPluginParameter>& parameters)
 {
-  if (mCachedAttrParamValues)
-    return NS_OK;
-
-  NS_PRECONDITION(((mNumCachedAttrs + mNumCachedParams) == 0) &&
-                    !mCachedAttrParamNames,
-                  "re-cache of attrs/params not implemented! use the DOM "
-                    "node directy instead");
-
-  // Convert to a 16-bit count. Subtract 3 in case we add an extra
-  // "src", "wmode", or "codebase" entry below.
-  uint32_t cattrs = mContent->GetAttrCount();
-  if (cattrs < 0x0000FFFC) {
-    mNumCachedAttrs = static_cast<uint16_t>(cattrs);
-  } else {
-    mNumCachedAttrs = 0xFFFC;
-  }
-
-  // Check if we are java for special codebase handling
-  const char* mime = nullptr;
-  bool isJava = NS_SUCCEEDED(mInstance->GetMIMEType(&mime)) && mime &&
-                nsPluginHost::IsJavaMIMEType(mime);
-
-  // now, we need to find all the PARAM tags that are children of us
-  // however, be careful not to include any PARAMs that don't have us
-  // as a direct parent. For nested object (or applet) tags, be sure
-  // to only round up the param tags that coorespond with THIS
-  // instance. And also, weed out any bogus tags that may get in the
-  // way, see bug 39609. Then, with any param tag that meet our
-  // qualification, temporarly cache them in an nsCOMArray until
-  // we can figure out what size to make our fixed char* array.
-  nsCOMArray<nsIDOMElement> ourParams;
-
-  // Get all dependent PARAM tags, even if they are not direct children.
-  nsCOMPtr<nsIDOMElement> mydomElement = do_QueryInterface(mContent);
-  NS_ENSURE_TRUE(mydomElement, NS_ERROR_NO_INTERFACE);
-
-  // Making DOM method calls can cause our frame to go away.
-  nsCOMPtr<nsIPluginInstanceOwner> kungFuDeathGrip(this);
-
-  nsCOMPtr<nsIDOMHTMLCollection> allParams;
-  NS_NAMED_LITERAL_STRING(xhtml_ns, "http://www.w3.org/1999/xhtml");
-  mydomElement->GetElementsByTagNameNS(xhtml_ns, NS_LITERAL_STRING("param"),
-                                       getter_AddRefs(allParams));
-  if (allParams) {
-    uint32_t numAllParams;
-    allParams->GetLength(&numAllParams);
-    for (uint32_t i = 0; i < numAllParams; i++) {
-      nsCOMPtr<nsIDOMNode> pnode;
-      allParams->Item(i, getter_AddRefs(pnode));
-      nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(pnode);
-      if (domelement) {
-        // Ignore params without a name attribute.
-        nsAutoString name;
-        domelement->GetAttribute(NS_LITERAL_STRING("name"), name);
-        if (!name.IsEmpty()) {
-          // Find the first object or applet parent.
-          nsCOMPtr<nsIDOMNode> parent;
-          nsCOMPtr<nsIDOMHTMLObjectElement> domobject;
-          nsCOMPtr<nsIDOMHTMLAppletElement> domapplet;
-          pnode->GetParentNode(getter_AddRefs(parent));
-          while (!(domobject || domapplet) && parent) {
-            domobject = do_QueryInterface(parent);
-            domapplet = do_QueryInterface(parent);
-            nsCOMPtr<nsIDOMNode> temp;
-            parent->GetParentNode(getter_AddRefs(temp));
-            parent = temp;
-          }
-          if (domapplet || domobject) {
-            if (domapplet) {
-              parent = do_QueryInterface(domapplet);
-            }
-            else {
-              parent = do_QueryInterface(domobject);
-            }
-            nsCOMPtr<nsIDOMNode> mydomNode = do_QueryInterface(mydomElement);
-            if (parent == mydomNode) {
-              ourParams.AppendObject(domelement);
-            }
-          }
-        }
-      }
-    }
-  }
-
-  // Convert to a 16-bit count.
-  uint32_t cparams = ourParams.Count();
-  if (cparams < 0x0000FFFF) {
-    mNumCachedParams = static_cast<uint16_t>(cparams);
-  } else {
-    mNumCachedParams = 0xFFFF;
-  }
-
-  uint16_t numRealAttrs = mNumCachedAttrs;
-
-  // Some plugins were never written to understand the "data" attribute of the OBJECT tag.
-  // Real and WMP will not play unless they find a "src" attribute, see bug 152334.
-  // Nav 4.x would simply replace the "data" with "src". Because some plugins correctly
-  // look for "data", lets instead copy the "data" attribute and add another entry
-  // to the bottom of the array if there isn't already a "src" specified.
-  nsAutoString data;
-  if (mContent->Tag() == nsGkAtoms::object &&
-      !mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src) &&
-      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::data, data) &&
-      !data.IsEmpty()) {
-    mNumCachedAttrs++;
-  }
-
-  // "plugins.force.wmode" forces us to send a specific "wmode" parameter,
-  // used by flash to select a rendering mode. Common values include
-  // "opaque", "transparent", "windowed", "direct"
-  nsCString wmodeType;
-  nsAdoptingCString wmodePref = Preferences::GetCString("plugins.force.wmode");
-  if (!wmodePref.IsEmpty()) {
-    mNumCachedAttrs++;
-    wmodeType = wmodePref;
-  }
-#if defined(XP_WIN) || defined(XP_LINUX)
-  // Bug 923745 - Until we support windowed mode plugins in content processes,
-  // force flash to use a windowless rendering mode. This hack should go away
-  // when bug 923746 lands. (OS X plugins always use some native widgets, so
-  // unfortunately this does not help there)
-  else if (XRE_GetProcessType() == GeckoProcessType_Content) {
-    mNumCachedAttrs++;
-    wmodeType.AssignLiteral("transparent");
-  }
-#endif
-
-  // (Bug 738396) java has quirks in its codebase parsing, pass the
-  // absolute codebase URI as content sees it.
-  bool addCodebase = false;
-  nsAutoCString codebaseStr;
-  if (isJava) {
-    nsCOMPtr<nsIObjectLoadingContent> objlc = do_QueryInterface(mContent);
-    NS_ENSURE_TRUE(objlc, NS_ERROR_UNEXPECTED);
-    nsCOMPtr<nsIURI> codebaseURI;
-    nsresult rv = objlc->GetBaseURI(getter_AddRefs(codebaseURI));
-    NS_ENSURE_SUCCESS(rv, rv);
-    codebaseURI->GetSpec(codebaseStr);
-    if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::codebase)) {
-      mNumCachedAttrs++;
-      addCodebase = true;
-    }
-  }
-
-  mCachedAttrParamNames  = (char**)NS_Alloc(sizeof(char*) * (mNumCachedAttrs + 1 + mNumCachedParams));
-  NS_ENSURE_TRUE(mCachedAttrParamNames,  NS_ERROR_OUT_OF_MEMORY);
-  mCachedAttrParamValues = (char**)NS_Alloc(sizeof(char*) * (mNumCachedAttrs + 1 + mNumCachedParams));
-  NS_ENSURE_TRUE(mCachedAttrParamValues, NS_ERROR_OUT_OF_MEMORY);
-
-  // Some plugins (eg Flash, see bug 234675.) are actually sensitive to the
-  // attribute order.  So we want to make sure we give the plugin the
-  // attributes in the order they came in in the source, to be compatible with
-  // other browsers.  Now in HTML, the storage order is the reverse of the
-  // source order, while in XML and XHTML it's the same as the source order
-  // (see the AddAttributes functions in the HTML and XML content sinks).
-  int32_t start, end, increment;
-  if (mContent->IsHTML() &&
-      mContent->IsInHTMLDocument()) {
-    // HTML.  Walk attributes in reverse order.
-    start = numRealAttrs - 1;
-    end = -1;
-    increment = -1;
-  } else {
-    // XHTML or XML.  Walk attributes in forward order.
-    start = 0;
-    end = numRealAttrs;
-    increment = 1;
-  }
-
-  // Set to the next slot to fill in name and value cache arrays.
-  uint32_t nextAttrParamIndex = 0;
-
-  // Whether or not we force the wmode below while traversing
-  // the name/value pairs.
-  bool wmodeSet = false;
-
-  // Add attribute name/value pairs.
-  for (int32_t index = start; index != end; index += increment) {
-    const nsAttrName* attrName = mContent->GetAttrNameAt(index);
-    nsIAtom* atom = attrName->LocalName();
-    nsAutoString value;
-    mContent->GetAttr(attrName->NamespaceID(), atom, value);
-    nsAutoString name;
-    atom->ToString(name);
-
-    FixUpURLS(name, value);
-
-    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name);
-    if (!wmodeType.IsEmpty() &&
-        0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "wmode")) {
-      mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
-
-      if (!wmodeSet) {
-        // We allocated space to add a wmode attr, but we don't need it now.
-        mNumCachedAttrs--;
-        wmodeSet = true;
-      }
-    } else if (isJava && 0 == PL_strcasecmp(mCachedAttrParamNames[nextAttrParamIndex], "codebase")) {
-      mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(codebaseStr));
-    } else {
-      mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
-    }
-    nextAttrParamIndex++;
-  }
-
-  // Potentially add CODEBASE attribute
-  if (addCodebase) {
-    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("codebase"));
-    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(codebaseStr));
-    nextAttrParamIndex++;
-  }
-
-  // Potentially add WMODE attribute.
-  if (!wmodeType.IsEmpty() && !wmodeSet) {
-    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("wmode"));
-    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_ConvertUTF8toUTF16(wmodeType));
-    nextAttrParamIndex++;
-  }
-
-  // Potentially add SRC attribute.
-  if (!data.IsEmpty()) {
-    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("SRC"));
-    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(data);
-    nextAttrParamIndex++;
-  }
-
-  // Add PARAM and null separator.
-  mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING("PARAM"));
-#ifdef MOZ_WIDGET_ANDROID
-  // Flash expects an empty string on android
-  mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(NS_LITERAL_STRING(""));
-#else
-  mCachedAttrParamValues[nextAttrParamIndex] = nullptr;
-#endif
-  nextAttrParamIndex++;
-
-  // Add PARAM name/value pairs.
-
-  // We may decrement mNumCachedParams below
-  uint16_t totalParams = mNumCachedParams;
-  for (uint16_t i = 0; i < totalParams; i++) {
-    nsIDOMElement* param = ourParams.ObjectAt(i);
-    if (!param) {
-      continue;
-    }
-
-    nsAutoString name;
-    nsAutoString value;
-    param->GetAttribute(NS_LITERAL_STRING("name"), name); // check for empty done above
-    param->GetAttribute(NS_LITERAL_STRING("value"), value);
-
-    FixUpURLS(name, value);
-
-    /*
-     * According to the HTML 4.01 spec, at
-     * http://www.w3.org/TR/html4/types.html#type-cdata
-     * ''User agents may ignore leading and trailing
-     * white space in CDATA attribute values (e.g., "
-     * myval " may be interpreted as "myval"). Authors
-     * should not declare attribute values with
-     * leading or trailing white space.''
-     * However, do not trim consecutive spaces as in bug 122119
-     */
-    name.Trim(" \n\r\t\b", true, true, false);
-    value.Trim(" \n\r\t\b", true, true, false);
-    if (isJava && name.EqualsIgnoreCase("codebase")) {
-      // We inserted normalized codebase above, don't include other versions in
-      // params
-      mNumCachedParams--;
-      continue;
-    }
-    mCachedAttrParamNames [nextAttrParamIndex] = ToNewUTF8String(name);
-    mCachedAttrParamValues[nextAttrParamIndex] = ToNewUTF8String(value);
-    nextAttrParamIndex++;
-  }
-
-  return NS_OK;
+  nsCOMPtr<nsIObjectLoadingContent> content = do_QueryInterface(mContent);
+  nsObjectLoadingContent *loadingContent =
+    static_cast<nsObjectLoadingContent*>(content.get());
+
+  loadingContent->GetPluginParameters(parameters);
 }
 
 #ifdef XP_MACOSX
 
 static void InitializeNPCocoaEvent(NPCocoaEvent* event)
 {
   memset(event, 0, sizeof(NPCocoaEvent));
 }
@@ -3163,29 +2801,16 @@ void nsPluginInstanceOwner::SetFrame(nsO
   }
 }
 
 nsObjectFrame* nsPluginInstanceOwner::GetFrame()
 {
   return mObjectFrame;
 }
 
-// Little helper function to resolve relative URL in
-// |value| for certain inputs of |name|
-void nsPluginInstanceOwner::FixUpURLS(const nsString &name, nsAString &value)
-{
-  if (name.LowerCaseEqualsLiteral("pluginspage")) {
-    nsCOMPtr<nsIURI> baseURI = GetBaseURI();
-    nsAutoString newURL;
-    NS_MakeAbsoluteURI(newURL, value, baseURI);
-    if (!newURL.IsEmpty())
-      value = newURL;
-  }
-}
-
 NS_IMETHODIMP nsPluginInstanceOwner::PrivateModeChanged(bool aEnabled)
 {
   return mInstance ? mInstance->PrivateModeStateChanged(aEnabled) : NS_OK;
 }
 
 already_AddRefed<nsIURI> nsPluginInstanceOwner::GetBaseURI() const
 {
   if (!mContent) {
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -24,16 +24,22 @@
 #endif
 
 class nsIInputStream;
 struct nsIntRect;
 class nsPluginDOMContextMenuListener;
 class nsObjectFrame;
 class nsDisplayListBuilder;
 
+namespace mozilla {
+namespace dom {
+struct MozPluginParameter;
+}
+}
+
 #ifdef MOZ_X11
 class gfxXlibSurface;
 #ifdef MOZ_WIDGET_QT
 #include "gfxQtNativeRenderer.h"
 #else
 #include "gfxXlibNativeRenderer.h"
 #endif
 #endif
@@ -67,60 +73,18 @@ public:
   virtual void SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) MOZ_OVERRIDE;
 
   /**
    * Get the type of the HTML tag that was used ot instantiate this
    * plugin.  Currently supported tags are EMBED, OBJECT and APPLET.
    */
   NS_IMETHOD GetTagType(nsPluginTagType *aResult);
 
-  /**
-   * Get a ptr to the paired list of parameter names and values,
-   * returns the length of the array.
-   *
-   * Each name or value is a null-terminated string.
-   */
-  NS_IMETHOD GetParameters(uint16_t& aCount,
-                           const char*const*& aNames,
-                           const char*const*& aValues);
-
-  /**
-   * Get the value for the named parameter.  Returns null
-   * if the parameter was not set.
-   *
-   * @param aName   - name of the parameter
-   * @param aResult - parameter value
-   * @result        - NS_OK if this operation was successful
-   */
-  NS_IMETHOD GetParameter(const char* aName, const char* *aResult);
-
-  /**
-   * QueryInterface on nsIPluginInstancePeer to get this.
-   *
-   * (Corresponds to NPP_New's argc, argn, and argv arguments.)
-   * Get a ptr to the paired list of attribute names and values,
-   * returns the length of the array.
-   *
-   * Each name or value is a null-terminated string.
-   */
-  NS_IMETHOD GetAttributes(uint16_t& aCount,
-                           const char*const*& aNames,
-                           const char*const*& aValues);
-
-
-  /**
-   * Gets the value for the named attribute.
-   *
-   * @param aName   - the name of the attribute to find
-   * @param aResult - the resulting attribute
-   * @result - NS_OK if this operation was successful, NS_ERROR_FAILURE if
-   * this operation failed. result is set to NULL if the attribute is not found
-   * else to the found value.
-   */
-  NS_IMETHOD GetAttribute(const char* aName, const char* *aResult);
+  void GetParameters(nsTArray<mozilla::dom::MozPluginParameter>& parameters);
+  void GetAttributes(nsTArray<mozilla::dom::MozPluginParameter>& attributes);
 
   /**
    * Returns the DOM element corresponding to the tag which references
    * this plugin in the document.
    *
    * @param aDOMElement - resulting DOM element
    * @result - NS_OK if this operation was successful
    */
@@ -295,18 +259,17 @@ private:
 
   // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet)
   bool IsUpToDate()
   {
     nsIntSize size;
     return NS_SUCCEEDED(mInstance->GetImageSize(&size)) &&
     size == nsIntSize(mPluginWindow->width, mPluginWindow->height);
   }
-  
-  void FixUpURLS(const nsString &name, nsAString &value);
+
 #ifdef MOZ_WIDGET_ANDROID
   mozilla::LayoutDeviceRect GetPluginRect();
   bool AddPluginView(const mozilla::LayoutDeviceRect& aRect = mozilla::LayoutDeviceRect(0, 0, 0, 0));
   void RemovePluginView();
 
   bool mFullScreen;
   void* mJavaView;
 #endif 
@@ -342,21 +305,16 @@ private:
 #endif
 #ifdef MOZ_X11
   // Used with windowless plugins only, initialized in CreateWidget().
   bool                        mFlash10Quirks;
 #endif
   bool                        mPluginWindowVisible;
   bool                        mPluginDocumentActiveState;
 
-  uint16_t          mNumCachedAttrs;
-  uint16_t          mNumCachedParams;
-  char              **mCachedAttrParamNames;
-  char              **mCachedAttrParamValues;
-  
 #ifdef XP_MACOSX
   NPEventModel mEventModel;
   // This is a hack! UseAsyncRendering() can incorrectly return false
   // when we don't have an object frame (possible as of bug 90268).
   // We hack around this by always returning true if we've ever
   // returned true.
   bool mUseAsyncRendering;
 #endif
@@ -365,19 +323,17 @@ private:
   nsRefPtr<nsPluginDOMContextMenuListener> mCXMenuListener;
   
   nsresult DispatchKeyToPlugin(nsIDOMEvent* aKeyEvent);
   nsresult DispatchMouseToPlugin(nsIDOMEvent* aMouseEvent,
                                  bool aAllowPropagate = false);
   nsresult DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent);
 
   int mLastMouseDownButtonType;
-  
-  nsresult EnsureCachedAttrParamArrays();
-  
+
 #ifdef MOZ_X11
   class Renderer
 #if defined(MOZ_WIDGET_QT)
   : public gfxQtNativeRenderer
 #else
   : public gfxXlibNativeRenderer
 #endif
   {
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -333,17 +333,18 @@ GonkGPSGeolocationProvider::GetDataConne
 
 void
 GonkGPSGeolocationProvider::SetAGpsDataConn(nsAString& aApn)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mAGpsInterface);
 
   bool hasUpdateNetworkAvailability = false;
-  if (mAGpsRilInterface->size >= sizeof(AGpsRilInterface) &&
+  if (mAGpsRilInterface &&
+      mAGpsRilInterface->size >= sizeof(AGpsRilInterface) &&
       mAGpsRilInterface->update_network_availability) {
     hasUpdateNetworkAvailability = true;
   }
 
   int32_t connectionState = GetDataConnectionState();
   NS_ConvertUTF16toUTF8 apn(aApn);
   if (connectionState == nsINetworkInterface::NETWORK_STATE_CONNECTED) {
     // The definition of availability is
@@ -421,17 +422,18 @@ GonkGPSGeolocationProvider::ReleaseDataC
   mRadioInterface->DeactivateDataCallByType(NS_LITERAL_STRING("supl"));
 }
 
 void
 GonkGPSGeolocationProvider::RequestSetID(uint32_t flags)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (!mRadioInterface) {
+  if (!mRadioInterface ||
+      !mAGpsInterface) {
     return;
   }
 
   AGpsSetIDType type = AGPS_SETID_TYPE_NONE;
 
   nsCOMPtr<nsIRilContext> rilCtx;
   mRadioInterface->GetRilContext(getter_AddRefs(rilCtx));
 
@@ -459,17 +461,18 @@ GonkGPSGeolocationProvider::RequestSetID
   }
 }
 
 void
 GonkGPSGeolocationProvider::SetReferenceLocation()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (!mRadioInterface) {
+  if (!mRadioInterface ||
+      !mAGpsRilInterface) {
     return;
   }
 
   nsCOMPtr<nsIRilContext> rilCtx;
   mRadioInterface->GetRilContext(getter_AddRefs(rilCtx));
 
   AGpsRefLocation location;
 
@@ -517,19 +520,17 @@ GonkGPSGeolocationProvider::SetReference
         cell->GetGsmCellId(&cid);
         // The valid range of cell id is 0x0 to 0xffffffff which is defined in
         // hardware/ril/include/telephony/ril.h
         if (cid >= 0x0 && cid <= 0xffffffff) {
           location.u.cellID.cid = cid;
         }
       }
     }
-    if (mAGpsRilInterface) {
-      mAGpsRilInterface->set_ref_location(&location, sizeof(location));
-    }
+    mAGpsRilInterface->set_ref_location(&location, sizeof(location));
   }
 }
 
 #endif // MOZ_B2G_RIL
 
 void
 GonkGPSGeolocationProvider::InjectLocation(double latitude,
                                            double longitude,
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -615,16 +615,18 @@ var interfaceNamesInGlobalScope =
     "MediaStream",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaStreamAudioDestinationNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaStreamAudioSourceNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MediaStreamEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "MediaStreamTrackEvent", pref: "media.peerconnection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaStreamTrack",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MessageEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MessagePort",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MimeType",
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -829,16 +831,20 @@ var interfaceNamesInGlobalScope =
     "Rect",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "RGBColor",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "RTCDataChannelEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "RTCPeerConnectionIceEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "RTCRtpReceiver", pref: "media.peerconnection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "RTCRtpSender", pref: "media.peerconnection.enabled"},
+// IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "RTCStatsReport", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Screen",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ScriptProcessorNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ScrollAreaEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/webidl/HTMLObjectElement.webidl
+++ b/dom/webidl/HTMLObjectElement.webidl
@@ -150,16 +150,23 @@ interface MozObjectLoadingContent {
   /**
    * Gets the content type that corresponds to the give MIME type.  See the
    * constants above for the list of possible values.  If nothing else fits,
    * TYPE_NULL will be returned.
    */
   [ChromeOnly]
   unsigned long getContentTypeForMIMEType(DOMString aMimeType);
 
+
+  [ChromeOnly]
+  sequence<MozPluginParameter> getPluginAttributes();
+
+  [ChromeOnly]
+  sequence<MozPluginParameter> getPluginParameters();
+
   /**
    * This method will play a plugin that has been stopped by the
    * click-to-play plugins or play-preview features.
    */
   [ChromeOnly, Throws]
   void playPlugin();
 
   /**
@@ -201,11 +208,20 @@ interface MozObjectLoadingContent {
 
   /**
    * This method will disable the play-preview plugin state.
    */
   [ChromeOnly, Throws]
   void cancelPlayPreview();
 };
 
+/**
+ * Name:Value pair type used for passing parameters to NPAPI or javascript
+ * plugins.
+ */
+dictionary MozPluginParameter {
+  DOMString name = "";
+  DOMString value = "";
+};
+
 HTMLObjectElement implements MozImageLoadingContent;
 HTMLObjectElement implements MozFrameLoaderOwner;
 HTMLObjectElement implements MozObjectLoadingContent;
--- a/dom/webidl/MediaStream.webidl
+++ b/dom/webidl/MediaStream.webidl
@@ -18,18 +18,19 @@ dictionary MediaStreamConstraints {
     (boolean or MediaTrackConstraints) video = false;
     boolean picture = false; // Mozilla legacy
     boolean fake = false;    // for testing
     DOMString? peerIdentity = null;
 };
 
 interface MediaStream {
     // readonly attribute DOMString    id;
-    sequence<AudioStreamTrack> getAudioTracks ();
-    sequence<VideoStreamTrack> getVideoTracks ();
+    sequence<AudioStreamTrack> getAudioTracks();
+    sequence<VideoStreamTrack> getVideoTracks();
+    sequence<MediaStreamTrack> getTracks();
     // MediaStreamTrack           getTrackById (DOMString trackId);
     // void                       addTrack (MediaStreamTrack track);
     // void                       removeTrack (MediaStreamTrack track);
     //         attribute boolean      ended;
     //         attribute EventHandler onended;
     //         attribute EventHandler onaddtrack;
     //         attribute EventHandler onremovetrack;
 	readonly attribute double currentTime;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MediaStreamTrackEvent.webidl
@@ -0,0 +1,22 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://dev.w3.org/2011/webrtc/editor/webrtc.html#mediastreamevent
+ */
+
+dictionary MediaStreamTrackEventInit : EventInit {
+  MediaStreamTrack? track = null;
+  RTCRtpReceiver? receiver = null;
+  MediaStream? stream = null;
+};
+
+[Pref="media.peerconnection.enabled",
+ Constructor(DOMString type, optional MediaStreamTrackEventInit eventInitDict)]
+interface MediaStreamTrackEvent : Event {
+  readonly attribute RTCRtpReceiver? receiver;
+  readonly attribute MediaStreamTrack? track;
+  readonly attribute MediaStream? stream;
+};
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -33,21 +33,21 @@ interface PeerConnectionImpl  {
   [Throws]
   void setRemoteDescription(long action, DOMString sdp);
 
   /* Stats call, calls either |onGetStatsSuccess| or |onGetStatsError| on our
      observer. (see the |PeerConnectionObserver| interface) */
   [Throws]
   void getStats(MediaStreamTrack? selector);
 
-  /* Adds the stream created by GetUserMedia */
+  /* Adds the tracks created by GetUserMedia */
   [Throws]
-  void addStream(MediaStream stream);
+  void addTrack(MediaStreamTrack track, MediaStream... streams);
   [Throws]
-  void removeStream(MediaStream stream);
+  void removeTrack(MediaStreamTrack track);
   [Throws]
   void closeStreams();
 
   sequence<MediaStream> getLocalStreams();
   sequence<MediaStream> getRemoteStreams();
 
   /* As the ICE candidates roll in this one should be called each time
    * in order to keep the candidate list up-to-date for the next SDP-related
--- a/dom/webidl/PeerConnectionObserver.webidl
+++ b/dom/webidl/PeerConnectionObserver.webidl
@@ -29,14 +29,14 @@ interface PeerConnectionObserver
   void onGetStatsError(unsigned long name, DOMString message);
 
   /* Data channel callbacks */
   void notifyDataChannel(DataChannel channel);
 
   /* Notification of one of several types of state changed */
   void onStateChange(PCObserverStateType state);
 
-  /* Changes to MediaStreams */
+  /* Changes to MediaStreamTracks */
   void onAddStream(MediaStream stream);
   void onRemoveStream();
-  void onAddTrack();
+  void onAddTrack(MediaStreamTrack track);
   void onRemoveTrack();
 };
--- a/dom/webidl/RTCPeerConnection.webidl
+++ b/dom/webidl/RTCPeerConnection.webidl
@@ -100,21 +100,35 @@ interface mozRTCPeerConnection : EventTa
   readonly attribute DOMString id;
 
   RTCConfiguration      getConfiguration ();
   sequence<MediaStream> getLocalStreams ();
   sequence<MediaStream> getRemoteStreams ();
   MediaStream? getStreamById (DOMString streamId);
   void addStream (MediaStream stream);
   void removeStream (MediaStream stream);
+
+  // replaces addStream; fails if already added
+  // because a track can be part of multiple streams, stream parameters
+  // indicate which particular streams should be referenced in signaling
+
+  RTCRtpSender addTrack(MediaStreamTrack track,
+                        MediaStream stream,
+                        MediaStream... moreStreams);
+  void removeTrack(RTCRtpSender sender);
+
+  sequence<RTCRtpSender> getSenders();
+  sequence<RTCRtpReceiver> getReceivers();
+
   void close ();
   attribute EventHandler onnegotiationneeded;
   attribute EventHandler onicecandidate;
   attribute EventHandler onsignalingstatechange;
   attribute EventHandler onaddstream;
+  attribute EventHandler onaddtrack;  // replaces onaddstream; see AddTrackEvent
   attribute EventHandler onremovestream;
   attribute EventHandler oniceconnectionstatechange;
 
   void getStats (MediaStreamTrack? selector,
                  RTCStatsCallback successCallback,
                  RTCPeerConnectionErrorCallback failureCallback);
 
   // Data channel.
new file mode 100644
--- /dev/null
+++ b/dom/webidl/RTCRtpReceiver.webidl
@@ -0,0 +1,14 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://lists.w3.org/Archives/Public/public-webrtc/2014May/0067.html
+ */
+
+[Pref="media.peerconnection.enabled",
+ JSImplementation="@mozilla.org/dom/rtpreceiver;1"]
+interface RTCRtpReceiver {
+  readonly attribute MediaStreamTrack track;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/RTCRtpSender.webidl
@@ -0,0 +1,14 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://lists.w3.org/Archives/Public/public-webrtc/2014May/0067.html
+ */
+
+[Pref="media.peerconnection.enabled",
+ JSImplementation="@mozilla.org/dom/rtpsender;1"]
+interface RTCRtpSender {
+  readonly attribute MediaStreamTrack track;
+};
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -309,16 +309,18 @@ WEBIDL_FILES = [
     'ResourceStats.webidl',
     'ResourceStatsManager.webidl',
     'RGBColor.webidl',
     'RTCConfiguration.webidl',
     'RTCIceCandidate.webidl',
     'RTCIdentityAssertion.webidl',
     'RTCPeerConnection.webidl',
     'RTCPeerConnectionStatic.webidl',
+    'RTCRtpReceiver.webidl',
+    'RTCRtpSender.webidl',
     'RTCSessionDescription.webidl',
     'RTCStatsReport.webidl',
     'Screen.webidl',
     'ScriptProcessorNode.webidl',
     'ScrollAreaEvent.webidl',
     'Selection.webidl',
     'ServiceWorker.webidl',
     'ServiceWorkerContainer.webidl',
@@ -640,16 +642,17 @@ GENERATED_EVENTS_WEBIDL_FILES = [
     'DeviceProximityEvent.webidl',
     'DeviceStorageChangeEvent.webidl',
     'DOMTransactionEvent.webidl',
     'DownloadEvent.webidl',
     'ErrorEvent.webidl',
     'HashChangeEvent.webidl',
     'IccChangeEvent.webidl',
     'MediaStreamEvent.webidl',
+    'MediaStreamTrackEvent.webidl',
     'MozApplicationEvent.webidl',
     'MozClirModeEvent.webidl',
     'MozContactChangeEvent.webidl',
     'MozEmergencyCbModeEvent.webidl',
     'MozInterAppMessageEvent.webidl',
     'MozMessageDeletedEvent.webidl',
     'MozMmsEvent.webidl',
     'MozOtaStatusEvent.webidl',
--- a/editor/libeditor/html/tests/test_bug599322.html
+++ b/editor/libeditor/html/tests/test_bug599322.html
@@ -16,18 +16,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="src">src<img src="/tests/editor/libeditor/html/tests/green.png"></div>
 <iframe id="dst" src="javascript:;"></iframe>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 599322.patch **/
 
-SimpleTest.expectAssertions(1);
-
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function() {
   var src = document.getElementById("src");
   var dst = document.getElementById("dst");
   var doc = dst.contentDocument;
   doc.open();
   doc.write("<html><head><base href='http://mochi.test:8888/'></head><body></body></html>");
   doc.close();
--- a/editor/libeditor/html/tests/test_bug674770-1.html
+++ b/editor/libeditor/html/tests/test_bug674770-1.html
@@ -17,21 +17,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <a href="file_bug674770-1.html" id="link1">test</a>
 <div contenteditable>
 <a href="file_bug674770-1.html" id="link2">test</a>
 </div>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
-if (!navigator.platform.startsWith("Linux")) {
-  SimpleTest.expectAssertions(1);
-}
-
-/** Test for Bug 674770 **/
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(function() {
   SpecialPowers.setBoolPref("middlemouse.paste", true);
   localStorage.removeItem("clicked");
   window.linkWasClicked = false;
 
   var link = document.querySelector("#link1");
   addEventListener("storage", function(e) {
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -4922,17 +4922,17 @@ nsEditor::InitializeSelection(nsIDOMEven
   nsCOMPtr<nsISelectionPrivate> selectionPrivate =
     do_QueryInterface(selection);
   NS_ENSURE_TRUE(selectionPrivate, NS_ERROR_UNEXPECTED);
 
   // Init the caret
   nsRefPtr<nsCaret> caret = presShell->GetCaret();
   NS_ENSURE_TRUE(caret, NS_ERROR_UNEXPECTED);
   caret->SetIgnoreUserModify(false);
-  caret->SetCaretDOMSelection(selection);
+  caret->SetSelection(selection);
   selCon->SetCaretReadOnly(IsReadonly());
   selCon->SetCaretEnabled(true);
 
   // Init selection
   selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
   selCon->SetSelectionFlags(nsISelectionDisplay::DISPLAY_ALL);
   selCon->RepaintSelection(nsISelectionController::SELECTION_NORMAL);
   // If the computed selection root isn't root content, we should set it
--- a/editor/libeditor/nsEditorEventListener.cpp
+++ b/editor/libeditor/nsEditorEventListener.cpp
@@ -690,48 +690,43 @@ nsEditorEventListener::DragOver(nsIDOMDr
   if (dropParent->IsEditable() && CanDrop(aDragEvent)) {
     aDragEvent->PreventDefault(); // consumed
 
     if (mCaret) {
       int32_t offset = 0;
       nsresult rv = aDragEvent->GetRangeOffset(&offset);
       NS_ENSURE_SUCCESS(rv, rv);
 
-      // to avoid flicker, we could track the node and offset to see if we moved
-      if (mCaret)
-        mCaret->EraseCaret();
-      
-      //mCaret->SetCaretVisible(true);   // make sure it's visible
-      mCaret->DrawAtPosition(parent, offset);
+      mCaret->SetVisible(true);
+      mCaret->SetCaretPosition(parent, offset);
     }
   }
   else
   {
     if (!IsFileControlTextBox()) {
       // This is needed when dropping on an input, to prevent the editor for
       // the editable parent from receiving the event.
       aDragEvent->StopPropagation();
     }
 
     if (mCaret)
     {
-      mCaret->EraseCaret();
+      mCaret->SetVisible(false);
     }
   }
 
   return NS_OK;
 }
 
 void
 nsEditorEventListener::CleanupDragDropCaret()
 {
   if (mCaret)
   {
-    mCaret->EraseCaret();
-    mCaret->SetCaretVisible(false);    // hide it, so that it turns off its timer
+    mCaret->SetVisible(false);    // hide it, so that it turns off its timer
 
     nsCOMPtr<nsIPresShell> presShell = GetPresShell();
     if (presShell)
     {
       nsCOMPtr<nsISelectionController> selCon(do_QueryInterface(presShell));
       if (selCon) {
         selCon->SetCaretEnabled(false);
       }
--- a/editor/libeditor/text/nsPlaintextEditor.cpp
+++ b/editor/libeditor/text/nsPlaintextEditor.cpp
@@ -757,22 +757,16 @@ NS_IMETHODIMP nsPlaintextEditor::InsertL
 
   nsAutoEditBatch beginBatching(this);
   nsAutoRules beginRulesSniffing(this, EditAction::insertBreak, nsIEditor::eNext);
 
   // pre-process
   nsRefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
-  // Batching the selection and moving nodes out from under the caret causes
-  // caret turds. Ask the shell to invalidate the caret now to avoid the turds.
-  nsCOMPtr<nsIPresShell> shell = GetPresShell();
-  NS_ENSURE_TRUE(shell, NS_ERROR_NOT_INITIALIZED);
-  shell->MaybeInvalidateCaretPosition();
-
   nsTextRulesInfo ruleInfo(EditAction::insertBreak);
   ruleInfo.maxLength = mMaxTextLength;
   bool cancel, handled;
   nsresult res = mRules->WillDoAction(selection, &ruleInfo, &cancel, &handled);
   NS_ENSURE_SUCCESS(res, res);
   if (!cancel && !handled)
   {
     // get the (collapsed) selection location
@@ -873,17 +867,17 @@ nsPlaintextEditor::UpdateIMEComposition(
     TextComposition::TextEventHandlingMarker
       textEventHandlingMarker(mComposition, widgetTextEvent);
 
     nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
 
     rv = InsertText(widgetTextEvent->theText);
 
     if (caretP) {
-      caretP->SetCaretDOMSelection(selection);
+      caretP->SetSelection(selection);
     }
   }
 
   // If still composing, we should fire input event via observer.
   // Note that if committed, we don't need to notify it since it will be
   // notified at followed compositionend event.
   // NOTE: We must notify after the auto batch will be gone.
   if (IsIMEComposing()) {
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -2030,32 +2030,31 @@ GLContext::OffscreenSize() const
 {
     MOZ_ASSERT(IsOffscreen());
     return mScreen->Size();
 }
 
 bool
 GLContext::CreateScreenBufferImpl(const IntSize& size, const SurfaceCaps& caps)
 {
-    GLScreenBuffer* newScreen = GLScreenBuffer::Create(this, size, caps);
+    UniquePtr<GLScreenBuffer> newScreen = GLScreenBuffer::Create(this, size, caps);
     if (!newScreen)
         return false;
 
     if (!newScreen->Resize(size)) {
-        delete newScreen;
         return false;
     }
 
     DestroyScreenBuffer();
 
     // This will rebind to 0 (Screen) if needed when
     // it falls out of scope.
     ScopedBindFramebuffer autoFB(this);
 
-    mScreen = newScreen;
+    mScreen = Move(newScreen);
 
     return true;
 }
 
 bool
 GLContext::ResizeScreenBuffer(const IntSize& size)
 {
     if (!IsOffscreenSizeAllowed(size))
@@ -2063,17 +2062,16 @@ GLContext::ResizeScreenBuffer(const IntS
 
     return mScreen->Resize(size);
 }
 
 
 void
 GLContext::DestroyScreenBuffer()
 {
-    delete mScreen;
     mScreen = nullptr;
 }
 
 void
 GLContext::ForceDirtyScreen()
 {
     ScopedBindFramebuffer autoFB(0);
 
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -2915,17 +2915,17 @@ public:
                               const GLuint depthRB,
                               const GLuint stencilRB,
                               const GLuint texture,
                               GLuint* drawFB,
                               GLuint* readFB);
 
 protected:
     friend class GLScreenBuffer;
-    GLScreenBuffer* mScreen;
+    UniquePtr<GLScreenBuffer> mScreen;
 
     void DestroyScreenBuffer();
 
     SharedSurface* mLockedSurface;
 
 public:
     void LockSurface(SharedSurface* surf) {
         MOZ_ASSERT(!mLockedSurface);
@@ -2941,17 +2941,17 @@ public:
         return mLockedSurface;
     }
 
     bool IsOffscreen() const {
         return mScreen;
     }
 
     GLScreenBuffer* Screen() const {
-        return mScreen;
+        return mScreen.get();
     }
 
     bool PublishFrame();
     SharedSurface* RequestFrame();
 
     /* Clear to transparent black, with 0 depth and stencil,
      * while preserving current ClearColor etc. values.
      * Useful for resizing offscreen buffers.
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -15,75 +15,78 @@
 #include "SharedSurfaceGralloc.h"
 #include "nsXULAppAPI.h"
 #endif
 #ifdef XP_MACOSX
 #include "SharedSurfaceIO.h"
 #endif
 #include "ScopedGLHelpers.h"
 #include "gfx2DGlue.h"
+#include "../layers/ipc/ShadowLayers.h"
 
 namespace mozilla {
 namespace gl {
 
 using gfx::SurfaceFormat;
 
-GLScreenBuffer*
+UniquePtr<GLScreenBuffer>
 GLScreenBuffer::Create(GLContext* gl,
                        const gfx::IntSize& size,
                        const SurfaceCaps& caps)
 {
+    UniquePtr<GLScreenBuffer> ret;
     if (caps.antialias &&
         !gl->IsSupported(GLFeature::framebuffer_multisample))
     {
-        return nullptr;
+        return Move(ret);
     }
 
-    SurfaceFactory* factory = nullptr;
+    UniquePtr<SurfaceFactory> factory;
 
 #ifdef MOZ_WIDGET_GONK
     /* On B2G, we want a Gralloc factory, and we want one right at the start */
     if (!factory &&
         caps.surfaceAllocator &&
         XRE_GetProcessType() != GeckoProcessType_Default)
     {
-        factory = new SurfaceFactory_Gralloc(gl, caps);
+        factory = MakeUnique<SurfaceFactory_Gralloc>(gl, caps);
     }
 #endif
 #ifdef XP_MACOSX
     /* On OSX, we want an IOSurface factory, and we want one right at the start */
     if (!factory) {
         factory = SurfaceFactory_IOSurface::Create(gl, caps);
     }
 #endif
 
-    if (!factory)
-        factory = new SurfaceFactory_Basic(gl, caps);
+    if (!factory) {
+        factory = MakeUnique<SurfaceFactory_Basic>(gl, caps);
+    }
 
-    SurfaceStream* stream = SurfaceStream::CreateForType(
-        SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
-                                          caps.preserve),
-        gl,
-        nullptr);
+    auto streamType = SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
+                                                        caps.preserve);
+    RefPtr<SurfaceStream> stream;
+    stream = SurfaceStream::CreateForType(streamType, gl, nullptr);
 
-    return new GLScreenBuffer(gl, caps, factory, stream);
+    ret.reset( new GLScreenBuffer(gl, caps, Move(factory), stream) );
+    return Move(ret);
 }
 
 GLScreenBuffer::~GLScreenBuffer()
 {
-    delete mDraw;
-    delete mRead;
+    mDraw = nullptr;
+    mRead = nullptr;
 
     // bug 914823: it is crucial to destroy the Factory _after_ we destroy
     // the SharedSurfaces around here! Reason: the shared surfaces will want
     // to ask the Allocator (e.g. the ClientLayerManager) to destroy their
     // buffers, but that Allocator may be kept alive by the Factory,
     // as it currently the case in SurfaceFactory_Gralloc holding a nsRefPtr
     // to the Allocator!
-    delete mFactory;
+    mFactory = nullptr;
 }
 
 
 void
 GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
 {
     GLuint drawFB = DrawFB();
     GLuint readFB = ReadFB();
@@ -367,32 +370,30 @@ GLScreenBuffer::AssureBlitted()
                                   LOCAL_GL_NEAREST);
         // Done!
     }
 
     mNeedsBlit = false;
 }
 
 void
-GLScreenBuffer::Morph(SurfaceFactory* newFactory, SurfaceStreamType streamType)
+GLScreenBuffer::Morph(UniquePtr<SurfaceFactory> newFactory,
+                      SurfaceStreamType streamType)
 {
     MOZ_ASSERT(mStream);
 
     if (newFactory) {
-        delete mFactory;
-        mFactory = newFactory;
+        mFactory = Move(newFactory);
     }
 
     if (mStream->mType == streamType)
         return;
 
-    SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mGL, mStream);
-    MOZ_ASSERT(newStream);
-
-    mStream = newStream;
+    mStream = SurfaceStream::CreateForType(streamType, mGL, mStream);
+    MOZ_ASSERT(mStream);
 }
 
 bool
 GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size)
 {
     ScopedBindFramebuffer autoFB(mGL);
 
     if (mRead && SharedSurf())
@@ -403,52 +404,46 @@ GLScreenBuffer::Attach(SharedSurface* su
     if (mRead &&
         surf->mAttachType == SharedSurf()->mAttachType &&
         size == Size())
     {
         // Same size, same type, ready for reuse!
         mRead->Attach(surf);
     } else {
         // Else something changed, so resize:
-        DrawBuffer* draw = nullptr;
+        UniquePtr<DrawBuffer> draw;
         bool drawOk = CreateDraw(size, &draw);  // Can be null.
 
-        ReadBuffer* read = CreateRead(surf);
+        UniquePtr<ReadBuffer> read = CreateRead(surf);
         bool readOk = !!read;
 
         if (!drawOk || !readOk) {
-            delete draw;
-            delete read;
-
             surf->UnlockProd();
 
             return false;
         }
 
-        delete mDraw;
-        delete mRead;
-
-        mDraw = draw;
-        mRead = read;
+        mDraw = Move(draw);
+        mRead = Move(read);
     }
 
     // Check that we're all set up.
     MOZ_ASSERT(SharedSurf() == surf);
 
     if (!PreserveBuffer()) {
         // DiscardFramebuffer here could help perf on some mobile platforms.
     }
 
     return true;
 }
 
 bool
 GLScreenBuffer::Swap(const gfx::IntSize& size)
 {
-    SharedSurface* nextSurf = mStream->SwapProducer(mFactory, size);
+    SharedSurface* nextSurf = mStream->SwapProducer(mFactory.get(), size);
     if (!nextSurf) {
         SurfaceFactory_Basic basicFactory(mGL, mFactory->mCaps);
         nextSurf = mStream->SwapProducer(&basicFactory, size);
         if (!nextSurf)
           return false;
 
         NS_WARNING("SwapProd failed for sophisticated Factory type, fell back to Basic.");
     }
@@ -464,34 +459,35 @@ GLScreenBuffer::PublishFrame(const gfx::
 
     bool good = Swap(size);
     return good;
 }
 
 bool
 GLScreenBuffer::Resize(const gfx::IntSize& size)
 {
-    SharedSurface* surface = mStream->Resize(mFactory, size);
-    if (!surface)
+    SharedSurface* surf = mStream->Resize(mFactory.get(), size);
+    if (!surf)
         return false;
 
-    return Attach(surface, size);
+    return Attach(surf, size);
 }
 
 bool
-GLScreenBuffer::CreateDraw(const gfx::IntSize& size, DrawBuffer** out_buffer)
+GLScreenBuffer::CreateDraw(const gfx::IntSize& size,
+                           UniquePtr<DrawBuffer>* out_buffer)
 {
     GLContext* gl = mFactory->mGL;
     const GLFormats& formats = mFactory->mFormats;
     const SurfaceCaps& caps = mFactory->DrawCaps();
 
     return DrawBuffer::Create(gl, caps, formats, size, out_buffer);
 }
 
-ReadBuffer*
+UniquePtr<ReadBuffer>
 GLScreenBuffer::CreateRead(SharedSurface* surf)
 {
     GLContext* gl = mFactory->mGL;
     const GLFormats& formats = mFactory->mFormats;
     const SurfaceCaps& caps = mFactory->ReadCaps();
 
     return ReadBuffer::Create(gl, caps, formats, surf);
 }
@@ -507,39 +503,40 @@ GLScreenBuffer::Readback(SharedSurface* 
   mGL->MakeCurrent();
 
   bool needsSwap = src != SharedSurf();
   if (needsSwap) {
       SharedSurf()->UnlockProd();
       src->LockProd();
   }
 
-  ReadBuffer* buffer = CreateRead(src);
-  MOZ_ASSERT(buffer);
 
-  ScopedBindFramebuffer autoFB(mGL, buffer->mFB);
-  ReadPixelsIntoDataSurface(mGL, dest);
+  {
+      UniquePtr<ReadBuffer> buffer = CreateRead(src);
+      MOZ_ASSERT(buffer);
 
-  delete buffer;
+      ScopedBindFramebuffer autoFB(mGL, buffer->mFB);
+      ReadPixelsIntoDataSurface(mGL, dest);
+  }
 
   if (needsSwap) {
       src->UnlockProd();
       SharedSurf()->LockProd();
   }
 }
 
 ////////////////////////////////////////////////////////////////////////
 // DrawBuffer
 
 bool
 DrawBuffer::Create(GLContext* const gl,
                    const SurfaceCaps& caps,
                    const GLFormats& formats,
                    const gfx::IntSize& size,
-                   DrawBuffer** out_buffer)
+                   UniquePtr<DrawBuffer>* out_buffer)
 {
     MOZ_ASSERT(out_buffer);
     *out_buffer = nullptr;
 
     if (!caps.color) {
         MOZ_ASSERT(!caps.alpha && !caps.depth && !caps.stencil);
 
         // Nothing is needed.
@@ -573,23 +570,23 @@ DrawBuffer::Create(GLContext* const gl,
 
     CreateRenderbuffersForOffscreen(gl, formats, size, caps.antialias,
                                     pColorMSRB, pDepthRB, pStencilRB);
 
     GLuint fb = 0;
     gl->fGenFramebuffers(1, &fb);
     gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
 
-    ScopedDeletePtr<DrawBuffer> buffer;
-    buffer = new DrawBuffer(gl, size, fb, colorMSRB, depthRB, stencilRB);
+    UniquePtr<DrawBuffer> ret( new DrawBuffer(gl, size, fb, colorMSRB,
+                                              depthRB, stencilRB) );
 
     if (!gl->IsFramebufferComplete(fb))
         return false;
 
-    *out_buffer = buffer.forget();
+    *out_buffer = Move(ret);
     return true;
 }
 
 DrawBuffer::~DrawBuffer()
 {
     mGL->MakeCurrent();
 
     GLuint fb = mFB;
@@ -601,30 +598,29 @@ DrawBuffer::~DrawBuffer()
 
     mGL->fDeleteFramebuffers(1, &fb);
     mGL->fDeleteRenderbuffers(3, rbs);
 }
 
 ////////////////////////////////////////////////////////////////////////
 // ReadBuffer
 
-ReadBuffer*
+UniquePtr<ReadBuffer>
 ReadBuffer::Create(GLContext* gl,
                    const SurfaceCaps& caps,
                    const GLFormats& formats,
                    SharedSurface* surf)
 {
     MOZ_ASSERT(surf);
 
     if (surf->mAttachType == AttachmentType::Screen) {
         // Don't need anything. Our read buffer will be the 'screen'.
 
-        return new ReadBuffer(gl,
-                              0, 0, 0,
-                              surf);
+        return UniquePtr<ReadBuffer>( new ReadBuffer(gl, 0, 0, 0,
+                                                     surf) );
     }
 
     GLuint depthRB = 0;
     GLuint stencilRB = 0;
 
     GLuint* pDepthRB   = caps.depth   ? &depthRB   : nullptr;
     GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
 
@@ -648,25 +644,23 @@ ReadBuffer::Create(GLContext* gl,
     }
     MOZ_ASSERT(colorTex || colorRB);
 
     GLuint fb = 0;
     gl->fGenFramebuffers(1, &fb);
     gl->AttachBuffersToFB(colorTex, colorRB, depthRB, stencilRB, fb, target);
     gl->mFBOMapping[fb] = surf;
 
+    UniquePtr<ReadBuffer> ret( new ReadBuffer(gl, fb, depthRB,
+                                              stencilRB, surf) );
+    if (!gl->IsFramebufferComplete(fb)) {
+        ret = nullptr;
+    }
 
-    ScopedDeletePtr<ReadBuffer> buffer;
-    buffer = new ReadBuffer(gl,
-                            fb, depthRB, stencilRB,
-                            surf);
-    if (!gl->IsFramebufferComplete(fb))
-        return nullptr;
-
-    return buffer.forget();
+    return Move(ret);
 }
 
 ReadBuffer::~ReadBuffer()
 {
     mGL->MakeCurrent();
 
     GLuint fb = mFB;
     GLuint rbs[] = {
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -16,16 +16,17 @@
 #define SCREEN_BUFFER_H_
 
 #include "SurfaceTypes.h"
 #include "SurfaceStream.h"
 #include "GLContextTypes.h"
 #include "GLDefs.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Point.h"
+#include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 namespace gl {
 
 class GLContext;
 class SharedSurface;
 class SurfaceStream;
 
@@ -33,17 +34,17 @@ class DrawBuffer
 {
 public:
     // Fallible!
     // But it may return true with *out_buffer==nullptr if unneeded.
     static bool Create(GLContext* const gl,
                        const SurfaceCaps& caps,
                        const GLFormats& formats,
                        const gfx::IntSize& size,
-                       DrawBuffer** out_buffer);
+                       UniquePtr<DrawBuffer>* out_buffer);
 
 protected:
     GLContext* const mGL;
 public:
     const gfx::IntSize mSize;
     const GLuint mFB;
 protected:
     const GLuint mColorMSRB;
@@ -67,20 +68,20 @@ protected:
 public:
     virtual ~DrawBuffer();
 };
 
 class ReadBuffer
 {
 public:
     // Infallible, always non-null.
-    static ReadBuffer* Create(GLContext* gl,
-                              const SurfaceCaps& caps,
-                              const GLFormats& formats,
-                              SharedSurface* surf);
+    static UniquePtr<ReadBuffer> Create(GLContext* gl,
+                                        const SurfaceCaps& caps,
+                                        const GLFormats& formats,
+                                        SharedSurface* surf);
 
 protected:
     GLContext* const mGL;
 public:
     const GLuint mFB;
 protected:
     // mFB has the following attachments:
     const GLuint mDepthRB;
@@ -113,51 +114,51 @@ public:
     }
 };
 
 
 class GLScreenBuffer
 {
 public:
     // Infallible.
-    static GLScreenBuffer* Create(GLContext* gl,
-                                  const gfx::IntSize& size,
-                                  const SurfaceCaps& caps);
+    static UniquePtr<GLScreenBuffer> Create(GLContext* gl,
+                                            const gfx::IntSize& size,
+                                            const SurfaceCaps& caps);
 
 protected:
-    GLContext* const mGL;         // Owns us.
+    GLContext* const mGL; // Owns us.
 public:
     const SurfaceCaps mCaps;
 protected:
-    SurfaceFactory* mFactory;  // Owned by us.
+    UniquePtr<SurfaceFactory> mFactory;
     RefPtr<SurfaceStream> mStream;
 
-    DrawBuffer* mDraw;            // Owned by us.
-    ReadBuffer* mRead;            // Owned by us.
+    UniquePtr<DrawBuffer> mDraw;
+    UniquePtr<ReadBuffer> mRead;
 
     bool mNeedsBlit;
 
     // Below are the parts that help us pretend to be framebuffer 0:
     GLuint mUserDrawFB;
     GLuint mUserReadFB;
     GLuint mInternalDrawFB;
     GLuint mInternalReadFB;
 
 #ifdef DEBUG
     bool mInInternalMode_DrawFB;
     bool mInInternalMode_ReadFB;
 #endif
 
     GLScreenBuffer(GLContext* gl,
                    const SurfaceCaps& caps,
-                   SurfaceFactory* factory,
-                   SurfaceStream* stream)
+                   UniquePtr<SurfaceFactory> factory,
+                   const RefPtr<SurfaceStream>& stream)
         : mGL(gl)
         , mCaps(caps)
-        , mFactory(factory)
+        , mFactory(Move(factory))
         , mStream(stream)
         , mDraw(nullptr)
         , mRead(nullptr)
         , mNeedsBlit(true)
         , mUserDrawFB(0)
         , mUserReadFB(0)
         , mInternalDrawFB(0)
         , mInternalReadFB(0)
@@ -170,17 +171,17 @@ protected:
 public:
     virtual ~GLScreenBuffer();
 
     SurfaceStream* Stream() const {
         return mStream;
     }
 
     SurfaceFactory* Factory() const {
-        return mFactory;
+        return mFactory.get();
     }
 
     SharedSurface* SharedSurf() const {
         MOZ_ASSERT(mRead);
         return mRead->SharedSurf();
     }
 
     bool PreserveBuffer() const {
@@ -230,34 +231,35 @@ public:
      * We haven't made any guarantee that rendering is actually
      * done when Morph is run, just that it can't run concurrently
      * with rendering. This means that we can't just drop the contents
      * of the buffer, since we may only be partially done rendering.
      *
      * Once you pass newFactory into Morph, newFactory will be owned by
      * GLScreenBuffer, so `forget` any references to it that still exist.
      */
-    void Morph(SurfaceFactory* newFactory, SurfaceStreamType streamType);
+    void Morph(UniquePtr<SurfaceFactory> newFactory,
+               SurfaceStreamType streamType);
 
 protected:
     // Returns false on error or inability to resize.
     bool Swap(const gfx::IntSize& size);
 
 public:
     bool PublishFrame(const gfx::IntSize& size);
 
     bool Resize(const gfx::IntSize& size);
 
     void Readback(SharedSurface* src, gfx::DataSourceSurface* dest);
 
 protected:
-    bool Attach(SharedSurface* surface, const gfx::IntSize& size);
+    bool Attach(SharedSurface* surf, const gfx::IntSize& size);
 
-    bool CreateDraw(const gfx::IntSize& size, DrawBuffer** out_buffer);
-    ReadBuffer* CreateRead(SharedSurface* surf);
+    bool CreateDraw(const gfx::IntSize& size, UniquePtr<DrawBuffer>* out_buffer);
+    UniquePtr<ReadBuffer> CreateRead(SharedSurface* surf);
 
 public:
     /* `fb` in these functions is the framebuffer the GLContext is hoping to
      * bind. When this is 0, we intercept the call and bind our own
      * framebuffers. As a client of these functions, just bind 0 when you want
      * to draw to the default framebuffer/'screen'.
      */
     void BindFB(GLuint fb);
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -24,25 +24,25 @@ SharedSurface::ProdCopy(SharedSurface* s
     MOZ_ASSERT((src == gl->GetLockedSurface()) == src->IsLocked());
 
     gl->MakeCurrent();
 
     if (src->mAttachType  == AttachmentType::Screen &&
         dest->mAttachType == AttachmentType::Screen)
     {
         // Here, we actually need to blit through a temp surface, so let's make one.
-        nsAutoPtr<SharedSurface_GLTexture> tempSurf;
+        UniquePtr<SharedSurface_GLTexture> tempSurf;
         tempSurf = SharedSurface_GLTexture::Create(gl,
                                                    gl,
                                                    factory->mFormats,
                                                    src->mSize,
                                                    factory->mCaps.alpha);
 
-        ProdCopy(src, tempSurf, factory);
-        ProdCopy(tempSurf, dest, factory);
+        ProdCopy(src, tempSurf.get(), factory);
+        ProdCopy(tempSurf.get(), dest, factory);
         return;
     }
 
     if (src->mAttachType == AttachmentType::Screen) {
         SharedSurface* origLocked = gl->GetLockedSurface();
         bool srcNeedsUnlock = false;
         bool origNeedsRelock = false;
         if (origLocked != src) {
@@ -263,53 +263,43 @@ SurfaceFactory::SurfaceFactory(GLContext
     , mType(type)
     , mFormats(gl->ChooseGLFormats(caps))
 {
     ChooseBufferBits(mCaps, &mDrawCaps, &mReadCaps);
 }
 
 SurfaceFactory::~SurfaceFactory()
 {
-    while (!mScraps.empty()) {
-        SharedSurface* cur = mScraps.front();
-        mScraps.pop();
-
-        delete cur;
+    while (!mScraps.Empty()) {
+        mScraps.Pop();
     }
 }
 
-SharedSurface*
+UniquePtr<SharedSurface>
 SurfaceFactory::NewSharedSurface(const gfx::IntSize& size)
 {
     // Attempt to reuse an old surface.
-    while (!mScraps.empty()) {
-        SharedSurface* cur = mScraps.front();
-        mScraps.pop();
+    while (!mScraps.Empty()) {
+        UniquePtr<SharedSurface> cur = mScraps.Pop();
+
         if (cur->mSize == size)
-            return cur;
+            return Move(cur);
 
-        // Destroy old surfaces of the wrong size.
-        delete cur;
+        // Let `cur` be destroyed as it falls out of scope, if it wasn't
+        // moved.
     }
 
-    SharedSurface* ret = CreateShared(size);
-
-    return ret;
+    return CreateShared(size);
 }
 
 // Auto-deletes surfs of the wrong type.
 void
-SurfaceFactory::Recycle(SharedSurface*& surf)
+SurfaceFactory::Recycle(UniquePtr<SharedSurface> surf)
 {
-    if (!surf)
-        return;
+    MOZ_ASSERT(surf);
 
     if (surf->mType == mType) {
-        mScraps.push(surf);
-    } else {
-        delete surf;
+        mScraps.Push(Move(surf));
     }
-
-    surf = nullptr;
 }
 
 } /* namespace gfx */
 } /* namespace mozilla */
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -17,16 +17,18 @@
 
 #include <queue>
 #include <stdint.h>
 
 #include "GLContextTypes.h"
 #include "GLDefs.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/gfx/Point.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/WeakPtr.h"
 #include "SurfaceTypes.h"
 
 namespace mozilla {
 namespace gl {
 
 class GLContext;
 class SurfaceFactory;
 
@@ -107,16 +109,47 @@ public:
                             GLsizei width, GLsizei height,
                             GLenum format, GLenum type,
                             GLvoid* pixels)
     {
         return false;
     }
 };
 
+template<typename T>
+class UniquePtrQueue
+{
+    std::queue<T*> mQueue;
+
+public:
+    ~UniquePtrQueue() {
+        MOZ_ASSERT(Empty());
+    }
+
+    bool Empty() const {
+        return mQueue.empty();
+    }
+
+    void Push(UniquePtr<T> up) {
+        T* p = up.release();
+        mQueue.push(p);
+    }
+
+    UniquePtr<T> Pop() {
+        UniquePtr<T> ret;
+
+        if (!mQueue.empty()) {
+            ret.reset(mQueue.front());
+            mQueue.pop();
+        }
+
+        return Move(ret);
+    }
+};
+
 class SurfaceFactory
 {
 public:
     GLContext* const mGL;
     const SurfaceCaps mCaps;
     const SharedSurfaceType mType;
     const GLFormats mFormats;
 
@@ -135,23 +168,23 @@ public:
         return mDrawCaps;
     }
 
     const SurfaceCaps& ReadCaps() const {
         return mReadCaps;
     }
 
 protected:
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) = 0;
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) = 0;
 
-    std::queue<SharedSurface*> mScraps;
+    UniquePtrQueue<SharedSurface> mScraps;
 
 public:
-    SharedSurface* NewSharedSurface(const gfx::IntSize& size);
+    UniquePtr<SharedSurface> NewSharedSurface(const gfx::IntSize& size);
 
     // Auto-deletes surfs of the wrong type.
-    void Recycle(SharedSurface*& surf);
+    void Recycle(UniquePtr<SharedSurface> surf);
 };
 
 } // namespace gl
 } // namespace mozilla
 
 #endif // SHARED_SURFACE_H_
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -6,33 +6,16 @@
 #include "SharedSurfaceANGLE.h"
 
 #include "GLContextEGL.h"
 #include "GLLibraryEGL.h"
 
 namespace mozilla {
 namespace gl {
 
-SurfaceFactory_ANGLEShareHandle*
-SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
-                                        const SurfaceCaps& caps)
-{
-    GLLibraryEGL* egl = &sEGLLibrary;
-    if (!egl)
-        return nullptr;
-
-    if (!egl->IsExtensionSupported(
-            GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle))
-    {
-        return nullptr;
-    }
-
-    return new SurfaceFactory_ANGLEShareHandle(gl, egl, caps);
-}
-
 EGLDisplay
 SharedSurface_ANGLEShareHandle::Display()
 {
     return mEGL->Display();
 }
 
 
 SharedSurface_ANGLEShareHandle::~SharedSurface_ANGLEShareHandle()
@@ -174,17 +157,17 @@ CreatePBufferSurface(GLLibraryEGL* egl,
         LOCAL_EGL_NONE
     };
 
     EGLSurface surface = egl->fCreatePbufferSurface(display, config, attribs);
 
     return surface;
 }
 
-SharedSurface_ANGLEShareHandle*
+/*static*/ UniquePtr<SharedSurface_ANGLEShareHandle>
 SharedSurface_ANGLEShareHandle::Create(GLContext* gl,
                                        EGLContext context, EGLConfig config,
                                        const gfx::IntSize& size, bool hasAlpha)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     MOZ_ASSERT(egl);
     MOZ_ASSERT(egl->IsExtensionSupported(
                GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle));
@@ -203,22 +186,40 @@ SharedSurface_ANGLEShareHandle::Create(G
                                              pbuffer,
                                              LOCAL_EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE,
                                              &shareHandle);
     if (!ok) {
         egl->fDestroySurface(egl->Display(), pbuffer);
         return nullptr;
     }
 
-    return new SharedSurface_ANGLEShareHandle(gl, egl,
-                                              size, hasAlpha,
-                                              context, pbuffer,
-                                              shareHandle);
+    typedef SharedSurface_ANGLEShareHandle ptrT;
+    UniquePtr<ptrT> ret( new ptrT(gl, egl, size, hasAlpha, context,
+                                  pbuffer, shareHandle) );
+    return Move(ret);
 }
 
+/*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
+SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl,
+                                        const SurfaceCaps& caps)
+{
+    GLLibraryEGL* egl = &sEGLLibrary;
+    if (!egl)
+        return nullptr;
+
+    auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle;
+    if (!egl->IsExtensionSupported(ext))
+    {
+        return nullptr;
+    }
+
+    typedef SurfaceFactory_ANGLEShareHandle ptrT;
+    UniquePtr<ptrT> ret( new ptrT(gl, egl, caps) );
+    return Move(ret);
+}
 
 SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
                                                                  GLLibraryEGL* egl,
                                                                  const SurfaceCaps& caps)
     : SurfaceFactory(gl, SharedSurfaceType::EGLSurfaceANGLE, caps)
     , mProdGL(gl)
     , mEGL(egl)
 {
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -15,20 +15,21 @@ namespace gl {
 
 class GLContext;
 class GLLibraryEGL;
 
 class SharedSurface_ANGLEShareHandle
     : public SharedSurface
 {
 public:
-    static SharedSurface_ANGLEShareHandle* Create(GLContext* gl,
-                                                  EGLContext context, EGLConfig config,
-                                                  const gfx::IntSize& size,
-                                                  bool hasAlpha);
+    static UniquePtr<SharedSurface_ANGLEShareHandle> Create(GLContext* gl,
+                                                            EGLContext context,
+                                                            EGLConfig config,
+                                                            const gfx::IntSize& size,
+                                                            bool hasAlpha);
 
     static SharedSurface_ANGLEShareHandle* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLSurfaceANGLE);
 
         return (SharedSurface_ANGLEShareHandle*)surf;
     }
 
 protected:
@@ -80,25 +81,25 @@ class SurfaceFactory_ANGLEShareHandle
 {
 protected:
     GLContext* const mProdGL;
     GLLibraryEGL* const mEGL;
     EGLContext mContext;
     EGLConfig mConfig;
 
 public:
-    static SurfaceFactory_ANGLEShareHandle* Create(GLContext* gl,
-                                                   const SurfaceCaps& caps);
+    static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
+                                                             const SurfaceCaps& caps);
 
 protected:
     SurfaceFactory_ANGLEShareHandle(GLContext* gl,
                                     GLLibraryEGL* egl,
                                     const SurfaceCaps& caps);
 
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_ANGLEShareHandle::Create(mProdGL,
                                                       mContext, mConfig,
                                                       size, hasAlpha);
     }
 };
 
 } /* namespace gfx */
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -11,52 +11,53 @@
 #include "GLReadTexImageHelper.h"
 #include "ScopedGLHelpers.h"
 #include "SharedSurface.h"
 #include "TextureGarbageBin.h"
 
 namespace mozilla {
 namespace gl {
 
-SharedSurface_EGLImage*
+/*static*/ UniquePtr<SharedSurface_EGLImage>
 SharedSurface_EGLImage::Create(GLContext* prodGL,
                                const GLFormats& formats,
                                const gfx::IntSize& size,
                                bool hasAlpha,
                                EGLContext context)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     MOZ_ASSERT(egl);
     MOZ_ASSERT(context);
 
+    UniquePtr<SharedSurface_EGLImage> ret;
+
     if (!HasExtensions(egl, prodGL)) {
-        return nullptr;
+        return Move(ret);
     }
 
     MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
     GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
     if (!prodTex) {
-        return nullptr;
+        return Move(ret);
     }
 
     EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex);
     EGLImage image = egl->fCreateImage(egl->Display(), context,
                                        LOCAL_EGL_GL_TEXTURE_2D, buffer,
                                        nullptr);
     if (!image) {
         prodGL->fDeleteTextures(1, &prodTex);
-        return nullptr;
+        return Move(ret);
     }
 
-    return new SharedSurface_EGLImage(prodGL, egl,
-                                      size, hasAlpha,
-                                      formats, prodTex, image);
+    ret.reset( new SharedSurface_EGLImage(prodGL, egl, size, hasAlpha,
+                                          formats, prodTex, image) );
+    return Move(ret);
 }
 
-
 bool
 SharedSurface_EGLImage::HasExtensions(GLLibraryEGL* egl, GLContext* gl)
 {
     return egl->HasKHRImageBase() &&
            egl->IsExtensionSupported(GLLibraryEGL::KHR_gl_texture_2D_image) &&
            gl->IsExtensionSupported(GLContext::OES_EGL_image_external);
 }
 
@@ -80,17 +81,16 @@ SharedSurface_EGLImage::SharedSurface_EG
     , mCurConsGL(nullptr)
     , mConsTex(0)
     , mSync(0)
 {}
 
 SharedSurface_EGLImage::~SharedSurface_EGLImage()
 {
     mEGL->fDestroyImage(Display(), mImage);
-    mImage = 0;
 
     mGL->MakeCurrent();
     mGL->fDeleteTextures(1, &mProdTex);
     mProdTex = 0;
 
     if (mConsTex) {
         MOZ_ASSERT(mGarbageBin);
         mGarbageBin->Trash(mConsTex);
@@ -211,24 +211,27 @@ SharedSurface_EGLImage::AcquireConsumerT
     }
 
     MOZ_ASSERT(consGL == mCurConsGL);
     *out_texture = mConsTex;
     *out_target = LOCAL_GL_TEXTURE_EXTERNAL;
 }
 
 
-SurfaceFactory_EGLImage*
+/*static*/ UniquePtr<SurfaceFactory_EGLImage>
 SurfaceFactory_EGLImage::Create(GLContext* prodGL,
-                                        const SurfaceCaps& caps)
+                                const SurfaceCaps& caps)
 {
     EGLContext context = GLContextEGL::Cast(prodGL)->GetEGLContext();
 
+    typedef SurfaceFactory_EGLImage ptrT;
+    UniquePtr<ptrT> ret;
+
     GLLibraryEGL* egl = &sEGLLibrary;
-    if (!SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
-        return nullptr;
+    if (SharedSurface_EGLImage::HasExtensions(egl, prodGL)) {
+        ret.reset( new ptrT(prodGL, context, caps) );
     }
 
-    return new SurfaceFactory_EGLImage(prodGL, context, caps);
+    return Move(ret);
 }
 
 } /* namespace gfx */
 } /* namespace mozilla */
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -17,36 +17,38 @@ namespace gl {
 class GLContext;
 class GLLibraryEGL;
 class TextureGarbageBin;
 
 class SharedSurface_EGLImage
     : public SharedSurface
 {
 public:
-    static SharedSurface_EGLImage* Create(GLContext* prodGL,
-                                          const GLFormats& formats,
-                                          const gfx::IntSize& size,
-                                          bool hasAlpha,
-                                          EGLContext context);
+    static UniquePtr<SharedSurface_EGLImage> Create(GLContext* prodGL,
+                                                    const GLFormats& formats,
+                                                    const gfx::IntSize& size,
+                                                    bool hasAlpha,
+                                                    EGLContext context);
 
     static SharedSurface_EGLImage* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLImageShare);
 
         return (SharedSurface_EGLImage*)surf;
     }
 
     static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
 
 protected:
     mutable Mutex mMutex;
     GLLibraryEGL* const mEGL;
     const GLFormats mFormats;
     GLuint mProdTex;
-    EGLImage mImage;
+public:
+    const EGLImage mImage;
+protected:
     GLContext* mCurConsGL;
     GLuint mConsTex;
     nsRefPtr<TextureGarbageBin> mGarbageBin;
     EGLSync mSync;
 
     SharedSurface_EGLImage(GLContext* gl,
                            GLLibraryEGL* egl,
                            const gfx::IntSize& size,
@@ -79,31 +81,31 @@ public:
 
 
 
 class SurfaceFactory_EGLImage
     : public SurfaceFactory
 {
 public:
     // Fallible:
-    static SurfaceFactory_EGLImage* Create(GLContext* prodGL,
-                                           const SurfaceCaps& caps);
+    static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
+                                                     const SurfaceCaps& caps);
 
 protected:
     const EGLContext mContext;
 
     SurfaceFactory_EGLImage(GLContext* prodGL,
                             EGLContext context,
                             const SurfaceCaps& caps)
         : SurfaceFactory(prodGL, SharedSurfaceType::EGLImageShare, caps)
         , mContext(context)
     {}
 
 public:
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_EGLImage::Create(mGL, mFormats, size, hasAlpha, mContext);
     }
 };
 
 } /* namespace gfx */
 } /* namespace mozilla */
 
--- a/gfx/gl/SharedSurfaceGL.cpp
+++ b/gfx/gl/SharedSurfaceGL.cpp
@@ -12,17 +12,17 @@
 #include "GLReadTexImageHelper.h"
 
 namespace mozilla {
 namespace gl {
 
 using gfx::IntSize;
 using gfx::SurfaceFormat;
 
-SharedSurface_Basic*
+/*static*/ UniquePtr<SharedSurface_Basic>
 SharedSurface_Basic::Create(GLContext* gl,
                             const GLFormats& formats,
                             const IntSize& size,
                             bool hasAlpha)
 {
     gl->MakeCurrent();
     GLuint tex = CreateTexture(gl, formats.color_texInternalFormat,
                                formats.color_texFormat,
@@ -40,17 +40,20 @@ SharedSurface_Basic::Create(GLContext* g
         break;
     case LOCAL_GL_RGBA:
     case LOCAL_GL_RGBA8:
         format = SurfaceFormat::B8G8R8A8;
         break;
     default:
         MOZ_CRASH("Unhandled Tex format.");
     }
-    return new SharedSurface_Basic(gl, size, hasAlpha, format, tex);
+
+    typedef SharedSurface_Basic ptrT;
+    UniquePtr<ptrT> ret( new ptrT(gl, size, hasAlpha, format, tex) );
+    return Move(ret);
 }
 
 SharedSurface_Basic::SharedSurface_Basic(GLContext* gl,
                                          const IntSize& size,
                                          bool hasAlpha,
                                          SurfaceFormat format,
                                          GLuint tex)
     : SharedSurface(SharedSurfaceType::Basic,
@@ -95,19 +98,20 @@ SharedSurface_Basic::~SharedSurface_Basi
 void
 SharedSurface_Basic::Fence()
 {
     mGL->MakeCurrent();
     ScopedBindFramebuffer autoFB(mGL, mFB);
     ReadPixelsIntoDataSurface(mGL, mData);
 }
 
-
+////////////////////////////////////////////////////////////////////////
+// SharedSurface_GLTexture
 
-SharedSurface_GLTexture*
+/*static*/ UniquePtr<SharedSurface_GLTexture>
 SharedSurface_GLTexture::Create(GLContext* prodGL,
                                 GLContext* consGL,
                                 const GLFormats& formats,
                                 const IntSize& size,
                                 bool hasAlpha,
                                 GLuint texture)
 {
     MOZ_ASSERT(prodGL);
@@ -119,17 +123,20 @@ SharedSurface_GLTexture::Create(GLContex
 
     bool ownsTex = false;
 
     if (!tex) {
       tex = CreateTextureForOffscreen(prodGL, formats, size);
       ownsTex = true;
     }
 
-    return new SharedSurface_GLTexture(prodGL, consGL, size, hasAlpha, tex, ownsTex);
+    typedef SharedSurface_GLTexture ptrT;
+    UniquePtr<ptrT> ret( new ptrT(prodGL, consGL, size, hasAlpha, tex,
+                                  ownsTex) );
+    return Move(ret);
 }
 
 SharedSurface_GLTexture::~SharedSurface_GLTexture()
 {
     if (!mGL->MakeCurrent())
         return;
 
     if (mOwnsTex) {
--- a/gfx/gl/SharedSurfaceGL.h
+++ b/gfx/gl/SharedSurfaceGL.h
@@ -29,20 +29,20 @@ namespace mozilla {
 namespace mozilla {
 namespace gl {
 
 // For readback and bootstrapping:
 class SharedSurface_Basic
     : public SharedSurface
 {
 public:
-    static SharedSurface_Basic* Create(GLContext* gl,
-                                       const GLFormats& formats,
-                                       const gfx::IntSize& size,
-                                       bool hasAlpha);
+    static UniquePtr<SharedSurface_Basic> Create(GLContext* gl,
+                                                 const GLFormats& formats,
+                                                 const gfx::IntSize& size,
+                                                 bool hasAlpha);
 
     static SharedSurface_Basic* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::Basic);
 
         return (SharedSurface_Basic*)surf;
     }
 
 protected:
@@ -85,34 +85,34 @@ public:
 class SurfaceFactory_Basic
     : public SurfaceFactory
 {
 public:
     SurfaceFactory_Basic(GLContext* gl, const SurfaceCaps& caps)
         : SurfaceFactory(gl, SharedSurfaceType::Basic, caps)
     {}
 
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_Basic::Create(mGL, mFormats, size, hasAlpha);
     }
 };
 
 
 // Using shared GL textures:
 class SharedSurface_GLTexture
     : public SharedSurface
 {
 public:
-    static SharedSurface_GLTexture* Create(GLContext* prodGL,
-                                           GLContext* consGL,
-                                           const GLFormats& formats,
-                                           const gfx::IntSize& size,
-                                           bool hasAlpha,
-                                           GLuint texture = 0);
+    static UniquePtr<SharedSurface_GLTexture> Create(GLContext* prodGL,
+                                                     GLContext* consGL,
+                                                     const GLFormats& formats,
+                                                     const gfx::IntSize& size,
+                                                     bool hasAlpha,
+                                                     GLuint texture = 0);
 
     static SharedSurface_GLTexture* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::GLTextureShare);
 
         return (SharedSurface_GLTexture*)surf;
     }
 
 protected:
@@ -178,17 +178,17 @@ public:
                              GLContext* consGL,
                              const SurfaceCaps& caps)
         : SurfaceFactory(prodGL, SharedSurfaceType::GLTextureShare, caps)
         , mConsGL(consGL)
     {
         MOZ_ASSERT(consGL != prodGL);
     }
 
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_GLTexture::Create(mGL, mConsGL, mFormats, size, hasAlpha);
     }
 };
 
 } /* namespace gfx */
 } /* namespace mozilla */
 
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -44,82 +44,88 @@ SurfaceFactory_Gralloc::SurfaceFactory_G
         allocator = caps.surfaceAllocator;
     }
 
     MOZ_ASSERT(allocator);
 
     mAllocator = allocator;
 }
 
-SharedSurface_Gralloc*
+/*static*/ UniquePtr<SharedSurface_Gralloc>
 SharedSurface_Gralloc::Create(GLContext* prodGL,
                               const GLFormats& formats,
                               const gfx::IntSize& size,
                               bool hasAlpha,
                               ISurfaceAllocator* allocator)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     MOZ_ASSERT(egl);
 
+    UniquePtr<SharedSurface_Gralloc> ret;
+
     DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
 
     if (!HasExtensions(egl, prodGL))
-        return nullptr;
+        return Move(ret);
 
     gfxContentType type = hasAlpha ? gfxContentType::COLOR_ALPHA
                                    : gfxContentType::COLOR;
 
     gfxImageFormat format
       = gfxPlatform::GetPlatform()->OptimalFormatForContent(type);
 
     RefPtr<GrallocTextureClientOGL> grallocTC =
       new GrallocTextureClientOGL(
           allocator,
           gfx::ImageFormatToSurfaceFormat(format),
           gfx::BackendType::NONE, // we don't need to use it with a DrawTarget
           layers::TextureFlags::DEFAULT);
 
     if (!grallocTC->AllocateForGLRendering(size)) {
-      return nullptr;
+      return Move(ret);
     }
 
     sp<GraphicBuffer> buffer = grallocTC->GetGraphicBuffer();
 
     EGLDisplay display = egl->Display();
     EGLClientBuffer clientBuffer = buffer->getNativeBuffer();
     EGLint attrs[] = {
         LOCAL_EGL_NONE, LOCAL_EGL_NONE
     };
     EGLImage image = egl->fCreateImage(display,
                                        EGL_NO_CONTEXT,
                                        LOCAL_EGL_NATIVE_BUFFER_ANDROID,
                                        clientBuffer, attrs);
     if (!image) {
-        return nullptr;
+        return Move(ret);
     }
 
     prodGL->MakeCurrent();
     GLuint prodTex = 0;
     prodGL->fGenTextures(1, &prodTex);
     ScopedBindTexture autoTex(prodGL, prodTex);
 
     prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
     prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
     prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
     prodGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 
     prodGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_2D, image);
 
     egl->fDestroyImage(display, image);
 
-    SharedSurface_Gralloc *surf = new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl, allocator, grallocTC, prodTex);
+    ret.reset( new SharedSurface_Gralloc(prodGL, size, hasAlpha, egl,
+                                         allocator, grallocTC,
+                                         prodTex) );
 
-    DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p, GraphicBuffer %p.\n", surf, buffer.get());
+    DEBUG_PRINT("SharedSurface_Gralloc::Create: success -- surface %p,"
+                " GraphicBuffer %p.\n",
+                ret.get(), buffer.get());
 
-    return surf;
+    return Move(ret);
 }
 
 
 SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
                                              const gfx::IntSize& size,
                                              bool hasAlpha,
                                              GLLibraryEGL* egl,
                                              layers::ISurfaceAllocator* allocator,
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -18,21 +18,21 @@ class GrallocTextureClientOGL;
 namespace gl {
 class GLContext;
 class GLLibraryEGL;
 
 class SharedSurface_Gralloc
     : public SharedSurface
 {
 public:
-    static SharedSurface_Gralloc* Create(GLContext* prodGL,
-                                         const GLFormats& formats,
-                                         const gfx::IntSize& size,
-                                         bool hasAlpha,
-                                         layers::ISurfaceAllocator* allocator);
+    static UniquePtr<SharedSurface_Gralloc> Create(GLContext* prodGL,
+                                                   const GLFormats& formats,
+                                                   const gfx::IntSize& size,
+                                                   bool hasAlpha,
+                                                   layers::ISurfaceAllocator* allocator);
 
     static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::Gralloc);
 
         return (SharedSurface_Gralloc*)surf;
     }
 
 protected:
@@ -79,21 +79,24 @@ class SurfaceFactory_Gralloc
 protected:
     RefPtr<layers::ISurfaceAllocator> mAllocator;
 
 public:
     SurfaceFactory_Gralloc(GLContext* prodGL,
                            const SurfaceCaps& caps,
                            layers::ISurfaceAllocator* allocator = nullptr);
 
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE {
         bool hasAlpha = mReadCaps.alpha;
-        if (!mAllocator) {
-            return nullptr;
+
+        UniquePtr<SharedSurface> ret;
+        if (mAllocator) {
+            ret = SharedSurface_Gralloc::Create(mGL, mFormats, size,
+                                                hasAlpha, mAllocator);
         }
-        return SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha, mAllocator);
+        return Move(ret);
     }
 };
 
 } /* namespace gl */
 } /* namespace mozilla */
 
 #endif /* SHARED_SURFACE_GRALLOC_H_ */
--- a/gfx/gl/SharedSurfaceIO.cpp
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -8,24 +8,29 @@
 #include "GLContextCGL.h"
 #include "mozilla/gfx/MacIOSurface.h"
 #include "mozilla/DebugOnly.h"
 #include "ScopedGLHelpers.h"
 
 namespace mozilla {
 namespace gl {
 
-/* static */ SharedSurface_IOSurface*
-SharedSurface_IOSurface::Create(MacIOSurface* surface, GLContext* gl, bool hasAlpha)
+/*static*/ UniquePtr<SharedSurface_IOSurface>
+SharedSurface_IOSurface::Create(const RefPtr<MacIOSurface>& ioSurf,
+                                GLContext* gl,
+                                bool hasAlpha)
 {
-    MOZ_ASSERT(surface);
+    MOZ_ASSERT(ioSurf);
     MOZ_ASSERT(gl);
 
-    gfx::IntSize size(surface->GetWidth(), surface->GetHeight());
-    return new SharedSurface_IOSurface(surface, gl, size, hasAlpha);
+    gfx::IntSize size(ioSurf->GetWidth(), ioSurf->GetHeight());
+
+    typedef SharedSurface_IOSurface ptrT;
+    UniquePtr<ptrT> ret( new ptrT(ioSurf, gl, size, hasAlpha) );
+    return Move(ret);
 }
 
 void
 SharedSurface_IOSurface::Fence()
 {
     mGL->MakeCurrent();
     mGL->fFlush();
 }
@@ -82,88 +87,94 @@ BackTextureWithIOSurf(GLContext* gl, GLu
                         LOCAL_GL_CLAMP_TO_EDGE);
 
     CGLContextObj cgl = GLContextCGL::Cast(gl)->GetCGLContext();
     MOZ_ASSERT(cgl);
 
     ioSurf->CGLTexImageIOSurface2D(cgl);
 }
 
-SharedSurface_IOSurface::SharedSurface_IOSurface(MacIOSurface* surface,
+SharedSurface_IOSurface::SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
                                                  GLContext* gl,
                                                  const gfx::IntSize& size,
                                                  bool hasAlpha)
   : SharedSurface(SharedSurfaceType::IOSurface,
                   AttachmentType::GLTexture,
                   gl,
                   size,
                   hasAlpha)
-  , mSurface(surface)
+  , mIOSurf(ioSurf)
   , mCurConsGL(nullptr)
   , mConsTex(0)
 {
     gl->MakeCurrent();
     mProdTex = 0;
     gl->fGenTextures(1, &mProdTex);
-    BackTextureWithIOSurf(gl, mProdTex, surface);
+    BackTextureWithIOSurf(gl, mProdTex, mIOSurf);
 }
 
 GLuint
 SharedSurface_IOSurface::ConsTexture(GLContext* consGL)
 {
     if (!mCurConsGL) {
         mCurConsGL = consGL;
     }
     MOZ_ASSERT(consGL == mCurConsGL);
 
     if (!mConsTex) {
         consGL->MakeCurrent();
         mConsTex = 0;
         consGL->fGenTextures(1, &mConsTex);
-        BackTextureWithIOSurf(consGL, mConsTex, mSurface);
+        BackTextureWithIOSurf(consGL, mConsTex, mIOSurf);
     }
 
     return mConsTex;
 }
 
 SharedSurface_IOSurface::~SharedSurface_IOSurface()
 {
     if (mProdTex) {
         DebugOnly<bool> success = mGL->MakeCurrent();
         MOZ_ASSERT(success);
         mGL->fDeleteTextures(1, &mProdTex);
         mGL->fDeleteTextures(1, &mConsTex); // This will work if we're shared.
     }
 }
 
+////////////////////////////////////////////////////////////////////////
+// SurfaceFactory_IOSurface
 
-/*static*/ SurfaceFactory_IOSurface*
+/*static*/ UniquePtr<SurfaceFactory_IOSurface>
 SurfaceFactory_IOSurface::Create(GLContext* gl,
                                  const SurfaceCaps& caps)
 {
     gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
                          MacIOSurface::GetMaxHeight());
-    return new SurfaceFactory_IOSurface(gl, caps, maxDims);
+
+    typedef SurfaceFactory_IOSurface ptrT;
+    UniquePtr<ptrT> ret( new ptrT(gl, caps, maxDims) );
+    return Move(ret);
 }
 
-SharedSurface*
+UniquePtr<SharedSurface>
 SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
 {
     if (size.width > mMaxDims.width ||
         size.height > mMaxDims.height)
     {
         return nullptr;
     }
 
     bool hasAlpha = mReadCaps.alpha;
-    RefPtr<MacIOSurface> surf =
-        MacIOSurface::CreateIOSurface(size.width, size.height, 1.0, hasAlpha);
+    RefPtr<MacIOSurface> ioSurf;
+    ioSurf = MacIOSurface::CreateIOSurface(size.width, size.height, 1.0,
+                                           hasAlpha);
 
-    if (!surf) {
+    if (!ioSurf) {
         NS_WARNING("Failed to create MacIOSurface.");
         return nullptr;
     }
 
-    return SharedSurface_IOSurface::Create(surf, mGL, hasAlpha);
+    return SharedSurface_IOSurface::Create(ioSurf, mGL, hasAlpha);
 }
 
 }
 }
--- a/gfx/gl/SharedSurfaceIO.h
+++ b/gfx/gl/SharedSurfaceIO.h
@@ -12,17 +12,19 @@
 class MacIOSurface;
 
 namespace mozilla {
 namespace gl {
 
 class SharedSurface_IOSurface : public SharedSurface
 {
 public:
-    static SharedSurface_IOSurface* Create(MacIOSurface* surface, GLContext* gl, bool hasAlpha);
+    static UniquePtr<SharedSurface_IOSurface> Create(const RefPtr<MacIOSurface>& ioSurf,
+                                                     GLContext* gl,
+                                                     bool hasAlpha);
 
     ~SharedSurface_IOSurface();
 
     virtual void LockProdImpl() MOZ_OVERRIDE { }
     virtual void UnlockProdImpl() MOZ_OVERRIDE { }
 
     virtual void Fence() MOZ_OVERRIDE;
     virtual bool WaitSync() MOZ_OVERRIDE { return true; }
@@ -46,44 +48,46 @@ public:
 
     GLuint ConsTexture(GLContext* consGL);
 
     GLenum ConsTextureTarget() const {
         return LOCAL_GL_TEXTURE_RECTANGLE_ARB;
     }
 
     MacIOSurface* GetIOSurface() const {
-        return mSurface;
+        return mIOSurf;
     }
 
 private:
-    SharedSurface_IOSurface(MacIOSurface* surface, GLContext* gl, const gfx::IntSize& size, bool hasAlpha);
+    SharedSurface_IOSurface(const RefPtr<MacIOSurface>& ioSurf,
+                            GLContext* gl, const gfx::IntSize& size,
+                            bool hasAlpha);
 
-    RefPtr<MacIOSurface> mSurface;
+    RefPtr<MacIOSurface> mIOSurf;
     GLuint mProdTex;
     const GLContext* mCurConsGL;
     GLuint mConsTex;
 };
 
 class SurfaceFactory_IOSurface : public SurfaceFactory
 {
 public:
     // Infallible.
-    static SurfaceFactory_IOSurface* Create(GLContext* gl,
-                                            const SurfaceCaps& caps);
+    static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
+                                                      const SurfaceCaps& caps);
 protected:
     const gfx::IntSize mMaxDims;
 
     SurfaceFactory_IOSurface(GLContext* gl,
                              const SurfaceCaps& caps,
                              const gfx::IntSize& maxDims)
         : SurfaceFactory(gl, SharedSurfaceType::IOSurface, caps)
         , mMaxDims(maxDims)
     {
     }
 
-    virtual SharedSurface* CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE;
+    virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) MOZ_OVERRIDE;
 };
 
 } /* namespace gfx */
 } /* namespace mozilla */
 
 #endif /* SHARED_SURFACEIO_H_ */
--- a/gfx/gl/SurfaceStream.cpp
+++ b/gfx/gl/SurfaceStream.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SurfaceStream.h"
 
 #include "gfxPoint.h"
 #include "SharedSurface.h"
 #include "SharedSurfaceGL.h"
 #include "GeckoProfiler.h"
+#include "mozilla/Move.h"
 
 namespace mozilla {
 namespace gl {
 
 SurfaceStreamType
 SurfaceStream::ChooseGLStreamType(SurfaceStream::OMTC omtc,
                                   bool preserveBuffer)
 {
@@ -25,20 +26,20 @@ SurfaceStream::ChooseGLStreamType(Surfac
     } else {
         if (preserveBuffer)
             return SurfaceStreamType::SingleBuffer;
         else
             return SurfaceStreamType::TripleBuffer;
     }
 }
 
-SurfaceStream*
+TemporaryRef<SurfaceStream>
 SurfaceStream::CreateForType(SurfaceStreamType type, mozilla::gl::GLContext* glContext, SurfaceStream* prevStream)
 {
-    SurfaceStream* result = nullptr;
+    RefPtr<SurfaceStream> result;
 
     switch (type) {
         case SurfaceStreamType::SingleBuffer:
             result = new SurfaceStream_SingleBuffer(prevStream);
             break;
         case SurfaceStreamType::TripleBuffer_Copy:
             result = new SurfaceStream_TripleBuffer_Copy(prevStream);
             break;
@@ -48,131 +49,185 @@ SurfaceStream::CreateForType(SurfaceStre
         case SurfaceStreamType::TripleBuffer:
             result = new SurfaceStream_TripleBuffer(prevStream);
             break;
         default:
             MOZ_CRASH("Invalid Type.");
     }
 
     result->mGLContext = glContext;
-    return result;
+
+    return result.forget();
 }
 
 bool
 SurfaceStream_TripleBuffer::CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory)
 {
     if (!mProducer) {
-        New(factory, src->mSize, mProducer);
+        New(factory, src->mSize, &mProducer);
         if (!mProducer) {
             return false;
         }
     }
 
     MOZ_ASSERT(src->mSize == mProducer->mSize, "Size mismatch");
 
-    SharedSurface::ProdCopy(src, mProducer, factory);
+    SharedSurface::ProdCopy(src, mProducer.get(), factory);
     return true;
 }
 
 void
 SurfaceStream::New(SurfaceFactory* factory, const gfx::IntSize& size,
-                   SharedSurface*& surf)
+                   UniquePtr<SharedSurface>* surfSlot)
 {
+    MOZ_ASSERT(surfSlot);
+    UniquePtr<SharedSurface>& surf = *surfSlot;
+
     MOZ_ASSERT(!surf);
     surf = factory->NewSharedSurface(size);
 
     if (surf) {
         // Before next use, wait until SharedSurface's buffer
         // is no longer being used.
         surf->WaitForBufferOwnership();
-        mSurfaces.insert(surf);
+#ifdef DEBUG
+        mSurfaces.insert(surf.get());
+#endif
     }
 }
 
 void
-SurfaceStream::Recycle(SurfaceFactory* factory, SharedSurface*& surf)
+SurfaceStream::MoveTo(UniquePtr<SharedSurface>* slotFrom,
+                      UniquePtr<SharedSurface>* slotTo)
 {
+    MOZ_ASSERT(slotFrom);
+    UniquePtr<SharedSurface>& from = *slotFrom;
+
+    MOZ_ASSERT(slotTo);
+    UniquePtr<SharedSurface>& to = *slotTo;
+
+    MOZ_ASSERT(!to);
+    to = Move(from);
+    MOZ_ASSERT(!from);
+}
+
+void
+SurfaceStream::Recycle(SurfaceFactory* factory, UniquePtr<SharedSurface>* surfSlot)
+{
+    MOZ_ASSERT(surfSlot);
+    UniquePtr<SharedSurface>& surf = *surfSlot;
+
     if (surf) {
-        mSurfaces.erase(surf);
-        factory->Recycle(surf);
+#ifdef DEBUG
+        mSurfaces.erase(surf.get());
+#endif
+        factory->Recycle(Move(surf));
     }
     MOZ_ASSERT(!surf);
 }
 
 void
-SurfaceStream::Delete(SharedSurface*& surf)
+SurfaceStream::Delete(UniquePtr<SharedSurface>* surfSlot)
 {
+    MOZ_ASSERT(surfSlot);
+    UniquePtr<SharedSurface>& surf = *surfSlot;
+
     if (surf) {
-        mSurfaces.erase(surf);
-        delete surf;
+#ifdef DEBUG
+        mSurfaces.erase(surf.get());
+#endif
         surf = nullptr;
     }
     MOZ_ASSERT(!surf);
 }
 
-SharedSurface*
-SurfaceStream::Surrender(SharedSurface*& surf)
+UniquePtr<SharedSurface>
+SurfaceStream::Surrender(UniquePtr<SharedSurface>* surfSlot)
 {
-    SharedSurface* ret = surf;
+    MOZ_ASSERT(surfSlot);
+    UniquePtr<SharedSurface>& surf = *surfSlot;
+
+#ifdef DEBUG
+    if (surf) {
+        mSurfaces.erase(surf.get());
+    }
+#endif
+
+    UniquePtr<SharedSurface> ret = Move(surf);
+    MOZ_ASSERT(!surf);
+
+    return Move(ret);
+}
+
+// Move `surfSlot` to `return`, but record that the surf is now part of
+// this stream.
+UniquePtr<SharedSurface>
+SurfaceStream::Absorb(UniquePtr<SharedSurface>* surfSlot)
+{
+    MOZ_ASSERT(surfSlot);
+    UniquePtr<SharedSurface>& surf = *surfSlot;
+
+#ifdef DEBUG
+    if (surf) {
+        mSurfaces.insert(surf.get());
+    }
+#endif
+
+    UniquePtr<SharedSurface> ret = Move(surf);
+    MOZ_ASSERT(!surf);
+
+    return Move(ret);
+}
+
+void
+SurfaceStream::Scrap(UniquePtr<SharedSurface>* surfSlot)
+{
+    MOZ_ASSERT(surfSlot);
+    UniquePtr<SharedSurface>& surf = *surfSlot;
 
     if (surf) {
-        mSurfaces.erase(surf);
-        surf = nullptr;
+        mScraps.Push(Move(surf));
     }
     MOZ_ASSERT(!surf);
 
-    return ret;
-}
-
-SharedSurface*
-SurfaceStream::Absorb(SharedSurface*& surf)
-{
-    SharedSurface* ret = surf;
-
-    if (surf) {
-        mSurfaces.insert(surf);
-        surf = nullptr;
-    }
-    MOZ_ASSERT(!surf);
-
-    return ret;
-}
-
-void
-SurfaceStream::Scrap(SharedSurface*& scrap)
-{
-    if (scrap) {
-        mScraps.push(scrap);
-        scrap = nullptr;
-    }
-    MOZ_ASSERT(!scrap);
 }
 
 void
 SurfaceStream::RecycleScraps(SurfaceFactory* factory)
 {
-    while (!mScraps.empty()) {
-        SharedSurface* cur = mScraps.top();
-        mScraps.pop();
+    while (!mScraps.Empty()) {
+        UniquePtr<SharedSurface> cur = mScraps.Pop();
 
-        Recycle(factory, cur);
+        Recycle(factory, &cur);
     }
 }
 
+////////////////////////////////////////////////////////////////////////
+// SurfaceStream
 
+SurfaceStream::SurfaceStream(SurfaceStreamType type,
+                             SurfaceStream* prevStream)
+    : mType(type)
+    , mProducer(nullptr)
+    , mMonitor("SurfaceStream monitor")
+    , mIsAlive(true)
+{
+    MOZ_ASSERT(!prevStream || mType != prevStream->mType,
+               "We should not need to create a SurfaceStream from another "
+               "of the same type.");
+}
 
 SurfaceStream::~SurfaceStream()
 {
-    Delete(mProducer);
+    Delete(&mProducer);
 
-    while (!mScraps.empty()) {
-        SharedSurface* cur = mScraps.top();
-        mScraps.pop();
+    while (!mScraps.Empty()) {
+        UniquePtr<SharedSurface> cur = mScraps.Pop();
 
-        Delete(cur);
+        Delete(&cur);
     }
 
     MOZ_ASSERT(mSurfaces.empty());
 }
 
 SharedSurface*
 SurfaceStream::SwapConsumer()
 {
@@ -190,66 +245,66 @@ SurfaceStream::SwapConsumer()
 }
 
 SharedSurface*
 SurfaceStream::Resize(SurfaceFactory* factory, const gfx::IntSize& size)
 {
     MonitorAutoLock lock(mMonitor);
 
     if (mProducer) {
-        Scrap(mProducer);
+        Scrap(&mProducer);
     }
 
-    New(factory, size, mProducer);
-    return mProducer;
+    New(factory, size, &mProducer);
+    return mProducer.get();
 }
 
+////////////////////////////////////////////////////////////////////////
+// SurfaceStream_SingleBuffer
+
 SurfaceStream_SingleBuffer::SurfaceStream_SingleBuffer(SurfaceStream* prevStream)
     : SurfaceStream(SurfaceStreamType::SingleBuffer, prevStream)
     , mConsumer(nullptr)
 {
     if (!prevStream)
         return;
 
-    SharedSurface* prevProducer = nullptr;
-    SharedSurface* prevConsumer = nullptr;
-    prevStream->SurrenderSurfaces(prevProducer, prevConsumer);
+    UniquePtr<SharedSurface> prevProducer;
+    UniquePtr<SharedSurface> prevConsumer;
+    prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer);
 
-    if (prevConsumer == prevProducer)
-        prevConsumer = nullptr;
-
-    mProducer = Absorb(prevProducer);
-    mConsumer = Absorb(prevConsumer);
+    mProducer = Absorb(&prevProducer);
+    mConsumer = Absorb(&prevConsumer);
 }
 
 SurfaceStream_SingleBuffer::~SurfaceStream_SingleBuffer()
 {
-    Delete(mConsumer);
+    Delete(&mConsumer);
 }
 
 void
-SurfaceStream_SingleBuffer::SurrenderSurfaces(SharedSurface*& producer,
-                                              SharedSurface*& consumer)
+SurfaceStream_SingleBuffer::SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                              UniquePtr<SharedSurface>* out_consumer)
 {
+    MOZ_ASSERT(out_producer);
+    MOZ_ASSERT(out_consumer);
+
     mIsAlive = false;
 
-    producer = Surrender(mProducer);
-    consumer = Surrender(mConsumer);
-
-    if (!consumer)
-        consumer = producer;
+    *out_producer = Surrender(&mProducer);
+    *out_consumer = Surrender(&mConsumer);
 }
 
 SharedSurface*
 SurfaceStream_SingleBuffer::SwapProducer(SurfaceFactory* factory,
                                          const gfx::IntSize& size)
 {
     MonitorAutoLock lock(mMonitor);
     if (mConsumer) {
-        Recycle(factory, mConsumer);
+        Recycle(factory, &mConsumer);
     }
 
     if (mProducer) {
         // Fence now, before we start (maybe) juggling Prod around.
         mProducer->Fence();
 
         // Size mismatch means we need to squirrel the current Prod
         // into Cons, and leave Prod empty, so it gets a new surface below.
@@ -259,143 +314,146 @@ SurfaceStream_SingleBuffer::SwapProducer
         // need to preserve, we should switch out for (presumedly) better perf.
         if (mProducer->mType != factory->mType &&
             !factory->mCaps.preserve)
         {
             needsNewBuffer = true;
         }
 
         if (needsNewBuffer) {
-            Move(mProducer, mConsumer);
+            MoveTo(&mProducer, &mConsumer);
         }
     }
 
     // The old Prod (if there every was one) was invalid,
     // so we need a new one.
     if (!mProducer) {
-        New(factory, size, mProducer);
+        New(factory, size, &mProducer);
     }
 
-    return mProducer;
+    return mProducer.get();
 }
 
 SharedSurface*
 SurfaceStream_SingleBuffer::SwapConsumer_NoWait()
 {
     MonitorAutoLock lock(mMonitor);
 
     // Use Cons, if present.
     // Otherwise, just use Prod directly.
-    SharedSurface* toConsume = mConsumer;
+    SharedSurface* toConsume = mConsumer.get();
     if (!toConsume)
-        toConsume = mProducer;
+        toConsume = mProducer.get();
 
     return toConsume;
 }
 
-
+////////////////////////////////////////////////////////////////////////
+// SurfaceStream_TripleBuffer_Copy
 
 SurfaceStream_TripleBuffer_Copy::SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream)
     : SurfaceStream(SurfaceStreamType::TripleBuffer_Copy, prevStream)
     , mStaging(nullptr)
     , mConsumer(nullptr)
 {
     if (!prevStream)
         return;
 
-    SharedSurface* prevProducer = nullptr;
-    SharedSurface* prevConsumer = nullptr;
-    prevStream->SurrenderSurfaces(prevProducer, prevConsumer);
+    UniquePtr<SharedSurface> prevProducer;
+    UniquePtr<SharedSurface> prevConsumer;
+    prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer);
 
-    if (prevConsumer == prevProducer)
-      prevConsumer = nullptr;
-
-    mProducer = Absorb(prevProducer);
-    mConsumer = Absorb(prevConsumer);
+    mProducer = Absorb(&prevProducer);
+    mConsumer = Absorb(&prevConsumer);
 }
 
 SurfaceStream_TripleBuffer_Copy::~SurfaceStream_TripleBuffer_Copy()
 {
-    Delete(mStaging);
-    Delete(mConsumer);
+    Delete(&mStaging);
+    Delete(&mConsumer);
 }
 
 void
-SurfaceStream_TripleBuffer_Copy::SurrenderSurfaces(SharedSurface*& producer,
-                                                   SharedSurface*& consumer)
+SurfaceStream_TripleBuffer_Copy::SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                                   UniquePtr<SharedSurface>* out_consumer)
 {
+    MOZ_ASSERT(out_producer);
+    MOZ_ASSERT(out_consumer);
+
     mIsAlive = false;
 
-    producer = Surrender(mProducer);
-    consumer = Surrender(mConsumer);
+    *out_producer = Surrender(&mProducer);
+    *out_consumer = Surrender(&mConsumer);
 
-    if (!consumer)
-        consumer = Surrender(mStaging);
+    if (!*out_consumer)
+        *out_consumer = Surrender(&mStaging);
 }
 
 SharedSurface*
 SurfaceStream_TripleBuffer_Copy::SwapProducer(SurfaceFactory* factory,
                                               const gfx::IntSize& size)
 {
     MonitorAutoLock lock(mMonitor);
 
     RecycleScraps(factory);
     if (mProducer) {
         if (mStaging) {
             // We'll re-use this for a new mProducer later on if
             // the size remains the same
-            Recycle(factory, mStaging);
+            Recycle(factory, &mStaging);
         }
 
-        Move(mProducer, mStaging);
+        MoveTo(&mProducer, &mStaging);
         mStaging->Fence();
 
-        New(factory, size, mProducer);
+        New(factory, size, &mProducer);
 
-        if (mProducer && mStaging->mSize == mProducer->mSize)
-            SharedSurface::ProdCopy(mStaging, mProducer, factory);
+        if (mProducer &&
+            mStaging->mSize == mProducer->mSize)
+        {
+            SharedSurface::ProdCopy(mStaging.get(), mProducer.get(), factory);
+        }
     } else {
-        New(factory, size, mProducer);
+        New(factory, size, &mProducer);
     }
 
-    return mProducer;
+    return mProducer.get();
 }
 
-
 SharedSurface*
 SurfaceStream_TripleBuffer_Copy::SwapConsumer_NoWait()
 {
     MonitorAutoLock lock(mMonitor);
 
     if (mStaging) {
-        Scrap(mConsumer);
-        Move(mStaging, mConsumer);
+        Scrap(&mConsumer);
+        MoveTo(&mStaging, &mConsumer);
     }
 
-    return mConsumer;
+    return mConsumer.get();
 }
 
+////////////////////////////////////////////////////////////////////////
+// SurfaceStream_TripleBuffer
+
 void SurfaceStream_TripleBuffer::Init(SurfaceStream* prevStream)
 {
     if (!prevStream)
         return;
 
-    SharedSurface* prevProducer = nullptr;
-    SharedSurface* prevConsumer = nullptr;
-    prevStream->SurrenderSurfaces(prevProducer, prevConsumer);
+    UniquePtr<SharedSurface> prevProducer;
+    UniquePtr<SharedSurface> prevConsumer;
+    prevStream->SurrenderSurfaces(&prevProducer, &prevConsumer);
 
-    if (prevConsumer == prevProducer)
-        prevConsumer = nullptr;
-
-    mProducer = Absorb(prevProducer);
-    mConsumer = Absorb(prevConsumer);
+    mProducer = Absorb(&prevProducer);
+    mConsumer = Absorb(&prevConsumer);
 }
 
-
-SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream)
+SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStreamType type,
+                                                       SurfaceStream* prevStream)
     : SurfaceStream(type, prevStream)
     , mStaging(nullptr)
     , mConsumer(nullptr)
 {
     SurfaceStream_TripleBuffer::Init(prevStream);
 }
 
 SurfaceStream_TripleBuffer::SurfaceStream_TripleBuffer(SurfaceStream* prevStream)
@@ -403,90 +461,98 @@ SurfaceStream_TripleBuffer::SurfaceStrea
     , mStaging(nullptr)
     , mConsumer(nullptr)
 {
     SurfaceStream_TripleBuffer::Init(prevStream);
 }
 
 SurfaceStream_TripleBuffer::~SurfaceStream_TripleBuffer()
 {
-    Delete(mStaging);
-    Delete(mConsumer);
+    Delete(&mStaging);
+    Delete(&mConsumer);
 }
 
 void
-SurfaceStream_TripleBuffer::SurrenderSurfaces(SharedSurface*& producer,
-                                              SharedSurface*& consumer)
+SurfaceStream_TripleBuffer::SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                              UniquePtr<SharedSurface>* out_consumer)
 {
+    MOZ_ASSERT(out_producer);
+    MOZ_ASSERT(out_consumer);
+
     mIsAlive = false;
 
-    producer = Surrender(mProducer);
-    consumer = Surrender(mConsumer);
+    *out_producer = Surrender(&mProducer);
+    *out_consumer = Surrender(&mConsumer);
 
-    if (!consumer)
-        consumer = Surrender(mStaging);
+    if (!*out_consumer)
+        *out_consumer = Surrender(&mStaging);
 }
 
 SharedSurface*
 SurfaceStream_TripleBuffer::SwapProducer(SurfaceFactory* factory,
                                          const gfx::IntSize& size)
 {
     PROFILER_LABEL("SurfaceStream_TripleBuffer", "SwapProducer",
-        js::ProfileEntry::Category::GRAPHICS);
+                   js::ProfileEntry::Category::GRAPHICS);
 
     MonitorAutoLock lock(mMonitor);
     if (mProducer) {
         RecycleScraps(factory);
 
         // If WaitForCompositor succeeds, mStaging has moved to mConsumer.
         // If it failed, we might have to scrap it.
         if (mStaging) {
             WaitForCompositor();
         }
         if (mStaging) {
-            Scrap(mStaging);
+            Scrap(&mStaging);
         }
 
-        Move(mProducer, mStaging);
+        MoveTo(&mProducer, &mStaging);
         mStaging->Fence();
     }
 
     MOZ_ASSERT(!mProducer);
-    New(factory, size, mProducer);
+    New(factory, size, &mProducer);
 
-    return mProducer;
+    return mProducer.get();
 }
 
 SharedSurface*
 SurfaceStream_TripleBuffer::SwapConsumer_NoWait()
 {
     MonitorAutoLock lock(mMonitor);
     if (mStaging) {
-        Scrap(mConsumer);
-        Move(mStaging, mConsumer);
+        Scrap(&mConsumer);
+        MoveTo(&mStaging, &mConsumer);
         mMonitor.NotifyAll();
     }
 
-    return mConsumer;
+    return mConsumer.get();
 }
 
+////////////////////////////////////////////////////////////////////////
+// SurfaceStream_TripleBuffer_Async
+
 SurfaceStream_TripleBuffer_Async::SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream)
-    : SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async, prevStream)
+    : SurfaceStream_TripleBuffer(SurfaceStreamType::TripleBuffer_Async,
+                                 prevStream)
 {
 }
 
 SurfaceStream_TripleBuffer_Async::~SurfaceStream_TripleBuffer_Async()
 {
 }
 
 void
 SurfaceStream_TripleBuffer_Async::WaitForCompositor()
 {
-    PROFILER_LABEL("SurfaceStream_TripleBuffer_Async", "WaitForCompositor",
-        js::ProfileEntry::Category::GRAPHICS);
+    PROFILER_LABEL("SurfaceStream_TripleBuffer_Async",
+                   "WaitForCompositor",
+                   js::ProfileEntry::Category::GRAPHICS);
 
     // If we haven't be notified within 100ms, then
     // something must have happened and it will never arrive.
     // Bail out to avoid deadlocking.
     mMonitor.Wait(PR_MillisecondsToInterval(100));
 }
 
 } /* namespace gfx */
--- a/gfx/gl/SurfaceStream.h
+++ b/gfx/gl/SurfaceStream.h
@@ -7,17 +7,19 @@
 #define SURFACESTREAM_H_
 
 #include <stack>
 #include <set>
 #include "mozilla/Monitor.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/GenericRefCounted.h"
+#include "mozilla/UniquePtr.h"
 #include "SurfaceTypes.h"
+#include "SharedSurface.h"
 
 namespace mozilla {
 
 namespace gl {
 class GLContext;
 class SharedSurface;
 class SurfaceFactory;
 
@@ -29,78 +31,68 @@ public:
     typedef enum {
         MainThread,
         OffMainThread
     } OMTC;
 
     static SurfaceStreamType ChooseGLStreamType(OMTC omtc,
                                                 bool preserveBuffer);
 
-    static SurfaceStream* CreateForType(SurfaceStreamType type,
-                                        mozilla::gl::GLContext* glContext,
-                                        SurfaceStream* prevStream = nullptr);
+    static TemporaryRef<SurfaceStream> CreateForType(SurfaceStreamType type,
+                                                     mozilla::gl::GLContext* glContext,
+                                                     SurfaceStream* prevStream = nullptr);
 
     const SurfaceStreamType mType;
 
     mozilla::gl::GLContext* GLContext() const { return mGLContext; }
 
 
 protected:
     // |mProd| is owned by us, but can be ripped away when
     // creating a new GLStream from this one.
-    SharedSurface* mProducer;
+    UniquePtr<SharedSurface> mProducer;
+#ifdef DEBUG
     std::set<SharedSurface*> mSurfaces;
-    std::stack<SharedSurface*> mScraps;
+#endif
+    UniquePtrQueue<SharedSurface> mScraps;
     mutable Monitor mMonitor;
     bool mIsAlive;
 
     // Do not use this. It exists solely so we can ref it in CanvasClientWebGL::Update()
     // before sent up to the compositor. You have been warned (Bug 894405)
     mozilla::gl::GLContext* mGLContext;
 
     // |previous| can be null, indicating this is the first one.
     // Otherwise, we pull in |mProd| from |previous| an our initial surface.
-    SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream)
-        : mType(type)
-        , mProducer(nullptr)
-        , mMonitor("SurfaceStream monitor")
-        , mIsAlive(true)
-    {
-        MOZ_ASSERT(!prevStream || mType != prevStream->mType,
-                   "We should not need to create a SurfaceStream from another "
-                   "of the same type.");
-    }
+    SurfaceStream(SurfaceStreamType type, SurfaceStream* prevStream);
 
 public:
     virtual ~SurfaceStream();
 
 protected:
     // These functions below are helpers to make trading buffers around easier.
     // For instance, using Move(a,b) instead of normal assignment assures that
     // we are never leaving anything hanging around, keeping things very safe.
-    static void Move(SharedSurface*& from, SharedSurface*& to) {
-        MOZ_ASSERT(!to);
-        to = from;
-        from = nullptr;
-    }
-
+    void MoveTo(UniquePtr<SharedSurface>* slotFrom,
+                UniquePtr<SharedSurface>* slotTo);
     void New(SurfaceFactory* factory, const gfx::IntSize& size,
-             SharedSurface*& surf);
-    void Delete(SharedSurface*& surf);
-    void Recycle(SurfaceFactory* factory, SharedSurface*& surf);
+             UniquePtr<SharedSurface>* surfSlot);
+    void Delete(UniquePtr<SharedSurface>* surfSlot);
+    void Recycle(SurfaceFactory* factory,
+                 UniquePtr<SharedSurface>* surfSlot);
 
     // Surrender control of a surface, and return it for use elsewhere.
-    SharedSurface* Surrender(SharedSurface*& surf);
+    UniquePtr<SharedSurface> Surrender(UniquePtr<SharedSurface>* surfSlot);
     // Absorb control of a surface from elsewhere, clears its old location.
-    SharedSurface* Absorb(SharedSurface*& surf);
+    UniquePtr<SharedSurface> Absorb(UniquePtr<SharedSurface>* surfSlot);
 
     // For holding on to surfaces we don't need until we can return them to the
     // Producer's factory via SurfaceFactory::Recycle.
     // Not thread-safe.
-    void Scrap(SharedSurface*& scrap);
+    void Scrap(UniquePtr<SharedSurface>* surfSlot);
 
     // Not thread-safe.
     void RecycleScraps(SurfaceFactory* factory);
 
 public:
     /* Note that ownership of the returned surfaces below
      * transfers to the caller.
      * SwapProd returns null on failure. Returning null doesn't mean nothing
@@ -119,105 +111,116 @@ public:
 protected:
     // SwapCons will return the same surface more than once,
     // if nothing new has been published.
     virtual SharedSurface* SwapConsumer_NoWait() = 0;
 
 public:
     virtual SharedSurface* SwapConsumer();
 
-    virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer) = 0;
+    virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                   UniquePtr<SharedSurface>* out_consumer) = 0;
 };
 
 // Not thread-safe. Don't use cross-threads.
 class SurfaceStream_SingleBuffer
     : public SurfaceStream
 {
 protected:
-    SharedSurface* mConsumer; // Only present after resize-swap.
+    UniquePtr<SharedSurface> mConsumer; // Only present after resize-swap.
 
 public:
     MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_SingleBuffer)
+
     explicit SurfaceStream_SingleBuffer(SurfaceStream* prevStream);
     virtual ~SurfaceStream_SingleBuffer();
 
     /* Since we're non-OMTC, we know the order of execution here:
      * SwapProd gets called in UpdateSurface, followed by
      * SwapCons being called in Render.
      */
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
-                                        const gfx::IntSize& size);
+                                        const gfx::IntSize& size) MOZ_OVERRIDE;
 
-    virtual SharedSurface* SwapConsumer_NoWait();
+    virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE;
 
-    virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer);
+    virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                   UniquePtr<SharedSurface>* out_consumer) MOZ_OVERRIDE;
 };
 
 // Our hero for preserveDrawingBuffer=true.
 class SurfaceStream_TripleBuffer_Copy
     : public SurfaceStream
 {
 protected:
-    SharedSurface* mStaging;
-    SharedSurface* mConsumer;
+    UniquePtr<SharedSurface> mStaging;
+    UniquePtr<SharedSurface> mConsumer;
 
 public:
     MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Copy)
+
     explicit SurfaceStream_TripleBuffer_Copy(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer_Copy();
 
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
-                                        const gfx::IntSize& size);
+                                        const gfx::IntSize& size) MOZ_OVERRIDE;
 
-    virtual SharedSurface* SwapConsumer_NoWait();
+    virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE;
 
-    virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer);
+    virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                   UniquePtr<SharedSurface>* out_consumer) MOZ_OVERRIDE;
 };
 
 
 class SurfaceStream_TripleBuffer
     : public SurfaceStream
 {
 protected:
-    SharedSurface* mStaging;
-    SharedSurface* mConsumer;
+    UniquePtr<SharedSurface> mStaging;
+    UniquePtr<SharedSurface> mConsumer;
 
     // Returns true if we were able to wait, false if not
     virtual void WaitForCompositor() {}
 
     // To support subclasses initializing the mType.
     SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream);
 
 public:
     MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer)
+
     explicit SurfaceStream_TripleBuffer(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer();
-    virtual bool CopySurfaceToProducer(SharedSurface* src, SurfaceFactory* factory);
+
+    virtual bool CopySurfaceToProducer(SharedSurface* src,
+                                       SurfaceFactory* factory) MOZ_OVERRIDE;
 
 private:
     // Common constructor code.
     void Init(SurfaceStream* prevStream);
 
 public:
     // Done writing to prod, swap prod and staging
     virtual SharedSurface* SwapProducer(SurfaceFactory* factory,
-                                        const gfx::IntSize& size);
+                                        const gfx::IntSize& size) MOZ_OVERRIDE;
 
-    virtual SharedSurface* SwapConsumer_NoWait();
+    virtual SharedSurface* SwapConsumer_NoWait() MOZ_OVERRIDE;
 
-    virtual void SurrenderSurfaces(SharedSurface*& producer, SharedSurface*& consumer);
+    virtual void SurrenderSurfaces(UniquePtr<SharedSurface>* out_producer,
+                                   UniquePtr<SharedSurface>* out_consumer) MOZ_OVERRIDE;
 };
 
 class SurfaceStream_TripleBuffer_Async
     : public SurfaceStream_TripleBuffer
 {
 protected:
     virtual void WaitForCompositor() MOZ_OVERRIDE;
 
 public:
+    MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SurfaceStream_TripleBuffer_Async)
+
     explicit SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream);
     virtual ~SurfaceStream_TripleBuffer_Async();
 };
 
 
 } // namespace gl
 } // namespace mozilla
 
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -138,16 +138,17 @@ MOZ_END_ENUM_CLASS(DiagnosticFlags)
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DiagnosticFlags)
 
 /**
  * See gfx/layers/Effects.h
  */
 MOZ_BEGIN_ENUM_CLASS(EffectTypes, uint8_t)
   MASK,
   BLEND_MODE,
+  COLOR_MATRIX,
   MAX_SECONDARY, // sentinel for the count of secondary effect types
   RGB,
   YCBCR,
   COMPONENT_ALPHA,
   SOLID_COLOR,
   RENDER_TARGET,
   MAX  //sentinel for the count of all effect types
 MOZ_END_ENUM_CLASS(EffectTypes)
--- a/gfx/layers/Effects.cpp
+++ b/gfx/layers/Effects.cpp
@@ -56,8 +56,16 @@ EffectSolidColor::PrintInfo(std::strings
 
 void
 EffectBlendMode::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("EffectBlendMode (0x%p) [blendmode=%i]", this, (int)mBlendMode).get();
 }
 
+void
+EffectColorMatrix::PrintInfo(std::stringstream& aStream, const char* aPrefix)
+{
+  aStream << aPrefix;
+  aStream << nsPrintfCString("EffectColorMatrix (0x%p)", this).get();
+  AppendToString(aStream, mColorMatrix, " [matrix=", "]");
+}
+
--- a/gfx/layers/Effects.h
+++ b/gfx/layers/Effects.h
@@ -116,18 +116,39 @@ struct EffectRenderTarget : public Textu
     : TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true, gfx::Filter::LINEAR)
     , mRenderTarget(aRenderTarget)
   {}
 
   virtual const char* Name() { return "EffectRenderTarget"; }
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
 
   RefPtr<CompositingRenderTarget> mRenderTarget;
+
+protected:
+  EffectRenderTarget(EffectTypes aType, CompositingRenderTarget *aRenderTarget)
+    : TexturedEffect(aType, aRenderTarget, true, gfx::Filter::LINEAR)
+    , mRenderTarget(aRenderTarget)
+  {}
+
 };
 
+// Render to a render target rather than the screen.
+struct EffectColorMatrix : public Effect
+{
+  EffectColorMatrix(gfx::Matrix5x4 aMatrix)
+    : Effect(EffectTypes::COLOR_MATRIX)
+    , mColorMatrix(aMatrix)
+  {}
+
+  virtual const char* Name() { return "EffectColorMatrix"; }
+  virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
+  const gfx::Matrix5x4 mColorMatrix;
+};
+
+
 struct EffectRGB : public TexturedEffect
 {
   EffectRGB(TextureSource *aTexture,
             bool aPremultiplied,
             gfx::Filter aFilter,
             bool aFlipped = false)
     : TexturedEffect(EffectTypes::RGB, aTexture, aPremultiplied, aFilter)
   {}
--- a/gfx/layers/LayersLogging.cpp
+++ b/gfx/layers/LayersLogging.cpp
@@ -165,16 +165,32 @@ AppendToString(std::stringstream& aStrea
       m._21, m._22, m._23, m._24,
       m._31, m._32, m._33, m._34,
       m._41, m._42, m._43, m._44).get();
   }
   aStream << sfx;
 }
 
 void
+AppendToString(std::stringstream& aStream, const Matrix5x4& m,
+               const char* pfx, const char* sfx)
+{
+  aStream << pfx;
+  aStream << nsPrintfCString(
+    "[ %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]",
+    m._11, m._12, m._13, m._14,
+    m._21, m._22, m._23, m._24,
+    m._31, m._32, m._33, m._34,
+    m._41, m._42, m._43, m._44,
+    m._51, m._52, m._53, m._54).get();
+  aStream << sfx;
+}
+
+
+void
 AppendToString(std::stringstream& aStream, const Filter filter,
                const char* pfx, const char* sfx)
 {
   aStream << pfx;
 
   switch (filter) {
     case Filter::GOOD: aStream << "Filter::GOOD"; break;
     case Filter::LINEAR: aStream << "Filter::LINEAR"; break;
--- a/gfx/layers/LayersLogging.h
+++ b/gfx/layers/LayersLogging.h
@@ -135,16 +135,20 @@ AppendToString(std::stringstream& aStrea
   aStream << sfx;
 }
 
 void
 AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix4x4& m,
                const char* pfx="", const char* sfx="");
 
 void
+AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix5x4& m,
+               const char* pfx="", const char* sfx="");
+
+void
 AppendToString(std::stringstream& aStream, const mozilla::gfx::Filter filter,
                const char* pfx="", const char* sfx="");
 
 void
 AppendToString(std::stringstream& aStream, mozilla::layers::TextureFlags flags,
                const char* pfx="", const char* sfx="");
 
 void
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -152,18 +152,20 @@ CanvasClientSurfaceStream::Update(gfx::I
   GLScreenBuffer* screen = aLayer->mGLContext->Screen();
   SurfaceStream* stream = nullptr;
 
   if (aLayer->mStream) {
     stream = aLayer->mStream;
 
     // Copy our current surface to the current producer surface in our stream, then
     // call SwapProducer to make a new buffer ready.
-    stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
-    stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
+    stream->CopySurfaceToProducer(aLayer->mTextureSurface.get(),
+                                  aLayer->mFactory.get());
+    stream->SwapProducer(aLayer->mFactory.get(),
+                         gfx::IntSize(aSize.width, aSize.height));
   } else {
     stream = screen->Stream();
   }
 
 #ifdef MOZ_WIDGET_GONK
   SharedSurface* surf = stream->SwapConsumer();
   if (!surf) {
     printf_stderr("surf is null post-SwapConsumer!\n");
--- a/gfx/layers/client/ClientCanvasLayer.cpp
+++ b/gfx/layers/client/ClientCanvasLayer.cpp
@@ -42,17 +42,17 @@ namespace layers {
 ClientCanvasLayer::~ClientCanvasLayer()
 {
   MOZ_COUNT_DTOR(ClientCanvasLayer);
   if (mCanvasClient) {
     mCanvasClient->OnDetach();
     mCanvasClient = nullptr;
   }
   if (mTextureSurface) {
-    delete mTextureSurface;
+    mTextureSurface = nullptr;
   }
 }
 
 void
 ClientCanvasLayer::Initialize(const Data& aData)
 {
   CopyableCanvasLayer::Initialize(aData);
 
@@ -68,40 +68,44 @@ ClientCanvasLayer::Initialize(const Data
     } else {
       caps = screen->mCaps;
     }
     MOZ_ASSERT(caps.alpha == aData.mHasAlpha);
 
     SurfaceStreamType streamType =
         SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread,
                                           screen->PreserveBuffer());
-    SurfaceFactory* factory = nullptr;
+    UniquePtr<SurfaceFactory> factory;
+
     if (!gfxPrefs::WebGLForceLayersReadback()) {
       switch (ClientManager()->AsShadowForwarder()->GetCompositorBackendType()) {
         case mozilla::layers::LayersBackend::LAYERS_OPENGL: {
           if (mGLContext->GetContextType() == GLContextType::EGL) {
 #ifdef MOZ_WIDGET_GONK
-            factory = new SurfaceFactory_Gralloc(mGLContext, caps, ClientManager()->AsShadowForwarder());
+            factory = MakeUnique<SurfaceFactory_Gralloc>(mGLContext,
+                                                         caps,
+                                                         ClientManager()->AsShadowForwarder());
 #else
             bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
             if (!isCrossProcess) {
               // [Basic/OGL Layers, OMTC] WebGL layer init.
               factory = SurfaceFactory_EGLImage::Create(mGLContext, caps);
             } else {
               // we could do readback here maybe
               NS_NOTREACHED("isCrossProcess but not on native B2G!");
             }
 #endif
           } else {
             // [Basic Layers, OMTC] WebGL layer init.
             // Well, this *should* work...
 #ifdef XP_MACOSX
             factory = SurfaceFactory_IOSurface::Create(mGLContext, caps);
 #else
-            factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps);
+            GLContext* nullConsGL = nullptr; // Bug 1050044.
+            factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, nullConsGL, caps);
 #endif
           }
           break;
         }
         case mozilla::layers::LayersBackend::LAYERS_D3D10:
         case mozilla::layers::LayersBackend::LAYERS_D3D11: {
 #ifdef XP_WIN
           if (mGLContext->IsANGLE()) {
@@ -112,36 +116,35 @@ ClientCanvasLayer::Initialize(const Data
         }
         default:
           break;
       }
     }
 
     if (mStream) {
       // We're using a stream other than the one in the default screen
-      mFactory = factory;
+      mFactory = Move(factory);
       if (!mFactory) {
         // Absolutely must have a factory here, so create a basic one
-        mFactory = new SurfaceFactory_Basic(mGLContext, caps);
+        mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
       }
 
       gfx::IntSize size = gfx::IntSize(aData.mSize.width, aData.mSize.height);
       mTextureSurface = SharedSurface_GLTexture::Create(mGLContext, mGLContext,
                                                         mGLContext->GetGLFormats(),
                                                         size, caps.alpha, aData.mTexID);
-      SharedSurface* producer = mStream->SwapProducer(mFactory, size);
+      SharedSurface* producer = mStream->SwapProducer(mFactory.get(), size);
       if (!producer) {
         // Fallback to basic factory
-        delete mFactory;
-        mFactory = new SurfaceFactory_Basic(mGLContext, caps);
-        producer = mStream->SwapProducer(mFactory, size);
+        mFactory = MakeUnique<SurfaceFactory_Basic>(mGLContext, caps);
+        producer = mStream->SwapProducer(mFactory.get(), size);
         MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory");
       }
     } else if (factory) {
-      screen->Morph(factory, streamType);
+      screen->Morph(Move(factory), streamType);
     }
   }
 }
 
 void
 ClientCanvasLayer::RenderLayer()
 {
   PROFILER_LABEL("ClientCanvasLayer", "RenderLayer",
--- a/gfx/layers/client/ClientCanvasLayer.h
+++ b/gfx/layers/client/ClientCanvasLayer.h
@@ -96,18 +96,18 @@ protected:
     if (mGLContext) {
       return CanvasClient::CanvasClientGLContext;
     }
     return CanvasClient::CanvasClientSurface;
   }
 
   RefPtr<CanvasClient> mCanvasClient;
 
-  gl::SharedSurface* mTextureSurface;
-  gl::SurfaceFactory* mFactory;
+  UniquePtr<gl::SharedSurface> mTextureSurface;
+  UniquePtr<gl::SurfaceFactory> mFactory;
 
   friend class DeprecatedCanvasClient2D;
   friend class CanvasClient2D;
   friend class DeprecatedCanvasClientSurfaceStream;
   friend class CanvasClientSurfaceStream;
 };
 }
 }
--- a/gfx/layers/composite/FPSCounter.cpp
+++ b/gfx/layers/composite/FPSCounter.cpp
@@ -44,17 +44,17 @@ FPSCounter::Init()
   }
   mLastInterval = TimeStamp::Now();
 }
 
 // Returns true if we captured a full interval of data
 bool
 FPSCounter::CapturedFullInterval(TimeStamp aTimestamp) {
   TimeDuration duration = aTimestamp - mLastInterval;
-  return duration.ToSecondsSigDigits() >= kFpsDumpInterval;
+  return duration.ToSeconds() >= kFpsDumpInterval;
 }
 
 void
 FPSCounter::AddFrame(TimeStamp aTimestamp) {
   NS_ASSERTION(mWriteIndex < kMaxFrames, "We probably have a bug with the circular buffer");
   NS_ASSERTION(mWriteIndex >= 0, "Circular Buffer index should never be negative");
 
   int index = mWriteIndex++;
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -405,16 +405,68 @@ LayerManagerComposite::RenderDebugOverla
 #endif
 
   if (drawFrameColorBars || drawFrameCounter) {
     // We intentionally overflow at 2^16.
     sFrameCount++;
   }
 }
 
+RefPtr<CompositingRenderTarget>
+LayerManagerComposite::PushGroup()
+{
+  RefPtr<CompositingRenderTarget> previousTarget = mCompositor->GetCurrentRenderTarget();
+  // make our render target the same size as the destination target
+  // so that we don't have to change size if the drawing area changes.
+  IntRect rect(previousTarget->GetOrigin(), previousTarget->GetSize());
+  // XXX: I'm not sure if this is true or not...
+  MOZ_ASSERT(rect.x == 0 && rect.y == 0);
+  if (!mTwoPassTmpTarget ||
+      mTwoPassTmpTarget->GetSize() != previousTarget->GetSize() ||
+      mTwoPassTmpTarget->GetOrigin() != previousTarget->GetOrigin()) {
+    mTwoPassTmpTarget = mCompositor->CreateRenderTarget(rect, INIT_MODE_NONE);
+  }
+  mCompositor->SetRenderTarget(mTwoPassTmpTarget);
+  return previousTarget;
+}
+void LayerManagerComposite::PopGroup(RefPtr<CompositingRenderTarget> aPreviousTarget, nsIntRect aClipRect)
+{
+  mCompositor->SetRenderTarget(aPreviousTarget);
+
+  EffectChain effectChain(RootLayer());
+  Matrix5x4 matrix;
+  if (gfxPrefs::Grayscale()) {
+    matrix._11 = matrix._12 = matrix._13 = 0.2126f;
+    matrix._21 = matrix._22 = matrix._23 = 0.7152f;
+    matrix._31 = matrix._32 = matrix._33 = 0.0722f;
+  }
+
+  if (gfxPrefs::Invert()) {
+    matrix._11 = -matrix._11;
+    matrix._12 = -matrix._12;
+    matrix._13 = -matrix._13;
+    matrix._21 = -matrix._21;
+    matrix._22 = -matrix._22;
+    matrix._23 = -matrix._23;
+    matrix._31 = -matrix._31;
+    matrix._32 = -matrix._32;
+    matrix._33 = -matrix._33;
+    matrix._51 = 1;
+    matrix._52 = 1;
+    matrix._53 = 1;
+  }
+
+  effectChain.mPrimaryEffect = new EffectRenderTarget(mTwoPassTmpTarget);
+  effectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX] = new EffectColorMatrix(matrix);
+
+  gfx::Rect clipRectF(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height);
+  mCompositor->DrawQuad(Rect(Point(0, 0), Size(mTwoPassTmpTarget->GetSize())), clipRectF, effectChain, 1.,
+                        Matrix4x4());
+}
+
 void
 LayerManagerComposite::Render()
 {
   PROFILER_LABEL("LayerManagerComposite", "Render",
     js::ProfileEntry::Category::GRAPHICS);
 
   if (mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
@@ -437,16 +489,20 @@ LayerManagerComposite::Render()
     // Create a LayersPacket, dump Layers into it and transfer the
     // packet('s ownership) to LayerScope.
     auto packet = MakeUnique<layerscope::Packet>();
     layerscope::LayersPacket* layersPacket = packet->mutable_layers();
     this->Dump(layersPacket);
     LayerScope::SendLayerDump(Move(packet));
   }
 
+  if (gfxPrefs::Invert() || gfxPrefs::Grayscale()) {
+    composer2D = nullptr;
+  }
+
   if (!mTarget && composer2D && composer2D->TryRender(mRoot, mWorldMatrix, mGeometryChanged)) {
     if (mFPS) {
       double fps = mFPS->mCompositionFps.AddFrameAndGetFps(TimeStamp::Now());
       if (gfxPrefs::LayersDrawFPS()) {
         printf_stderr("HWComposer: FPS is %g\n", fps);
       }
     }
     mCompositor->EndFrameForExternalComposition(mWorldMatrix);
@@ -496,28 +552,39 @@ LayerManagerComposite::Render()
   }
 
   // Allow widget to render a custom background.
   mCompositor->GetWidget()->DrawWindowUnderlay(this, nsIntRect(actualBounds.x,
                                                                actualBounds.y,
                                                                actualBounds.width,
                                                                actualBounds.height));
 
+  RefPtr<CompositingRenderTarget> previousTarget;
+  if (gfxPrefs::Invert() || gfxPrefs::Grayscale()) {
+    previousTarget = PushGroup();
+  } else {
+    mTwoPassTmpTarget = nullptr;
+  }
+
   // Render our layers.
   RootLayer()->Prepare(clipRect);
   RootLayer()->RenderLayer(clipRect);
 
   if (!mRegionToClear.IsEmpty()) {
     nsIntRegionRectIterator iter(mRegionToClear);
     const nsIntRect *r;
     while ((r = iter.Next())) {
       mCompositor->ClearRect(Rect(r->x, r->y, r->width, r->height));
     }
   }
 
+  if (mTwoPassTmpTarget) {
+    PopGroup(previousTarget, clipRect);
+  }
+
   // Allow widget to render a custom foreground.
   mCompositor->GetWidget()->DrawWindowOverlay(this, nsIntRect(actualBounds.x,
                                                               actualBounds.y,
                                                               actualBounds.width,
                                                               actualBounds.height));
 
   // Debugging
   RenderDebugOverlay(actualBounds);
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -58,16 +58,17 @@ struct EffectChain;
 class ImageLayer;
 class ImageLayerComposite;
 class LayerComposite;
 class RefLayerComposite;
 class SurfaceDescriptor;
 class ThebesLayerComposite;
 class TiledLayerComposer;
 class TextRenderer;
+class CompositingRenderTarget;
 struct FPSState;
 
 class LayerManagerComposite : public LayerManager
 {
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::IntSize IntSize;
   typedef mozilla::gfx::SurfaceFormat SurfaceFormat;
 
@@ -263,16 +264,19 @@ private:
 
   /**
    * Render debug overlays such as the FPS/FrameCounter above the frame.
    */
   void RenderDebugOverlay(const gfx::Rect& aBounds);
 
   void WorldTransformRect(nsIntRect& aRect);
 
+  RefPtr<CompositingRenderTarget> PushGroup();
+  void PopGroup(RefPtr<CompositingRenderTarget> aPreviousTarget, nsIntRect aClipRect);
+
   RefPtr<Compositor> mCompositor;
   nsAutoPtr<LayerProperties> mClonedLayerTreeProperties;
 
   /**
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
   nsIntRect mTargetBounds;
@@ -280,16 +284,17 @@ private:
   gfx::Matrix mWorldMatrix;
   nsIntRegion mInvalidRegion;
   nsAutoPtr<FPSState> mFPS;
 
   bool mInTransaction;
   bool mIsCompositorReady;
   bool mDebugOverlayWantsNextFrame;
 
+  RefPtr<CompositingRenderTarget> mTwoPassTmpTarget;
   RefPtr<TextRenderer> mTextRenderer;
   bool mGeometryChanged;
 };
 
 /**
  * Composite layers are for use with OMTC on the compositor thread only. There
  * must be corresponding Basic layers on the content thread. For composite
  * layers, the layer manager only maintains the layer tree, all rendering is
--- a/gfx/layers/d3d10/CanvasLayerD3D10.cpp
+++ b/gfx/layers/d3d10/CanvasLayerD3D10.cpp
@@ -46,26 +46,26 @@ CanvasLayerD3D10::Initialize(const Data&
     mDataIsPremultiplied = aData.mIsGLAlphaPremult;
     mNeedsYFlip = true;
 
     GLScreenBuffer* screen = mGLContext->Screen();
     SurfaceStreamType streamType =
         SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
                                           screen->PreserveBuffer());
 
-    SurfaceFactory* factory = nullptr;
+    UniquePtr<SurfaceFactory> factory = nullptr;
     if (!gfxPrefs::WebGLForceLayersReadback()) {
       if (mGLContext->IsANGLE()) {
         factory = SurfaceFactory_ANGLEShareHandle::Create(mGLContext,
                                                           screen->mCaps);
       }
     }
 
     if (factory) {
-      screen->Morph(factory, streamType);
+      screen->Morph(Move(factory), streamType);
     }
   } else if (aData.mDrawTarget) {
     mDrawTarget = aData.mDrawTarget;
     mNeedsYFlip = false;
     mDataIsPremultiplied = true;
     void *texture = mDrawTarget->GetNativeSurface(NativeSurfaceType::D3D10_TEXTURE);
 
     if (texture) {
--- a/gfx/layers/opengl/CompositingRenderTargetOGL.h
+++ b/gfx/layers/opengl/CompositingRenderTargetOGL.h
@@ -132,19 +132,17 @@ public:
   TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE
   {
     // XXX - Bug 900770
     MOZ_ASSERT(false, "CompositingRenderTargetOGL should not be used as a TextureSource");
     return nullptr;
   }
   gfx::IntSize GetSize() const MOZ_OVERRIDE
   {
-    // XXX - Bug 900770
-    MOZ_ASSERT(false, "CompositingRenderTargetOGL should not be used as a TextureSource");
-    return gfx::IntSize(0, 0);
+    return mInitParams.mSize;
   }
 
   gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
   {
     // XXX - Should it be implemented ? is the above assert true ?
     MOZ_ASSERT(false, "Not implemented");
     return gfx::SurfaceFormat::UNKNOWN;
   }
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -892,17 +892,18 @@ CompositorOGL::CreateFBOWithTexture(cons
 
   *aFBO = fbo;
   *aTexture = tex;
 }
 
 ShaderConfigOGL
 CompositorOGL::GetShaderConfigFor(Effect *aEffect,
                                   MaskType aMask,
-                                  gfx::CompositionOp aOp) const
+                                  gfx::CompositionOp aOp,
+                                  bool aColorMatrix) const
 {
   ShaderConfigOGL config;
 
   switch(aEffect->mType) {
   case EffectTypes::SOLID_COLOR:
     config.SetRenderColor(true);
     break;
   case EffectTypes::YCBCR:
@@ -939,16 +940,17 @@ CompositorOGL::GetShaderConfigFor(Effect
         !texturedEffect->mPremultiplied) {
       // We can do these blend modes just using glBlendFunc but we need the data
       // to be premultiplied first.
       config.SetPremultiply(true);
     }
     break;
   }
   }
+  config.SetColorMatrix(aColorMatrix);
   config.SetMask2D(aMask == MaskType::Mask2d);
   config.SetMask3D(aMask == MaskType::Mask3d);
   return config;
 }
 
 ShaderProgramOGL*
 CompositorOGL::GetShaderProgramFor(const ShaderConfigOGL &aConfig)
 {
@@ -1086,22 +1088,30 @@ CompositorOGL::DrawQuad(const Rect& aRec
 
   gfx::CompositionOp blendMode = gfx::CompositionOp::OP_OVER;
   if (aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) {
     EffectBlendMode *blendEffect =
       static_cast<EffectBlendMode*>(aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get());
     blendMode = blendEffect->mBlendMode;
   }
 
-  ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode);
+  bool colorMatrix = aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX];
+  ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode, colorMatrix);
   config.SetOpacity(aOpacity != 1.f);
   ShaderProgramOGL *program = GetShaderProgramFor(config);
   program->Activate();
   program->SetProjectionMatrix(mProjMatrix);
   program->SetLayerTransform(aTransform);
+
+  if (colorMatrix) {
+      EffectColorMatrix* effectColorMatrix =
+        static_cast<EffectColorMatrix*>(aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX].get());
+      program->SetColorMatrix(effectColorMatrix->mColorMatrix);
+  }
+
   IntPoint offset = mCurrentRenderTarget->GetOrigin();
   program->SetRenderOffset(offset.x, offset.y);
   if (aOpacity != 1.f)
     program->SetLayerOpacity(aOpacity);
   if (config.mFeatures & ENABLE_TEXTURE_RECT) {
     TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
     TextureSourceOGL* source = texturedEffect->mTexture->AsSourceOGL();
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -328,17 +328,18 @@ private:
                           const gfx::Rect *aClipRectIn,
                           const gfx::Matrix& aTransform,
                           const gfx::Rect& aRenderBounds,
                           gfx::Rect *aClipRectOut = nullptr,
                           gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
 
   ShaderConfigOGL GetShaderConfigFor(Effect *aEffect,
                                      MaskType aMask = MaskType::MaskNone,
-                                     gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER) const;
+                                     gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER,
+                                     bool aColorMatrix = false) const;
   ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig);
 
   /**
    * Create a FBO backed by a texture.
    * Note that the texture target type will be
    * of the type returned by FBOTextureTarget; different
    * shaders are required to sample from the different
    * texture types.
--- a/gfx/layers/opengl/OGLShaderProgram.cpp
+++ b/gfx/layers/opengl/OGLShaderProgram.cpp
@@ -42,16 +42,18 @@ AddUniforms(ProgramProfileOGL& aProfile)
         "uCbTexture",
         "uCrTexture",
         "uBlackTexture",
         "uWhiteTexture",
         "uMaskTexture",
         "uRenderColor",
         "uTexCoordMultiplier",
         "uTexturePass2",
+        "uColorMatrix",
+        "uColorMatrixVector",
         nullptr
     };
 
     for (int i = 0; sKnownUniformNames[i] != nullptr; ++i) {
         aProfile.mUniforms[i].mNameString = sKnownUniformNames[i];
         aProfile.mUniforms[i].mName = (KnownUniform::KnownUniformName) i;
     }
 }
--- a/gfx/layers/opengl/OGLShaderProgram.h
+++ b/gfx/layers/opengl/OGLShaderProgram.h
@@ -63,16 +63,18 @@ public:
     CbTexture,
     CrTexture,
     BlackTexture,
     WhiteTexture,
     MaskTexture,
     RenderColor,
     TexCoordMultiplier,
     TexturePass2,
+    ColorMatrix,
+    ColorMatrixVector,
 
     KnownUniformCount
   };
 
   KnownUniform()
   {
     mName = NotAKnownUniform;
     mNameString = nullptr;
@@ -364,16 +366,22 @@ public:
   void SetRenderColor(const gfxRGBA& aColor) {
     SetUniform(KnownUniform::RenderColor, aColor);
   }
 
   void SetRenderColor(const gfx::Color& aColor) {
     SetUniform(KnownUniform::RenderColor, aColor);
   }
 
+  void SetColorMatrix(const gfx::Matrix5x4& aColorMatrix)
+  {
+    SetMatrixUniform(KnownUniform::ColorMatrix, &aColorMatrix._11);
+    SetUniform(KnownUniform::ColorMatrixVector, 4, &aColorMatrix._51);
+  }
+
   void SetTexCoordMultiplier(float aWidth, float aHeight) {
     float f[] = {aWidth, aHeight};
     SetUniform(KnownUniform::TexCoordMultiplier, 2, f);
   }
 
   // Set whether we want the component alpha shader to return the color
   // vector (pass 1, false) or the alpha vector (pass2, true). With support
   // for multiple render targets we wouldn't need two passes here.
@@ -427,17 +435,17 @@ protected:
     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
 
     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
     if (ku.UpdateUniform(aColor.r, aColor.g, aColor.b, aColor.a)) {
       mGL->fUniform4fv(ku.mLocation, 1, ku.mValue.f16v);
     }
   }
 
-  void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, float *aFloatValues)
+  void SetUniform(KnownUniform::KnownUniformName aKnownUniform, int aLength, const float *aFloatValues)
   {
     ASSERT_THIS_PROGRAM;
     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
 
     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
     if (ku.UpdateUniform(aLength, aFloatValues)) {
       switch (aLength) {
       case 1: mGL->fUniform1fv(ku.mLocation, 1, ku.mValue.f16v); break;
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -245,16 +245,18 @@ private:
   DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.testing.enabled", LayersOffMainThreadCompositionTestingEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces",   UseImageOffscreenSurfaces, bool, false);
   DECL_GFX_PREF(Live, "layers.orientation.sync.timeout",       OrientationSyncMillis, uint32_t, (uint32_t)0);
   DECL_GFX_PREF(Once, "layers.prefer-d3d9",                    LayersPreferD3D9, bool, false);
   DECL_GFX_PREF(Once, "layers.prefer-opengl",                  LayersPreferOpenGL, bool, false);
   DECL_GFX_PREF(Once, "layers.progressive-paint",              UseProgressiveTilePainting, bool, false);
   DECL_GFX_PREF(Once, "layers.scroll-graph",                   LayersScrollGraph, bool, false);
   DECL_GFX_PREF(Once, "layers.uniformity-info",                UniformityInfo, bool, false);
+  DECL_GFX_PREF(Live, "layers.invert",                         Invert, bool, false);
+  DECL_GFX_PREF(Live, "layers.grayscale",                      Grayscale, bool, false);
 
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.damping-ratio", ScrollBehaviorDampingRatio, float, 1.0f);
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.enabled",    ScrollBehaviorEnabled, bool, false);
   DECL_GFX_PREF(Live, "layout.css.scroll-behavior.spring-constant", ScrollBehaviorSpringConstant, float, 250.0f);
   DECL_GFX_PREF(Once, "layout.css.touch_action.enabled",       TouchActionEnabled, bool, false);
   DECL_GFX_PREF(Once, "layout.frame_rate",                     LayoutFrameRate, int32_t, -1);
   DECL_GFX_PREF(Live, "layout.display-list.dump",              LayoutDumpDisplayList, bool, false);
   DECL_GFX_PREF(Once, "layout.paint_rects_separately",         LayoutPaintRectsSeparately, bool, true);
--- a/js/ipc/JavaScriptChild.cpp
+++ b/js/ipc/JavaScriptChild.cpp
@@ -15,42 +15,28 @@
 #include "AccessCheck.h"
 
 using namespace JS;
 using namespace mozilla;
 using namespace mozilla::jsipc;
 
 using mozilla::AutoSafeJSContext;
 
-#ifdef NIGHTLY_BUILD
-static void
-UrgentMessageCheck(JSContext *cx, HandleScript script)
-{
-    // We're only allowed to enter chrome JS code while processing urgent
-    // messages.
-    if (ipc::ProcessingUrgentMessages())
-        MOZ_RELEASE_ASSERT(xpc::AccessCheck::isChrome(js::GetContextCompartment(cx)));
-}
-#endif
-
 static void
 FinalizeChild(JSFreeOp *fop, JSFinalizeStatus status, bool isCompartment, void *data)
 {
     if (status == JSFINALIZE_GROUP_START) {
         static_cast<JavaScriptChild *>(data)->finalize(fop);
     }
 }
 
 JavaScriptChild::JavaScriptChild(JSRuntime *rt)
   : JavaScriptShared(rt),
     JavaScriptBase<PJavaScriptChild>(rt)
 {
-#ifdef NIGHTLY_BUILD
-    js::SetAssertOnScriptEntryHook(rt, UrgentMessageCheck);
-#endif
 }
 
 JavaScriptChild::~JavaScriptChild()
 {
     JS_RemoveFinalizeCallback(rt_, FinalizeChild);
 }
 
 bool
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -1798,22 +1798,22 @@ GetCPUID(uint32_t *cpuId)
         X86 = 0x1,
         X64 = 0x2,
         ARM = 0x3,
         MIPS = 0x4,
         ARCH_BITS = 3
     };
 
 #if defined(JS_CODEGEN_X86)
-    JS_ASSERT(uint32_t(JSC::MacroAssembler::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
-    *cpuId = X86 | (JSC::MacroAssembler::getSSEState() << ARCH_BITS);
+    JS_ASSERT(uint32_t(JSC::MacroAssemblerX86Common::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
+    *cpuId = X86 | (JSC::MacroAssemblerX86Common::getSSEState() << ARCH_BITS);
     return true;
 #elif defined(JS_CODEGEN_X64)
-    JS_ASSERT(uint32_t(JSC::MacroAssembler::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
-    *cpuId = X64 | (JSC::MacroAssembler::getSSEState() << ARCH_BITS);
+    JS_ASSERT(uint32_t(JSC::MacroAssemblerX86Common::getSSEState()) <= (UINT32_MAX >> ARCH_BITS));
+    *cpuId = X64 | (JSC::MacroAssemblerX86Common::getSSEState() << ARCH_BITS);
     return true;
 #elif defined(JS_CODEGEN_ARM)
     JS_ASSERT(GetARMFlags() <= (UINT32_MAX >> ARCH_BITS));
     *cpuId = ARM | (GetARMFlags() << ARCH_BITS);
     return true;
 #elif defined(JS_CODEGEN_MIPS)
     JS_ASSERT(GetMIPSFlags() <= (UINT32_MAX >> ARCH_BITS));
     *cpuId = MIPS | (GetMIPSFlags() << ARCH_BITS);
--- a/js/src/asmjs/AsmJSSignalHandlers.cpp
+++ b/js/src/asmjs/AsmJSSignalHandlers.cpp
@@ -16,17 +16,16 @@
  * limitations under the License.
  */
 
 #include "asmjs/AsmJSSignalHandlers.h"
 
 #include "mozilla/DebugOnly.h"
 
 #include "asmjs/AsmJSModule.h"
-#include "assembler/assembler/MacroAssembler.h"
 #include "vm/Runtime.h"
 
 using namespace js;
 using namespace js::jit;
 
 using JS::GenericNaN;
 using mozilla::DebugOnly;
 
--- a/js/src/assembler/assembler/AssemblerBuffer.h
+++ b/js/src/assembler/assembler/AssemblerBuffer.h
@@ -25,20 +25,16 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef assembler_assembler_AssemblerBuffer_h
 #define assembler_assembler_AssemblerBuffer_h
 
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER
-
 #include <string.h>
 #include <limits.h>
 #include <stdarg.h>
 
 #include "jsfriendapi.h"
 #include "jsopcode.h"
 #include "jsutil.h"
 
@@ -324,11 +320,9 @@ namespace JSC {
                 if (i > -1)
                     js::jit::IonSpew(js::jit::IonSpew_Codegen, "%s", buf);
             }
         }
     };
 
 } // namespace JSC
 
-#endif // ENABLE(ASSEMBLER)
-
 #endif /* assembler_assembler_AssemblerBuffer_h */
deleted file mode 100644
--- a/js/src/assembler/assembler/MacroAssembler.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef assembler_assembler_MacroAssembler_h
-#define assembler_assembler_MacroAssembler_h
-
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER
-
-#if JS_CODEGEN_NONE
-
-#include "jit/none/BaseMacroAssembler-none.h"
-namespace JSC { typedef MacroAssemblerNone MacroAssembler; }
-
-#elif JS_CODEGEN_ARM
-// Merged with the jit backend support.
-
-#elif JS_CODEGEN_MIPS
-#include "assembler/assembler/MacroAssemblerMIPS.h"
-namespace JSC { typedef MacroAssemblerMIPS MacroAssembler; }
-
-#elif JS_CODEGEN_X86
-#include "assembler/assembler/MacroAssemblerX86.h"
-namespace JSC { typedef MacroAssemblerX86 MacroAssembler; }
-
-#elif JS_CODEGEN_X64
-#include "assembler/assembler/MacroAssemblerX86_64.h"
-namespace JSC { typedef MacroAssemblerX86_64 MacroAssembler; }
-
-#elif WTF_CPU_SPARC
-#include "assembler/assembler/MacroAssemblerSparc.h"
-namespace JSC { typedef MacroAssemblerSparc MacroAssembler; }
-
-#else
-#error "The MacroAssembler is not supported on this platform."
-#endif
-
-#endif // ENABLE(ASSEMBLER)
-
-#endif /* assembler_assembler_MacroAssembler_h */
deleted file mode 100644
--- a/js/src/assembler/assembler/MacroAssemblerMIPS.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY MIPS TECHNOLOGIES, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MIPS TECHNOLOGIES, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef assembler_assembler_MacroAssemblerMIPS_h
-#define assembler_assembler_MacroAssemblerMIPS_h
-
-#if ENABLE(ASSEMBLER) && CPU(MIPS)
-
-#include "assembler/wtf/Platform.h"
-
-namespace JSC {
-
-class MacroAssemblerMIPS {
-public:
-    static bool supportsFloatingPoint()
-    {
-#if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_MIPS_SIMULATOR)
-        return true;
-#else
-        return false;
-#endif
-    }
-};
-
-}
-
-#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
-
-#endif /* assembler_assembler_MacroAssemblerMIPS_h */
deleted file mode 100644
--- a/js/src/assembler/assembler/MacroAssemblerSparc.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99: */
-/* 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 assembler_assembler_MacroAssemblerSparc_h
-#define assembler_assembler_MacroAssemblerSparc_h
-
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER && WTF_CPU_SPARC
-
-namespace JSC {
-
-class MacroAssemblerSparc {
-public:
-    static bool supportsFloatingPoint() { return true; }
-};
-
-}
-
-#endif // ENABLE(ASSEMBLER) && CPU(SPARC)
-
-#endif /* assembler_assembler_MacroAssemblerSparc_h */
deleted file mode 100644
--- a/js/src/assembler/assembler/MacroAssemblerX86.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef assembler_assembler_MacroAssemblerX86_h
-#define assembler_assembler_MacroAssemblerX86_h
-
-#include "assembler/assembler/MacroAssemblerX86Common.h"
-
-namespace JSC {
-
-class MacroAssemblerX86 : public MacroAssemblerX86Common {
-public:
-    static bool supportsFloatingPoint() { return isSSE2Present(); }
-};
-
-} // namespace JSC
-
-#endif /* assembler_assembler_MacroAssemblerX86_h */
--- a/js/src/assembler/assembler/MacroAssemblerX86Common.cpp
+++ b/js/src/assembler/assembler/MacroAssemblerX86Common.cpp
@@ -1,18 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99: */
 /* 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 "assembler/assembler/MacroAssemblerX86Common.h"
 
-#include "assembler/wtf/Platform.h"
-
 #ifdef _MSC_VER
 #ifdef JS_CODEGEN_X64
 /* for __cpuid */
 #include <intrin.h>
 #endif
 #endif
 
 using namespace JSC;
--- a/js/src/assembler/assembler/MacroAssemblerX86Common.h
+++ b/js/src/assembler/assembler/MacroAssemblerX86Common.h
@@ -25,20 +25,16 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef assembler_assembler_MacroAssemblerX86Common_h
 #define assembler_assembler_MacroAssemblerX86Common_h
 
-#include "assembler/wtf/Platform.h"
-
-#if ENABLE_ASSEMBLER
-
 #include "assembler/assembler/X86Assembler.h"
 
 namespace JSC {
 
 class MacroAssemblerX86Common {
 public:
     // As the SSE's were introduced in order, the presence of a later SSE implies
     // the presence of an earlier SSE. For example, SSE4_2 support implies SSE2 support.
@@ -187,11 +183,9 @@ private:
     static void SetSSE4Disabled() {
         s_SSE4Disabled = true;
     }
 #endif
 };
 
 } // namespace JSC
 
-#endif // ENABLE(ASSEMBLER)
-
 #endif /* assembler_assembler_MacroAssemblerX86Common_h */
deleted file mode 100644
--- a/js/src/assembler/assembler/MacroAssemblerX86_64.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef assembler_assembler_MacroAssemblerX86_64_h
-#define assembler_assembler_MacroAssemblerX86_64_h
-
-#include "assembler/assembler/MacroAssemblerX86Common.h"
-
-namespace JSC {
-
-class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
-public:
-    static bool supportsFloatingPoint() { return true; }
-};
-
-} // namespace JSC
-
-#endif /* assembler_assembler_MacroAssemblerX86_64_h */
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -27,18 +27,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef assembler_assembler_X86Assembler_h
 #define assembler_assembler_X86Assembler_h
 
 #include <stdarg.h>
 
-#include "assembler/wtf/Platform.h"
-
 #include "assembler/assembler/AssemblerBuffer.h"
 #include "js/Vector.h"
 
 namespace JSC {
 
 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
 inline bool CAN_ZERO_EXTEND_8_32(int32_t value) { return value == (int32_t)(unsigned char)value; }
 inline bool CAN_ZERO_EXTEND_8H_32(int32_t value) { return value == (value & 0xff00); }
deleted file mode 100644
--- a/js/src/assembler/wtf/Platform.h
+++ /dev/null
@@ -1,1272 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc.  All rights reserved.
- * Copyright (C) 2007-2009 Torch Mobile, Inc.
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef assembler_wtf_Platform_h
-#define assembler_wtf_Platform_h
-
-/* ==== PLATFORM handles OS, operating environment, graphics API, and
-   CPU. This macro will be phased out in favor of platform adaptation
-   macros, policy decision macros, and top-level port definitions. ==== */
-#define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE  && WTF_PLATFORM_##WTF_FEATURE)
-
-
-/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */
-
-/* COMPILER() - the compiler being used to build the project */
-#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE  && WTF_COMPILER_##WTF_FEATURE)
-/* CPU() - the target CPU architecture */
-#define CPU(WTF_FEATURE) (defined WTF_CPU_##WTF_FEATURE  && WTF_CPU_##WTF_FEATURE)
-/* HAVE() - specific system features (headers, functions or similar) that are present or not */
-#define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE  && HAVE_##WTF_FEATURE)
-/* OS() - underlying operating system; only to be used for mandated low-level services like
-   virtual memory, not to choose a GUI toolkit */
-#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE  && WTF_OS_##WTF_FEATURE)
-
-
-/* ==== Policy decision macros: these define policy choices for a particular port. ==== */
-
-/* USE() - use a particular third-party library or optional OS service */
-#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE  && WTF_USE_##WTF_FEATURE)
-/* ENABLE() - turn on a specific feature of WebKit */
-#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE  && ENABLE_##WTF_FEATURE)
-
-
-
-/* ==== COMPILER() - the compiler being used to build the project ==== */
-
-/* WTF_COMPILER_MSVC Microsoft Visual C++ */
-/* WTF_COMPILER_MSVC7_OR_LOWER Microsoft Visual C++ 2003 or lower*/
-/* WTF_COMPILER_MSVC9_OR_LOWER Microsoft Visual C++ 2008 or lower*/
-#if defined(_MSC_VER)
-#define WTF_COMPILER_MSVC 1
-#if _MSC_VER < 1400
-#define WTF_COMPILER_MSVC7_OR_LOWER 1
-#elif _MSC_VER < 1600
-#define WTF_COMPILER_MSVC9_OR_LOWER 1
-#endif
-#endif
-
-/* WTF_COMPILER_RVCT  - ARM RealView Compilation Tools */
-/* WTF_COMPILER_RVCT4_OR_GREATER - ARM RealView Compilation Tools 4.0 or greater */
-#if defined(__CC_ARM) || defined(__ARMCC__)
-#define WTF_COMPILER_RVCT 1
-#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) (__ARMCC_VERSION >= (major * 100000 + minor * 10000 + patch * 1000 + build))
-#else
-/* Define this for !RVCT compilers, just so we can write things like RVCT_VERSION_AT_LEAST(3, 0, 0, 0). */
-#define RVCT_VERSION_AT_LEAST(major, minor, patch, build) 0
-#endif
-
-/* WTF_COMPILER_GCC - GNU Compiler Collection */
-/* --gnu option of the RVCT compiler also defines __GNUC__ */
-#if defined(__GNUC__) && !WTF_COMPILER_RVCT
-#define WTF_COMPILER_GCC 1
-#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch))
-#else
-/* Define this for !GCC compilers, just so we can write things like GCC_VERSION_AT_LEAST(4, 1, 0). */
-#define GCC_VERSION_AT_LEAST(major, minor, patch) 0
-#endif
-
-/* WTF_COMPILER_MINGW - MinGW GCC */
-/* WTF_COMPILER_MINGW64 - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */
-#if defined(__MINGW32__)
-#define WTF_COMPILER_MINGW 1
-#include <_mingw.h> /* private MinGW header */
-    #if defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */
-        #define WTF_COMPILER_MINGW64 1
-    #endif /* __MINGW64_VERSION_MAJOR */
-#endif /* __MINGW32__ */
-
-/* WTF_COMPILER_WINSCW - CodeWarrior for Symbian emulator */
-#if defined(__WINSCW__)
-#define WTF_COMPILER_WINSCW 1
-/* cross-compiling, it is not really windows */
-#undef WIN32
-#undef _WIN32
-#endif
-
-/* WTF_COMPILER_INTEL - Intel C++ Compiler */
-#if defined(__INTEL_COMPILER)
-#define WTF_COMPILER_INTEL 1
-#endif
-
-/* WTF_COMPILER_SUNCC */
-#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
-#define WTF_COMPILER_SUNCC 1
-#endif
-
-/* ==== CPU() - the target CPU architecture ==== */
-
-/* This also defines WTF_CPU_BIG_ENDIAN or WTF_CPU_MIDDLE_ENDIAN or neither, as appropriate. */
-
-/* WTF_CPU_ALPHA - DEC Alpha */
-#if defined(__alpha__)
-#define WTF_CPU_ALPHA 1
-#endif
-
-/* WTF_CPU_IA64 - Itanium / IA-64 */
-#if defined(__ia64__)
-#define WTF_CPU_IA64 1
-/* 32-bit mode on Itanium */
-#if !defined(__LP64__)
-#define WTF_CPU_IA64_32 1
-#endif
-#endif
-
-/* WTF_CPU_MIPS - MIPS 32-bit */
-/* Note: Only O32 ABI is tested, so we enable it for O32 ABI for now.  */
-#if (defined(mips) || defined(__mips__) || defined(MIPS) || defined(_MIPS_)) \
-    && defined(_ABIO32)
-#define WTF_CPU_MIPS 1
-#if defined(__MIPSEB__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#define WTF_MIPS_PIC (defined __PIC__)
-#define WTF_MIPS_ARCH __mips
-#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v)
-#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v)
-#define WTF_MIPS_ARCH_REV __mips_isa_rev
-#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
-#define WTF_MIPS_DOUBLE_FLOAT (defined __mips_hard_float && !defined __mips_single_float)
-#define WTF_MIPS_FP64 (defined __mips_fpr && __mips_fpr == 64)
-/* MIPS requires allocators to use aligned memory */
-#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
-#endif /* MIPS */
-
-#if defined(JS_MIPS_SIMULATOR)
-#define WTF_MIPS_ARCH 32
-#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v)
-#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v)
-#define WTF_MIPS_ARCH_REV 2
-#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
-#define WTF_MIPS_DOUBLE_FLOAT 1
-#undef WTF_MIPS_FP64
-#endif
-
-/* WTF_CPU_PPC - PowerPC 32-bit */
-#if   defined(__ppc__)     \
-    || defined(__PPC__)     \
-    || defined(__powerpc__) \
-    || defined(__powerpc)   \
-    || defined(__POWERPC__) \
-    || defined(_M_PPC)      \
-    || defined(__PPC)
-#if !defined(__ppc64__) && !defined(__PPC64__)
-#define WTF_CPU_PPC 1
-#endif
-#if !defined(__LITTLE_ENDIAN__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#endif
-
-/* WTF_CPU_PPC64 - PowerPC 64-bit */
-#if   defined(__ppc64__) \
-    || defined(__PPC64__)
-#define WTF_CPU_PPC64 1
-#if !defined(__LITTLE_ENDIAN__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#endif
-
-/* WTF_CPU_SH4 - SuperH SH-4 */
-#if defined(__SH4__)
-#define WTF_CPU_SH4 1
-#endif
-
-/* WTF_CPU_SPARC32 - SPARC 32-bit */
-#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8)
-#define WTF_CPU_SPARC32 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-/* WTF_CPU_SPARC64 - SPARC 64-bit */
-#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9)
-#define WTF_CPU_SPARC64 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-/* WTF_CPU_SPARC - any SPARC, true for WTF_CPU_SPARC32 and WTF_CPU_SPARC64 */
-#if WTF_CPU_SPARC32 || WTF_CPU_SPARC64
-#define WTF_CPU_SPARC 1
-#endif
-
-/* WTF_CPU_S390X - S390 64-bit */
-#if defined(__s390x__)
-#define WTF_CPU_S390X 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-/* WTF_CPU_S390 - S390 32-bit */
-#if defined(__s390__)
-#define WTF_CPU_S390 1
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-
-#if defined(__aarch64__)
-#define WTF_CPU_AARCH64 1
-#if defined(__AARCH64EB__)
-#define WTF_CPU_BIG_ENDIAN 1
-#endif
-#endif
-
-/* WTF_CPU_X86 - i386 / x86 32-bit */
-#if   defined(__i386__) \
-    || defined(i386)     \
-    || defined(_M_IX86)  \
-    || defined(_X86_)    \
-    || defined(__THW_INTEL)
-#define WTF_CPU_X86 1
-#endif
-
-/* WTF_CPU_X86_64 - AMD64 / Intel64 / x86_64 64-bit */
-#if   defined(__x86_64__) \
-    || defined(_M_X64)
-#define WTF_CPU_X86_64 1
-#endif
-
-/* WTF_CPU_ARM - ARM, any version*/
-#if   defined(arm) \
-    || defined(__arm__) \
-    || defined(ARM) \
-    || defined(_ARM_)
-#define WTF_CPU_ARM 1
-
-#if defined(__ARMEB__) || (WTF_COMPILER_RVCT && defined(__BIG_ENDIAN))
-#define WTF_CPU_BIG_ENDIAN 1
-
-#elif !defined(__ARM_EABI__) \
-    && !defined(__EABI__) \
-    && !defined(__VFP_FP__) \
-    && !defined(_WIN32_WCE) \
-    && !defined(ANDROID)
-#define WTF_CPU_MIDDLE_ENDIAN 1
-
-#endif
-
-#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N)
-#define WTF_ARM_ARCH_AT_LEAST_5 (WTF_CPU_ARM && WTF_ARM_ARCH_VERSION >= 5)
-
-/* Set WTF_ARM_ARCH_VERSION */
-#if   defined(__ARM_ARCH_4__) \
-    || defined(__ARM_ARCH_4T__) \
-    || defined(__MARM_ARMV4__) \
-    || defined(_ARMV4I_)
-#define WTF_ARM_ARCH_VERSION 4
-
-#elif defined(__ARM_ARCH_5__) \
-    || defined(__ARM_ARCH_5T__) \
-    || defined(__MARM_ARMV5__)
-#define WTF_ARM_ARCH_VERSION 5
-
-#elif defined(__ARM_ARCH_5E__) \
-    || defined(__ARM_ARCH_5TE__) \
-    || defined(__ARM_ARCH_5TEJ__)
-#define WTF_ARM_ARCH_VERSION 5
-/*ARMv5TE requires allocators to use aligned memory*/
-#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
-
-#elif defined(__ARM_ARCH_6__) \
-    || defined(__ARM_ARCH_6J__) \
-    || defined(__ARM_ARCH_6K__) \
-    || defined(__ARM_ARCH_6Z__) \
-    || defined(__ARM_ARCH_6ZK__) \
-    || defined(__ARM_ARCH_6T2__) \
-    || defined(__ARMV6__)
-#define WTF_ARM_ARCH_VERSION 6
-
-#elif defined(__ARM_ARCH_7A__) \
-    || defined(__ARM_ARCH_7R__)
-#define WTF_ARM_ARCH_VERSION 7
-
-/* RVCT sets _TARGET_ARCH_ARM */
-#elif defined(__TARGET_ARCH_ARM)
-#define WTF_ARM_ARCH_VERSION __TARGET_ARCH_ARM
-
-#if defined(__TARGET_ARCH_5E) \
-    || defined(__TARGET_ARCH_5TE) \
-    || defined(__TARGET_ARCH_5TEJ)
-/*ARMv5TE requires allocators to use aligned memory*/
-#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1
-#endif
-
-#else
-#define WTF_ARM_ARCH_VERSION 0
-
-#endif
-
-/* Set WTF_THUMB_ARCH_VERSION */
-#if   defined(__ARM_ARCH_4T__)
-#define WTF_THUMB_ARCH_VERSION 1
-
-#elif defined(__ARM_ARCH_5T__) \
-    || defined(__ARM_ARCH_5TE__) \
-    || defined(__ARM_ARCH_5TEJ__)
-#define WTF_THUMB_ARCH_VERSION 2
-
-#elif defined(__ARM_ARCH_6J__) \
-    || defined(__ARM_ARCH_6K__) \
-    || defined(__ARM_ARCH_6Z__) \
-    || defined(__ARM_ARCH_6ZK__) \
-    || defined(__ARM_ARCH_6M__)
-#define WTF_THUMB_ARCH_VERSION 3
-
-#elif defined(__ARM_ARCH_6T2__) \
-    || defined(__ARM_ARCH_7__) \
-    || defined(__ARM_ARCH_7A__) \
-    || defined(__ARM_ARCH_7R__) \
-    || defined(__ARM_ARCH_7M__)
-#define WTF_THUMB_ARCH_VERSION 4
-
-/* RVCT sets __TARGET_ARCH_THUMB */
-#elif defined(__TARGET_ARCH_THUMB)
-#define WTF_THUMB_ARCH_VERSION __TARGET_ARCH_THUMB
-
-#else
-#define WTF_THUMB_ARCH_VERSION 0
-#endif
-
-
-/* WTF_CPU_ARMV5_OR_LOWER - ARM instruction set v5 or earlier */
-/* On ARMv5 and below the natural alignment is required.
-   And there are some other differences for v5 or earlier. */
-#if !defined(ARMV5_OR_LOWER) && WTF_CPU_ARM && !(WTF_ARM_ARCH_VERSION >= 6)
-#define WTF_CPU_ARMV5_OR_LOWER 1
-#endif
-
-
-/* WTF_CPU_ARM_TRADITIONAL - Thumb2 is not available, only traditional ARM (v4 or greater) */
-/* WTF_CPU_ARM_THUMB2 - Thumb2 instruction set is available */
-/* Only one of these will be defined. */
-#if !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2)
-#  if defined(thumb2) || defined(__thumb2__) \
-    || ((defined(__thumb) || defined(__thumb__)) && WTF_THUMB_ARCH_VERSION == 4)
-#    define WTF_CPU_ARM_TRADITIONAL 1
-#    define WTF_CPU_ARM_THUMB2 0
-#  elif WTF_CPU_ARM && WTF_ARM_ARCH_VERSION >= 4
-#    define WTF_CPU_ARM_TRADITIONAL 1
-#    define WTF_CPU_ARM_THUMB2 0
-#  else
-#    error "Not supported ARM architecture"
-#  endif
-#elif WTF_CPU_ARM_TRADITIONAL && WTF_CPU_ARM_THUMB2 /* Sanity Check */
-#  error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms"
-#endif /* !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) */
-
-#if defined(__ARM_NEON__) && !defined(WTF_CPU_ARM_NEON)
-#define WTF_CPU_ARM_NEON 1
-#endif
-
-#endif /* ARM */
-
-#if defined(JS_ARM_SIMULATOR)
-#  undef WTF_CPU_X86
-#  undef WTF_CPU_X64
-#  define WTF_CPU_ARM_TRADITIONAL 1
-#  define WTF_CPU_ARM 1
-#endif
-
-#if defined(JS_MIPS_SIMULATOR)
-#  undef WTF_CPU_X86
-#  undef WTF_CPU_X64
-#  define WTF_CPU_MIPS 1
-#endif
-
-#if WTF_CPU_ARM || WTF_CPU_MIPS
-#define WTF_CPU_NEEDS_ALIGNED_ACCESS 1
-#endif
-
-/* ==== OS() - underlying operating system; only to be used for mandated low-level services like
-   virtual memory, not to choose a GUI toolkit ==== */
-
-/* WTF_OS_ANDROID - Android */
-#ifdef ANDROID
-#define WTF_OS_ANDROID 1
-#endif
-
-/* WTF_OS_AIX - AIX */
-#ifdef _AIX
-#define WTF_OS_AIX 1
-#endif
-
-/* WTF_OS_DARWIN - Any Darwin-based OS, including Mac OS X and iPhone OS */
-#ifdef __APPLE__
-#define WTF_OS_DARWIN 1
-
-/* FIXME: BUILDING_ON_.., and TARGETING... macros should be folded into the OS() system */
-#include <AvailabilityMacros.h>
-#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
-#define BUILDING_ON_TIGER 1
-#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
-#define BUILDING_ON_LEOPARD 1
-#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-#define BUILDING_ON_SNOW_LEOPARD 1
-#endif
-#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
-#define TARGETING_TIGER 1
-#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
-#define TARGETING_LEOPARD 1
-#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
-#define TARGETING_SNOW_LEOPARD 1
-#endif
-#include <TargetConditionals.h>
-
-#endif
-
-/* WTF_OS_IOS - iOS */
-/* WTF_OS_MAC_OS_X - Mac OS X (not including iOS) */
-#if WTF_OS_DARWIN && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED)  \
-    || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)                   \
-    || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR))
-#define WTF_OS_IOS 1
-#elif WTF_OS_DARWIN && defined(TARGET_OS_MAC) && TARGET_OS_MAC
-#define WTF_OS_MAC_OS_X 1
-#endif
-
-
-/* WTF_OS_FREEBSD - FreeBSD */
-#if defined(__FreeBSD__) || defined(__DragonFly__)
-#define WTF_OS_FREEBSD 1
-#endif
-
-/* WTF_OS_HAIKU - Haiku */
-#ifdef __HAIKU__
-#define WTF_OS_HAIKU 1
-#endif
-
-/* WTF_OS_LINUX - Linux */
-#if defined(__linux__) && !defined(ANDROID)
-#define WTF_OS_LINUX 1
-#endif
-
-/* WTF_OS_NETBSD - NetBSD */
-#if defined(__NetBSD__)
-#define WTF_OS_NETBSD 1
-#endif
-
-/* WTF_OS_OPENBSD - OpenBSD */
-#ifdef __OpenBSD__
-#define WTF_OS_OPENBSD 1
-#endif
-
-/* WTF_OS_QNX - QNX */
-#if defined(__QNXNTO__)
-#define WTF_OS_QNX 1
-#endif
-
-/* WTF_OS_SOLARIS - Solaris */
-#if defined(sun) || defined(__sun)
-#define WTF_OS_SOLARIS 1
-#endif
-
-/* WTF_OS_WINCE - Windows CE; note that for this platform WTF_OS_WINDOWS is also defined */
-#if defined(_WIN32_WCE)
-#define WTF_OS_WINCE 1
-#endif
-
-/* WTF_OS_WINDOWS - Any version of Windows */
-#if defined(WIN32) || defined(_WIN32)
-#define WTF_OS_WINDOWS 1
-#endif
-
-/* WTF_OS_SYMBIAN - Symbian */
-#if defined (__SYMBIAN32__)
-#define WTF_OS_SYMBIAN 1
-#endif
-
-/* WTF_OS_UNIX - Any Unix-like system */
-#if   WTF_OS_AIX              \
-    || WTF_OS_ANDROID          \
-    || WTF_OS_DARWIN           \
-    || WTF_OS_FREEBSD          \
-    || WTF_OS_HAIKU            \
-    || WTF_OS_LINUX            \
-    || WTF_OS_NETBSD           \
-    || WTF_OS_OPENBSD          \
-    || WTF_OS_QNX              \
-    || WTF_OS_SOLARIS          \
-    || WTF_OS_SYMBIAN          \
-    || defined(unix)        \
-    || defined(__unix)      \
-    || defined(__unix__)
-#define WTF_OS_UNIX 1
-#endif
-
-/* WTF_OS_OS2 - OS/2 */
-#if defined (__OS2__)
-#define WTF_OS_OS2 1
-#endif
-
-/* Operating environments */
-
-/* FIXME: these are all mixes of OS, operating environment and policy choices. */
-/* WTF_PLATFORM_CHROMIUM */
-/* WTF_PLATFORM_QT */
-/* WTF_PLATFORM_WX */
-/* WTF_PLATFORM_GTK */
-/* WTF_PLATFORM_HAIKU */
-/* WTF_PLATFORM_MAC */
-/* WTF_PLATFORM_WIN */
-#if defined(BUILDING_CHROMIUM__)
-#define WTF_PLATFORM_CHROMIUM 1
-#elif defined(BUILDING_QT__)
-#define WTF_PLATFORM_QT 1
-#elif defined(BUILDING_WX__)
-#define WTF_PLATFORM_WX 1
-#elif defined(BUILDING_GTK__)
-#define WTF_PLATFORM_GTK 1
-#elif defined(BUILDING_HAIKU__)
-#define WTF_PLATFORM_HAIKU 1
-#elif defined(BUILDING_BREWMP__)
-#define WTF_PLATFORM_BREWMP 1
-#if defined(AEE_SIMULATOR)
-#define WTF_PLATFORM_BREWMP_SIMULATOR 1
-#else
-#define WTF_PLATFORM_BREWMP_SIMULATOR 0
-#endif
-#undef WTF_OS_WINDOWS
-#undef WTF_PLATFORM_WIN
-#elif WTF_OS_DARWIN
-#define WTF_PLATFORM_MAC 1
-#elif WTF_OS_WINDOWS
-#define WTF_PLATFORM_WIN 1
-#endif
-
-/* WTF_PLATFORM_IOS */
-/* FIXME: this is sometimes used as an OS switch and sometimes for higher-level things */
-#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
-#define WTF_PLATFORM_IOS 1
-#endif
-
-/* WTF_PLATFORM_IOS_SIMULATOR */
-#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
-#define WTF_PLATFORM_IOS 1
-#define WTF_PLATFORM_IOS_SIMULATOR 1
-#else
-#define WTF_PLATFORM_IOS_SIMULATOR 0
-#endif
-
-#if !defined(WTF_PLATFORM_IOS)
-#define WTF_PLATFORM_IOS 0
-#endif
-
-/* WTF_PLATFORM_ANDROID */
-/* FIXME: this is sometimes used as an OS() switch, and other times to drive
-   policy choices */
-#if defined(ANDROID)
-#define WTF_PLATFORM_ANDROID 1
-#endif
-
-/* Graphics engines */
-
-/* WTF_USE_CG and WTF_PLATFORM_CI */
-#if WTF_PLATFORM_MAC || WTF_PLATFORM_IOS
-#define WTF_USE_CG 1
-#endif
-#if WTF_PLATFORM_MAC || WTF_PLATFORM_IOS || (WTF_PLATFORM_WIN && WTF_USE_CG)
-#define WTF_USE_CA 1
-#endif
-
-/* WTF_USE_SKIA for Win/Linux, CG for Mac */
-#if WTF_PLATFORM_CHROMIUM
-#if WTF_OS_DARWIN
-#define WTF_USE_CG 1
-#define WTF_USE_ATSUI 1
-#define WTF_USE_CORE_TEXT 1
-#define WTF_USE_ICCJPEG 1
-#else
-#define WTF_USE_SKIA 1
-#define WTF_USE_CHROMIUM_NET 1
-#endif
-#endif
-
-#if WTF_PLATFORM_BREWMP
-#define WTF_USE_SKIA 1
-#endif
-
-#if WTF_PLATFORM_GTK
-#define WTF_USE_CAIRO 1
-#endif
-
-
-#if WTF_OS_WINCE
-#include <ce_time.h>
-#define WTF_USE_MERSENNE_TWISTER_19937 1
-#endif
-
-#if WTF_PLATFORM_QT && WTF_OS_UNIX && !WTF_OS_SYMBIAN && !WTF_OS_DARWIN
-#define WTF_USE_PTHREAD_BASED_QT 1
-#endif
-
-#if (WTF_PLATFORM_GTK || WTF_PLATFORM_IOS || WTF_PLATFORM_MAC || WTF_PLATFORM_WIN || (WTF_PLATFORM_QT && (WTF_OS_DARWIN || WTF_USE_PTHREAD_BASED_QT) && !ENABLE_SINGLE_THREADED)) && !defined(ENABLE_JSC_MULTIPLE_THREADS)
-#define ENABLE_JSC_MULTIPLE_THREADS 1
-#endif
-
-#if ENABLE_JSC_MULTIPLE_THREADS
-#define ENABLE_WTF_MULTIPLE_THREADS 1
-#endif
-
-/* On Windows, use QueryPerformanceCounter by default */
-#if WTF_OS_WINDOWS
-#define WTF_USE_QUERY_PERFORMANCE_COUNTER  1
-#endif
-
-#if WTF_OS_WINCE && !WTF_PLATFORM_QT
-#define NOMINMAX       /* Windows min and max conflict with standard macros */
-#define NOSHLWAPI      /* shlwapi.h not available on WinCe */
-
-/* MSDN documentation says these functions are provided with uspce.lib.  But we cannot find this file. */
-#define __usp10__      /* disable "usp10.h" */
-
-#define _INC_ASSERT    /* disable "assert.h" */
-#define assert(x)
-
-#endif  /* WTF_OS_WINCE && !WTF_PLATFORM_QT */
-
-#if WTF_PLATFORM_QT
-#define WTF_USE_QT4_UNICODE 1
-#elif WTF_OS_WINCE
-#define WTF_USE_WINCE_UNICODE 1
-#elif WTF_PLATFORM_BREWMP
-#define WTF_USE_BREWMP_UNICODE 1
-#elif WTF_PLATFORM_GTK
-/* The GTK+ Unicode backend is configurable */
-#else
-#define WTF_USE_ICU_UNICODE 1
-#endif
-
-#if WTF_PLATFORM_MAC && !WTF_PLATFORM_IOS
-#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && WTF_CPU_X86_64
-#define WTF_USE_PLUGIN_HOST_PROCESS 1
-#endif
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
-#define ENABLE_GESTURE_EVENTS 1
-#define ENABLE_RUBBER_BANDING 1
-#define WTF_USE_WK_SCROLLBAR_PAINTER 1
-#endif
-#if !defined(ENABLE_JAVA_BRIDGE)
-#define ENABLE_JAVA_BRIDGE 1
-#endif
-#if !defined(ENABLE_DASHBOARD_SUPPORT)
-#define ENABLE_DASHBOARD_SUPPORT 1
-#endif
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#define HAVE_READLINE 1
-#define HAVE_RUNLOOP_TIMER 1
-#define ENABLE_FULLSCREEN_API 1
-#define ENABLE_SMOOTH_SCROLLING 1
-#define ENABLE_WEB_ARCHIVE 1
-#endif /* WTF_PLATFORM_MAC && !WTF_PLATFORM_IOS */
-
-#if WTF_PLATFORM_CHROMIUM && WTF_OS_DARWIN
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#endif
-
-#if WTF_PLATFORM_BREWMP
-#define ENABLE_SINGLE_THREADED 1
-#endif
-
-#if WTF_PLATFORM_QT && WTF_OS_DARWIN
-#define WTF_USE_CF 1
-#endif
-
-#if WTF_OS_DARWIN && !defined(BUILDING_ON_TIGER) && !WTF_PLATFORM_GTK && !WTF_PLATFORM_QT
-#define ENABLE_PURGEABLE_MEMORY 1
-#endif
-
-#if WTF_PLATFORM_IOS
-#define ENABLE_CONTEXT_MENUS 0
-#define ENABLE_DRAG_SUPPORT 0
-#define ENABLE_DATA_TRANSFER_ITEMS 0
-#define ENABLE_FTPDIR 1
-#define ENABLE_GEOLOCATION 1
-#define ENABLE_ICONDATABASE 0
-#define ENABLE_INSPECTOR 0
-#define ENABLE_JAVA_BRIDGE 0
-#define ENABLE_NETSCAPE_PLUGIN_API 0
-#define ENABLE_ORIENTATION_EVENTS 1
-#define ENABLE_REPAINT_THROTTLING 1
-#define HAVE_READLINE 1
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#define ENABLE_WEB_ARCHIVE 1
-#endif
-
-#if WTF_PLATFORM_ANDROID
-#define WTF_USE_PTHREADS 1
-#define USE_SYSTEM_MALLOC 1
-#define ENABLE_JAVA_BRIDGE 1
-#define LOG_DISABLED 1
-/* Prevents Webkit from drawing the caret in textfields and textareas
-   This prevents unnecessary invals. */
-#define ENABLE_TEXT_CARET 1
-#define ENABLE_JAVASCRIPT_DEBUGGER 0
-#endif
-
-#if WTF_PLATFORM_WIN && !WTF_OS_WINCE
-#define WTF_USE_CF 1
-#define WTF_USE_PTHREADS 0
-#endif
-
-#if WTF_PLATFORM_WIN && !WTF_OS_WINCE && !WTF_PLATFORM_CHROMIUM && !defined(WIN_CAIRO)
-#define WTF_USE_CFNETWORK 1
-#endif
-
-#if WTF_USE_CFNETWORK || WTF_PLATFORM_MAC
-#define WTF_USE_CFURLCACHE 1
-#define WTF_USE_CFURLSTORAGESESSIONS 1
-#endif
-
-#if WTF_PLATFORM_WIN && !WTF_OS_WINCE && !WTF_PLATFORM_CHROMIUM && !WTF_PLATFORM_QT
-#define ENABLE_WEB_ARCHIVE 1
-#endif
-
-#if WTF_PLATFORM_WX
-#define ENABLE_ASSEMBLER 1
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#if WTF_OS_DARWIN
-#define WTF_USE_CF 1
-#ifndef BUILDING_ON_TIGER
-#define WTF_USE_CORE_TEXT 1
-#define ENABLE_WEB_ARCHIVE 1
-#else
-#define WTF_USE_ATSUI 1
-#endif
-#endif
-#endif
-
-#if WTF_PLATFORM_GTK
-#if HAVE_PTHREAD_H
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#endif
-#endif
-
-#if WTF_PLATFORM_HAIKU
-#define HAVE_POSIX_MEMALIGN 1
-#define WTF_USE_CURL 1
-#define WTF_USE_PTHREADS 1
-#define HAVE_PTHREAD_RWLOCK 1
-#define USE_SYSTEM_MALLOC 1
-#define ENABLE_NETSCAPE_PLUGIN_API 0
-#endif
-
-#if WTF_PLATFORM_BREWMP
-#define USE_SYSTEM_MALLOC 1
-#endif
-
-#if WTF_PLATFORM_BREWMP_SIMULATOR
-#define ENABLE_JIT 0
-#endif
-
-#if !defined(HAVE_ACCESSIBILITY)
-#if WTF_PLATFORM_IOS || WTF_PLATFORM_MAC || WTF_PLATFORM_WIN || WTF_PLATFORM_GTK || WTF_PLATFORM_CHROMIUM
-#define HAVE_ACCESSIBILITY 1
-#endif
-#endif /* !defined(HAVE_ACCESSIBILITY) */
-
-#if WTF_OS_UNIX && !WTF_OS_SYMBIAN
-#define HAVE_SIGNAL_H 1
-#endif
-
-#if !defined(HAVE_STRNSTR)
-#if WTF_OS_DARWIN || WTF_OS_FREEBSD
-#define HAVE_STRNSTR 1
-#endif
-#endif
-
-#if !WTF_OS_WINDOWS && !WTF_OS_SOLARIS && !WTF_OS_QNX \
-    && !WTF_OS_SYMBIAN && !WTF_OS_HAIKU && !WTF_OS_RVCT \
-    && !WTF_OS_ANDROID && !WTF_PLATFORM_BREWMP
-#define HAVE_TM_GMTOFF 1
-#define HAVE_TM_ZONE 1
-#define HAVE_TIMEGM 1
-#endif
-
-#if WTF_OS_DARWIN
-
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 1
-#define HAVE_MMAP 1
-#define HAVE_MERGESORT 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_SYS_TIMEB_H 1
-#define WTF_USE_ACCELERATE 1
-
-#if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD)
-
-#define HAVE_DISPATCH_H 1
-#define HAVE_HOSTED_CORE_ANIMATION 1
-
-#if !WTF_PLATFORM_IOS
-#define HAVE_MADV_FREE_REUSE 1
-#define HAVE_MADV_FREE 1
-#define HAVE_PTHREAD_SETNAME_NP 1
-#endif
-
-#endif
-
-#if WTF_PLATFORM_IOS
-#define HAVE_MADV_FREE 1
-#endif
-
-#elif WTF_OS_WINDOWS
-
-#if WTF_OS_WINCE
-#define HAVE_ERRNO_H 0
-#else
-#define HAVE_SYS_TIMEB_H 1
-#define HAVE_ALIGNED_MALLOC 1
-#define HAVE_ISDEBUGGERPRESENT 1
-#endif
-#define HAVE_VIRTUALALLOC 1
-
-#elif WTF_OS_SYMBIAN
-
-#define HAVE_ERRNO_H 1
-#define HAVE_MMAP 0
-#define HAVE_SBRK 1
-
-#define HAVE_SYS_TIME_H 1
-#define HAVE_STRINGS_H 1
-
-#if !WTF_COMPILER_RVCT
-#define HAVE_SYS_PARAM_H 1
-#endif
-
-#elif WTF_PLATFORM_BREWMP
-
-#define HAVE_ERRNO_H 1
-
-#elif WTF_OS_QNX
-
-#define HAVE_ERRNO_H 1
-#define HAVE_MMAP 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#elif WTF_OS_ANDROID
-
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 0
-#define HAVE_MMAP 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#elif WTF_OS_OS2
-
-#define USE_SYSTEM_MALLOC 1
-#define HAVE_ERRNO_H 1
-#define HAVE_LANGINFO_H 1
-#define HAVE_MMAP 0
-#define HAVE_POSIX_MEMALIGN 1
-#define HAVE_SBRK 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_STRINGS_H 1
-
-#else
-
-/* FIXME: is this actually used or do other platforms generate their own config.h? */
-
-#define HAVE_ERRNO_H 1
-/* As long as Haiku doesn't have a complete support of locale this will be disabled. */
-#if !WTF_OS_HAIKU
-#define HAVE_LANGINFO_H 1
-#endif
-#define HAVE_MMAP 1
-#define HAVE_SBRK 1
-#define HAVE_STRINGS_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_TIME_H 1
-
-#endif
-
-/* ENABLE macro defaults */
-
-#if WTF_PLATFORM_QT
-/* We must not customize the global operator new and delete for the Qt port. */
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
-#if !WTF_OS_UNIX || WTF_OS_SYMBIAN
-#define USE_SYSTEM_MALLOC 1
-#endif
-#endif
-
-/* fastMalloc match validation allows for runtime verification that
-   new is matched by delete, fastMalloc is matched by fastFree, etc. */
-#if !defined(ENABLE_FAST_MALLOC_MATCH_VALIDATION)
-#define ENABLE_FAST_MALLOC_MATCH_VALIDATION 0
-#endif
-
-#if !defined(ENABLE_ICONDATABASE)
-#define ENABLE_ICONDATABASE 1
-#endif
-
-#if !defined(ENABLE_DATABASE)
-#define ENABLE_DATABASE 1
-#endif
-
-#if !defined(ENABLE_JAVASCRIPT_DEBUGGER)
-#define ENABLE_JAVASCRIPT_DEBUGGER 1
-#endif
-
-#if !defined(ENABLE_FTPDIR)
-#define ENABLE_FTPDIR 1
-#endif
-
-#if !defined(ENABLE_CONTEXT_MENUS)
-#define ENABLE_CONTEXT_MENUS 1
-#endif
-
-#if !defined(ENABLE_DRAG_SUPPORT)
-#define ENABLE_DRAG_SUPPORT 1
-#endif
-
-#if !defined(ENABLE_DATA_TRANSFER_ITEMS)
-#define ENABLE_DATA_TRANSFER_ITEMS 0
-#endif
-
-#if !defined(ENABLE_DASHBOARD_SUPPORT)
-#define ENABLE_DASHBOARD_SUPPORT 0
-#endif
-
-#if !defined(ENABLE_INSPECTOR)
-#define ENABLE_INSPECTOR 1
-#endif
-
-#if !defined(ENABLE_JAVA_BRIDGE)
-#define ENABLE_JAVA_BRIDGE 0
-#endif
-
-#if !defined(ENABLE_NETSCAPE_PLUGIN_API)
-#define ENABLE_NETSCAPE_PLUGIN_API 1
-#endif
-
-#if !defined(ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE)
-#define ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE 0
-#endif
-
-#if !defined(ENABLE_PURGEABLE_MEMORY)
-#define ENABLE_PURGEABLE_MEMORY 0
-#endif
-
-#if !defined(WTF_USE_PLUGIN_HOST_PROCESS)
-#define WTF_USE_PLUGIN_HOST_PROCESS 0
-#endif
-
-#if !defined(ENABLE_ORIENTATION_EVENTS)
-#define ENABLE_ORIENTATION_EVENTS 0
-#endif
-
-#if !defined(ENABLE_OPCODE_STATS)
-#define ENABLE_OPCODE_STATS 0
-#endif
-
-#if !defined(ENABLE_GLOBAL_FASTMALLOC_NEW)
-#define ENABLE_GLOBAL_FASTMALLOC_NEW 1
-#endif
-
-#define ENABLE_DEBUG_WITH_BREAKPOINT 0
-#define ENABLE_SAMPLING_COUNTERS 0
-#define ENABLE_SAMPLING_FLAGS 0
-#define ENABLE_OPCODE_SAMPLING 0
-#define ENABLE_CODEBLOCK_SAMPLING 0
-#if ENABLE_CODEBLOCK_SAMPLING && !ENABLE_OPCODE_SAMPLING
-#error "CODEBLOCK_SAMPLING requires OPCODE_SAMPLING"
-#endif
-#if ENABLE_OPCODE_SAMPLING || ENABLE_SAMPLING_FLAGS
-#define ENABLE_SAMPLING_THREAD 1
-#endif
-
-#if !defined(ENABLE_GEOLOCATION)
-#define ENABLE_GEOLOCATION 0
-#endif
-
-#if !defined(ENABLE_GESTURE_RECOGNIZER)
-#define ENABLE_GESTURE_RECOGNIZER 0
-#endif
-
-#if !defined(ENABLE_NOTIFICATIONS)
-#define ENABLE_NOTIFICATIONS 0
-#endif
-
-#if WTF_PLATFORM_IOS
-#define ENABLE_TEXT_CARET 0
-#endif
-
-#if !defined(ENABLE_TEXT_CARET)
-#define ENABLE_TEXT_CARET 1
-#endif
-
-#if !defined(ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL)
-#define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0
-#endif
-
-#if !defined(ENABLE_FULLSCREEN_API)
-#define ENABLE_FULLSCREEN_API 0
-#endif
-
-#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64)
-#if (WTF_CPU_X86_64 && (WTF_OS_UNIX || WTF_OS_WINDOWS)) \
-    || (WTF_CPU_IA64 && !WTF_CPU_IA64_32) \
-    || WTF_CPU_ALPHA \
-    || WTF_CPU_SPARC64 \
-    || WTF_CPU_S390X \
-    || WTF_CPU_PPC64
-#define WTF_USE_JSVALUE64 1
-#else
-#define WTF_USE_JSVALUE32_64 1
-#endif
-#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) */
-
-#if !defined(ENABLE_REPAINT_THROTTLING)
-#define ENABLE_REPAINT_THROTTLING 0
-#endif
-
-/* Disable the JIT on versions of GCC prior to 4.1 */
-#if !defined(ENABLE_JIT) && WTF_COMPILER_GCC && !GCC_VERSION_AT_LEAST(4, 1, 0)
-#define ENABLE_JIT 0
-#endif
-
-/* The JIT is enabled by default on all x86, x64-64, ARM platforms. */
-#if !defined(ENABLE_JIT) \
-    && (WTF_CPU_X86 || WTF_CPU_X86_64 || WTF_CPU_ARM || WTF_CPU_SPARC32 || WTF_CPU_MIPS) \
-    && (WTF_OS_DARWIN || !WTF_COMPILER_GCC || GCC_VERSION_AT_LEAST(4, 1, 0)) \
-    && !WTF_OS_WINCE
-#define ENABLE_JIT 1
-#endif
-
-/* Currently only implemented for JSVALUE64, only tested on WTF_PLATFORM_MAC */
-#if ENABLE_JIT && WTF_USE_JSVALUE64 && WTF_PLATFORM_MAC
-#define ENABLE_DFG_JIT 1
-/* Enabled with restrictions to circumvent known performance regressions. */
-#define ENABLE_DFG_JIT_RESTRICTIONS 1
-#endif
-
-/* Ensure that either the JIT or the interpreter has been enabled. */
-#if !defined(ENABLE_INTERPRETER) && !ENABLE_JIT
-#define ENABLE_INTERPRETER 1
-#endif
-#if !(ENABLE_JIT || ENABLE_INTERPRETER)
-#error You have to have at least one execution model enabled to build JSC
-#endif
-
-#if WTF_CPU_SH4 && WTF_PLATFORM_QT
-#define ENABLE_JIT 1
-#define ENABLE_YARR 1
-#define ENABLE_YARR_JIT 1
-#define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
-#define ENABLE_ASSEMBLER 1
-#endif
-
-/* Configure the JIT */
-#if ENABLE_JIT
-    #if WTF_CPU_ARM
-    #if !defined(ENABLE_JIT_USE_SOFT_MODULO) && WTF_CPU_ARM && WTF_ARM_ARCH_VERSION >= 5
-    #define ENABLE_JIT_USE_SOFT_MODULO 1
-    #endif
-    #endif
-
-    #ifndef ENABLE_JIT_OPTIMIZE_CALL
-    #define ENABLE_JIT_OPTIMIZE_CALL 1
-    #endif
-    #ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL
-    #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1
-    #endif
-    #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS
-    #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
-    #endif
-    #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
-    #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
-    #endif
-#endif
-
-#if WTF_CPU_X86 && WTF_COMPILER_MSVC
-#define JSC_HOST_CALL __fastcall
-#elif WTF_CPU_X86 && WTF_COMPILER_GCC
-#define JSC_HOST_CALL __attribute__ ((fastcall))
-#else
-#define JSC_HOST_CALL
-#endif
-
-/* Configure the interpreter */
-#if WTF_COMPILER_GCC || (RVCT_VERSION_AT_LEAST(4, 0, 0, 0) && defined(__GNUC__))
-#define HAVE_COMPUTED_GOTO 1
-#endif
-#if HAVE_COMPUTED_GOTO && ENABLE_INTERPRETER
-#define ENABLE_COMPUTED_GOTO_INTERPRETER 1
-#endif
-
-/* Regular Expression Tracing - Set to 1 to trace RegExp's in jsc.  Results dumped at exit */
-#define ENABLE_REGEXP_TRACING 0
-
-/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */
-#if WTF_PLATFORM_CHROMIUM
-#define ENABLE_YARR_JIT 0
-
-#elif ENABLE_YARR_JIT
-/* Setting this flag compares JIT results with interpreter results. */
-#define ENABLE_YARR_JIT_DEBUG 0
-#endif
-
-#if ENABLE_JIT || ENABLE_YARR_JIT
-#define ENABLE_ASSEMBLER 1
-#endif
-/* Setting this flag prevents the assembler from using RWX memory; this may improve
-   security but currectly comes at a significant performance cost. */
-#if WTF_PLATFORM_IOS
-//XXX: this doesn't currently compile in the spidermonkey build
-#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0
-#endif
-
-/* Pick which allocator to use; we only need an executable allocator if the assembler is compiled in.
-   On x86-64 we use a single fixed mmap, on other platforms we mmap on demand. */
-#if ENABLE_ASSEMBLER
-#if WTF_CPU_X86_64
-#define ENABLE_EXECUTABLE_ALLOCATOR_FIXED 1
-#else
-#define ENABLE_EXECUTABLE_ALLOCATOR_DEMAND 1
-#endif
-#endif
-
-#if !defined(ENABLE_PAN_SCROLLING) && WTF_OS_WINDOWS
-#define ENABLE_PAN_SCROLLING 1
-#endif
-
-#if !defined(ENABLE_SMOOTH_SCROLLING)
-#define ENABLE_SMOOTH_SCROLLING 0
-#endif
-
-#if !defined(ENABLE_WEB_ARCHIVE)
-#define ENABLE_WEB_ARCHIVE 0
-#endif
-
-/* Use the QXmlStreamReader implementation for XMLDocumentParser */
-/* Use the QXmlQuery implementation for XSLTProcessor */
-#if WTF_PLATFORM_QT
-#define WTF_USE_QXMLSTREAM 1
-#define WTF_USE_QXMLQUERY 1
-#endif
-
-#if WTF_PLATFORM_MAC
-/* Complex text framework */
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
-#define WTF_USE_ATSUI 0
-#define WTF_USE_CORE_TEXT 1
-#else
-#define WTF_USE_ATSUI 1
-#define WTF_USE_CORE_TEXT 0
-#endif
-#endif
-
-/* Accelerated compositing */
-#if (WTF_PLATFORM_MAC && !defined(BUILDING_ON_TIGER)) || WTF_PLATFORM_IOS || WTF_PLATFORM_QT || (WTF_PLATFORM_WIN && !WTF_OS_WINCE &&!defined(WIN_CAIRO))
-#define WTF_USE_ACCELERATED_COMPOSITING 1
-#endif
-
-#if (WTF_PLATFORM_MAC && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)) || WTF_PLATFORM_IOS
-#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1
-#endif
-
-#if WTF_PLATFORM_MAC && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
-#define WTF_USE_AVFOUNDATION 1
-#endif
-
-#if WTF_COMPILER_GCC
-#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
-#else
-#define WARN_UNUSED_RETURN
-#endif
-
-/* COMPILER(CLANG) - Clang  */
-#if defined(__clang__)
-#define WTF_COMPILER_CLANG 1
-#endif
-
-#if !ENABLE_NETSCAPE_PLUGIN_API || (ENABLE_NETSCAPE_PLUGIN_API && ((WTF_OS_UNIX && (WTF_PLATFORM_QT || WTF_PLATFORM_WX)) || WTF_PLATFORM_GTK))
-#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1
-#endif
-
-/* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */
-#define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK
-
-#define ENABLE_JSC_ZOMBIES 0
-
-/* FIXME: Eventually we should enable this for all platforms and get rid of the define. */
-#if WTF_PLATFORM_MAC || WTF_PLATFORM_WIN || WTF_PLATFORM_QT
-#define WTF_USE_PLATFORM_STRATEGIES 1
-#endif
-
-#if WTF_PLATFORM_WIN
-#define WTF_USE_CROSS_PLATFORM_CONTEXT_MENUS 1
-#endif
-
-/* Geolocation request policy. pre-emptive policy is to acquire user permission before acquiring location.
-   Client based implementations will have option to choose between pre-emptive and nonpre-emptive permission policy.
-   pre-emptive permission policy is enabled by default for all client-based implementations. */
-#if ENABLE_CLIENT_BASED_GEOLOCATION
-#define WTF_USE_PREEMPT_GEOLOCATION_PERMISSION 1
-#endif
-
-#if WTF_CPU_ARM_THUMB2
-#define ENABLE_BRANCH_COMPACTION 1
-#endif
-
-#if !defined(ENABLE_THREADING_OPENMP) && defined(_OPENMP)
-#define ENABLE_THREADING_OPENMP 1
-#endif
-
-#if !defined(ENABLE_PARALLEL_JOBS) && !ENABLE_SINGLE_THREADED && (ENABLE_THREADING_GENERIC || ENABLE_THREADING_LIBDISPATCH || ENABLE_THREADING_OPENMP)
-#define ENABLE_PARALLEL_JOBS 1
-#endif
-
-#if ENABLE_GLIB_SUPPORT
-//#include "GTypedefs.h"
-#endif
-
-/* FIXME: This define won't be needed once #27551 is fully landed. However,
-   since most ports try to support sub-project independence, adding new headers
-   to WTF causes many ports to break, and so this way we can address the build
-   breakages one port at a time. */
-#define WTF_USE_EXPORT_MACROS 0
-
-#if WTF_PLATFORM_QT || WTF_PLATFORM_GTK
-#define WTF_USE_UNIX_DOMAIN_SOCKETS 1
-#endif
-
-#endif /* assembler_wtf_Platform_h */
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -103,24 +103,24 @@ class OrderedHashTable
   public:
     explicit OrderedHashTable(AllocPolicy &ap)
         : hashTable(nullptr), data(nullptr), dataLength(0), ranges(nullptr), alloc(ap) {}
 
     bool init() {
         MOZ_ASSERT(!hashTable, "init must be called at most once");
 
         uint32_t buckets = initialBuckets();
-        Data **tableAlloc = static_cast<Data **>(alloc.malloc_(buckets * sizeof(Data *)));
+        Data **tableAlloc = alloc.template pod_malloc<Data *>(buckets);
         if (!tableAlloc)
             return false;
         for (uint32_t i = 0; i < buckets; i++)
             tableAlloc[i] = nullptr;
 
         uint32_t capacity = uint32_t(buckets * fillFactor());
-        Data *dataAlloc = static_cast<Data *>(alloc.malloc_(capacity * sizeof(Data)));
+        Data *dataAlloc = alloc.template pod_malloc<Data>(capacity);
         if (!dataAlloc) {
             alloc.free_(tableAlloc);
             return false;
         }
 
         // clear() requires that members are assigned only after all allocation
         // has succeeded, and that this->ranges is left untouched.
         hashTable = tableAlloc;
@@ -620,24 +620,24 @@ class OrderedHashTable
         // If the size of the table is not changing, rehash in place to avoid
         // allocating memory.
         if (newHashShift == hashShift) {
             rehashInPlace();
             return true;
         }
 
         size_t newHashBuckets = 1 << (HashNumberSizeBits - newHashShift);
-        Data **newHashTable = static_cast<Data **>(alloc.malloc_(newHashBuckets * sizeof(Data *)));
+        Data **newHashTable = alloc.template pod_malloc<Data *>(newHashBuckets);
         if (!newHashTable)
             return false;
         for (uint32_t i = 0; i < newHashBuckets; i++)
             newHashTable[i] = nullptr;
 
         uint32_t newCapacity = uint32_t(newHashBuckets * fillFactor());
-        Data *newData = static_cast<Data *>(alloc.malloc_(newCapacity * sizeof(Data)));
+        Data *newData = alloc.template pod_malloc<Data>(newCapacity);
         if (!newData) {
             alloc.free_(newHashTable);
             return false;
         }
 
         Data *wp = newData;
         for (Data *p = data, *end = data + dataLength; p != end; p++) {
             if (!Ops::isEmpty(Ops::getKey(p->element))) {
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -33,16 +33,17 @@
 
 #include "jscntxt.h"
 #include "jsfun.h"
 #include "jsnum.h"
 #include "jsprf.h"
 
 #include "builtin/TypedObject.h"
 #include "ctypes/Library.h"
+#include "gc/Zone.h"
 
 using namespace std;
 using mozilla::NumericLimits;
 
 using JS::AutoCheckCannotGC;
 
 namespace js {
 namespace ctypes {
@@ -6092,17 +6093,17 @@ CClosure::Create(JSContext* cx,
     }
 
     // With the exception of void, the FunctionType constructor ensures that
     // the return type has a defined size.
     JS_ASSERT(CType::IsSizeDefined(fninfo->mReturnType));
 
     // Allocate a buffer for the return value.
     size_t rvSize = CType::GetSize(fninfo->mReturnType);
-    cinfo->errResult = cx->malloc_(rvSize);
+    cinfo->errResult = result->zone()->pod_malloc<uint8_t>(rvSize);
     if (!cinfo->errResult)
       return nullptr;
 
     // Do the value conversion. This might fail, in which case we throw.
     if (!ImplicitConvert(cx, errVal, fninfo->mReturnType, cinfo->errResult,
                          false, nullptr))
       return nullptr;
   } else {
@@ -6377,17 +6378,17 @@ CData::Create(JSContext* cx,
   }
 
   char* data;
   if (!ownResult) {
     data = static_cast<char*>(source);
   } else {
     // Initialize our own buffer.
     size_t size = CType::GetSize(typeObj);
-    data = (char*)cx->malloc_(size);
+    data = dataObj->zone()->pod_malloc<char>(size);
     if (!data) {
       // Report a catchable allocation error.
       JS_ReportAllocationOverflow(cx);
       js_free(buffer);
       return nullptr;
     }
 
     if (!source)
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -511,35 +511,38 @@ template <Fallibility fb>
 class LifoAllocPolicy
 {
     LifoAlloc &alloc_;
 
   public:
     MOZ_IMPLICIT LifoAllocPolicy(LifoAlloc &alloc)
       : alloc_(alloc)
     {}
-    void *malloc_(size_t bytes) {
-        return fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes);
+    template <typename T>
+    T *pod_malloc(size_t numElems) {
+        if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
+            return nullptr;
+        size_t bytes = numElems * sizeof(T);
+        void *p = fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes);
+        return static_cast<T *>(p);
     }
     template <typename T>
     T *pod_calloc(size_t numElems) {
-        if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
-            return nullptr;
-        T *p = (T *)malloc_(numElems * sizeof(T));
+        T *p = pod_malloc<T>(numElems);
         if (fb == Fallible && !p)
             return nullptr;
         memset(p, 0, numElems * sizeof(T));
         return p;
     }
     void *realloc_(void *p, size_t oldBytes, size_t bytes) {
-        void *n = malloc_(bytes);
+        uint8_t *n = pod_malloc<uint8_t>(bytes);
         if (fb == Fallible && !n)
             return nullptr;
         memcpy(n, p, Min(oldBytes, bytes));
-        return n;
+        return static_cast<void *>(n);
     }
     void free_(void *p) {
     }
     void reportAllocOverflow() const {
     }
 };
 
 } // namespace js
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -294,17 +294,17 @@ class FullParseHandler
         if (isShorthand)
             literal->pn_xflags |= PNX_NONCONST;
         if (!propdef)
             return false;
         literal->append(propdef);
         return true;
     }
 
-    bool addAccessorPropertyDefinition(ParseNode *literal, ParseNode *name, ParseNode *fn, JSOp op)
+    bool addMethodDefinition(ParseNode *literal, ParseNode *name, ParseNode *fn, JSOp op)
     {
         JS_ASSERT(literal->isArity(PN_LIST));
         literal->pn_xflags |= PNX_NONCONST;
 
         ParseNode *propdef = newBinary(PNK_COLON, name, fn, op);
         if (!propdef)
             return false;
         literal->append(propdef);
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -1509,17 +1509,17 @@ class ObjectBox
 enum ParseReportKind
 {
     ParseError,
     ParseWarning,
     ParseExtraWarning,
     ParseStrictError
 };
 
-enum FunctionSyntaxKind { Expression, Statement, Arrow };
+enum FunctionSyntaxKind { Expression, Statement, Arrow, Method };
 
 static inline ParseNode *
 FunctionArgsList(ParseNode *fn, unsigned *numFormals)
 {
     JS_ASSERT(fn->isKind(PNK_FUNCTION));
     ParseNode *argsBody = fn->pn_body;
     JS_ASSERT(argsBody->isKind(PNK_ARGSBODY));
     *numFormals = argsBody->pn_count;
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -51,24 +51,23 @@ namespace js {
 namespace frontend {
 
 typedef Rooted<StaticBlockObject*> RootedStaticBlockObject;
 typedef Handle<StaticBlockObject*> HandleStaticBlockObject;
 typedef Rooted<NestedScopeObject*> RootedNestedScopeObject;
 typedef Handle<NestedScopeObject*> HandleNestedScopeObject;
 
 
-/*
- * Insist that the next token be of type tt, or report errno and return null.
- * NB: this macro uses cx and ts from its lexical environment.
- */
+/* Read a token. Report an error and return null() if that token isn't of type tt. */
 #define MUST_MATCH_TOKEN(tt, errno)                                                         \
     JS_BEGIN_MACRO                                                                          \
-        if (tokenStream.getToken() != tt) {                                                 \
-            report(ParseError, false, null(), errno);                                       \
+        TokenKind token = tokenStream.getToken();                                           \
+        if (token != tt) {                                                                  \
+            if (token != TOK_ERROR)                                                         \
+                report(ParseError, false, null(), errno);                                   \
             return null();                                                                  \
         }                                                                                   \
     JS_END_MACRO
 
 static const unsigned BlockIdLimit = 1 << ParseNode::NumBlockIdBits;
 
 template <typename ParseHandler>
 bool
@@ -634,149 +633,16 @@ Parser<ParseHandler>::parse(JSObject *ch
         if (foldConstants) {
             if (!FoldConstants(context, &pn, this))
                 return null();
         }
     }
     return pn;
 }
 
-/*
- * Insist on a final return before control flows out of pn.  Try to be a bit
- * smart about loops: do {...; return e2;} while(0) at the end of a function
- * that contains an early return e1 will get a strict warning.  Similarly for
- * iloops: while (true){...} is treated as though ... returns.
- */
-enum {
-    ENDS_IN_OTHER = 0,
-    ENDS_IN_RETURN = 1,
-    ENDS_IN_BREAK = 2
-};
-
-static int
-HasFinalReturn(ParseNode *pn)
-{
-    ParseNode *pn2, *pn3;
-    unsigned rv, rv2, hasDefault;
-
-    switch (pn->getKind()) {
-      case PNK_STATEMENTLIST:
-        if (!pn->pn_head)
-            return ENDS_IN_OTHER;
-        return HasFinalReturn(pn->last());
-
-      case PNK_IF:
-        if (!pn->pn_kid3)
-            return ENDS_IN_OTHER;
-        return HasFinalReturn(pn->pn_kid2) & HasFinalReturn(pn->pn_kid3);
-
-      case PNK_WHILE:
-        pn2 = pn->pn_left;
-        if (pn2->isKind(PNK_TRUE))
-            return ENDS_IN_RETURN;
-        if (pn2->isKind(PNK_NUMBER) && pn2->pn_dval)
-            return ENDS_IN_RETURN;
-        return ENDS_IN_OTHER;
-
-      case PNK_DOWHILE:
-        pn2 = pn->pn_right;
-        if (pn2->isKind(PNK_FALSE))
-            return HasFinalReturn(pn->pn_left);
-        if (pn2->isKind(PNK_TRUE))
-            return ENDS_IN_RETURN;
-        if (pn2->isKind(PNK_NUMBER)) {
-            if (pn2->pn_dval == 0)
-                return HasFinalReturn(pn->pn_left);
-            return ENDS_IN_RETURN;
-        }
-        return ENDS_IN_OTHER;
-
-      case PNK_FOR:
-        pn2 = pn->pn_left;
-        if (pn2->isArity(PN_TERNARY) && !pn2->pn_kid2)
-            return ENDS_IN_RETURN;
-        return ENDS_IN_OTHER;
-
-      case PNK_SWITCH:
-        rv = ENDS_IN_RETURN;
-        hasDefault = ENDS_IN_OTHER;
-        pn2 = pn->pn_right;
-        if (pn2->isKind(PNK_LEXICALSCOPE))
-            pn2 = pn2->expr();
-        for (pn2 = pn2->pn_head; rv && pn2; pn2 = pn2->pn_next) {
-            if (pn2->isKind(PNK_DEFAULT))
-                hasDefault = ENDS_IN_RETURN;
-            pn3 = pn2->pn_right;
-            JS_ASSERT(pn3->isKind(PNK_STATEMENTLIST));
-            if (pn3->pn_head) {
-                rv2 = HasFinalReturn(pn3->last());
-                if (rv2 == ENDS_IN_OTHER && pn2->pn_next)
-                    /* Falling through to next case or default. */;
-                else
-                    rv &= rv2;
-            }
-        }
-        /* If a final switch has no default case, we judge it harshly. */
-        rv &= hasDefault;
-        return rv;
-
-      case PNK_BREAK:
-        return ENDS_IN_BREAK;
-
-      case PNK_WITH:
-        return HasFinalReturn(pn->pn_right);
-
-      case PNK_RETURN:
-        return ENDS_IN_RETURN;
-
-      case PNK_LABEL:
-      case PNK_LEXICALSCOPE:
-        return HasFinalReturn(pn->expr());
-
-      case PNK_THROW:
-        return ENDS_IN_RETURN;
-
-      case PNK_TRY:
-        /* If we have a finally block that returns, we are done. */
-        if (pn->pn_kid3) {
-            rv = HasFinalReturn(pn->pn_kid3);
-            if (rv == ENDS_IN_RETURN)
-                return rv;
-        }
-
-        /* Else check the try block and any and all catch statements. */
-        rv = HasFinalReturn(pn->pn_kid1);
-        if (pn->pn_kid2) {
-            JS_ASSERT(pn->pn_kid2->isArity(PN_LIST));
-            for (pn2 = pn->pn_kid2->pn_head; pn2; pn2 = pn2->pn_next)
-                rv &= HasFinalReturn(pn2);
-        }
-        return rv;
-
-      case PNK_CATCH:
-        /* Check this catch block's body. */
-        return HasFinalReturn(pn->pn_kid3);
-
-      case PNK_LET:
-        /* Non-binary let statements are let declarations. */
-        if (!pn->isArity(PN_BINARY))
-            return ENDS_IN_OTHER;
-        return HasFinalReturn(pn->pn_right);
-
-      default:
-        return ENDS_IN_OTHER;
-    }
-}
-
-static int
-HasFinalReturn(SyntaxParseHandler::Node pn)
-{
-    return ENDS_IN_RETURN;
-}
-
 template <typename ParseHandler>
 bool
 Parser<ParseHandler>::reportBadReturn(Node pn, ParseReportKind kind,
                                       unsigned errnum, unsigned anonerrnum)
 {
     JSAutoByteString name;
     JSAtom *atom = pc->sc->asFunctionBox()->function()->atom();
     if (atom) {
@@ -7223,19 +7089,27 @@ Parser<ParseHandler>::objectLiteral()
         return null();
 
     RootedAtom atom(context);
     for (;;) {
         TokenKind ltok = tokenStream.getToken(TokenStream::KeywordIsName);
         if (ltok == TOK_RC)
             break;
 
+        bool isGenerator = false;
+        if (ltok == TOK_MUL) {
+            isGenerator = true;
+            ltok = tokenStream.getToken(TokenStream::KeywordIsName);
+        }
+
         JSOp op = JSOP_INITPROP;
         Node propname;
         switch (ltok) {
+          case TOK_ERROR:
+            return null();
           case TOK_NUMBER:
             atom = DoubleToAtom(context, tokenStream.currentToken().number());
             if (!atom)
                 return null();
             propname = newNumber(tokenStream.currentToken());
             break;
 
           case TOK_LB: {
@@ -7250,18 +7124,26 @@ Parser<ParseHandler>::objectLiteral()
                   return null();
               handler.setListFlag(literal, PNX_NONCONST);
               break;
           }
 
           case TOK_NAME: {
             atom = tokenStream.currentName();
             if (atom == context->names().get) {
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 op = JSOP_INITPROP_GETTER;
             } else if (atom == context->names().set) {
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 op = JSOP_INITPROP_SETTER;
             } else {
                 propname = handler.newIdentifier(atom, pos());
                 if (!propname)
                     return null();
                 break;
             }
 
@@ -7329,16 +7211,20 @@ Parser<ParseHandler>::objectLiteral()
             report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
             return null();
         }
 
         if (op == JSOP_INITPROP) {
             TokenKind tt = tokenStream.getToken();
             Node propexpr;
             if (tt == TOK_COLON) {
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 propexpr = assignExpr();
                 if (!propexpr)
                     return null();
 
                 if (foldConstants && !FoldConstants(context, &propexpr, this))
                     return null();
 
                 /*
@@ -7351,44 +7237,49 @@ Parser<ParseHandler>::objectLiteral()
 
                 if (!handler.addPropertyDefinition(literal, propname, propexpr))
                     return null();
             } else if (ltok == TOK_NAME && (tt == TOK_COMMA || tt == TOK_RC)) {
                 /*
                  * Support, e.g., |var {x, y} = o| as destructuring shorthand
                  * for |var {x: x, y: y} = o|, per proposed JS2/ES4 for JS1.8.
                  */
+                if (isGenerator) {
+                    report(ParseError, false, null(), JSMSG_BAD_PROP_ID);
+                    return null();
+                }
                 if (!abortIfSyntaxParser())
                     return null();
                 tokenStream.ungetToken();
                 if (!tokenStream.checkForKeyword(atom, nullptr))
                     return null();
                 PropertyName *name = handler.isName(propname);
                 JS_ASSERT(atom);
                 propname = newName(name);
                 if (!propname)
                     return null();
                 Node ident = identifierName();
                 if (!handler.addPropertyDefinition(literal, propname, ident, true))
                     return null();
+            } else if (tt == TOK_LP) {
+                tokenStream.ungetToken();
+                if (!methodDefinition(literal, propname, Normal, Method,
+                                      isGenerator ? StarGenerator : NotGenerator, op)) {
+                    return null();
+                }
             } else {
                 report(ParseError, false, null(), JSMSG_COLON_AFTER_ID);
                 return null();
             }
         } else {
             /* NB: Getter function in { get x(){} } is unnamed. */
-            Rooted<PropertyName*> funName(context, nullptr);
-            TokenStream::Position start(keepAtoms);
-            tokenStream.tell(&start);
-            Node accessor = functionDef(funName, start, op == JSOP_INITPROP_GETTER ? Getter : Setter,
-                                        Expression, NotGenerator);
-            if (!accessor)
+            if (!methodDefinition(literal, propname, op == JSOP_INITPROP_GETTER ? Getter : Setter,
+                                  Expression, NotGenerator, op)) {
                 return null();
-            if (!handler.addAccessorPropertyDefinition(literal, propname, accessor, op))
-                return null();
+            }
         }
 
         /*
          * Check for duplicate property names.  Duplicate data properties
          * only conflict in strict mode.  Duplicate getter or duplicate
          * setter halves always conflict.  A data property conflicts with
          * any part of an accessor property.
          */
@@ -7438,16 +7329,38 @@ Parser<ParseHandler>::objectLiteral()
         }
     }
 
     handler.setEndPosition(literal, pos().end);
     return literal;
 }
 
 template <typename ParseHandler>
+bool
+Parser<ParseHandler>::methodDefinition(Node literal, Node propname, FunctionType type,
+                                       FunctionSyntaxKind kind, GeneratorKind generatorKind,
+                                       JSOp op)
+{
+    RootedPropertyName funName(context);
+    if (kind == Method && tokenStream.isCurrentTokenType(TOK_NAME))
+        funName = tokenStream.currentName();
+    else
+        funName = nullptr;
+
+    TokenStream::Position start(keepAtoms);
+    tokenStream.tell(&start);
+    Node fn = functionDef(funName, start, type, kind, generatorKind);
+    if (!fn)
+        return false;
+    if (!handler.addMethodDefinition(literal, propname, fn, op))
+        return false;
+    return true;
+}
+
+template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::primaryExpr(TokenKind tt)
 {
     JS_ASSERT(tokenStream.isCurrentTokenType(tt));
     JS_CHECK_RECURSION(context, return null());
 
     switch (tt) {
       case TOK_FUNCTION:
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -533,16 +533,19 @@ class Parser : private JS::AutoGCRooter,
     Node condExpr1();
     Node orExpr1();
     Node unaryExpr();
     Node memberExpr(TokenKind tt, bool allowCallSyntax);
     Node primaryExpr(TokenKind tt);
     Node parenExprOrGeneratorComprehension();
     Node exprInParens();
 
+    bool methodDefinition(Node literal, Node propname, FunctionType type, FunctionSyntaxKind kind,
+                          GeneratorKind generatorKind, JSOp Op);
+
     /*
      * Additional JS parsers.
      */
     bool functionArguments(FunctionSyntaxKind kind, Node *list, Node funcpn, bool *hasRest);
 
     Node functionDef(HandlePropertyName name, const TokenStream::Position &start,
                      FunctionType type, FunctionSyntaxKind kind, GeneratorKind generatorKind);
     bool functionArgsAndBody(Node pn, HandleFunction fun,
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -129,17 +129,17 @@ class SyntaxParseHandler
     Node newArrayLiteral(uint32_t begin, unsigned blockid) { return NodeGeneric; }
     bool addElision(Node literal, const TokenPos &pos) { return true; }
     bool addSpreadElement(Node literal, uint32_t begin, Node inner) { return true; }
     bool addArrayElement(Node literal, Node element) { return true; }
 
     Node newObjectLiteral(uint32_t begin) { return NodeGeneric; }
     bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; }
     bool addPropertyDefinition(Node literal, Node name, Node expr, bool isShorthand = false) { return true; }
-    bool addAccessorPropertyDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
+    bool addMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; }
 
     // Statements
 
     Node newStatementList(unsigned blockid, const TokenPos &pos) { return NodeGeneric; }
     void addStatementToList(Node list, Node stmt, ParseContext<SyntaxParseHandler> *pc) {}
     Node newEmptyStatement(const TokenPos &pos) { return NodeGeneric; }
 
     Node newExprStatement(Node expr, uint32_t end) {
--- a/js/src/gc/ForkJoinNursery.cpp
+++ b/js/src/gc/ForkJoinNursery.cpp
@@ -134,27 +134,16 @@
 //   other, never a combination.  After gc the fromspace is always
 //   discarded.
 //
 // - If the gc copies objects into a nursery tospace then this tospace
 //   becomes known as the "newspace" following gc.  Otherwise, a new
 //   newspace won't be needed (if the parallel section is finished) or
 //   can be created empty (if the gc just needed to evacuate).
 //
-//
-// Style note:
-//
-// - Use js_memcpy, malloc_, realloc_, and js_free uniformly, do not
-//   use PodCopy or pod_malloc: the type information for the latter is
-//   not always correct and surrounding code usually operates in terms
-//   of bytes, anyhow.
-//
-//   With power comes responsibility, etc: code that used pod_malloc
-//   gets safe size computation built-in; here we must handle that
-//   manually.
 
 namespace js {
 namespace gc {
 
 ForkJoinNursery::ForkJoinNursery(ForkJoinContext *cx, ForkJoinGCShared *shared, Allocator *tenured)
   : cx_(cx)
   , tenured_(tenured)
   , shared_(shared)
@@ -558,29 +547,29 @@ ForkJoinNursery::allocateObject(size_t b
 HeapSlot *
 ForkJoinNursery::allocateSlots(JSObject *obj, uint32_t nslots)
 {
     JS_ASSERT(obj);
     JS_ASSERT(nslots > 0);
 
     if (nslots & mozilla::tl::MulOverflowMask<sizeof(HeapSlot)>::value)
         return nullptr;
-    size_t size = nslots * sizeof(HeapSlot);
 
     if (!isInsideNewspace(obj))
-        return reinterpret_cast<HeapSlot *>(cx_->malloc_(size));
+        return obj->zone()->pod_malloc<HeapSlot>(nslots);
 
     if (nslots > MaxNurserySlots)
-        return allocateHugeSlots(nslots);
+        return allocateHugeSlots(obj, nslots);
 
+    size_t size = nslots * sizeof(HeapSlot);
     HeapSlot *slots = static_cast<HeapSlot *>(allocate(size));
     if (slots)
         return slots;
 
-    return allocateHugeSlots(nslots);
+    return allocateHugeSlots(obj, nslots);
 }
 
 HeapSlot *
 ForkJoinNursery::reallocateSlots(JSObject *obj, HeapSlot *oldSlots,
                                  uint32_t oldCount, uint32_t newCount)
 {
     if (newCount & mozilla::tl::MulOverflowMask<sizeof(HeapSlot)>::value)
         return nullptr;
@@ -629,23 +618,22 @@ ForkJoinNursery::freeSlots(HeapSlot *slo
 {
     if (!isInsideNewspace(slots)) {
         hugeSlots[hugeSlotsNew].remove(slots);
         js_free(slots);
     }
 }
 
 HeapSlot *
-ForkJoinNursery::allocateHugeSlots(size_t nslots)
+ForkJoinNursery::allocateHugeSlots(JSObject *obj, size_t nslots)
 {
     if (nslots & mozilla::tl::MulOverflowMask<sizeof(HeapSlot)>::value)
         return nullptr;
 
-    size_t size = nslots * sizeof(HeapSlot);
-    HeapSlot *slots = reinterpret_cast<HeapSlot *>(cx_->malloc_(size));
+    HeapSlot *slots = obj->zone()->pod_malloc<HeapSlot>(nslots);
     if (!slots)
         return slots;
 
     // If this put fails, we will only leak the slots.
     (void)hugeSlots[hugeSlotsNew].put(slots);
     return slots;
 }
 
@@ -772,22 +760,23 @@ ForkJoinNursery::allocateInTospace(gc::A
         // either because memory is exhausted or if the allocation
         // budget is used up.  There is a guard in
         // Chunk::allocateArena() against the latter case.
         return tenured_->arenas.allocateFromArena(evacuationZone_, thingKind);
     }
     return allocateInTospaceInfallible(thingSize);
 }
 
-void *
-ForkJoinNursery::allocateInTospace(size_t nelem, size_t elemSize)
+template <typename T>
+T *
+ForkJoinNursery::allocateInTospace(size_t nelem)
 {
     if (isEvacuating_)
-        return evacuationZone_->malloc_(nelem * elemSize);
-    return allocateInTospaceInfallible(nelem * elemSize);
+        return evacuationZone_->pod_malloc<T>(nelem);
+    return static_cast<T *>(allocateInTospaceInfallible(nelem * sizeof(T)));
 }
 
 MOZ_ALWAYS_INLINE void
 ForkJoinNursery::insertIntoFixupList(RelocationOverlay *entry)
 {
     *tail_ = entry;
     tail_ = &entry->next_;
     *tail_ = nullptr;
@@ -845,17 +834,17 @@ ForkJoinNursery::copySlotsToTospace(JSOb
     if (!isInsideFromspace(src->slots)) {
         hugeSlots[hugeSlotsFrom].remove(src->slots);
         if (!isEvacuating_)
             hugeSlots[hugeSlotsNew].put(src->slots);
         return 0;
     }
 
     size_t count = src->numDynamicSlots();
-    dst->slots = reinterpret_cast<HeapSlot *>(allocateInTospace(count, sizeof(HeapSlot)));
+    dst->slots = allocateInTospace<HeapSlot>(count);
     if (!dst->slots)
         CrashAtUnhandlableOOM("Failed to allocate slots while moving object.");
     js_memcpy(dst->slots, src->slots, count * sizeof(HeapSlot));
     setSlotsForwardingPointer(src->slots, dst->slots, count);
     return count * sizeof(HeapSlot);
 }
 
 size_t
@@ -884,17 +873,17 @@ ForkJoinNursery::copyElementsToTospace(J
         dst->setFixedElements();
         dstHeader = dst->getElementsHeader();
         js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
         setElementsForwardingPointer(srcHeader, dstHeader, nslots);
         return nslots * sizeof(HeapSlot);
     }
 
     JS_ASSERT(nslots >= 2);
-    dstHeader = reinterpret_cast<ObjectElements *>(allocateInTospace(nslots, sizeof(HeapSlot)));
+    dstHeader = reinterpret_cast<ObjectElements *>(allocateInTospace<HeapSlot>(nslots));
     if (!dstHeader)
         CrashAtUnhandlableOOM("Failed to allocate elements while moving object.");
     js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
     setElementsForwardingPointer(srcHeader, dstHeader, nslots);
     dst->elements = dstHeader->elements();
     return nslots * sizeof(HeapSlot);
 }
 
--- a/js/src/gc/ForkJoinNursery.h
+++ b/js/src/gc/ForkJoinNursery.h
@@ -200,17 +200,17 @@ class ForkJoinNursery
     static const int NurseryLoadFactor = 3;
 
     // Allocate an object in the nursery's newspace.  Return nullptr
     // when allocation fails (ie the object can't fit in the current
     // chunk and the number of chunks it at its maximum).
     void *allocate(size_t size);
 
     // Allocate an external slot array and register it with this nursery.
-    HeapSlot *allocateHugeSlots(size_t nslots);
+    HeapSlot *allocateHugeSlots(JSObject *obj, size_t nslots);
 
     // Reallocate an external slot array, unregister the old array and
     // register the new array.  If the allocation fails then leave
     // everything unchanged.
     HeapSlot *reallocateHugeSlots(HeapSlot *oldSlots, uint32_t oldSize, uint32_t newSize);
 
     // Walk the list of registered slot arrays and free them all.
     void sweepHugeSlots();
@@ -235,19 +235,19 @@ class ForkJoinNursery
     void forwardFromStack(ForkJoinNurseryCollectionTracer *trc);
     void forwardFromTenured(ForkJoinNurseryCollectionTracer *trc);
     void forwardFromRematerializedFrames(ForkJoinNurseryCollectionTracer *trc);
     void collectToFixedPoint(ForkJoinNurseryCollectionTracer *trc);
     void freeFromspace();
     void computeNurserySizeAfterGC(size_t live, const char **msg);
 
     AllocKind getObjectAllocKind(JSObject *src);
+    void *allocateInTospaceInfallible(size_t thingSize);
     void *allocateInTospace(AllocKind thingKind);
-    void *allocateInTospace(size_t nelem, size_t elemSize);
-    void *allocateInTospaceInfallible(size_t thingSize);
+    template <typename T> T *allocateInTospace(size_t nelem);
     MOZ_ALWAYS_INLINE bool shouldMoveObject(void **thingp);
     void *moveObjectToTospace(JSObject *src);
     size_t copyObjectToTospace(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
     size_t copyElementsToTospace(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
     size_t copySlotsToTospace(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
     MOZ_ALWAYS_INLINE void insertIntoFixupList(RelocationOverlay *entry);
 
     void setSlotsForwardingPointer(HeapSlot *oldSlots, HeapSlot *newSlots, uint32_t nslots);
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -690,18 +690,17 @@ js::Nursery::moveElementsToTenured(JSObj
         dst->setFixedElements();
         dstHeader = dst->getElementsHeader();
         js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
         setElementsForwardingPointer(srcHeader, dstHeader, nslots);
         return nslots * sizeof(HeapSlot);
     }
 
     JS_ASSERT(nslots >= 2);
-    size_t nbytes = nslots * sizeof(HeapValue);
-    dstHeader = static_cast<ObjectElements *>(zone->malloc_(nbytes));
+    dstHeader = reinterpret_cast<ObjectElements *>(zone->pod_malloc<HeapSlot>(nslots));
     if (!dstHeader)
         CrashAtUnhandlableOOM("Failed to allocate elements while tenuring.");
     js_memcpy(dstHeader, srcHeader, nslots * sizeof(HeapSlot));
     setElementsForwardingPointer(srcHeader, dstHeader, nslots);
     dst->elements = dstHeader->elements();
     return nslots * sizeof(HeapSlot);
 }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/spread-call-near-maxarg.js
@@ -0,0 +1,73 @@
+var config = getBuildConfiguration();
+
+// FIXME: ASAN and debug builds run this too slowly for now.
+if (!config.debug && !config.asan) {
+    let longArray = [];
+    longArray.length = getMaxArgs() - 1;
+    let shortArray = [];
+    let a;
+
+    let f = function() {
+    };
+
+    // Call_Scripted
+    //   Optimized stub is used after some calls.
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            f(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // Call_Scripted (constructing)
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            new f(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // Call_Native
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            Math.max(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // Call_Native (constructing)
+    a = shortArray;
+    for (let i = 0; i < 4; i++) {
+        if (i == 3) {
+            a = longArray;
+        }
+        try {
+            new Date(...a);
+        } catch (e) {
+            assertEq(e.message, "too much recursion");
+        }
+    }
+
+    // No optimized stub for eval.
+    a = longArray;
+    try {
+        eval(...a);
+    } catch (e) {
+        assertEq(e.message, "too much recursion");
+    }
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/class/methDefn.js
@@ -0,0 +1,15 @@
+load(libdir + "asserts.js");
+
+function f(tag) { return {[tag](){return 1;}}; }
+a = [];
+for (var i = 0; i < 2000; i++)
+    a[i] = f("first");
+
+for (var i = 0; i < 2000; i++)
+    assertEq(a[i].first(), 1);
+
+for (var i = 0; i < 2000; i++)
+    a[i] = f("second");
+
+for (var i = 0; i < 2000; i++)
+    assertEq(a[i].second(), 1);
--- a/js/src/jit/BacktrackingAllocator.h
+++ b/js/src/jit/BacktrackingAllocator.h
@@ -77,17 +77,17 @@ class BacktrackingVirtualRegister : publ
         return mustCopyInput_;
     }
 
     void setCanonicalSpill(LAllocation alloc) {
         JS_ASSERT(!alloc.isUse());
         canonicalSpill_ = alloc;
     }
     const LAllocation *canonicalSpill() const {
-        return canonicalSpill_.isUse() ? nullptr : &canonicalSpill_;
+        return canonicalSpill_.isBogus() ? nullptr : &canonicalSpill_;
     }
 
     void setCanonicalSpillExclude(CodePosition pos) {
         canonicalSpillExclude_ = pos;
     }
     bool hasCanonicalSpillExclude() const {
         return canonicalSpillExclude_.bits() != 0;
     }
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -3311,18 +3311,20 @@ EffectlesslyLookupProperty(JSContext *cx
                            MutableHandleObject holder, MutableHandleShape shape,
                            bool *checkDOMProxy=nullptr,
                            DOMProxyShadowsResult *shadowsResult=nullptr,
                            bool *domProxyHasGeneration=nullptr)
 {
     shape.set(nullptr);
     holder.set(nullptr);
 
-    if (checkDOMProxy)
+    if (checkDOMProxy) {
         *checkDOMProxy = false;
+        *shadowsResult = ShadowCheckFailed;
+    }
 
     // Check for list base if asked to.
     RootedObject checkObj(cx, obj);
     if (checkDOMProxy && IsCacheableDOMProxy(obj)) {
         JS_ASSERT(domProxyHasGeneration);
         JS_ASSERT(shadowsResult);
 
         *checkDOMProxy = true;
@@ -8516,18 +8518,22 @@ ICCallStubCompiler::pushCallArguments(Ma
 
 void
 ICCallStubCompiler::guardSpreadCall(MacroAssembler &masm, Register argcReg, Label *failure)
 {
     masm.unboxObject(Address(BaselineStackReg, ICStackValueOffset), argcReg);
     masm.loadPtr(Address(argcReg, JSObject::offsetOfElements()), argcReg);
     masm.load32(Address(argcReg, ObjectElements::offsetOfLength()), argcReg);
 
-    // Ensure actual argc <= ARGS_LENGTH_MAX
-    masm.branch32(Assembler::Above, argcReg, Imm32(ARGS_LENGTH_MAX), failure);
+    // Limit actual argc to something reasonable (huge number of arguments can
+    // blow the stack limit).
+    static_assert(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH <= ARGS_LENGTH_MAX,
+                  "maximum arguments length for optimized stub should be <= ARGS_LENGTH_MAX");
+    masm.branch32(Assembler::Above, argcReg, Imm32(ICCall_Scripted::MAX_ARGS_SPREAD_LENGTH),
+                  failure);
 }
 
 void
 ICCallStubCompiler::pushSpreadCallArguments(MacroAssembler &masm, GeneralRegisterSet regs,
                                             Register argcReg)
 {
     // Push arguments
     Register startReg = regs.takeAny();
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -5601,16 +5601,21 @@ class ICCall_Fallback : public ICMonitor
             return stub;
         }
     };
 };
 
 class ICCall_Scripted : public ICMonitoredStub
 {
     friend class ICStubSpace;
+  public:
+    // The maximum number of inlineable spread call arguments. Keep this small
+    // to avoid controllable stack overflows by attackers passing large arrays
+    // to spread call. This value is shared with ICCall_Native.
+    static const uint32_t MAX_ARGS_SPREAD_LENGTH = 16;
 
   protected:
     HeapPtrScript calleeScript_;
     HeapPtrObject templateObject_;
     uint32_t pcOffset_;
 
     ICCall_Scripted(JitCode *stubCode, ICStub *firstMonitorStub,
                     HandleScript calleeScript, HandleObject templateObject,
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -368,17 +368,17 @@ BaselineScript::New(JSContext *cx, uint3
     size_t paddedBytecodeTypesMapSize = AlignBytes(bytecodeTypeMapSize, DataAlignment);
 
     size_t allocBytes = paddedBaselineScriptSize +
         paddedICEntriesSize +
         paddedPCMappingIndexEntriesSize +
         paddedPCMappingSize +
         paddedBytecodeTypesMapSize;
 
-    uint8_t *buffer = (uint8_t *)cx->malloc_(allocBytes);
+    uint8_t *buffer = cx->zone()->pod_malloc<uint8_t>(allocBytes);
     if (!buffer)
         return nullptr;
 
     BaselineScript *script = reinterpret_cast<BaselineScript *>(buffer);
     new (script) BaselineScript(prologueOffset, epilogueOffset,
                                 spsPushToggleOffset, postDebugPrologueOffset);
 
     size_t offsetCursor = paddedBaselineScriptSize;
--- a/js/src/jit/ExecutableAllocator.h
+++ b/js/src/jit/ExecutableAllocator.h
@@ -26,17 +26,16 @@
 #ifndef jit_ExecutableAllocator_h
 #define jit_ExecutableAllocator_h
 
 #include <limits>
 #include <stddef.h> // for ptrdiff_t
 
 #include "jsalloc.h"
 
-#include "assembler/wtf/Platform.h"
 #include "jit/arm/Simulator-arm.h"
 #include "jit/mips/Simulator-mips.h"
 #include "js/HashTable.h"
 #include "js/Vector.h"
 
 #ifdef JS_CPU_SPARC
 #ifdef __linux__  // bugzilla 502369
 static void sync_instruction_memory(caddr_t v, u_int len)
@@ -397,18 +396,20 @@ public:
 #elif defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
     static void cacheFlush(void *code, size_t size)
     {
         js::jit::Simulator::FlushICache(code, size);
     }
 #elif defined(JS_CODEGEN_MIPS)
     static void cacheFlush(void* code, size_t size)
     {
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+
 #if defined(__GNUC__) && (GCC_VERSION >= 40300)
-#if WTF_MIPS_ISA_REV(2) && (GCC_VERSION < 40403)
+#if (__mips_isa_rev == 2) && (GCC_VERSION < 40403)
         int lineSize;
         asm("rdhwr %0, $1" : "=r" (lineSize));
         //
         // Modify "start" and "end" to avoid GCC 4.3.0-4.4.2 bug in
         // mips_expand_synci_loop that may execute synci one more time.
         // "start" points to the first byte of the cache line.
         // "end" points to the last byte of the line before the last cache line.
         // Because size is always a multiple of 4, this is safe to set
@@ -419,18 +420,20 @@ public:
         __builtin___clear_cache(reinterpret_cast<char*>(start), reinterpret_cast<char*>(end));
 #else
         intptr_t end = reinterpret_cast<intptr_t>(code) + size;
         __builtin___clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(end));
 #endif
 #else
         _flush_cache(reinterpret_cast<char*>(code), size, BCACHE);
 #endif
+
+#undef GCC_VERSION
     }
-#elif WTF_CPU_ARM_TRADITIONAL && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
+#elif defined(JS_CODEGEN_ARM) && (defined(__linux__) || defined(ANDROID)) && defined(__GNUC__)
     static void cacheFlush(void* code, size_t size)
     {
         asm volatile (
             "push    {r7}\n"
             "mov     r0, %0\n"
             "mov     r1, %1\n"
             "mov     r7, #0xf0000\n"
             "add     r7, r7, #0x2\n"
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -895,17 +895,17 @@ IonScript::New(JSContext *cx, types::Rec
                    paddedConstantsSize +
                    paddedSafepointIndicesSize+
                    paddedOsiIndicesSize +
                    paddedCacheEntriesSize +
                    paddedRuntimeSize +
                    paddedSafepointSize +
                    paddedCallTargetSize +
                    paddedBackedgeSize;
-    uint8_t *buffer = (uint8_t *)cx->malloc_(sizeof(IonScript) + bytes);
+    uint8_t *buffer = cx->zone()->pod_malloc<uint8_t>(sizeof(IonScript) + bytes);
     if (!buffer)
         return nullptr;
 
     IonScript *script = reinterpret_cast<IonScript *>(buffer);
     new (script) IonScript();
 
     uint32_t offsetCursor = sizeof(IonScript);
 
@@ -3209,8 +3209,14 @@ AutoDebugModeInvalidation::~AutoDebugMod
             FinishInvalidation<ParallelExecution>(fop, script);
             FinishDiscardBaselineScript(fop, script);
             script->resetUseCount();
         } else if (script->hasBaselineScript()) {
             script->baselineScript()->resetActive();
         }
     }
 }
+
+bool
+jit::JitSupportsFloatingPoint()
+{
+    return js::jit::MacroAssembler::SupportsFloatingPoint();
+}
--- a/js/src/jit/Ion.h
+++ b/js/src/jit/Ion.h
@@ -198,12 +198,14 @@ void DestroyIonScripts(FreeOp *fop, JSSc
 void TraceIonScripts(JSTracer* trc, JSScript *script);
 
 void RequestInterruptForIonCode(JSRuntime *rt, JSRuntime::InterruptMode mode);
 
 bool RematerializeAllFrames(JSContext *cx, JSCompartment *comp);
 bool UpdateForDebugMode(JSContext *maybecx, JSCompartment *comp,
                         AutoDebugModeInvalidation &invalidate);
 
+bool JitSupportsFloatingPoint();
+
 } // namespace jit
 } // namespace js
 
 #endif /* jit_Ion_h */
--- a/js/src/jit/IonAllocPolicy.h
+++ b/js/src/jit/IonAllocPolicy.h
@@ -95,57 +95,52 @@ class AutoTempAllocatorRooter : private 
 class IonAllocPolicy
 {
     TempAllocator &alloc_;
 
   public:
     MOZ_IMPLICIT IonAllocPolicy(TempAllocator &alloc)
       : alloc_(alloc)
     {}
-    void *malloc_(size_t bytes) {
-        return alloc_.allocate(bytes);
+    template <typename T>
+    T *pod_malloc(size_t numElems) {
+        if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
+            return nullptr;
+        return static_cast<T *>(alloc_.allocate(numElems * sizeof(T)));
     }
     template <typename T>
     T *pod_calloc(size_t numElems) {
-        if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
-            return nullptr;
-        T *p = (T *)alloc_.allocate(numElems * sizeof(T));
+        T *p = pod_malloc<T>(numElems);
         if (p)
             memset(p, 0, numElems * sizeof(T));
         return p;
     }
     void *realloc_(void *p, size_t oldBytes, size_t bytes) {
-        void *n = malloc_(bytes);
+        void *n = static_cast<void *>(pod_malloc<uint8_t>(bytes));
         if (!n)
             return n;
         memcpy(n, p, Min(oldBytes, bytes));
         return n;
     }
     void free_(void *p) {
     }
     void reportAllocOverflow() const {
     }
 };
 
-// Deprecated. Don't use this. Will be removed after everything has been
-// converted to IonAllocPolicy.
 class OldIonAllocPolicy
 {
   public:
     OldIonAllocPolicy()
     {}
-    void *malloc_(size_t bytes) {
-        return GetIonContext()->temp->allocate(bytes);
-    }
-    void *realloc_(void *p, size_t oldBytes, size_t bytes) {
-        void *n = malloc_(bytes);
-        if (!n)
-            return n;
-        memcpy(n, p, Min(oldBytes, bytes));
-        return n;
+    template <typename T>
+    T *pod_malloc(size_t numElems) {
+        if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)
+            return nullptr;
+        return static_cast<T *>(GetIonContext()->temp->allocate(numElems * sizeof(T)));
     }
     void free_(void *p) {
     }
     void reportAllocOverflow() const {
     }
 };
 
 class AutoIonContextAlloc
--- a/js/src/jit/JitcodeMap.cpp
+++ b/js/src/jit/JitcodeMap.cpp
@@ -547,17 +547,17 @@ JitcodeIonTable::makeIonEntry(JSContext 
     }
 
     if (numScripts < uint32_t(JitcodeGlobalEntry::IonEntry::Multi)) {
         out.init(code->raw(), code->raw() + code->instructionsSize(), numScripts, scripts, this);
         return true;
     }
 
     // Create SizedScriptList
-    void *mem = cx->malloc_(SizedScriptList::AllocSizeFor(numScripts));
+    void *mem = (void *)cx->pod_malloc<uint8_t>(SizedScriptList::AllocSizeFor(numScripts));
     if (!mem)
         return false;
     SizedScriptList *scriptList = new (mem) SizedScriptList(numScripts, scripts);
     out.init(code->raw(), code->raw() + code->instructionsSize(), scriptList, this);
     return true;
 }
 
 uint32_t
--- a/js/src/jit/LIR.cpp
+++ b/js/src/jit/LIR.cpp
@@ -357,34 +357,34 @@ static const char * const TypeChars[] =
 };
 
 static void
 PrintDefinition(char *buf, size_t size, const LDefinition &def)
 {
     char *cursor = buf;
     char *end = buf + size;
 
-    if (def.virtualRegister())
-        cursor += JS_snprintf(cursor, end - cursor, "v%u", def.virtualRegister());
-
+    cursor += JS_snprintf(cursor, end - cursor, "v%u", def.virtualRegister());
     cursor += JS_snprintf(cursor, end - cursor, "<%s>", TypeChars[def.type()]);
 
     if (def.policy() == LDefinition::FIXED)
         cursor += JS_snprintf(cursor, end - cursor, ":%s", def.output()->toString());
     else if (def.policy() == LDefinition::MUST_REUSE_INPUT)
         cursor += JS_snprintf(cursor, end - cursor, ":tied(%u)", def.getReusedInput());
-    else if (def.policy() == LDefinition::PASSTHROUGH)
-        cursor += JS_snprintf(cursor, end - cursor, ":-");
 }
 
 const char *
 LDefinition::toString() const
 {
     // Not reentrant!
     static char buf[40];
+
+    if (isBogusTemp())
+        return "bogus";
+
     PrintDefinition(buf, sizeof(buf), *this);
     return buf;
 }
 
 static void
 PrintUse(char *buf, size_t size, const LUse *use)
 {
     switch (use->policy()) {
@@ -413,16 +413,19 @@ PrintUse(char *buf, size_t size, const L
 }
 
 const char *
 LAllocation::toString() const
 {
     // Not reentrant!
     static char buf[40];
 
+    if (isBogus())
+        return "bogus";
+
     switch (kind()) {
       case LAllocation::CONSTANT_VALUE:
       case LAllocation::CONSTANT_INDEX:
         return "c";
       case LAllocation::GPR:
         JS_snprintf(buf, sizeof(buf), "%s", toGeneralReg()->reg().name());
         return buf;
       case LAllocation::FPU:
--- a/js/src/jit/LIR.h
+++ b/js/src/jit/LIR.h
@@ -52,90 +52,90 @@ static const uint32_t PAYLOAD_INDEX = 1;
 #endif
 
 // Represents storage for an operand. For constants, the pointer is tagged
 // with a single bit, and the untagged pointer is a pointer to a Value.
 class LAllocation : public TempObject
 {
     uintptr_t bits_;
 
-    static const uintptr_t TAG_BIT = 1;
-    static const uintptr_t TAG_SHIFT = 0;
-    static const uintptr_t TAG_MASK = 1 << TAG_SHIFT;
+    // 3 bits gives us enough for an interesting set of Kinds and also fits
+    // within the alignment bits of pointers to Value, which are always
+    // 8-byte aligned.
     static const uintptr_t KIND_BITS = 3;
-    static const uintptr_t KIND_SHIFT = TAG_SHIFT + TAG_BIT;
+    static const uintptr_t KIND_SHIFT = 0;
     static const uintptr_t KIND_MASK = (1 << KIND_BITS) - 1;
 
   protected:
-    static const uintptr_t DATA_BITS = (sizeof(uint32_t) * 8) - KIND_BITS - TAG_BIT;
+    static const uintptr_t DATA_BITS = (sizeof(uint32_t) * 8) - KIND_BITS;
     static const uintptr_t DATA_SHIFT = KIND_SHIFT + KIND_BITS;
     static const uintptr_t DATA_MASK = (1 << DATA_BITS) - 1;
 
   public:
     enum Kind {
-        USE,            // Use of a virtual register, with physical allocation policy.
         CONSTANT_VALUE, // Constant js::Value.
         CONSTANT_INDEX, // Constant arbitrary index.
+        USE,            // Use of a virtual register, with physical allocation policy.
         GPR,            // General purpose register.
         FPU,            // Floating-point register.
         STACK_SLOT,     // Stack slot.
         ARGUMENT_SLOT   // Argument slot.
     };
 
   protected:
-    bool isTagged() const {
-        return !!(bits_ & TAG_MASK);
+    uint32_t data() const {
+        return uint32_t(bits_) >> DATA_SHIFT;
     }
-
-    int32_t data() const {
-        return int32_t(bits_) >> DATA_SHIFT;
-    }
-    void setData(int32_t data) {
-        JS_ASSERT(int32_t(data) <= int32_t(DATA_MASK));
+    void setData(uint32_t data) {
+        JS_ASSERT(data <= DATA_MASK);
         bits_ &= ~(DATA_MASK << DATA_SHIFT);
         bits_ |= (data << DATA_SHIFT);
     }
     void setKindAndData(Kind kind, uint32_t data) {
-        JS_ASSERT(int32_t(data) <= int32_t(DATA_MASK));
+        JS_ASSERT(data <= DATA_MASK);
         bits_ = (uint32_t(kind) << KIND_SHIFT) | data << DATA_SHIFT;
     }
 
     LAllocation(Kind kind, uint32_t data) {
         setKindAndData(kind, data);
     }
     explicit LAllocation(Kind kind) {
         setKindAndData(kind, 0);
     }
 
   public:
     LAllocation() : bits_(0)
-    { }
+    {
+        JS_ASSERT(isBogus());
+    }
 
     static LAllocation *New(TempAllocator &alloc) {
         return new(alloc) LAllocation();
     }
     template <typename T>
     static LAllocation *New(TempAllocator &alloc, const T &other) {
         return new(alloc) LAllocation(other);
     }
 
-    // The value pointer must be rooted in MIR and have its low bit cleared.
+    // The value pointer must be rooted in MIR and have its low bits cleared.
     explicit LAllocation(const Value *vp) {
+        JS_ASSERT(vp);
         bits_ = uintptr_t(vp);
-        JS_ASSERT(!isTagged());
-        bits_ |= TAG_MASK;
+        JS_ASSERT((bits_ & (KIND_MASK << KIND_SHIFT)) == 0);
+        bits_ |= CONSTANT_VALUE << KIND_SHIFT;
     }
     inline explicit LAllocation(AnyRegister reg);
 
     Kind kind() const {
-        if (isTagged())
-            return CONSTANT_VALUE;
         return (Kind)((bits_ >> KIND_SHIFT) & KIND_MASK);
     }
 
+    bool isBogus() const {
+        return bits_ == 0;
+    }
     bool isUse() const {
         return kind() == USE;
     }
     bool isConstant() const {
         return isConstantValue() || isConstantIndex();
     }
     bool isConstantValue() const {
         return kind() == CONSTANT_VALUE;
@@ -170,17 +170,17 @@ class LAllocation : public TempObject
     inline const LFloatReg *toFloatReg() const;
     inline const LStackSlot *toStackSlot() const;
     inline const LArgument *toArgument() const;
     inline const LConstantIndex *toConstantIndex() const;
     inline AnyRegister toRegister() const;
 
     const Value *toConstant() const {
         JS_ASSERT(isConstantValue());
-        return reinterpret_cast<const Value *>(bits_ & ~TAG_MASK);
+        return reinterpret_cast<const Value *>(bits_ & ~(KIND_MASK << KIND_SHIFT));
     }
 
     bool operator ==(const LAllocation &other) const {
         return bits_ == other.bits_;
     }
 
     bool operator !=(const LAllocation &other) const {
         return bits_ != other.bits_;
@@ -280,16 +280,17 @@ class LUse : public LAllocation
     }
 
     Policy policy() const {
         Policy policy = (Policy)((data() >> POLICY_SHIFT) & POLICY_MASK);
         return policy;
     }
     uint32_t virtualRegister() const {
         uint32_t index = (data() >> VREG_SHIFT) & VREG_MASK;
+        JS_ASSERT(index != 0);
         return index;
     }
     uint32_t registerCode() const {
         JS_ASSERT(policy() == FIXED);
         return (data() >> REG_SHIFT) & REG_MASK;
     }
     bool isFixedRegister() const {
         return policy() == FIXED;
@@ -328,21 +329,16 @@ class LFloatReg : public LAllocation
 // Arbitrary constant index.
 class LConstantIndex : public LAllocation
 {
     explicit LConstantIndex(uint32_t index)
       : LAllocation(CONSTANT_INDEX, index)
     { }
 
   public:
-    // Used as a placeholder for inputs that can be ignored.
-    static LConstantIndex Bogus() {
-        return LConstantIndex(0);
-    }
-
     static LConstantIndex FromIndex(uint32_t index) {
         return LConstantIndex(index);
     }
 
     uint32_t index() const {
         return data();
     }
 };
@@ -399,36 +395,30 @@ class LDefinition
     static const uint32_t VREG_SHIFT = POLICY_SHIFT + POLICY_BITS;
     static const uint32_t VREG_MASK = (1 << VREG_BITS) - 1;
 
   public:
     // Note that definitions, by default, are always allocated a register,
     // unless the policy specifies that an input can be re-used and that input
     // is a stack slot.
     enum Policy {
-        // A random register of an appropriate class will be assigned.
-        REGISTER,
-
         // The policy is predetermined by the LAllocation attached to this
         // definition. The allocation may be:
         //   * A register, which may not appear as any fixed temporary.
         //   * A stack slot or argument.
         //
         // Register allocation will not modify a fixed allocation.
         FIXED,
 
+        // A random register of an appropriate class will be assigned.
+        REGISTER,
+
         // One definition per instruction must re-use the first input
         // allocation, which (for now) must be a register.
-        MUST_REUSE_INPUT,
-
-        // This definition's virtual register is the same as another; this is
-        // for instructions which consume a register and silently define it as
-        // the same register. It is not legal to use this if doing so would
-        // change the type of the virtual register.
-        PASSTHROUGH
+        MUST_REUSE_INPUT
     };
 
     enum Type {
         GENERAL,    // Generic, integer or pointer-width data (GPR).
         INT32,      // int32 data (GPR).
         OBJECT,     // Pointer that may be collected as garbage (GPR).
         SLOTS,      // Slots/elements pointer that may be moved by minor GCs (GPR).
         FLOAT32,    // 32-bit floating-point value (FPU).
@@ -468,20 +458,22 @@ class LDefinition
 
     LDefinition(uint32_t index, Type type, const LAllocation &a)
       : output_(a)
     {
         set(index, type, FIXED);
     }
 
     LDefinition() : bits_(0)
-    { }
+    {
+        JS_ASSERT(isBogusTemp());
+    }
 
     static LDefinition BogusTemp() {
-        return LDefinition(GENERAL, LConstantIndex::Bogus());
+        return LDefinition();
     }
 
     Policy policy() const {
         return (Policy)((bits_ >> POLICY_SHIFT) & POLICY_MASK);
     }
     Type type() const {
         return (Type)((bits_ >> TYPE_SHIFT) & TYPE_MASK);
     }
@@ -509,29 +501,31 @@ class LDefinition
         return isFloatReg() == other.isFloatReg();
 #endif
     }
 
     bool isFloatReg() const {
         return type() == FLOAT32 || type() == DOUBLE || isSimdType();
     }
     uint32_t virtualRegister() const {
-        return (bits_ >> VREG_SHIFT) & VREG_MASK;
+        uint32_t index = (bits_ >> VREG_SHIFT) & VREG_MASK;
+        JS_ASSERT(index != 0);
+        return index;
     }
     LAllocation *output() {
         return &output_;
     }
     const LAllocation *output() const {
         return &output_;
     }
     bool isFixed() const {
         return policy() == FIXED;
     }
     bool isBogusTemp() const {
-        return isFixed() && output()->isConstantIndex();
+        return isFixed() && output()->isBogus();
     }
     void setVirtualRegister(uint32_t index) {
         JS_ASSERT(index < VREG_MASK);
         bits_ &= ~(VREG_MASK << VREG_SHIFT);
         bits_ |= index << VREG_SHIFT;
     }
     void setOutput(const LAllocation &a) {
         output_ = a;
--- a/js/src/jit/LinearScan.cpp
+++ b/js/src/jit/LinearScan.cpp
@@ -79,17 +79,17 @@ LinearScanAllocator::allocateRegisters()
     for (size_t i = 0; i < AnyRegister::Total; i++) {
         if (fixedIntervals[i]->numRanges() > 0)
             fixed.pushBack(fixedIntervals[i]);
     }
 
     // Iterate through all intervals in ascending start order.
     CodePosition prevPosition = CodePosition::MIN;
     while ((current = unhandled.dequeue()) != nullptr) {
-        JS_ASSERT(current->getAllocation()->isUse());
+        JS_ASSERT(current->getAllocation()->isBogus());
         JS_ASSERT(current->numRanges() > 0);
 
         if (mir->shouldCancel("LSRA Allocate Registers (main loop)"))
             return false;
 
         CodePosition position = current->start();
         const Requirement *req = current->requirement();
         const Requirement *hint = current->hint();
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -520,20 +520,20 @@ LiveRangeAllocator<VREG, forLSRA>::init(
     for (size_t i = 0; i < graph.numBlocks(); i++) {
         if (mir->shouldCancel("Create data structures (main loop)"))
             return false;
 
         LBlock *block = graph.getBlock(i);
         for (LInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
             for (size_t j = 0; j < ins->numDefs(); j++) {
                 LDefinition *def = ins->getDef(j);
-                if (def->policy() != LDefinition::PASSTHROUGH) {
-                    if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ false))
-                        return false;
-                }
+                if (def->isBogusTemp())
+                    continue;
+                if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ false))
+                    return false;
             }
 
             for (size_t j = 0; j < ins->numTemps(); j++) {
                 LDefinition *def = ins->getTemp(j);
                 if (def->isBogusTemp())
                     continue;
                 if (!vregs[def].init(alloc(), block, *ins, def, /* isTemp */ true))
                     return false;
@@ -660,60 +660,60 @@ LiveRangeAllocator<VREG, forLSRA>::build
                         }
                         if (!found && !addFixedRangeAtHead(*iter, outputOf(*ins), outputOf(*ins).next()))
                             return false;
                     }
                 }
             }
 
             for (size_t i = 0; i < ins->numDefs(); i++) {
-                if (ins->getDef(i)->policy() != LDefinition::PASSTHROUGH) {
-                    LDefinition *def = ins->getDef(i);
+                LDefinition *def = ins->getDef(i);
+                if (def->isBogusTemp())
+                    continue;
 
-                    CodePosition from;
-                    if (def->policy() == LDefinition::FIXED && def->output()->isRegister() && forLSRA) {
-                        // The fixed range covers the current instruction so the
-                        // interval for the virtual register starts at the next
-                        // instruction. If the next instruction has a fixed use,
-                        // this can lead to unnecessary register moves. To avoid
-                        // special handling for this, assert the next instruction
-                        // has no fixed uses. defineFixed guarantees this by inserting
-                        // an LNop.
-                        JS_ASSERT(!NextInstructionHasFixedUses(block, *ins));
-                        AnyRegister reg = def->output()->toRegister();
-                        if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins).next()))
-                            return false;
-                        from = outputOf(*ins).next();
-                    } else {
-                        from = forLSRA ? inputOf(*ins) : outputOf(*ins);
-                    }
+                CodePosition from;
+                if (def->policy() == LDefinition::FIXED && def->output()->isRegister() && forLSRA) {
+                    // The fixed range covers the current instruction so the
+                    // interval for the virtual register starts at the next
+                    // instruction. If the next instruction has a fixed use,
+                    // this can lead to unnecessary register moves. To avoid
+                    // special handling for this, assert the next instruction
+                    // has no fixed uses. defineFixed guarantees this by inserting
+                    // an LNop.
+                    JS_ASSERT(!NextInstructionHasFixedUses(block, *ins));
+                    AnyRegister reg = def->output()->toRegister();
+                    if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins).next()))
+                        return false;
+                    from = outputOf(*ins).next();
+                } else {
+                    from = forLSRA ? inputOf(*ins) : outputOf(*ins);
+                }
 
-                    if (def->policy() == LDefinition::MUST_REUSE_INPUT) {
-                        // MUST_REUSE_INPUT is implemented by allocating an output
-                        // register and moving the input to it. Register hints are
-                        // used to avoid unnecessary moves. We give the input an
-                        // LUse::ANY policy to avoid allocating a register for the
-                        // input.
-                        LUse *inputUse = ins->getOperand(def->getReusedInput())->toUse();
-                        JS_ASSERT(inputUse->policy() == LUse::REGISTER);
-                        JS_ASSERT(inputUse->usedAtStart());
-                        *inputUse = LUse(inputUse->virtualRegister(), LUse::ANY, /* usedAtStart = */ true);
-                    }
+                if (def->policy() == LDefinition::MUST_REUSE_INPUT) {
+                    // MUST_REUSE_INPUT is implemented by allocating an output
+                    // register and moving the input to it. Register hints are
+                    // used to avoid unnecessary moves. We give the input an
+                    // LUse::ANY policy to avoid allocating a register for the
+                    // input.
+                    LUse *inputUse = ins->getOperand(def->getReusedInput())->toUse();
+                    JS_ASSERT(inputUse->policy() == LUse::REGISTER);
+                    JS_ASSERT(inputUse->usedAtStart());
+                    *inputUse = LUse(inputUse->virtualRegister(), LUse::ANY, /* usedAtStart = */ true);
+                }
 
-                    LiveInterval *interval = vregs[def].getInterval(0);
-                    interval->setFrom(from);
+                LiveInterval *interval = vregs[def].getInterval(0);
+                interval->setFrom(from);
 
-                    // Ensure that if there aren't any uses, there's at least
-                    // some interval for the output to go into.
-                    if (interval->numRanges() == 0) {
-                        if (!interval->addRangeAtHead(from, from.next()))
-                            return false;
-                    }
-                    live->remove(def->virtualRegister());
+                // Ensure that if there aren't any uses, there's at least
+                // some interval for the output to go into.
+                if (interval->numRanges() == 0) {
+                    if (!interval->addRangeAtHead(from, from.next()))
+                        return false;
                 }
+                live->remove(def->virtualRegister());
             }
 
             for (size_t i = 0; i < ins->numTemps(); i++) {
                 LDefinition *temp = ins->getTemp(i);
                 if (temp->isBogusTemp())
                     continue;
 
                 if (forLSRA) {
@@ -1075,17 +1075,17 @@ LiveInterval::toString() const
             cursor += n;
         }
 
         n = JS_snprintf(cursor, end - cursor, ")");
         if (n < 0) return "???";
         cursor += n;
     }
 
-    if (alloc_.kind() != LAllocation::USE) {
+    if (!alloc_.isBogus()) {
         n = JS_snprintf(cursor, end - cursor, " has(%s)", alloc_.toString());
         if (n < 0) return "???";
         cursor += n;
     }
 
     n = JS_snprintf(cursor, end - cursor, "%s", rangesToString());
     if (n < 0) return "???";
     cursor += n;
--- a/js/src/jit/LiveRangeAllocator.h
+++ b/js/src/jit/LiveRangeAllocator.h
@@ -47,41 +47,41 @@ class Requirement
         // These have dedicated constructors.
         JS_ASSERT(kind != FIXED && kind != MUST_REUSE_INPUT);
     }
 
     explicit Requirement(LAllocation fixed)
       : kind_(FIXED),
         allocation_(fixed)
     {
-        JS_ASSERT(fixed == LAllocation() || !fixed.isUse());
+        JS_ASSERT(!fixed.isBogus() && !fixed.isUse());
     }
 
     // Only useful as a hint, encodes where the fixed requirement is used to
     // avoid allocating a fixed register too early.
     Requirement(LAllocation fixed, CodePosition at)
       : kind_(FIXED),
         allocation_(fixed),
         position_(at)
     {
-        JS_ASSERT(fixed == LAllocation() || !fixed.isUse());
+        JS_ASSERT(!fixed.isBogus() && !fixed.isUse());
     }
 
     Requirement(uint32_t vreg, CodePosition at)
       : kind_(MUST_REUSE_INPUT),
         allocation_(LUse(vreg, LUse::ANY)),
         position_(at)
     { }
 
     Kind kind() const {
         return kind_;
     }
 
     LAllocation allocation() const {
-        JS_ASSERT(!allocation_.isUse());
+        JS_ASSERT(!allocation_.isBogus() && !allocation_.isUse());
         return allocation_;
     }
 
     uint32_t virtualRegister() const {
         JS_ASSERT(allocation_.isUse());
         JS_ASSERT(kind() == MUST_REUSE_INPUT);
         return allocation_.toUse()->virtualRegister();
     }
@@ -180,18 +180,16 @@ DefinitionCompatibleWith(LInstruction *i
             return false;
         return alloc.isFloatReg() == def->isFloatReg();
       case LDefinition::FIXED:
         return alloc == *def->output();
       case LDefinition::MUST_REUSE_INPUT:
         if (!alloc.isRegister() || !ins->numOperands())
             return false;
         return alloc == *ins->getOperand(def->getReusedInput());
-      case LDefinition::PASSTHROUGH:
-        return true;
       default:
         MOZ_ASSUME_UNREACHABLE("Unknown definition policy");
     }
 }
 
 #endif // DEBUG
 
 static inline LDefinition *
@@ -485,16 +483,17 @@ class VirtualRegister
     }
     void replaceInterval(LiveInterval *old, LiveInterval *interval) {
         JS_ASSERT(intervals_[old->index()] == old);
         interval->setIndex(old->index());
         intervals_[old->index()] = interval;
     }
     bool addInterval(LiveInterval *interval) {
         JS_ASSERT(interval->numRanges());
+        JS_ASSERT(interval->vreg() != 0);
 
         // Preserve ascending order for faster lookups.
         LiveInterval **found = nullptr;
         LiveInterval **i;
         for (i = intervals_.begin(); i != intervals_.end(); i++) {
             if (!found && interval->start() < (*i)->start())
                 found = i;
             if (found)
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -2576,18 +2576,16 @@ LIRGenerator::visitInArray(MInArray *ins
     JS_ASSERT(ins->index()->type() == MIRType_Int32);
     JS_ASSERT(ins->initLength()->type() == MIRType_Int32);
     JS_ASSERT(ins->object()->type() == MIRType_Object);
     JS_ASSERT(ins->type() == MIRType_Boolean);
 
     LAllocation object;
     if (ins->needsNegativeIntCheck())
         object = useRegister(ins->object());
-    else
-        object = LConstantIndex::Bogus();
 
     LInArray *lir = new(alloc()) LInArray(useRegister(ins->elements()),
                                           useRegisterOrConstant(ins->index()),
                                           useRegister(ins->initLength()),
                                           object);
     return define(lir, ins) && assignSafepoint(lir, ins);
 }
 
--- a/js/src/jit/RegisterAllocator.cpp
+++ b/js/src/jit/RegisterAllocator.cpp
@@ -48,24 +48,28 @@ AllocationIntegrityState::record()
             }
         }
 
         for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
             LInstruction *ins = *iter;
             InstructionInfo &info = instructions[ins->id()];
 
             for (size_t k = 0; k < ins->numTemps(); k++) {
-                uint32_t vreg = ins->getTemp(k)->virtualRegister();
-                virtualRegisters[vreg] = ins->getTemp(k);
+                if (!ins->getTemp(k)->isBogusTemp()) {
+                    uint32_t vreg = ins->getTemp(k)->virtualRegister();
+                    virtualRegisters[vreg] = ins->getTemp(k);
+                }
                 if (!info.temps.append(*ins->getTemp(k)))
                     return false;
             }
             for (size_t k = 0; k < ins->numDefs(); k++) {
-                uint32_t vreg = ins->getDef(k)->virtualRegister();
-                virtualRegisters[vreg] = ins->getDef(k);
+                if (!ins->getDef(k)->isBogusTemp()) {
+                    uint32_t vreg = ins->getDef(k)->virtualRegister();
+                    virtualRegisters[vreg] = ins->getDef(k);
+                }
                 if (!info.outputs.append(*ins->getDef(k)))
                     return false;
             }
             for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
                 if (!info.inputs.append(**alloc))
                     return false;
             }
         }
@@ -90,17 +94,17 @@ AllocationIntegrityState::check(bool pop
         for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
             LInstruction *ins = *iter;
 
             for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next())
                 JS_ASSERT(!alloc->isUse());
 
             for (size_t i = 0; i < ins->numDefs(); i++) {
                 LDefinition *def = ins->getDef(i);
-                JS_ASSERT_IF(def->policy() != LDefinition::PASSTHROUGH, !def->output()->isUse());
+                JS_ASSERT(!def->output()->isUse());
 
                 LDefinition oldDef = instructions[ins->id()].outputs[i];
                 JS_ASSERT_IF(oldDef.policy() == LDefinition::MUST_REUSE_INPUT,
                              *def->output() == *ins->getOperand(oldDef.getReusedInput()));
             }
 
             for (size_t i = 0; i < ins->numTemps(); i++) {
                 LDefinition *temp = ins->getTemp(i);
@@ -127,16 +131,18 @@ AllocationIntegrityState::check(bool pop
         LBlock *block = graph.getBlock(blockIndex);
         for (LInstructionIterator iter = block->begin(); iter != block->end(); iter++) {
             LInstruction *ins = *iter;
             const InstructionInfo &info = instructions[ins->id()];
 
             LSafepoint *safepoint = ins->safepoint();
             if (safepoint) {
                 for (size_t i = 0; i < ins->numTemps(); i++) {
+                    if (ins->getTemp(i)->isBogusTemp())
+                        continue;
                     uint32_t vreg = info.temps[i].virtualRegister();
                     LAllocation *alloc = ins->getTemp(i)->output();
                     if (!checkSafepointAllocation(ins, vreg, *alloc, populateSafepoints))
                         return false;
                 }
                 JS_ASSERT_IF(ins->isCall() && !populateSafepoints,
                              safepoint->liveRegs().empty(true) &&
                              safepoint->liveRegs().empty(false));
@@ -195,17 +201,17 @@ AllocationIntegrityState::checkIntegrity
         const InstructionInfo &info = instructions[ins->id()];
 
         // Make sure the physical location being tracked is not clobbered by
         // another instruction, and that if the originating vreg definition is
         // found that it is writing to the tracked location.
 
         for (size_t i = 0; i < ins->numDefs(); i++) {
             LDefinition *def = ins->getDef(i);
-            if (def->policy() == LDefinition::PASSTHROUGH)
+            if (def->isBogusTemp())
                 continue;
             if (info.outputs[i].virtualRegister() == vreg) {
                 JS_ASSERT(*def->output() == alloc);
 
                 // Found the original definition, done scanning.
                 return true;
             } else {
                 JS_ASSERT(*def->output() != alloc);
@@ -564,17 +570,19 @@ RegisterAllocator::dumpInstructions()
                 fprintf(stderr, " [def %s]", ins->getDef(i)->toString());
 
             for (size_t i = 0; i < ins->numTemps(); i++) {
                 LDefinition *temp = ins->getTemp(i);
                 if (!temp->isBogusTemp())
                     fprintf(stderr, " [temp %s]", temp->toString());
             }
 
-            for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next())
-                fprintf(stderr, " [use %s]", alloc->toString());
+            for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
+                if (!alloc->isBogus())
+                    fprintf(stderr, " [use %s]", alloc->toString());
+            }
 
             fprintf(stderr, "\n");
         }
     }
     fprintf(stderr, "\n");
 #endif // DEBUG
 }
--- a/js/src/jit/StupidAllocator.cpp
+++ b/js/src/jit/StupidAllocator.cpp
@@ -46,18 +46,17 @@ StupidAllocator::init()
     if (!virtualRegisters.appendN((LDefinition *)nullptr, graph.numVirtualRegisters()))
         return false;
 
     for (size_t i = 0; i < graph.numBlocks(); i++) {
         LBlock *block = graph.getBlock(i);
         for (LInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
             for (size_t j = 0; j < ins->numDefs(); j++) {
                 LDefinition *def = ins->getDef(j);
-                if (def->policy() != LDefinition::PASSTHROUGH)
-                    virtualRegisters[def->virtualRegister()] = def;
+                virtualRegisters[def->virtualRegister()] = def;
             }
 
             for (size_t j = 0; j < ins->numTemps(); j++) {
                 LDefinition *def = ins->getTemp(j);
                 if (def->isBogusTemp())
                     continue;
                 virtualRegisters[def->virtualRegister()] = def;
             }
@@ -365,18 +364,17 @@ StupidAllocator::allocateForInstruction(
     // Find registers to hold all temporaries and outputs of the instruction.
     for (size_t i = 0; i < ins->numTemps(); i++) {
         LDefinition *def = ins->getTemp(i);
         if (!def->isBogusTemp())
             allocateForDefinition(ins, def);
     }
     for (size_t i = 0; i < ins->numDefs(); i++) {
         LDefinition *def = ins->getDef(i);
-        if (def->policy() != LDefinition::PASSTHROUGH)
-            allocateForDefinition(ins, def);
+        allocateForDefinition(ins, def);
     }
 
     // Allocate for remaining inputs which do not need to be in registers.
     for (LInstruction::InputIterator alloc(*ins); alloc.more(); alloc.next()) {
         if (!alloc->isUse())
             continue;
         LUse *use = alloc->toUse();
         uint32_t vreg = use->virtualRegister();
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1533,16 +1533,20 @@ class Assembler : public AssemblerShared
     void call(void *target);
 
     void as_bkpt();
 
   public:
     static void TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
     static void TraceDataRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
 
+    static bool SupportsFloatingPoint() {
+        return HasVFP();
+    }
+
   protected:
     void addPendingJump(BufferOffset src, ImmPtr target, Relocation::Kind kind) {
         enoughMemory_ &= jumps_.append(RelativePatch(target.value, kind));
         if (kind == Relocation::JITCODE)
             writeRelocation(src);
     }
 
   public:
--- a/js/src/jit/arm/Lowering-arm.cpp
+++ b/js/src/jit/arm/Lowering-arm.cpp
@@ -102,25 +102,24 @@ LIRGeneratorARM::visitBox(MBox *box)
     LBox *lir = new(alloc()) LBox(use(inner), inner->type());
 
     // Otherwise, we should not define a new register for the payload portion
     // of the output, so bypass defineBox().
     uint32_t vreg = getVirtualRegister();
     if (vreg >= MAX_VIRTUAL_REGISTERS)
         return false;
 
-    // Note that because we're using PASSTHROUGH, we do not change the type of
+    // Note that because we're using BogusTemp(), we do not change the type of
     // the definition. We also do not define the first output as "TYPE",
     // because it has no corresponding payload at (vreg + 1). Also note that
     // although we copy the input's original type for the payload half of the
-    // definition, this is only for clarity. PASSTHROUGH definitions are
+    // definition, this is only for clarity. BogusTemp() definitions are
     // ignored.
     lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
-    lir->setDef(1, LDefinition(inner->virtualRegister(), LDefinition::TypeFrom(inner->type()),
-                               LDefinition::PASSTHROUGH));
+    lir->setDef(1, LDefinition::BogusTemp());
     box->setVirtualRegister(vreg);
     return add(lir);
 }
 
 bool
 LIRGeneratorARM::visitUnbox(MUnbox *unbox)
 {
     // An unbox on arm reads in a type tag (either in memory or a register) and
@@ -143,22 +142,21 @@ LIRGeneratorARM::visitUnbox(MUnbox *unbo
     // Swap the order we use the box pieces so we can re-use the payload register.
     LUnbox *lir = new(alloc()) LUnbox;
     lir->setOperand(0, usePayloadInRegisterAtStart(inner));
     lir->setOperand(1, useType(inner, LUse::REGISTER));
 
     if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind()))
         return false;
 
-    // Note that PASSTHROUGH here is illegal, since types and payloads form two
-    // separate intervals. If the type becomes dead before the payload, it
-    // could be used as a Value without the type being recoverable. Unbox's
-    // purpose is to eagerly kill the definition of a type tag, so keeping both
-    // alive (for the purpose of gcmaps) is unappealing. Instead, we create a
-    // new virtual register.
+    // Types and payloads form two separate intervals. If the type becomes dead
+    // before the payload, it could be used as a Value without the type being
+    // recoverable. Unbox's purpose is to eagerly kill the definition of a type
+    // tag, so keeping both alive (for the purpose of gcmaps) is unappealing.
+    // Instead, we create a new virtual register.
     return defineReuseInput(lir, unbox, 0);
 }
 
 bool
 LIRGeneratorARM::visitReturn(MReturn *ret)
 {
     MDefinition *opd = ret->getOperand(0);
     JS_ASSERT(opd->type() == MIRType_Value);
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jscompartment.h"
 
-#include "assembler/assembler/MacroAssembler.h"
 #include "jit/arm/BaselineHelpers-arm.h"
 #include "jit/Bailouts.h"
 #include "jit/IonFrames.h"
 #include "jit/IonLinker.h"
 #include "jit/IonSpewer.h"
 #include "jit/JitCompartment.h"
 #ifdef JS_ION_PERF
 # include "jit/PerfSpewer.h"
--- a/js/src/jit/mips/Assembler-mips.h
+++ b/js/src/jit/mips/Assembler-mips.h
@@ -991,16 +991,24 @@ class Assembler : public AssemblerShared
     void call(void *target);
 
     void as_break(uint32_t code);
 
   public:
     static void TraceJumpRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
     static void TraceDataRelocations(JSTracer *trc, JitCode *code, CompactBufferReader &reader);
 
+    static bool SupportsFloatingPoint() {
+#if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_MIPS_SIMULATOR)
+        return true;
+#else
+        return false;
+#endif
+    }
+
   protected:
     InstImm invertBranch(InstImm branch, BOffImm16 skipOffset);
     void bind(InstImm *inst, uint32_t branch, uint32_t target);
     void addPendingJump(BufferOffset src, ImmPtr target, Relocation::Kind kind) {
         enoughMemory_ &= jumps_.append(RelativePatch(src, target.value, kind));
         if (kind == Relocation::JITCODE)
             writeRelocation(src);
     }
--- a/js/src/jit/mips/Lowering-mips.cpp
+++ b/js/src/jit/mips/Lowering-mips.cpp
@@ -104,25 +104,24 @@ LIRGeneratorMIPS::visitBox(MBox *box)
     LBox *lir = new(alloc()) LBox(use(inner), inner->type());
 
     // Otherwise, we should not define a new register for the payload portion
     // of the output, so bypass defineBox().
     uint32_t vreg = getVirtualRegister();
     if (vreg >= MAX_VIRTUAL_REGISTERS)
         return false;
 
-    // Note that because we're using PASSTHROUGH, we do not change the type of
+    // Note that because we're using BogusTemp(), we do not change the type of
     // the definition. We also do not define the first output as "TYPE",
     // because it has no corresponding payload at (vreg + 1). Also note that
     // although we copy the input's original type for the payload half of the
-    // definition, this is only for clarity. PASSTHROUGH definitions are
+    // definition, this is only for clarity. BogusTemp() definitions are
     // ignored.
     lir->setDef(0, LDefinition(vreg, LDefinition::GENERAL));
-    lir->setDef(1, LDefinition(inner->virtualRegister(), LDefinition::TypeFrom(inner->type()),
-                               LDefinition::PASSTHROUGH));
+    lir->setDef(1, LDefinition::BogusTemp());
     box->setVirtualRegister(vreg);
     return add(lir);
 }
 
 bool
 LIRGeneratorMIPS::visitUnbox(MUnbox *unbox)
 {
     // An unbox on mips reads in a type tag (either in memory or a register) and
@@ -146,22 +145,21 @@ LIRGeneratorMIPS::visitUnbox(MUnbox *unb
     // register.
     LUnbox *lir = new(alloc()) LUnbox;
     lir->setOperand(0, usePayloadInRegisterAtStart(inner));
     lir->setOperand(1, useType(inner, LUse::REGISTER));
 
     if (unbox->fallible() && !assignSnapshot(lir, unbox->bailoutKind()))
         return false;
 
-    // Note that PASSTHROUGH here is illegal, since types and payloads form two
-    // separate intervals. If the type becomes dead before the payload, it
-    // could be used as a Value without the type being recoverable. Unbox's
-    // purpose is to eagerly kill the definition of a type tag, so keeping both
-    // alive (for the purpose of gcmaps) is unappealing. Instead, we create a
-    // new virtual register.
+    // Types and payloads form two separate intervals. If the type becomes dead
+    // before the payload, it could be used as a Value without the type being
+    // recoverable. Unbox's purpose is to eagerly kill the definition of a type
+    // tag, so keeping both alive (for the purpose of gcmaps) is unappealing.
+    // Instead, we create a new virtual register.
     return defineReuseInput(lir, unbox, 0);
 }
 
 bool
 LIRGeneratorMIPS::visitReturn(MReturn *ret)
 {
     MDefinition *opd = ret->getOperand(0);
     MOZ_ASSERT(opd->type() == MIRType_Value);
--- a/js/src/jit/none/Architecture-none.h
+++ b/js/src/jit/none/Architecture-none.h
@@ -2,17 +2,19 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 jit_none_Architecture_none_h
 #define jit_none_Architecture_none_h
 
-#include "assembler/assembler/MacroAssembler.h"
+// IonSpewer.h is included through MacroAssembler implementations for other
+// platforms, so include it here to avoid inadvertent build bustage.
+#include "jit/IonSpewer.h"
 
 namespace js {
 namespace jit {
 
 static const bool SupportsSimd = false;
 static const uint32_t SimdStackAlignment = 0;
 
 class Registers
deleted file mode 100644
--- a/js/src/jit/none/BaseMacroAssembler-none.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 jit_none_BaseMacroAssembler_none_h
-#define jit_none_BaseMacroAssembler_none_h
-
-// Shim to act like a JSC MacroAssembler for platforms where no MacroAssembler exists.
-
-// IonSpewer.h is included through MacroAssembler implementations for other
-// platforms, so include it here to avoid inadvertent build bustage.
-#include "jit/IonSpewer.h"
-
-namespace JSC {
-
-class MacroAssemblerNone
-{
-  public:
-    static bool supportsFloatingPoint() { return false; }
-};
-
-} // namespace JSC
-
-#endif /* jit_none_BaseMacroAssembler_none_h */
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -147,16 +147,18 @@ class MacroAssemblerNone : public Assemb
 
     size_t numCodeLabels() const { MOZ_CRASH(); }
     CodeLabel codeLabel(size_t) { MOZ_CRASH(); }
 
     void trace(JSTracer *) { MOZ_CRASH(); }
     static void TraceJumpRelocations(JSTracer *, JitCode *, CompactBufferReader &) { MOZ_CRASH(); }
     static void TraceDataRelocations(JSTracer *, JitCode *, CompactBufferReader &) { MOZ_CRASH(); }
 
+    static bool SupportsFloatingPoint() { return false; }
+
     void executableCopy(void *) { MOZ_CRASH(); }
     void copyJumpRelocationTable(uint8_t *) { MOZ_CRASH(); }
     void copyDataRelocationTable(uint8_t *) { MOZ_CRASH(); }
     void copyPreBarrierTable(uint8_t *) { MOZ_CRASH(); }
     void processCodeLabels(uint8_t *) { MOZ_CRASH(); }
 
     void flushBuffer() { MOZ_CRASH(); }
 
--- a/js/src/jit/shared/Assembler-x86-shared.h
+++ b/js/src/jit/shared/Assembler-x86-shared.h
@@ -4,16 +4,17 @@
  * 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 jit_shared_Assembler_x86_shared_h
 #define jit_shared_Assembler_x86_shared_h
 
 #include <cstddef>
 
+#include "assembler/assembler/MacroAssemblerX86Common.h"
 #include "assembler/assembler/X86Assembler.h"
 #include "jit/shared/Assembler-shared.h"
 
 namespace js {
 namespace jit {
 
 class Operand
 {
@@ -866,24 +867,24 @@ class AssemblerX86Shared : public Assemb
     }
 
     void breakpoint() {
         masm.int3();
     }
 
 #ifdef DEBUG
     static bool HasSSE2() {
-        return JSC::MacroAssembler::isSSE2Present();
+        return JSC::MacroAssemblerX86Common::isSSE2Present();
     }
 #endif
     static bool HasSSE3() {
-        return JSC::MacroAssembler::isSSE3Present();
+        return JSC::MacroAssemblerX86Common::isSSE3Present();
     }
     static bool HasSSE41() {
-        return JSC::MacroAssembler::isSSE41Present();
+        return JSC::MacroAssemblerX86Common::isSSE41Present();
     }
 
     // The below cmpl methods switch the lhs and rhs when it invokes the