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 id27326
push userryanvm@gmail.com
push dateSat, 16 Aug 2014 21:43:28 +0000
treeherdermozilla-central@94ba78a42305 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone34.0a1
first release with
nightly linux32
94ba78a42305 / 34.0a1 / 20140817030204 / files
nightly linux64
94ba78a42305 / 34.0a1 / 20140817030204 / files
nightly mac
94ba78a42305 / 34.0a1 / 20140817030204 / files
nightly win32
94ba78a42305 / 34.0a1 / 20140817030204 / files
nightly win64
94ba78a42305 / 34.0a1 / 20140817030204 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
-{
<