Merge inbound to m-c.
authorMs2ger <ms2ger@gmail.com>
Sun, 20 Oct 2013 10:40:40 +0200
changeset 165278 0d316980f21f45f47daae605bf632348ad521136
parent 165240 182b8450e32fbfa4b238aef6ca01939e86a10904 (current diff)
parent 165277 dbf01bda0a79667646ee07be6c66bceacdff765b (diff)
child 165282 89914159a708b1aa7992100cfe1618c9477105c4
child 165284 50ad84fae4019eeebc209ba6cd43cc3e6e01f034
child 170461 33b905cce599961f7b599d5a1ef069c0c2afdb9e
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
0d316980f21f / 27.0a1 / 20131020030202 / files
nightly linux64
0d316980f21f / 27.0a1 / 20131020030202 / files
nightly mac
0d316980f21f / 27.0a1 / 20131020030202 / files
nightly win32
0d316980f21f / 27.0a1 / 20131020030202 / files
nightly win64
0d316980f21f / 27.0a1 / 20131020030202 / 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.
gfx/layers/opengl/CompositorOGL.cpp
gfx/src/nsFont.cpp
gfx/src/nsRect.cpp
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 895047 - Clobber needed for touching js/src/js-confdefs.h.in
+Bug 924992 - WebIDL headers changes not correctly picked up by the build system somehow
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -877,33 +877,33 @@ refRelationSetCB(AtkObject *aAtkObj)
   AtkRelationSet* relation_set =
     ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj);
 
   AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
   if (!accWrap)
     return relation_set;
 
   // Keep in sync with AtkRelationType enum.
-  static const uint32_t relationTypes[] = {
-    nsIAccessibleRelation::RELATION_CONTROLLED_BY,
-    nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
-    nsIAccessibleRelation::RELATION_LABEL_FOR,
-    nsIAccessibleRelation::RELATION_LABELLED_BY,
-    nsIAccessibleRelation::RELATION_MEMBER_OF,
-    nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
-    nsIAccessibleRelation::RELATION_FLOWS_TO,
-    nsIAccessibleRelation::RELATION_FLOWS_FROM,
-    nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
-    nsIAccessibleRelation::RELATION_EMBEDS,
-    nsIAccessibleRelation::RELATION_EMBEDDED_BY,
-    nsIAccessibleRelation::RELATION_POPUP_FOR,
-    nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF,
-    nsIAccessibleRelation::RELATION_DESCRIBED_BY,
-    nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
-    nsIAccessibleRelation::RELATION_NODE_PARENT_OF
+  static const RelationType relationTypes[] = {
+    RelationType::CONTROLLED_BY,
+    RelationType::CONTROLLER_FOR,
+    RelationType::LABEL_FOR,
+    RelationType::LABELLED_BY,
+    RelationType::MEMBER_OF,
+    RelationType::NODE_CHILD_OF,
+    RelationType::FLOWS_TO,
+    RelationType::FLOWS_FROM,
+    RelationType::SUBWINDOW_OF,
+    RelationType::EMBEDS,
+    RelationType::EMBEDDED_BY,
+    RelationType::POPUP_FOR,
+    RelationType::PARENT_WINDOW_OF,
+    RelationType::DESCRIBED_BY,
+    RelationType::DESCRIPTION_FOR,
+    RelationType::NODE_PARENT_OF
   };
 
   for (uint32_t i = 0; i < ArrayLength(relationTypes); i++) {
     // Shift to 1 to skip ATK_RELATION_NULL.
     AtkRelationType atkType = static_cast<AtkRelationType>(i + 1);
     AtkRelation* atkRelation =
       atk_relation_set_get_relation_by_type(relation_set, atkType);
     if (atkRelation)
--- a/accessible/src/base/Relation.h
+++ b/accessible/src/base/Relation.h
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 RELATION_H_
-#define RELATION_H_
+#ifndef mozilla_a11y_relation_h_
+#define mozilla_a11y_relation_h_
 
 #include "AccIterator.h"
 
 namespace mozilla {
 namespace a11y {
 
 /**
  * This class is used to return Relation objects from functions.  A copy
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/RelationType.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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 mozilla_a11y_relationtype_h_
+#define mozilla_a11y_relationtype_h_
+
+#include "mozilla/TypedEnum.h"
+
+namespace mozilla {
+namespace a11y {
+
+MOZ_BEGIN_ENUM_CLASS(RelationType)
+
+  /**
+   * This object is labelled by a target object.
+   */
+  LABELLED_BY = 0x00,
+
+  /**
+   * This object is label for a target object.
+   */
+  LABEL_FOR = 0x01,
+
+  /**
+   * This object is described by the target object.
+   */
+  DESCRIBED_BY = 0x02,
+
+  /**
+   * This object is describes the target object.
+   */
+  DESCRIPTION_FOR = 0x3,
+
+  /**
+   * This object is a child of a target object.
+   */
+  NODE_CHILD_OF = 0x4,
+
+  /**
+   * This object is a parent of a target object. A dual relation to
+   * NODE_CHILD_OF.
+   */
+  NODE_PARENT_OF = 0x5,
+
+  /**
+   * Some attribute of this object is affected by a target object.
+   */
+  CONTROLLED_BY = 0x06,
+
+  /**
+   * This object is interactive and controls some attribute of a target object.
+   */
+  CONTROLLER_FOR = 0x07,
+
+  /**
+   * Content flows from this object to a target object, i.e. has content that
+   * flows logically to another object in a sequential way, e.g. text flow.
+   */
+  FLOWS_TO = 0x08,
+
+  /**
+   * Content flows to this object from a target object, i.e. has content that
+   * flows logically from another object in a sequential way, e.g. text flow.
+   */
+  FLOWS_FROM = 0x09,
+
+  /**
+   * This object is a member of a group of one or more objects. When there is
+   * more than one object in the group each member may have one and the same
+   * target, e.g. a grouping object.  It is also possible that each member has
+   * multiple additional targets, e.g. one for every other member in the group.
+   */
+  MEMBER_OF = 0x0a,
+
+  /**
+   * This object is a sub window of a target object.
+   */
+  SUBWINDOW_OF = 0x0b,
+
+  /**
+   * This object embeds a target object. This relation can be used on the
+   * OBJID_CLIENT accessible for a top level window to show where the content
+   * areas are.
+   */
+  EMBEDS = 0x0c,
+
+  /**
+   * This object is embedded by a target object.
+   */
+  EMBEDDED_BY = 0x0d,
+
+  /**
+   * This object is a transient component related to the target object. When
+   * this object is activated the target object doesn't lose focus.
+   */
+  POPUP_FOR = 0x0e,
+
+  /**
+   * This object is a parent window of the target object.
+   */
+  PARENT_WINDOW_OF = 0x0f,
+
+  /**
+   * Part of a form/dialog with a related default button. It is used for
+   * MSAA/XPCOM, it isn't for IA2 or ATK.
+   */
+  DEFAULT_BUTTON = 0x10,
+
+  LAST = DEFAULT_BUTTON
+
+MOZ_END_ENUM_CLASS(RelationType)
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -14,16 +14,17 @@ EXPORTS += [
     'nsAccessibilityService.h',
 ]
 
 EXPORTS.mozilla.a11y += [
     'AccTypes.h',
     'DocManager.h',
     'FocusManager.h',
     'Platform.h',
+    'RelationType.h',
     'Role.h',
     'SelectionManager.h',
     'States.h',
 ]
 
 if CONFIG['MOZ_DEBUG']:
     EXPORTS.mozilla.a11y += [
         'Logging.h',
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -1514,17 +1514,17 @@ Accessible::State()
                              nsGkAtoms::_false, eCaseMatters)) {
     // Special case for tabs: focused tab or focus inside related tab panel
     // implies selected state.
     if (mRoleMapEntry->role == roles::PAGETAB) {
       if (state & states::FOCUSED) {
         state |= states::SELECTED;
       } else {
         // If focus is in a child of the tab panel surely the tab is selected!
-        Relation rel = RelationByType(nsIAccessibleRelation::RELATION_LABEL_FOR);
+        Relation rel = RelationByType(RelationType::LABEL_FOR);
         Accessible* relTarget = nullptr;
         while ((relTarget = rel.Next())) {
           if (relTarget->Role() == roles::PROPERTYPAGE &&
               FocusMgr()->IsFocusWithin(relTarget))
             state |= states::SELECTED;
         }
       }
     } else if (state & states::FOCUSED) {
@@ -1809,17 +1809,17 @@ Accessible::ARIATransformRole(role aRole
     }
 
   } else if (aRole == roles::LISTBOX) {
     // A listbox inside of a combobox needs a special role because of ATK
     // mapping to menu.
     if (mParent && mParent->Role() == roles::COMBOBOX) {
       return roles::COMBOBOX_LIST;
 
-      Relation rel = RelationByType(nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
+      Relation rel = RelationByType(RelationType::NODE_CHILD_OF);
       Accessible* targetAcc = nullptr;
       while ((targetAcc = rel.Next()))
         if (targetAcc->Role() == roles::COMBOBOX)
           return roles::COMBOBOX_LIST;
     }
 
   } else if (aRole == roles::OPTION) {
     if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
@@ -1979,84 +1979,86 @@ Accessible::GetAtomicRegion() const
   while (loopContent && !loopContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_atomic, atomic))
     loopContent = loopContent->GetParent();
 
   return atomic.EqualsLiteral("true") ? loopContent : nullptr;
 }
 
 // nsIAccessible getRelationByType()
 NS_IMETHODIMP
-Accessible::GetRelationByType(uint32_t aType,
-                                nsIAccessibleRelation** aRelation)
+Accessible::GetRelationByType(uint32_t aType, nsIAccessibleRelation** aRelation)
 {
   NS_ENSURE_ARG_POINTER(aRelation);
   *aRelation = nullptr;
+
+  NS_ENSURE_ARG(aType <= static_cast<uint32_t>(RelationType::LAST));
+
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  Relation rel = RelationByType(aType);
+  Relation rel = RelationByType(static_cast<RelationType>(aType));
   NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &rel));
   return *aRelation ? NS_OK : NS_ERROR_FAILURE;
 }
 
 Relation
-Accessible::RelationByType(uint32_t aType)
+Accessible::RelationByType(RelationType aType)
 {
   if (!HasOwnContent())
     return Relation();
 
   // Relationships are defined on the same content node that the role would be
   // defined on.
   switch (aType) {
-    case nsIAccessibleRelation::RELATION_LABELLED_BY: {
+    case RelationType::LABELLED_BY: {
       Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_labelledby));
       if (mContent->IsHTML()) {
         rel.AppendIter(new HTMLLabelIterator(Document(), this));
       } else if (mContent->IsXUL()) {
         rel.AppendIter(new XULLabelIterator(Document(), mContent));
       }
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_LABEL_FOR: {
+    case RelationType::LABEL_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_labelledby));
       if (mContent->Tag() == nsGkAtoms::label && mContent->IsXUL())
         rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::control));
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_DESCRIBED_BY: {
+    case RelationType::DESCRIBED_BY: {
       Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_describedby));
       if (mContent->IsXUL())
         rel.AppendIter(new XULDescriptionIterator(Document(), mContent));
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR: {
+    case RelationType::DESCRIPTION_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_describedby));
 
       // This affectively adds an optional control attribute to xul:description,
       // which only affects accessibility, by allowing the description to be
       // tied to a control.
       if (mContent->Tag() == nsGkAtoms::description &&
           mContent->IsXUL())
         rel.AppendIter(new IDRefsIterator(mDoc, mContent,
                                           nsGkAtoms::control));
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
+    case RelationType::NODE_CHILD_OF: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_owns));
 
       // This is an ARIA tree or treegrid that doesn't use owns, so we need to
       // get the parent the hard way.
       if (mRoleMapEntry && (mRoleMapEntry->role == roles::OUTLINEITEM ||
                             mRoleMapEntry->role == roles::LISTITEM ||
                             mRoleMapEntry->role == roles::ROW)) {
@@ -2077,17 +2079,17 @@ Accessible::RelationByType(uint32_t aTyp
           if (scrollFrame || view->GetWidget() || !frame->GetParent())
             rel.AppendTarget(Parent());
         }
       }
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_NODE_PARENT_OF: {
+    case RelationType::NODE_PARENT_OF: {
       Relation rel(new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_owns));
 
       // ARIA tree or treegrid can do the hierarchy by @aria-level, ARIA trees
       // also can be organized by groups.
       if (mRoleMapEntry &&
           (mRoleMapEntry->role == roles::OUTLINEITEM ||
            mRoleMapEntry->role == roles::LISTITEM ||
            mRoleMapEntry->role == roles::ROW ||
@@ -2095,46 +2097,46 @@ Accessible::RelationByType(uint32_t aTyp
            mRoleMapEntry->role == roles::LIST ||
            mRoleMapEntry->role == roles::TREE_TABLE)) {
         rel.AppendIter(new ItemIterator(this));
       }
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
+    case RelationType::CONTROLLED_BY:
       return Relation(new RelatedAccIterator(Document(), mContent,
                                              nsGkAtoms::aria_controls));
 
-    case nsIAccessibleRelation::RELATION_CONTROLLER_FOR: {
+    case RelationType::CONTROLLER_FOR: {
       Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_controls));
       rel.AppendIter(new HTMLOutputIterator(Document(), mContent));
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_FLOWS_TO:
+    case RelationType::FLOWS_TO:
       return Relation(new IDRefsIterator(mDoc, mContent,
                                          nsGkAtoms::aria_flowto));
 
-    case nsIAccessibleRelation::RELATION_FLOWS_FROM:
+    case RelationType::FLOWS_FROM:
       return Relation(new RelatedAccIterator(Document(), mContent,
                                              nsGkAtoms::aria_flowto));
 
-    case nsIAccessibleRelation::RELATION_MEMBER_OF:
+    case RelationType::MEMBER_OF:
           return Relation(mDoc, GetAtomicRegion());
 
-    case nsIAccessibleRelation::RELATION_SUBWINDOW_OF:
-    case nsIAccessibleRelation::RELATION_EMBEDS:
-    case nsIAccessibleRelation::RELATION_EMBEDDED_BY:
-    case nsIAccessibleRelation::RELATION_POPUP_FOR:
-    case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
+    case RelationType::SUBWINDOW_OF:
+    case RelationType::EMBEDS:
+    case RelationType::EMBEDDED_BY:
+    case RelationType::POPUP_FOR:
+    case RelationType::PARENT_WINDOW_OF:
       return Relation();
 
-    case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON: {
+    case RelationType::DEFAULT_BUTTON: {
       if (mContent->IsHTML()) {
         // HTML form controls implements nsIFormControl interface.
         nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
         if (control) {
           nsCOMPtr<nsIForm> form(do_QueryInterface(control->GetFormElement()));
           if (form) {
             nsCOMPtr<nsIContent> formContent =
               do_QueryInterface(form->GetDefaultSubmitElement());
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _Accessible_H_
 #define _Accessible_H_
 
 #include "mozilla/a11y/AccTypes.h"
+#include "mozilla/a11y/RelationType.h"
 #include "mozilla/a11y/Role.h"
 #include "mozilla/a11y/States.h"
 #include "nsAccessNode.h"
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleHyperLink.h"
 #include "nsIAccessibleSelectable.h"
 #include "nsIAccessibleValue.h"
@@ -289,17 +290,17 @@ public:
    * @param  aSetSize   [out] the group size
    */
   virtual void GetPositionAndSizeInternal(int32_t *aPosInSet,
                                           int32_t *aSetSize);
 
   /**
    * Get the relation of the given type.
    */
-  virtual mozilla::a11y::Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType);
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing methods
 
   /**
    * Set the ARIA role map entry for a new accessible.
    */
   void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -136,17 +136,17 @@ ApplicationAccessible::FocusedChild()
   Accessible* focus = FocusMgr()->FocusedAccessible();
   if (focus && focus->Parent() == this)
     return focus;
 
   return nullptr;
 }
 
 Relation
-ApplicationAccessible::RelationByType(uint32_t aRelationType)
+ApplicationAccessible::RelationByType(RelationType aRelationType)
 {
   return Relation();
 }
 
 NS_IMETHODIMP
 ApplicationAccessible::GetBounds(int32_t* aX, int32_t* aY,
                                  int32_t* aWidth, int32_t* aHeight)
 {
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -65,17 +65,17 @@ public:
   virtual GroupPos GroupPosition();
   virtual ENameValueFlag Name(nsString& aName);
   virtual void ApplyARIAState(uint64_t* aState) const;
   virtual void Description(nsString& aDescription);
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t State();
   virtual uint64_t NativeState();
-  virtual Relation RelationByType(uint32_t aRelType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
   virtual Accessible* FocusedChild();
 
   virtual void InvalidateChildren();
 
   // ActionAccessible
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -476,19 +476,19 @@ RootAccessible::Shutdown()
   if (!PresShell())
     return;  // Already shutdown
 
   DocAccessibleWrap::Shutdown();
 }
 
 // nsIAccessible method
 Relation
-RootAccessible::RelationByType(uint32_t aType)
+RootAccessible::RelationByType(RelationType aType)
 {
-  if (!mDocumentNode || aType != nsIAccessibleRelation::RELATION_EMBEDS)
+  if (!mDocumentNode || aType != RelationType::EMBEDS)
     return DocAccessibleWrap::RelationByType(aType);
 
   nsIDOMWindow* rootWindow = mDocumentNode->GetWindow();
   if (rootWindow) {
     nsCOMPtr<nsIDOMWindow> contentWindow;
     rootWindow->GetContent(getter_AddRefs(contentWindow));
     if (contentWindow) {
       nsCOMPtr<nsIDOMDocument> contentDOMDocument;
--- a/accessible/src/generic/RootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -29,17 +29,17 @@ public:
   // nsIDOMEventListener
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
 
   // RootAccessible
 
   /**
    * Notify that the sub document presshell was activated.
    */
--- a/accessible/src/html/HTMLElementAccessibles.cpp
+++ b/accessible/src/html/HTMLElementAccessibles.cpp
@@ -60,20 +60,20 @@ NS_IMPL_ISUPPORTS_INHERITED0(HTMLLabelAc
 ENameValueFlag
 HTMLLabelAccessible::NativeName(nsString& aName)
 {
   nsTextEquivUtils::GetNameFromSubtree(this, aName);
   return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 Relation
-HTMLLabelAccessible::RelationByType(uint32_t aType)
+HTMLLabelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
+  if (aType == RelationType::LABEL_FOR) {
     nsRefPtr<dom::HTMLLabelElement> label = dom::HTMLLabelElement::FromContent(mContent);
     rel.AppendTarget(mDoc, label->GetControl());
   }
 
   return rel;
 }
 
 role
@@ -84,20 +84,20 @@ HTMLLabelAccessible::NativeRole()
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLOuputAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLOutputAccessible, HyperTextAccessible)
 
 Relation
-HTMLOutputAccessible::RelationByType(uint32_t aType)
+HTMLOutputAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_CONTROLLED_BY)
+  if (aType == RelationType::CONTROLLED_BY)
     rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::_for));
 
   return rel;
 }
 
 role
 HTMLOutputAccessible::NativeRole()
 {
--- a/accessible/src/html/HTMLElementAccessibles.h
+++ b/accessible/src/html/HTMLElementAccessibles.h
@@ -56,17 +56,17 @@ public:
 
   HTMLLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType) MOZ_OVERRIDE;
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for HTML output element.
  */
@@ -77,15 +77,15 @@ public:
   HTMLOutputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual a11y::role NativeRole();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -654,41 +654,41 @@ HTMLGroupboxAccessible::NativeName(nsStr
   nsIContent* legendContent = GetLegend();
   if (legendContent)
     nsTextEquivUtils::AppendTextEquivFromContent(this, legendContent, &aName);
 
   return eNameOK;
 }
 
 Relation
-HTMLGroupboxAccessible::RelationByType(uint32_t aType)
+HTMLGroupboxAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
     // No override for label, so use <legend> for this <fieldset>
-  if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType == RelationType::LABELLED_BY)
     rel.AppendTarget(mDoc, GetLegend());
 
   return rel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLLegendAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLLegendAccessible::
   HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HyperTextAccessibleWrap(aContent, aDoc)
 {
 }
 
 Relation
-HTMLLegendAccessible::RelationByType(uint32_t aType)
+HTMLLegendAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType != RelationType::LABEL_FOR)
     return rel;
 
   Accessible* groupbox = Parent();
   if (groupbox && groupbox->Role() == roles::GROUPING)
     rel.AppendTarget(groupbox);
 
   return rel;
 }
@@ -737,20 +737,20 @@ HTMLFigureAccessible::NativeName(nsStrin
   nsIContent* captionContent = Caption();
   if (captionContent)
     nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent, &aName);
 
   return eNameOK;
 }
 
 Relation
-HTMLFigureAccessible::RelationByType(uint32_t aType)
+HTMLFigureAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType == RelationType::LABELLED_BY)
     rel.AppendTarget(mDoc, Caption());
 
   return rel;
 }
 
 nsIContent*
 HTMLFigureAccessible::Caption() const
 {
@@ -777,20 +777,20 @@ HTMLFigcaptionAccessible::
 
 role
 HTMLFigcaptionAccessible::NativeRole()
 {
   return roles::CAPTION;
 }
 
 Relation
-HTMLFigcaptionAccessible::RelationByType(uint32_t aType)
+HTMLFigcaptionAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType != RelationType::LABEL_FOR)
     return rel;
 
   Accessible* figure = Parent();
   if (figure &&
       figure->GetContent()->NodeInfo()->Equals(nsGkAtoms::figure,
                                                mContent->GetNameSpaceID())) {
     rel.AppendTarget(figure);
   }
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -188,17 +188,17 @@ public:
  */
 class HTMLGroupboxAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 
   // HTMLGroupboxAccessible
   nsIContent* GetLegend();
 };
@@ -209,31 +209,31 @@ protected:
  */
 class HTMLLegendAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 /**
  * Accessible for HTML5 figure element.
  */
 class HTMLFigureAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 
   // HTMLLegendAccessible
   nsIContent* Caption() const;
 };
@@ -244,15 +244,15 @@ protected:
  */
 class HTMLFigcaptionAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLFigcaptionAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -446,20 +446,20 @@ HTMLTableAccessible::NativeAttributes()
 
   return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible: nsIAccessible implementation
 
 Relation
-HTMLTableAccessible::RelationByType(uint32_t aType)
+HTMLTableAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType == RelationType::LABELLED_BY)
     rel.AppendTarget(Caption());
 
   return rel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible: nsIAccessibleTable implementation
 
@@ -1113,20 +1113,20 @@ HTMLTableAccessible::IsProbablyLayoutTab
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCaptionAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 Relation
-HTMLCaptionAccessible::RelationByType(uint32_t aType)
+HTMLCaptionAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessible::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType == RelationType::LABEL_FOR)
     rel.AppendTarget(Parent());
 
   return rel;
 }
 
 role
 HTMLCaptionAccessible::NativeRole()
 {
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -167,17 +167,17 @@ public:
   virtual void Shutdown();
 
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
   virtual void Description(nsString& aDescription);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aRelationType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren();
 
   // HTMLTableAccessible
 
@@ -226,15 +226,15 @@ public:
   HTMLCaptionAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) { }
   virtual ~HTMLCaptionAccessible() { }
 
   // nsIAccessible
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aRelationType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -188,17 +188,17 @@ GetClosestInterestingAccessible(id anObj
     return [self size];
   if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
     return [self window];
   if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
     return [self window];
   if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
     return [self title];
   if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
-    Relation rel = mGeckoAccessible->RelationByType(nsIAccessibleRelation::RELATION_LABELLED_BY);
+    Relation rel = mGeckoAccessible->RelationByType(RelationType::LABELLED_BY);
     Accessible* tempAcc = rel.Next();
     return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
   }
   if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
     return [self help];
     
 #ifdef DEBUG
  NSLog (@"!!! %@ can't respond to attribute %@", self, attribute);
--- a/accessible/src/windows/ia2/ia2Accessible.cpp
+++ b/accessible/src/windows/ia2/ia2Accessible.cpp
@@ -81,20 +81,20 @@ ia2Accessible::get_relation(long aRelati
   *aRelation = nullptr;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   long relIdx = 0;
   for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
-    uint32_t relType = sRelationTypesForIA2[idx];
-    Relation rel = acc->RelationByType(relType);
+    RelationType relationType = sRelationTypesForIA2[idx];
+    Relation rel = acc->RelationByType(relationType);
     nsRefPtr<ia2AccessibleRelation> ia2Relation =
-      new ia2AccessibleRelation(relType, &rel);
+      new ia2AccessibleRelation(relationType, &rel);
     if (ia2Relation->HasTargets()) {
       if (relIdx == aRelationIndex) {
         ia2Relation.forget(aRelation);
         return S_OK;
       }
 
       relIdx++;
     }
@@ -117,20 +117,20 @@ ia2Accessible::get_relations(long aMaxRe
   *aNRelations = 0;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2) &&
        *aNRelations < aMaxRelations; idx++) {
-    uint32_t relType = sRelationTypesForIA2[idx];
-    Relation rel = acc->RelationByType(relType);
+    RelationType relationType = sRelationTypesForIA2[idx];
+    Relation rel = acc->RelationByType(relationType);
     nsRefPtr<ia2AccessibleRelation> ia2Rel =
-      new ia2AccessibleRelation(relType, &rel);
+      new ia2AccessibleRelation(relationType, &rel);
     if (ia2Rel->HasTargets()) {
       ia2Rel.forget(aRelation + (*aNRelations));
       (*aNRelations)++;
     }
   }
   return S_OK;
 
   A11Y_TRYBLOCK_END
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
@@ -3,131 +3,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 "ia2AccessibleRelation.h"
 
 #include "Relation.h"
-#include "IUnknownImpl.h"
 #include "nsIAccessibleRelation.h"
 #include "nsID.h"
 
 #include "AccessibleRelation_i.c"
 
 using namespace mozilla::a11y;
 
-ia2AccessibleRelation::ia2AccessibleRelation(uint32_t aType, Relation* aRel) :
-  mType(aType), mReferences(0)
+ia2AccessibleRelation::ia2AccessibleRelation(RelationType aType, Relation* aRel) :
+  mType(aType)
 {
   Accessible* target = nullptr;
   while ((target = aRel->Next()))
     mTargets.AppendElement(target);
 }
 
 // IUnknown
 
-STDMETHODIMP
-ia2AccessibleRelation::QueryInterface(REFIID iid, void** ppv)
-{
-  if (!ppv)
-    return E_INVALIDARG;
-
-  *ppv = nullptr;
-
-  if (IID_IAccessibleRelation == iid || IID_IUnknown == iid) {
-    *ppv = static_cast<IAccessibleRelation*>(this);
-    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-    return S_OK;
-  }
-
-  return E_NOINTERFACE;
-}
-
-ULONG STDMETHODCALLTYPE
-ia2AccessibleRelation::AddRef()
-{
-  return mReferences++;
-}
-
-ULONG STDMETHODCALLTYPE 
-ia2AccessibleRelation::Release()
-{
-  mReferences--;
-  ULONG references = mReferences;
-  if (!mReferences)
-    delete this;
-
-  return references;
-}
+IMPL_IUNKNOWN_QUERY_HEAD(ia2AccessibleRelation)
+  IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleRelation)
+  IMPL_IUNKNOWN_QUERY_IFACE(IUnknown)
+IMPL_IUNKNOWN_QUERY_TAIL
 
 // IAccessibleRelation
 
 STDMETHODIMP
 ia2AccessibleRelation::get_relationType(BSTR *aRelationType)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aRelationType)
     return E_INVALIDARG;
 
   *aRelationType = nullptr;
 
   switch (mType) {
-    case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
+    case RelationType::CONTROLLED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
+    case RelationType::CONTROLLER_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLER_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_DESCRIBED_BY:
+    case RelationType::DESCRIBED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIBED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
+    case RelationType::DESCRIPTION_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIPTION_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_EMBEDDED_BY:
+    case RelationType::EMBEDDED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDDED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_EMBEDS:
+    case RelationType::EMBEDS:
       *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDS);
       break;
-    case nsIAccessibleRelation::RELATION_FLOWS_FROM:
+    case RelationType::FLOWS_FROM:
       *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_FROM);
       break;
-    case nsIAccessibleRelation::RELATION_FLOWS_TO:
+    case RelationType::FLOWS_TO:
       *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_TO);
       break;
-    case nsIAccessibleRelation::RELATION_LABEL_FOR:
+    case RelationType::LABEL_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_LABEL_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_LABELLED_BY:
+    case RelationType::LABELLED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_LABELED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_MEMBER_OF:
+    case RelationType::MEMBER_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_MEMBER_OF);
       break;
-    case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
+    case RelationType::NODE_CHILD_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_NODE_CHILD_OF);
       break;
-    case nsIAccessibleRelation::RELATION_NODE_PARENT_OF:
+    case RelationType::NODE_PARENT_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_NODE_PARENT_OF);
       break;
-    case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
+    case RelationType::PARENT_WINDOW_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_PARENT_WINDOW_OF);
       break;
-    case nsIAccessibleRelation::RELATION_POPUP_FOR:
+    case RelationType::POPUP_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_POPUP_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_SUBWINDOW_OF:
+    case RelationType::SUBWINDOW_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_SUBWINDOW_OF);
       break;
-    default:
-      return E_FAIL;
   }
 
   return *aRelationType ? S_OK : E_OUTOFMEMORY;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.h
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.h
@@ -4,35 +4,33 @@
 /* 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 _NS_ACCESSIBLE_RELATION_WRAP_H
 #define _NS_ACCESSIBLE_RELATION_WRAP_H
 
 #include "Accessible.h"
+#include "IUnknownImpl.h"
 #include "nsIAccessibleRelation.h"
 
 #include "nsTArray.h"
 
 #include "AccessibleRelation.h"
 
 namespace mozilla {
 namespace a11y {
 
-class ia2AccessibleRelation : public IAccessibleRelation
+class ia2AccessibleRelation MOZ_FINAL : public IAccessibleRelation
 {
 public:
-  ia2AccessibleRelation(uint32_t aType, Relation* aRel);
-  virtual ~ia2AccessibleRelation() { }
+  ia2AccessibleRelation(RelationType aType, Relation* aRel);
 
   // IUnknown
-  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID, void** aOutPtr);
-  virtual ULONG STDMETHODCALLTYPE AddRef();
-  virtual ULONG STDMETHODCALLTYPE Release();
+  DECL_IUNKNOWN
 
   // IAccessibleRelation
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_relationType(
       /* [retval][out] */ BSTR *relationType);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_localizedRelationType(
       /* [retval][out] */ BSTR *localizedRelationType);
 
@@ -51,41 +49,40 @@ public:
   inline bool HasTargets() const
     { return mTargets.Length(); }
 
 private:
   ia2AccessibleRelation();
   ia2AccessibleRelation(const ia2AccessibleRelation&);
   ia2AccessibleRelation& operator = (const ia2AccessibleRelation&);
 
-  uint32_t mType;
+  RelationType mType;
   nsTArray<nsRefPtr<Accessible> > mTargets;
-  ULONG mReferences;
 };
 
 
 /**
  * Relations exposed to IAccessible2.
  */
-static const uint32_t sRelationTypesForIA2[] = {
-  nsIAccessibleRelation::RELATION_LABELLED_BY,
-  nsIAccessibleRelation::RELATION_LABEL_FOR,
-  nsIAccessibleRelation::RELATION_DESCRIBED_BY,
-  nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
-  nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
-  nsIAccessibleRelation::RELATION_NODE_PARENT_OF,
-  nsIAccessibleRelation::RELATION_CONTROLLED_BY,
-  nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
-  nsIAccessibleRelation::RELATION_FLOWS_TO,
-  nsIAccessibleRelation::RELATION_FLOWS_FROM,
-  nsIAccessibleRelation::RELATION_MEMBER_OF,
-  nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
-  nsIAccessibleRelation::RELATION_EMBEDS,
-  nsIAccessibleRelation::RELATION_EMBEDDED_BY,
-  nsIAccessibleRelation::RELATION_POPUP_FOR,
-  nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF
+static const RelationType sRelationTypesForIA2[] = {
+  RelationType::LABELLED_BY,
+  RelationType::LABEL_FOR,
+  RelationType::DESCRIBED_BY,
+  RelationType::DESCRIPTION_FOR,
+  RelationType::NODE_CHILD_OF,
+  RelationType::NODE_PARENT_OF,
+  RelationType::CONTROLLED_BY,
+  RelationType::CONTROLLER_FOR,
+  RelationType::FLOWS_TO,
+  RelationType::FLOWS_FROM,
+  RelationType::MEMBER_OF,
+  RelationType::SUBWINDOW_OF,
+  RelationType::EMBEDS,
+  RelationType::EMBEDDED_BY,
+  RelationType::POPUP_FOR,
+  RelationType::PARENT_WINDOW_OF
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/AccessibleWrap.cpp
@@ -916,75 +916,75 @@ AccessibleWrap::accNavigate(
     case NAVDIR_DOWN:
     case NAVDIR_LEFT:
     case NAVDIR_RIGHT:
     case NAVDIR_UP:
       return E_NOTIMPL;
 
     // MSAA relationship extensions to accNavigate
     case NAVRELATION_CONTROLLED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_CONTROLLED_BY;
+      xpRelation = static_cast<int32_t>(RelationType::CONTROLLED_BY);
       break;
     case NAVRELATION_CONTROLLER_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_CONTROLLER_FOR;
+      xpRelation = static_cast<int32_t>(RelationType::CONTROLLER_FOR);
       break;
     case NAVRELATION_LABEL_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_LABEL_FOR;
+      xpRelation = static_cast<int32_t>(RelationType::LABEL_FOR);
       break;
     case NAVRELATION_LABELLED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_LABELLED_BY;
+      xpRelation = static_cast<int32_t>(RelationType::LABELLED_BY);
       break;
     case NAVRELATION_MEMBER_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_MEMBER_OF;
+      xpRelation = static_cast<int32_t>(RelationType::MEMBER_OF);
       break;
     case NAVRELATION_NODE_CHILD_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_NODE_CHILD_OF;
+      xpRelation = static_cast<int32_t>(RelationType::NODE_CHILD_OF);
       break;
     case NAVRELATION_FLOWS_TO:
-      xpRelation = nsIAccessibleRelation::RELATION_FLOWS_TO;
+      xpRelation = static_cast<int32_t>(RelationType::FLOWS_TO);
       break;
     case NAVRELATION_FLOWS_FROM:
-      xpRelation = nsIAccessibleRelation::RELATION_FLOWS_FROM;
+      xpRelation = static_cast<int32_t>(RelationType::FLOWS_FROM);
       break;
     case NAVRELATION_SUBWINDOW_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_SUBWINDOW_OF;
+      xpRelation = static_cast<int32_t>(RelationType::SUBWINDOW_OF);
       break;
     case NAVRELATION_EMBEDS:
-      xpRelation = nsIAccessibleRelation::RELATION_EMBEDS;
+      xpRelation = static_cast<int32_t>(RelationType::EMBEDS);
       break;
     case NAVRELATION_EMBEDDED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_EMBEDDED_BY;
+      xpRelation = static_cast<int32_t>(RelationType::EMBEDDED_BY);
       break;
     case NAVRELATION_POPUP_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_POPUP_FOR;
+      xpRelation = static_cast<int32_t>(RelationType::POPUP_FOR);
       break;
     case NAVRELATION_PARENT_WINDOW_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF;
+      xpRelation = static_cast<int32_t>(RelationType::PARENT_WINDOW_OF);
       break;
     case NAVRELATION_DEFAULT_BUTTON:
-      xpRelation = nsIAccessibleRelation::RELATION_DEFAULT_BUTTON;
+      xpRelation = static_cast<int32_t>(RelationType::DEFAULT_BUTTON);
       break;
     case NAVRELATION_DESCRIBED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_DESCRIBED_BY;
+      xpRelation = static_cast<int32_t>(RelationType::DESCRIBED_BY);
       break;
     case NAVRELATION_DESCRIPTION_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_DESCRIPTION_FOR;
+      xpRelation = static_cast<int32_t>(RelationType::DESCRIPTION_FOR);
       break;
     case NAVRELATION_NODE_PARENT_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_NODE_PARENT_OF;
+      xpRelation = static_cast<int32_t>(RelationType::NODE_PARENT_OF);
       break;
 
     default:
       return E_INVALIDARG;
   }
 
   pvarEndUpAt->vt = VT_EMPTY;
 
   if (xpRelation >= 0) {
-    Relation rel = RelationByType(xpRelation);
+    Relation rel = RelationByType(static_cast<RelationType>(xpRelation));
     navAccessible = rel.Next();
   }
 
   if (!navAccessible)
     return E_FAIL;
 
   pvarEndUpAt->pdispVal = NativeAccessible(navAccessible);
   pvarEndUpAt->vt = VT_DISPATCH;
--- a/accessible/src/xul/XULElementAccessibles.cpp
+++ b/accessible/src/xul/XULElementAccessibles.cpp
@@ -82,20 +82,20 @@ uint64_t
 XULLabelAccessible::NativeState()
 {
   // Labels and description have read only state
   // They are not focusable or selectable
   return HyperTextAccessibleWrap::NativeState() | states::READONLY;
 }
 
 Relation
-XULLabelAccessible::RelationByType(uint32_t aType)
+XULLabelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
+  if (aType == RelationType::LABEL_FOR) {
     // Caption is the label for groupbox
     nsIContent* parent = mContent->GetFlattenedTreeParent();
     if (parent && parent->Tag() == nsGkAtoms::caption) {
       Accessible* parent = Parent();
       if (parent && parent->Role() == roles::GROUPING)
         rel.AppendTarget(parent);
     }
   }
--- a/accessible/src/xul/XULElementAccessibles.h
+++ b/accessible/src/xul/XULElementAccessibles.h
@@ -21,17 +21,17 @@ class XULLabelAccessible : public HyperT
 {
 public:
   XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Shutdown();
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   void UpdateLabelValue(const nsString& aValue);
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren() MOZ_OVERRIDE;
 
--- a/accessible/src/xul/XULFormControlAccessible.cpp
+++ b/accessible/src/xul/XULFormControlAccessible.cpp
@@ -380,40 +380,39 @@ XULGroupboxAccessible::NativeRole()
   return roles::GROUPING;
 }
 
 ENameValueFlag
 XULGroupboxAccessible::NativeName(nsString& aName)
 {
   // XXX: we use the first related accessible only.
   Accessible* label =
-    RelationByType(nsIAccessibleRelation::RELATION_LABELLED_BY).Next();
+    RelationByType(RelationType::LABELLED_BY).Next();
   if (label)
     return label->Name(aName);
 
   return eNameOK;
 }
 
 Relation
-XULGroupboxAccessible::RelationByType(uint32_t aType)
+XULGroupboxAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType != RelationType::LABELLED_BY)
     return rel;
 
   // The label for xul:groupbox is generated from xul:label that is
   // inside the anonymous content of the xul:caption.
   // The xul:label has an accessible object but the xul:caption does not
   uint32_t childCount = ChildCount();
   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* childAcc = GetChildAt(childIdx);
     if (childAcc->Role() == roles::LABEL) {
       // Ensure that it's our label
-      Relation reverseRel =
-        childAcc->RelationByType(nsIAccessibleRelation::RELATION_LABEL_FOR);
+      Relation reverseRel = childAcc->RelationByType(RelationType::LABEL_FOR);
       Accessible* testGroupbox = nullptr;
       while ((testGroupbox = reverseRel.Next()))
         if (testGroupbox == this) {
           // The <label> points back to this groupbox
           rel.AppendTarget(childAcc);
         }
     }
   }
--- a/accessible/src/xul/XULFormControlAccessible.h
+++ b/accessible/src/xul/XULFormControlAccessible.h
@@ -110,17 +110,17 @@ private:
  */
 class XULGroupboxAccessible : public AccessibleWrap
 {
 public:
   XULGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL radio element (radio button).
--- a/accessible/src/xul/XULTabAccessible.cpp
+++ b/accessible/src/xul/XULTabAccessible.cpp
@@ -103,20 +103,20 @@ uint64_t
 XULTabAccessible::NativeInteractiveState() const
 {
   uint64_t state = Accessible::NativeInteractiveState();
   return (state & states::UNAVAILABLE) ? state : state | states::SELECTABLE;
 }
 
 // nsIAccessible
 Relation
-XULTabAccessible::RelationByType(uint32_t aType)
+XULTabAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType != RelationType::LABEL_FOR)
     return rel;
 
   // Expose 'LABEL_FOR' relation on tab accessible for tabpanel accessible.
   nsCOMPtr<nsIDOMXULRelatedElement> tabsElm =
     do_QueryInterface(mContent->GetParent());
   if (!tabsElm)
     return rel;
 
@@ -190,20 +190,20 @@ XULTabpanelAccessible::
 
 role
 XULTabpanelAccessible::NativeRole()
 {
   return roles::PROPERTYPAGE;
 }
 
 Relation
-XULTabpanelAccessible::RelationByType(uint32_t aType)
+XULTabpanelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType != RelationType::LABELLED_BY)
     return rel;
 
   // Expose 'LABELLED_BY' relation on tabpanel accessible for tab accessible.
   nsCOMPtr<nsIDOMXULRelatedElement> tabpanelsElm =
     do_QueryInterface(mContent->GetParent());
   if (!tabpanelsElm)
     return rel;
 
--- a/accessible/src/xul/XULTabAccessible.h
+++ b/accessible/src/xul/XULTabAccessible.h
@@ -26,17 +26,17 @@ public:
   // nsIAccessible
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD DoAction(uint8_t index);
 
   // Accessible
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 };
 
 
 /**
  * A container of tab objects, xul:tabs element.
@@ -86,16 +86,16 @@ public:
  */
 class XULTabpanelAccessible : public AccessibleWrap
 {
 public:
   XULTabpanelAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -437,19 +437,19 @@ XULTreeAccessible::ChildCount() const
   int32_t rowCount = 0;
   mTreeView->GetRowCount(&rowCount);
   childCount += rowCount;
 
   return childCount;
 }
 
 Relation
-XULTreeAccessible::RelationByType(uint32_t aType)
+XULTreeAccessible::RelationByType(RelationType aType)
 {
-  if (aType == nsIAccessibleRelation::RELATION_NODE_PARENT_OF) {
+  if (aType == RelationType::NODE_PARENT_OF) {
     if (mTreeView)
       return Relation(new XULTreeItemIterator(this, mTreeView, -1));
 
     return Relation();
   }
 
   return Accessible::RelationByType(aType);
 }
@@ -803,33 +803,33 @@ XULTreeItemAccessibleBase::TakeFocus()
   if (selection)
     selection->SetCurrentIndex(mRow);
 
   // focus event will be fired here
   return Accessible::TakeFocus();
 }
 
 Relation
-XULTreeItemAccessibleBase::RelationByType(uint32_t aType)
+XULTreeItemAccessibleBase::RelationByType(RelationType aType)
 {
 
   switch (aType) {
-    case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
+    case RelationType::NODE_CHILD_OF: {
       int32_t parentIndex = -1;
       if (!NS_SUCCEEDED(mTreeView->GetParentIndex(mRow, &parentIndex)))
         return Relation();
 
       if (parentIndex == -1)
         return Relation(mParent);
 
       XULTreeAccessible* treeAcc = mParent->AsXULTree();
       return Relation(treeAcc->GetTreeItemAccessible(parentIndex));
     }
 
-    case nsIAccessibleRelation::RELATION_NODE_PARENT_OF: {
+    case RelationType::NODE_PARENT_OF: {
       bool isTrue = false;
       if (NS_FAILED(mTreeView->IsContainerEmpty(mRow, &isTrue)) || isTrue)
         return Relation();
 
       if (NS_FAILED(mTreeView->IsContainerOpen(mRow, &isTrue)) || !isTrue)
         return Relation();
 
       XULTreeAccessible* tree = mParent->AsXULTree();
--- a/accessible/src/xul/XULTreeAccessible.h
+++ b/accessible/src/xul/XULTreeAccessible.h
@@ -45,17 +45,17 @@ public:
   virtual void Value(nsString& aValue);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
 
   virtual Accessible* GetChildAt(uint32_t aIndex);
   virtual uint32_t ChildCount() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   // SelectAccessible
   virtual already_AddRefed<nsIArray> SelectedItems();
   virtual uint32_t SelectedItemCount();
   virtual Accessible* GetSelectedItem(uint32_t aIndex);
   virtual bool IsItemSelected(uint32_t aIndex);
   virtual bool AddItemToSelection(uint32_t aIndex);
   virtual bool RemoveItemFromSelection(uint32_t aIndex);
@@ -158,17 +158,17 @@ public:
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual GroupPos GroupPosition();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
   virtual int32_t IndexInParent() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
   virtual Accessible* FocusedChild();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // Widgets
   virtual Accessible* ContainerWidget() const;
 
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -757,17 +757,17 @@ XULTreeGridCellAccessible::NativeInterac
 
 int32_t
 XULTreeGridCellAccessible::IndexInParent() const
 {
   return ColIdx();
 }
 
 Relation
-XULTreeGridCellAccessible::RelationByType(uint32_t aType)
+XULTreeGridCellAccessible::RelationByType(RelationType aType)
 {
   return Relation();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: public implementation
 
 void
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -155,17 +155,17 @@ public:
 
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual ENameValueFlag Name(nsString& aName);
   virtual Accessible* FocusedChild();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual int32_t IndexInParent() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // TableCellAccessible
--- a/b2g/components/ErrorPage.jsm
+++ b/b2g/components/ErrorPage.jsm
@@ -152,18 +152,22 @@ let ErrorPage = {
   init: function errorPageInit() {
     Services.obs.addObserver(this, 'in-process-browser-or-app-frame-shown', false);
     Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
   },
 
   observe: function errorPageObserve(aSubject, aTopic, aData) {
     let frameLoader = aSubject.QueryInterface(Ci.nsIFrameLoader);
     let mm = frameLoader.messageManager;
+
+    // This won't happen from dom/ipc/preload.js in non-OOP builds.
     try {
-      mm.loadFrameScript(kErrorPageFrameScript, true);
+      if (Services.prefs.getBoolPref("dom.ipc.tabs.disabled") === true) {
+        mm.loadFrameScript(kErrorPageFrameScript, true);
+      }
     } catch (e) {
       dump('Error loading ' + kErrorPageFrameScript + ' as frame script: ' + e + '\n');
     }
     mm.addMessageListener('ErrorPage:AddCertException', this._addCertException.bind(this));
   }
 };
 
 ErrorPage.init();
--- a/content/media/webrtc/MediaEngineTabVideoSource.cpp
+++ b/content/media/webrtc/MediaEngineTabVideoSource.cpp
@@ -251,17 +251,16 @@ MediaEngineTabVideoSource::Draw() {
   rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
 
   NS_ENSURE_SUCCESS_VOID(rv);
 
   layers::CairoImage::Data cairoData;
   cairoData.mSurface = surf;
   cairoData.mSize = size;
 
-  ImageFormat cairoFormat = CAIRO_SURFACE;
   nsRefPtr<layers::CairoImage> image = new layers::CairoImage();
 
   image->SetData(cairoData);
 
   MonitorAutoLock mon(mMonitor);
   mImage = image;
 }
 
--- a/content/svg/content/src/SVGPathSegUtils.h
+++ b/content/svg/content/src/SVGPathSegUtils.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_SVGPATHSEGUTILS_H__
 #define MOZILLA_SVGPATHSEGUTILS_H__
 
 #include "gfxPoint.h"
 #include "nsDebug.h"
 #include "nsMemory.h"
-#include "prtypes.h"
 
 namespace mozilla {
 
 // Path Segment Types
 static const unsigned short PATHSEG_UNKNOWN                      = 0;
 static const unsigned short PATHSEG_CLOSEPATH                    = 1;
 static const unsigned short PATHSEG_MOVETO_ABS                   = 2;
 static const unsigned short PATHSEG_MOVETO_REL                   = 3;
@@ -108,23 +107,23 @@ public:
    *
    * At some point in the future we will likely want to encode other
    * information into the float, such as whether the command was explicit or
    * not. For now all this method does is save on int to float runtime
    * conversion by requiring uint32_t and float to be of the same size so we
    * can simply do a bitwise uint32_t<->float copy.
    */
   static float EncodeType(uint32_t aType) {
-    PR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(float));
+    static_assert(sizeof(uint32_t) == sizeof(float), "sizeof uint32_t and float must be the same");
     NS_ABORT_IF_FALSE(IsValidType(aType), "Seg type not recognized");
     return *(reinterpret_cast<float*>(&aType));
   }
 
   static uint32_t DecodeType(float aType) {
-    PR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(float));
+    static_assert(sizeof(uint32_t) == sizeof(float), "sizeof uint32_t and float must be the same");
     uint32_t type = *(reinterpret_cast<uint32_t*>(&aType));
     NS_ABORT_IF_FALSE(IsValidType(type), "Seg type not recognized");
     return type;
   }
 
   static PRUnichar GetPathSegTypeAsLetter(uint32_t aType) {
     NS_ABORT_IF_FALSE(IsValidType(aType), "Seg type not recognized");
 
@@ -145,17 +144,17 @@ public:
       PRUnichar('h'),  // 13 == PATHSEG_LINETO_HORIZONTAL_REL
       PRUnichar('V'),  // 14 == PATHSEG_LINETO_VERTICAL_ABS
       PRUnichar('v'),  // 15 == PATHSEG_LINETO_VERTICAL_REL
       PRUnichar('S'),  // 16 == PATHSEG_CURVETO_CUBIC_SMOOTH_ABS
       PRUnichar('s'),  // 17 == PATHSEG_CURVETO_CUBIC_SMOOTH_REL
       PRUnichar('T'),  // 18 == PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS
       PRUnichar('t')   // 19 == PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL
     };
-    PR_STATIC_ASSERT(NS_ARRAY_LENGTH(table) == NS_SVG_PATH_SEG_TYPE_COUNT);
+    static_assert(NS_ARRAY_LENGTH(table) == NS_SVG_PATH_SEG_TYPE_COUNT, "Unexpected table size");
 
     return table[aType];
   }
 
   static uint32_t ArgCountForType(uint32_t aType) {
     NS_ABORT_IF_FALSE(IsValidType(aType), "Seg type not recognized");
 
     static const uint8_t table[] = {
@@ -175,17 +174,17 @@ public:
       1,  // 13 == PATHSEG_LINETO_HORIZONTAL_REL
       1,  // 14 == PATHSEG_LINETO_VERTICAL_ABS
       1,  // 15 == PATHSEG_LINETO_VERTICAL_REL
       4,  // 16 == PATHSEG_CURVETO_CUBIC_SMOOTH_ABS
       4,  // 17 == PATHSEG_CURVETO_CUBIC_SMOOTH_REL
       2,  // 18 == PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS
       2   // 19 == PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL
     };
-    PR_STATIC_ASSERT(NS_ARRAY_LENGTH(table) == NS_SVG_PATH_SEG_TYPE_COUNT);
+    static_assert(NS_ARRAY_LENGTH(table) == NS_SVG_PATH_SEG_TYPE_COUNT, "Unexpected table size");
 
     return table[aType];
   }
 
   /**
    * Convenience so that callers can pass a float containing an encoded type
    * and have it decoded implicitly.
    */
@@ -217,44 +216,44 @@ public:
            aType == PATHSEG_ARC_REL;
   }
 
   static bool IsRelativeOrAbsoluteType(uint32_t aType) {
     NS_ABORT_IF_FALSE(IsValidType(aType), "Seg type not recognized");
 
     // When adding a new path segment type, ensure that the returned condition
     // below is still correct.
-    PR_STATIC_ASSERT(NS_SVG_PATH_SEG_LAST_VALID_TYPE ==
-                       PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL);
+    static_assert(NS_SVG_PATH_SEG_LAST_VALID_TYPE == PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,
+                  "Unexpected type");
 
     return aType >= PATHSEG_MOVETO_ABS;
   }
 
   static bool IsRelativeType(uint32_t aType) {
     NS_ABORT_IF_FALSE
       (IsRelativeOrAbsoluteType(aType),
        "IsRelativeType called with segment type that does not come in relative and absolute forms");
 
     // When adding a new path segment type, ensure that the returned condition
     // below is still correct.
-    PR_STATIC_ASSERT(NS_SVG_PATH_SEG_LAST_VALID_TYPE ==
-                       PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL);
+    static_assert(NS_SVG_PATH_SEG_LAST_VALID_TYPE == PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,
+                  "Unexpected type");
 
     return aType & 1;
   }
 
   static uint32_t RelativeVersionOfType(uint32_t aType) {
     NS_ABORT_IF_FALSE
       (IsRelativeOrAbsoluteType(aType),
        "RelativeVersionOfType called with segment type that does not come in relative and absolute forms");
 
     // When adding a new path segment type, ensure that the returned condition
     // below is still correct.
-    PR_STATIC_ASSERT(NS_SVG_PATH_SEG_LAST_VALID_TYPE ==
-                       PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL);
+    static_assert(NS_SVG_PATH_SEG_LAST_VALID_TYPE == PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL,
+                  "Unexpected type");
 
     return aType | 1;
   }
 
   static uint32_t SameTypeModuloRelativeness(uint32_t aType1, uint32_t aType2) {
     if (!IsRelativeOrAbsoluteType(aType1)) {
       return aType1 == aType2;
     }
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1414,20 +1414,20 @@ nsDOMClassInfo::GetArrayIndexFromId(JSCo
   if (aIsNumber) {
     *aIsNumber = false;
   }
 
   int i;
   if (JSID_IS_INT(id)) {
       i = JSID_TO_INT(id);
   } else {
-      jsval idval;
+      JS::RootedValue idval(cx);
       double array_index;
-      if (!::JS_IdToValue(cx, id, &idval) ||
-          !::JS_ValueToNumber(cx, idval, &array_index) ||
+      if (!::JS_IdToValue(cx, id, idval.address()) ||
+          !JS::ToNumber(cx, idval, &array_index) ||
           !::JS_DoubleIsInt32(array_index, &i)) {
         return -1;
       }
   }
 
   if (aIsNumber) {
     *aIsNumber = true;
   }
--- a/dom/bindings/DOMJSProxyHandler.cpp
+++ b/dom/bindings/DOMJSProxyHandler.cpp
@@ -262,21 +262,21 @@ DOMProxyHandler::has(JSContext* cx, JS::
     *bp = protoHasProp;
   }
   return ok;
 }
 
 int32_t
 IdToInt32(JSContext* cx, JS::Handle<jsid> id)
 {
-  JS::Value idval;
+  JS::RootedValue idval(cx);
   double array_index;
   int32_t i;
-  if (!::JS_IdToValue(cx, id, &idval) ||
-      !::JS_ValueToNumber(cx, idval, &array_index) ||
+  if (!::JS_IdToValue(cx, id, idval.address()) ||
+      !JS::ToNumber(cx, idval, &array_index) ||
       !::JS_DoubleIsInt32(array_index, &i)) {
     return -1;
   }
 
   return i;
 }
 
 } // namespace dom
--- a/dom/browser-element/BrowserElementChild.js
+++ b/dom/browser-element/BrowserElementChild.js
@@ -19,18 +19,19 @@ docShell.isActive = true;
 
 let infos = sendSyncMessage('browser-element-api:call',
                             { 'msg_name': 'hello' })[0];
 docShell.QueryInterface(Ci.nsIDocShellTreeItem).name = infos.name;
 docShell.setFullscreenAllowed(infos.fullscreenAllowed);
 
 
 if (!('BrowserElementIsPreloaded' in this)) {
-  // This is a produc-specific file that's sometimes unavailable.
+  // Those are produc-specific files that's sometimes unavailable.
   try {
     Services.scriptloader.loadSubScript("chrome://browser/content/forms.js");
+    Services.scriptloader.loadSubScript("chrome://browser/content/ErrorPage.js");
   } catch (e) {
   }
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementPanning.js");
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js");
 }
 
 var BrowserElementIsReady = true;
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -315,16 +315,18 @@ BrowserElementChild.prototype = {
                    .getInterface(Ci.nsIDOMWindowUtils);
 
     args.windowID = { outer: utils.outerWindowID,
                       inner: this._tryGetInnerWindowID(win) };
     sendAsyncMsg('showmodalprompt', args);
 
     let returnValue = this._waitForResult(win);
 
+    Services.obs.notifyObservers(null, 'BEC:ShownModalPrompt', null);
+
     if (args.promptType == 'prompt' ||
         args.promptType == 'confirm' ||
         args.promptType == 'custom-prompt') {
       return returnValue;
     }
   },
 
   /**
--- a/dom/browser-element/BrowserElementPanning.js
+++ b/dom/browser-element/BrowserElementPanning.js
@@ -58,16 +58,18 @@ const ContentPanning = {
         els.addSystemEventListener(global, type,
                                    this.handleEvent.bind(this),
                                    /* useCapture = */ false);
       }.bind(this));
     }
 
     addMessageListener("Viewport:Change", this._recvViewportChange.bind(this));
     addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
+    addEventListener("visibilitychange", this._recvVisibilityChange.bind(this));
+    Services.obs.addObserver(this, "BEC:ShownModalPrompt", false);
   },
 
   handleEvent: function cp_handleEvent(evt) {
     if (evt.defaultPrevented || evt.multipleActionsPrevented) {
       // clean up panning state even if touchend/mouseup has been preventDefault.
       if(evt.type === 'touchend' || evt.type === 'mouseup') {
         if (this.dragging &&
             (this.watchedEventsType === 'mouse' ||
@@ -105,16 +107,22 @@ const ContentPanning = {
         let target = evt.target;
         let view = target.ownerDocument ? target.ownerDocument.defaultView
                                         : target;
         view.removeEventListener('click', this, true, true);
         break;
     }
   },
 
+  observe: function cp_observe(subject, topic, data) {
+    if (topic === 'BEC:ShownModalPrompt') {
+      this._resetHover();
+    }
+  },
+
   position: new Point(0 , 0),
 
   findPrimaryPointer: function cp_findPrimaryPointer(touches) {
     if (!('primaryPointerId' in this))
       return null;
 
     for (let i = 0; i < touches.length; i++) {
       if (touches[i].identifier === this.primaryPointerId) {
@@ -491,16 +499,22 @@ const ContentPanning = {
   },
 
   _resetActive: function cp_resetActive() {
     let elt = this.target || this.pointerDownTarget;
     let root = elt.ownerDocument || elt.document;
     this._setActive(root.documentElement);
   },
 
+  _resetHover: function cp_resetHover() {
+    const kStateHover = 0x00000004;
+    let element = content.document.createElement('foo');
+    this._domUtils.setContentState(element, kStateHover);
+  },
+
   _setActive: function cp_setActive(elt) {
     const kStateActive = 0x00000001;
     this._domUtils.setContentState(elt, kStateActive);
   },
 
   get _asyncPanZoomForViewportFrame() {
     return docShell.asyncPanZoomEnabled;
   },
@@ -576,16 +590,23 @@ const ContentPanning = {
         rect.y = cssTapY - (rect.h / 2);
       }
 
       var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
       os.notifyObservers(docShell, 'browser-zoom-to-rect', JSON.stringify(rect));
     }
   },
 
+  _recvVisibilityChange: function(evt) {
+    if (!evt.target.hidden)
+      return;
+
+    this._resetHover();
+  },
+
   _shouldZoomToElement: function(aElement) {
     let win = aElement.ownerDocument.defaultView;
     if (win.getComputedStyle(aElement, null).display == "inline")
       return false;
     if (aElement instanceof Ci.nsIDOMHTMLLIElement)
       return false;
     if (aElement instanceof Ci.nsIDOMHTMLQuoteElement)
       return false;
--- a/dom/browser-element/mochitest/Makefile.in
+++ b/dom/browser-element/mochitest/Makefile.in
@@ -213,17 +213,16 @@ MOCHITEST_FILES += \
 		test_browserElement_oop_AlertInFrame.html \
 		test_browserElement_oop_TargetTop.html \
 		test_browserElement_oop_ForwardName.html \
 		test_browserElement_oop_TargetBlank.html \
 		test_browserElement_oop_PromptCheck.html \
 		test_browserElement_oop_PromptConfirm.html \
 		test_browserElement_oop_CookiesNotThirdParty.html \
 		test_browserElement_oop_Close.html \
-		test_browserElement_oop_CloseFromOpener.html \
 		test_browserElement_oop_CloseApp.html \
 		test_browserElement_oop_OpenWindow.html \
 		test_browserElement_oop_OpenWindowInFrame.html \
 		test_browserElement_oop_OpenWindowRejected.html \
 		test_browserElement_oop_OpenWindowDifferentOrigin.html \
 		test_browserElement_oop_OpenNamed.html \
 		test_browserElement_oop_SecurityChange.html \
 		test_browserElement_oop_BackForward.html \
@@ -239,12 +238,15 @@ MOCHITEST_FILES += \
 		test_browserElement_oop_FrameWrongURI.html \
 		test_browserElement_oop_ReloadPostRequest.html \
 		test_browserElement_oop_PurgeHistory.html \
 		test_browserElement_oop_DocumentFirstPaint.html \
 		test_browserElement_oop_VisibilityChange.html \
 		test_browserElement_oop_BrowserWindowResize.html \
 	$(NULL)
 
+# Disabled until bug 924771 makes it stop timing out
+# 		test_browserElement_oop_CloseFromOpener.html \
+
 # Disabled until we fix bug 906096.
 #		test_browserElement_oop_SetInputMethodActive.html \
 
 endif #}
--- a/dom/icc/interfaces/nsIDOMIccManager.idl
+++ b/dom/icc/interfaces/nsIDOMIccManager.idl
@@ -1,16 +1,15 @@
 /* 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 "nsIDOMEventTarget.idl"
 #include "SimToolKit.idl"
 
-interface nsIDOMContact;
 interface nsIDOMDOMRequest;
 interface nsIDOMEventListener;
 interface nsIDOMMozIccInfo;
 
 [scriptable, builtinclass, uuid(6b5875dc-de44-4681-84a1-9ea12d60fbe2)]
 interface nsIDOMMozIccManager : nsIDOMEventTarget
 {
   /**
@@ -492,17 +491,17 @@ interface nsIDOMMozIccManager : nsIDOMEv
    *        - 'adn': Abbreviated Dialling Number
    *        - 'fdn': Fixed Dialling Number
    * @param contact
    *        The contact will be updated in ICC
    * @param [optional] pin2
    *        PIN2 is only required for 'fdn'.
    */
   nsIDOMDOMRequest updateContact(in DOMString contactType,
-                                 in nsISupports contact,
+                                 in jsval contact,
                                  [optional] in DOMString pin2);
 
   // End of UICC Phonebook Interfaces.
 
   // UICC Secure Element Interfaces
 
   /**
    * A secure element is a smart card chip that can hold
--- a/dom/icc/interfaces/nsIIccProvider.idl
+++ b/dom/icc/interfaces/nsIIccProvider.idl
@@ -1,15 +1,14 @@
 /* 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 "nsISupports.idl"
 
-interface nsIDOMContact;
 interface nsIDOMDOMRequest;
 interface nsIDOMMozIccInfo;
 interface nsIDOMWindow;
 
 [scriptable, uuid(87e9ad03-e8e2-40d1-bf28-a6d287c31b93)]
 interface nsIIccListener : nsISupports
 {
   void notifyStkCommand(in DOMString aMessage);
@@ -67,17 +66,17 @@ interface nsIIccProvider : nsISupports
   /**
    * Phonebook interfaces.
    */
   nsIDOMDOMRequest readContacts(in nsIDOMWindow window,
                                 in DOMString contactType);
 
   nsIDOMDOMRequest updateContact(in nsIDOMWindow window,
                                  in DOMString contactType,
-                                 in nsISupports contact,
+                                 in jsval contact,
                                  in DOMString pin2);
 
   /**
    * Secure Card Icc communication channel
    */
   nsIDOMDOMRequest iccOpenChannel(in nsIDOMWindow window,
                                   in DOMString aid);
 
--- a/dom/icc/src/IccManager.cpp
+++ b/dom/icc/src/IccManager.cpp
@@ -229,17 +229,17 @@ IccManager::ReadContacts(const nsAString
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->ReadContacts(GetOwner(), aContactType, aRequest);
 }
 
 NS_IMETHODIMP
 IccManager::UpdateContact(const nsAString& aContactType,
-                          nsISupports* aContact,
+                          const JS::Value& aContact,
                           const nsAString& aPin2,
                           nsIDOMDOMRequest** aRequest)
 {
   if (!mProvider) {
     return NS_ERROR_FAILURE;
   }
 
   return mProvider->UpdateContact(GetOwner(), aContactType, aContact, aPin2, aRequest);
--- a/dom/ipc/preload.js
+++ b/dom/ipc/preload.js
@@ -86,19 +86,20 @@ const BrowserElementIsPreloaded = true;
 
   try {
     if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
       Cc["@mozilla.org/system-message-manager;1"].getService(Ci["nsIDOMNavigatorSystemMessages"]);
     }
   } catch(e) {
   }
 
-  // This is a produc-specific file that's sometimes unavailable.
+  // Those are produc-specific files that's sometimes unavailable.
   try {
     Services.scriptloader.loadSubScript("chrome://browser/content/forms.js", global);
+    Services.scriptloader.loadSubScript("chrome://browser/content/ErrorPage.js", global);
   } catch (e) {
   }
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementPanning.js", global);
   Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js", global);
 
   Services.io.getProtocolHandler("app");
   Services.io.getProtocolHandler("default");
 
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -886,16 +886,17 @@ RTCError.prototype = {
     "INCOMPATIBLE_MEDIASTREAMTRACK",
     "INTERNAL_ERROR"
   ]
 };
 
 // This is a separate object because we don't want to expose it to DOM.
 function PeerConnectionObserver() {
   this._dompc = null;
+  this._guard = new WeakReferent(this);
 }
 PeerConnectionObserver.prototype = {
   classDescription: "PeerConnectionObserver",
   classID: PC_OBS_CID,
   contractID: PC_OBS_CONTRACT,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
   init: function(win) { this._win = win; },
@@ -1187,15 +1188,29 @@ PeerConnectionObserver.prototype = {
   },
 
   notifyClosedConnection: function() {
     this.dispatchEvent(new this._dompc._win.Event("closedconnection"));
   },
 
   getSupportedConstraints: function(dict) {
     return dict;
+  },
+
+  get weakReferent() {
+    return this._guard;
   }
 };
 
+// A PeerConnectionObserver member that c++ can do weak references on
+
+function WeakReferent(parent) {
+  this._parent = parent; // prevents parent from going away without us
+}
+WeakReferent.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
+                                         Ci.nsISupportsWeakReference]),
+};
+
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
   [GlobalPCList, RTCIceCandidate, RTCSessionDescription, RTCPeerConnection,
    RTCStatsReport, PeerConnectionObserver]
 );
--- a/dom/webidl/PeerConnectionObserver.webidl
+++ b/dom/webidl/PeerConnectionObserver.webidl
@@ -1,14 +1,16 @@
 /* -*- 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/.
  */
 
+interface nsISupports;
+
 [ChromeOnly,
  JSImplementation="@mozilla.org/dom/peerconnectionobserver;1",
  Constructor (object domPC)]
 interface PeerConnectionObserver
 {
   /* JSEP callbacks */
   void onCreateOfferSuccess(DOMString offer);
   void onCreateOfferError(unsigned long name, DOMString message);
@@ -35,16 +37,19 @@ interface PeerConnectionObserver
   void onStateChange(PCObserverStateType state);
 
   /* Changes to MediaStreams */
   void onAddStream(MediaStream stream);
   void onRemoveStream();
   void onAddTrack();
   void onRemoveTrack();
 
+  /* Used by c++ to know when Observer goes away */
+  readonly attribute nsISupports weakReferent;
+
   /* Helper function to access supported constraints defined in webidl. Needs to
    * be in a separate webidl object we hold, so putting it here was convenient.
    */
 // TODO: Bug 863949
 //  MediaConstraintSet getSupportedConstraints(optional
   object getSupportedConstraints(optional
       MediaConstraintSet constraints);
 };
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -4641,17 +4641,18 @@ WorkerPrivate::SetTimeout(JSContext* aCx
     JS_ReportError(aCx, "Useless %s call (missing quotes around argument?)",
                    aIsInterval ? "setInterval" : "setTimeout");
     return false;
   }
 
   // See if any of the optional arguments were passed.
   if (aArgc > 1) {
     double intervalMS = 0;
-    if (!JS_ValueToNumber(aCx, argv[1], &intervalMS)) {
+    JS::RootedValue interval(aCx, argv[1]);
+    if (!JS::ToNumber(aCx, interval, &intervalMS)) {
       return false;
     }
     newInfo->mInterval = TimeDuration::FromMilliseconds(intervalMS);
 
     if (aArgc > 2 && newInfo->mTimeoutVal.isObject()) {
       nsTArray<JS::Heap<JS::Value> > extraArgVals(aArgc - 2);
       for (unsigned index = 2; index < aArgc; index++) {
         extraArgVals.AppendElement(argv[index]);
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -573,16 +573,25 @@ public:
   /**
    * Returns a SourceSurface which is a snapshot of the current contents of the DrawTarget.
    * Multiple calls to Snapshot() without any drawing operations in between will
    * normally return the same SourceSurface object.
    */
   virtual TemporaryRef<SourceSurface> Snapshot() = 0;
   virtual IntSize GetSize() = 0;
 
+  /**
+   * If possible returns the bits to this DrawTarget for direct manipulation. While
+   * the bits is locked any modifications to this DrawTarget is forbidden.
+   * Release takes the original data pointer for safety.
+   */
+  virtual bool LockBits(uint8_t** aData, IntSize* aSize,
+                        int32_t* aStride, SurfaceFormat* aFormat) { return false; }
+  virtual void ReleaseBits(uint8_t* aData) {}
+
   /* Ensure that the DrawTarget backend has flushed all drawing operations to
    * this draw target. This must be called before using the backing surface of
    * this draw target outside of GFX 2D code.
    */
   virtual void Flush() = 0;
 
   /*
    * Draw a surface to the draw target. Possibly doing partial drawing or
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -394,25 +394,27 @@ NeedIntermediateSurface(const Pattern& a
   if (aOptions.mAlpha == 1.0)
     return false;
 
   return true;
 }
 
 DrawTargetCairo::DrawTargetCairo()
   : mContext(nullptr)
+  , mLockedBits(nullptr)
 {
 }
 
 DrawTargetCairo::~DrawTargetCairo()
 {
   cairo_destroy(mContext);
   if (mSurface) {
     cairo_surface_destroy(mSurface);
   }
+  MOZ_ASSERT(!mLockedBits);
 }
 
 IntSize
 DrawTargetCairo::GetSize()
 {
   return mSize;
 }
 
@@ -428,16 +430,41 @@ DrawTargetCairo::Snapshot()
   cairo_content_t content = cairo_surface_get_content(mSurface);
   mSnapshot = new SourceSurfaceCairo(mSurface,
                                      size,
                                      CairoContentToGfxFormat(content),
                                      this);
   return mSnapshot;
 }
 
+bool
+DrawTargetCairo::LockBits(uint8_t** aData, IntSize* aSize,
+                          int32_t* aStride, SurfaceFormat* aFormat)
+{
+  if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
+    WillChange();
+
+    mLockedBits = cairo_image_surface_get_data(mSurface);
+    *aData = mLockedBits;
+    *aSize = GetSize();
+    *aStride = cairo_image_surface_get_stride(mSurface);
+    *aFormat = GetFormat();
+    return true;
+  }
+
+  return false;
+}
+
+void
+DrawTargetCairo::ReleaseBits(uint8_t* aData)
+{
+  MOZ_ASSERT(mLockedBits == aData);
+  mLockedBits = nullptr;
+}
+
 void
 DrawTargetCairo::Flush()
 {
   cairo_surface_t* surf = cairo_get_target(mContext);
   cairo_surface_flush(surf);
 }
 
 void
@@ -1147,16 +1174,17 @@ DrawTargetCairo::MarkSnapshotIndependent
     mSnapshot = nullptr;
   }
 }
 
 void
 DrawTargetCairo::WillChange(const Path* aPath /* = nullptr */)
 {
   MarkSnapshotIndependent();
+  MOZ_ASSERT(!mLockedBits);
 }
 
 void
 DrawTargetCairo::SetTransform(const Matrix& aTransform)
 {
   mTransform = aTransform;
 
   cairo_matrix_t mat;
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -55,16 +55,20 @@ public:
 
   DrawTargetCairo();
   virtual ~DrawTargetCairo();
 
   virtual BackendType GetType() const { return BACKEND_CAIRO; }
   virtual TemporaryRef<SourceSurface> Snapshot();
   virtual IntSize GetSize();
 
+  virtual bool LockBits(uint8_t** aData, IntSize* aSize,
+                        int32_t* aStride, SurfaceFormat* aFormat);
+  virtual void ReleaseBits(uint8_t* aData);
+
   virtual void Flush();
   virtual void DrawSurface(SourceSurface *aSurface,
                            const Rect &aDest,
                            const Rect &aSource,
                            const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
                            const DrawOptions &aOptions = DrawOptions());
   virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
                                      const Point &aDest,
@@ -180,16 +184,18 @@ private: // methods
   // If the current operator is "source" then clear the destination before we
   // draw into it, to simulate the effect of an unbounded source operator.
   void ClearSurfaceForUnboundedSource(const CompositionOp &aOperator);
 private: // data
   cairo_t* mContext;
   cairo_surface_t* mSurface;
   IntSize mSize;
 
+  uint8_t* mLockedBits;
+
   // The latest snapshot of this surface. This needs to be told when this
   // target is modified. We keep it alive as a cache.
   RefPtr<SourceSurfaceCairo> mSnapshot;
   static cairo_surface_t *mDummySurface;
 };
 
 }
 }
new file mode 100644
--- /dev/null
+++ b/gfx/layers/BufferUnrotate.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 20; 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/. */
+
+#include <algorithm> // min & max
+#include <cstdlib>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void BufferUnrotate(uint8_t* aBuffer, int aByteWidth, int aHeight,
+                    int aByteStride, int aXBoundary, int aYBoundary)
+{
+  if (aXBoundary != 0) {
+    uint8_t* line = new uint8_t[aByteWidth];
+    uint32_t smallStart = 0;
+    uint32_t smallLen = aXBoundary;
+    uint32_t smallDest = aByteWidth - aXBoundary;
+    uint32_t largeStart = aXBoundary;
+    uint32_t largeLen = aByteWidth - aXBoundary;
+    uint32_t largeDest = 0;
+    if (aXBoundary > aByteWidth / 2) {
+      smallStart = aXBoundary;
+      smallLen = aByteWidth - aXBoundary;
+      smallDest = 0;
+      largeStart = 0;
+      largeLen = aXBoundary;
+      largeDest = smallLen;
+    }
+
+    for (int y = 0; y < aHeight; y++) {
+      int yOffset = y * aByteStride;
+      memcpy(line, &aBuffer[yOffset + smallStart], smallLen);
+      memmove(&aBuffer[yOffset + largeDest], &aBuffer[yOffset + largeStart], largeLen);
+      memcpy(&aBuffer[yOffset + smallDest], line, smallLen);
+    }
+
+    delete[] line;
+  }
+
+  if (aYBoundary != 0) {
+    uint32_t smallestHeight = std::min(aHeight - aYBoundary, aYBoundary);
+    uint32_t largestHeight = std::max(aHeight - aYBoundary, aYBoundary);
+    uint32_t smallOffset = 0;
+    uint32_t largeOffset = aYBoundary * aByteStride;
+    uint32_t largeDestOffset = 0;
+    uint32_t smallDestOffset = largestHeight * aByteStride;
+    if (aYBoundary > aHeight / 2) {
+      smallOffset = aYBoundary * aByteStride;
+      largeOffset = 0;
+      largeDestOffset = smallestHeight * aByteStride;
+      smallDestOffset = 0;
+    }
+
+    uint8_t* smallestSide = new uint8_t[aByteStride * smallestHeight];
+    memcpy(smallestSide, &aBuffer[smallOffset], aByteStride * smallestHeight);
+    memmove(&aBuffer[largeDestOffset], &aBuffer[largeOffset], aByteStride * largestHeight);
+    memcpy(&aBuffer[smallDestOffset], smallestSide, aByteStride * smallestHeight);
+    delete[] smallestSide;
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/gfx/layers/BufferUnrotate.h
@@ -0,0 +1,14 @@
+/* -*- Mode: C++; tab-width: 20; 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/. */
+
+#ifndef GFX_BUFFERUNROTATE_H
+#define GFX_BUFFERUNROTATE_H
+
+#include "mozilla/Types.h"
+
+void BufferUnrotate(uint8_t* aBuffer, int aByteWidth, int aHeight,
+                    int aByteStride, int aXByteBoundary, int aYBoundary);
+
+#endif // GFX_BUFFERUNROTATE_H
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ThebesLayerBuffer.h"
 #include <sys/types.h>                  // for int32_t
 #include <algorithm>                    // for max
 #include "BasicImplData.h"              // for BasicImplData
 #include "BasicLayersImpl.h"            // for ToData
+#include "BufferUnrotate.h"             // for BufferUnrotate
 #include "GeckoProfiler.h"              // for PROFILER_LABEL
 #include "Layers.h"                     // for ThebesLayer, Layer, etc
 #include "gfxColor.h"                   // for gfxRGBA
 #include "gfxContext.h"                 // for gfxContext, etc
 #include "gfxMatrix.h"                  // for gfxMatrix
 #include "gfxPattern.h"                 // for gfxPattern
 #include "gfxPlatform.h"                // for gfxPlatform
 #include "gfxPoint.h"                   // for gfxPoint
@@ -670,28 +671,64 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
             mBuffer->MovePixels(srcRect, dest);
             if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
               EnsureBufferOnWhite();
               MOZ_ASSERT(mBufferOnWhite);
               mBufferOnWhite->MovePixels(srcRect, dest);
             }
           }
           result.mDidSelfCopy = true;
+          mDidSelfCopy = true;
           // Don't set destBuffer; we special-case self-copies, and
           // just did the necessary work above.
           mBufferRect = destBufferRect;
         } else {
-          // We can't do a real self-copy because the buffer is rotated.
-          // So allocate a new buffer for the destination.
-          destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
-          CreateBuffer(contentType, destBufferRect, bufferFlags,
-                       getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
-                       &destDTBuffer, &destDTBufferOnWhite);
-          if (!destBuffer && !destDTBuffer)
-            return result;
+          // With azure and a data surface perform an buffer unrotate
+          // (SelfCopy).
+          if (IsAzureBuffer()) {
+            unsigned char* data;
+            IntSize size;
+            int32_t stride;
+            SurfaceFormat format;
+
+            if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
+              uint8_t bytesPerPixel = BytesPerPixel(format);
+              BufferUnrotate(data,
+                             size.width * bytesPerPixel,
+                             size.height, stride,
+                             newRotation.x * bytesPerPixel, newRotation.y);
+              mDTBuffer->ReleaseBits(data);
+
+              if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
+                mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
+                uint8_t bytesPerPixel = BytesPerPixel(format);
+                BufferUnrotate(data,
+                               size.width * bytesPerPixel,
+                               size.height, stride,
+                               newRotation.x * bytesPerPixel, newRotation.y);
+                mDTBufferOnWhite->ReleaseBits(data);
+              }
+
+              // Buffer unrotate moves all the pixels, note that
+              // we self copied for SyncBackToFrontBuffer
+              result.mDidSelfCopy = true;
+              mDidSelfCopy = true;
+              mBufferRect = destBufferRect;
+              mBufferRotation = nsIntPoint(0, 0);
+            }
+          }
+
+          if (!result.mDidSelfCopy) {
+            destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
+            CreateBuffer(contentType, destBufferRect, bufferFlags,
+                         getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
+                         &destDTBuffer, &destDTBufferOnWhite);
+            if (!destBuffer && !destDTBuffer)
+              return result;
+          }
         }
       } else {
         mBufferRect = destBufferRect;
         mBufferRotation = newRotation;
       }
     } else {
       // No pixels are going to be kept. The whole visible region
       // will be redrawn, so we don't need to copy anything, so we don't
--- a/gfx/layers/ThebesLayerBuffer.h
+++ b/gfx/layers/ThebesLayerBuffer.h
@@ -141,16 +141,19 @@ protected:
    * is tiled to fill the plane, and the result is clipped to mBufferRect.
    * So the pixel at mBufferRotation within the buffer is what gets painted at
    * mBufferRect.TopLeft().
    * This is "rotation" in the sense of rotating items in a linear buffer,
    * where items falling off the end of the buffer are returned to the
    * buffer at the other end, not 2D rotation!
    */
   nsIntPoint            mBufferRotation;
+  // When this is true it means that all pixels have moved inside the buffer.
+  // It's not possible to sync with another buffer without a full copy.
+  bool                  mDidSelfCopy;
 };
 
 /**
  * This class encapsulates the buffer used to retain ThebesLayer contents,
  * i.e., the contents of the layer's GetVisibleRegion().
  */
 class ThebesLayerBuffer : public RotatedBuffer {
 public:
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -474,31 +474,23 @@ ContentClientDoubleBuffered::SyncFrontBu
                   this,
                   mFrontUpdatedRegion.GetBounds().x,
                   mFrontUpdatedRegion.GetBounds().y,
                   mFrontUpdatedRegion.GetBounds().width,
                   mFrontUpdatedRegion.GetBounds().height));
 
   nsIntRegion updateRegion = mFrontUpdatedRegion;
 
-  int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
-  int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
-
-  // Figure out whether the area we want to copy wraps the edges of our buffer.
-  bool needFullCopy = (xBoundary < updateRegion.GetBounds().XMost() &&
-                       xBoundary > updateRegion.GetBounds().x) ||
-                      (yBoundary < updateRegion.GetBounds().YMost() &&
-                       yBoundary > updateRegion.GetBounds().y);
-  
   // This is a tricky trade off, we're going to get stuff out of our
   // frontbuffer now, but the next PaintThebes might throw it all (or mostly)
   // away if the visible region has changed. This is why in reality we want
   // this code integrated with PaintThebes to always do the optimal thing.
 
-  if (needFullCopy) {
+  if (mDidSelfCopy) {
+    mDidSelfCopy = false;
     // We can't easily draw our front buffer into us, since we're going to be
     // copying stuff around anyway it's easiest if we just move our situation
     // to non-rotated while we're at it. If this situation occurs we'll have
     // hit a self-copy path in PaintThebes before as well anyway.
     mBufferRect.MoveTo(mFrontBufferRect.TopLeft());
     mBufferRotation = nsIntPoint();
     updateRegion = mBufferRect;
   } else {
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -95,17 +95,16 @@ bool
 ImageBridgeParent::RecvUpdateNoSwap(const EditArray& aEdits)
 {
   InfallibleTArray<EditReply> noReplies;
   bool success = RecvUpdate(aEdits, &noReplies);
   NS_ABORT_IF_FALSE(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
   return success;
 }
 
-
 static void
 ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
                                   Transport* aTransport,
                                   ProcessHandle aOtherProcess)
 {
   aBridge->Open(aTransport, aOtherProcess, XRE_GetIOMessageLoop(), ipc::ParentSide);
 }
 
@@ -174,18 +173,16 @@ ImageBridgeParent::AllocPCompositablePar
 }
 
 bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
 {
   delete aActor;
   return true;
 }
 
-
-
 MessageLoop * ImageBridgeParent::GetMessageLoop() {
   return mMessageLoop;
 }
 
 void
 ImageBridgeParent::DeferredDestroy()
 {
   mSelfRef = nullptr;
@@ -193,17 +190,17 @@ ImageBridgeParent::DeferredDestroy()
 }
 
 IToplevelProtocol*
 ImageBridgeParent::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
                                  base::ProcessHandle aPeerProcess,
                                  mozilla::ipc::ProtocolCloneContext* aCtx)
 {
   for (unsigned int i = 0; i < aFds.Length(); i++) {
-    if (aFds[i].protocolId() == (int)GetProtocolId()) {
+    if (aFds[i].protocolId() == unsigned(GetProtocolId())) {
       Transport* transport = OpenDescriptor(aFds[i].fd(),
                                             Transport::MODE_SERVER);
       PImageBridgeParent* bridge = Create(transport, base::GetProcId(aPeerProcess));
       bridge->CloneManagees(this, aCtx);
       bridge->IToplevelProtocol::SetTransport(transport);
       return bridge;
     }
   }
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -189,16 +189,17 @@ CPP_SOURCES += [
     'basic/BasicColorLayer.cpp',
     'basic/BasicCompositor.cpp',
     'basic/BasicContainerLayer.cpp',
     'basic/BasicImageLayer.cpp',
     'basic/BasicImages.cpp',
     'basic/BasicLayerManager.cpp',
     'basic/BasicLayersImpl.cpp',
     'basic/BasicThebesLayer.cpp',
+    'BufferUnrotate.cpp',
     'client/CanvasClient.cpp',
     'composite/CanvasLayerComposite.cpp',
     'opengl/CanvasLayerOGL.cpp',
     'client/ClientCanvasLayer.cpp',
     'client/ClientColorLayer.cpp',
     'client/ClientContainerLayer.cpp',
     'client/ClientImageLayer.cpp',
     'client/ClientLayerManager.cpp',
--- a/gfx/src/nsColor.h
+++ b/gfx/src/nsColor.h
@@ -5,17 +5,16 @@
 
 #ifndef nsColor_h___
 #define nsColor_h___
 
 #include <stddef.h>                     // for size_t
 #include <stdint.h>                     // for uint8_t, uint32_t
 #include "gfxCore.h"                    // for NS_GFX_
 #include "nscore.h"                     // for nsAString
-#include "prtypes.h"                    // for PR_BEGIN_MACRO, etc
 
 class nsAString;
 class nsString;
 class nsCString;
 
 // A color is a 32 bit unsigned integer with four components: R, G, B
 // and A.
 typedef uint32_t nscolor;
new file mode 100644
--- /dev/null
+++ b/gfx/tests/gtest/TestBufferRotation.cpp
@@ -0,0 +1,151 @@
+/* -*- Mode: C++; 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/. */
+
+#include "gtest/gtest.h"
+
+#include "BufferUnrotate.h"
+
+static unsigned char* GenerateBuffer(int bytesPerPixel,
+                                     int width, int height,
+                                     int stride, int xBoundary, int yBoundary)
+{
+  unsigned char* buffer = new unsigned char[stride*height];
+  for (int y = 0; y < height; y++) {
+    for (int x = 0; x < width; x++) {
+     int pos = ((yBoundary + y) % height) * stride +
+       ((xBoundary + x) % width) * bytesPerPixel;
+     for (int i = 0; i < bytesPerPixel; i++) {
+        buffer[pos+i] = (x+y+i*2)%256;
+      }
+    }
+  }
+  return buffer;
+}
+
+static bool CheckBuffer(unsigned char* buffer, int bytesPerPixel,
+                        int width, int height, int stride)
+{
+  int xBoundary = 0;
+  int yBoundary = 0;
+  for (int y = 0; y < height; y++) {
+    for (int x = 0; x < width; x++) {
+     int pos = ((yBoundary + y) % height) * stride +
+       ((xBoundary + x) % width) * bytesPerPixel;
+     for (int i = 0; i < bytesPerPixel; i++) {
+        if (buffer[pos+i] != (x+y+i*2)%256) {
+          printf("Buffer differs at %i, %i, is %i\n", x, y, (int)buffer[pos+i]);
+          return false;
+        }
+      }
+    }
+  }
+  return true;
+}
+
+TEST(Gfx, BufferUnrotateHorizontal) {
+  const int NUM_OF_TESTS = 8;
+  int bytesPerPixelList[2] = {2,4};
+  int width[NUM_OF_TESTS] = {100, 100, 99, 99, 100, 100, 99, 99};
+  int height[NUM_OF_TESTS] = {100, 99, 100, 99, 100, 99, 100, 99};
+  int xBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 31, 31, 31, 31};
+  int yBoundary[NUM_OF_TESTS] = {0, 0, 0, 0};
+
+  for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
+    int bytesPerPixel = bytesPerPixelList[bytesPerId];
+    int stride = 256 * bytesPerPixel;
+    for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
+      unsigned char* buffer = GenerateBuffer(bytesPerPixel,
+          width[testId], height[testId], stride,
+          xBoundary[testId], yBoundary[testId]);
+      BufferUnrotate(buffer,
+          width[testId] * bytesPerPixel, height[testId], stride,
+          xBoundary[testId] * bytesPerPixel, yBoundary[testId]);
+
+      EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel,
+            width[testId], height[testId], stride));
+      delete[] buffer;
+    }
+  }
+}
+
+TEST(Gfx, BufferUnrotateVertical) {
+  const int NUM_OF_TESTS = 8;
+  int bytesPerPixelList[2] = {2,4};
+  int width[NUM_OF_TESTS] = {100, 100, 99, 99, 100, 100, 99, 99};
+  int height[NUM_OF_TESTS] = {100, 99, 100, 99, 100, 99, 100, 99};
+  int xBoundary[NUM_OF_TESTS] = {0, 0, 0, 0};
+  int yBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 31, 31, 31, 31};
+
+  for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
+    int bytesPerPixel = bytesPerPixelList[bytesPerId];
+    int stride = 256 * bytesPerPixel;
+    for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
+      unsigned char* buffer = GenerateBuffer(bytesPerPixel,
+          width[testId], height[testId], stride,
+          xBoundary[testId], yBoundary[testId]);
+      BufferUnrotate(buffer, width[testId] * bytesPerPixel,
+          height[testId], stride,
+          xBoundary[testId] * bytesPerPixel, yBoundary[testId]);
+
+      EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel,
+            width[testId], height[testId], stride));
+      delete[] buffer;
+    }
+  }
+}
+
+
+TEST(Gfx, BufferUnrotateBoth) {
+  const int NUM_OF_TESTS = 16;
+  int bytesPerPixelList[2] = {2,4};
+  int width[NUM_OF_TESTS] = {100, 100, 99, 99, 100, 100, 99, 99, 100, 100, 99, 99, 100, 100, 99, 99};
+  int height[NUM_OF_TESTS] = {100, 99, 100, 99, 100, 99, 100, 99, 100, 99, 100, 99, 100, 99, 100, 99};
+  int xBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 31, 31, 31, 31, 30, 30, 30, 30, 31, 31, 31, 31};
+  int yBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31};
+
+  for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
+    int bytesPerPixel = bytesPerPixelList[bytesPerId];
+    int stride = 256 * bytesPerPixel;
+    for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
+      unsigned char* buffer = GenerateBuffer(bytesPerPixel,
+          width[testId], height[testId], stride,
+          xBoundary[testId], yBoundary[testId]);
+      BufferUnrotate(buffer,
+          width[testId] * bytesPerPixel, height[testId], stride,
+          xBoundary[testId] * bytesPerPixel, yBoundary[testId]);
+
+      EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel,
+            width[testId], height[testId], stride));
+      delete[] buffer;
+    }
+  }
+}
+
+TEST(Gfx, BufferUnrotateUneven) {
+  const int NUM_OF_TESTS = 16;
+  int bytesPerPixelList[2] = {2,4};
+  int width[NUM_OF_TESTS] = {10, 100, 99, 39, 100, 40, 99, 39, 100, 50, 39, 99, 74, 60, 99, 39};
+  int height[NUM_OF_TESTS] = {100, 39, 10, 99, 10, 99, 40, 99, 73, 39, 100, 39, 67, 99, 84, 99};
+  int xBoundary[NUM_OF_TESTS] = {0, 0, 30, 30, 99, 31, 0, 31, 30, 30, 30, 30, 31, 31, 31, 38};
+  int yBoundary[NUM_OF_TESTS] = {30, 30, 0, 30, 0, 30, 0, 30, 31, 31, 31, 31, 31, 31, 31, 98};
+
+  for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
+    int bytesPerPixel = bytesPerPixelList[bytesPerId];
+    int stride = 256 * bytesPerPixel;
+    for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
+      unsigned char* buffer = GenerateBuffer(bytesPerPixel,
+          width[testId], height[testId], stride,
+          xBoundary[testId], yBoundary[testId]);
+      BufferUnrotate(buffer,
+          width[testId]*bytesPerPixel, height[testId], stride,
+          xBoundary[testId]*bytesPerPixel, yBoundary[testId]);
+
+      EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel, width[testId], height[testId], stride));
+      delete[] buffer;
+    }
+  }
+}
+
+
--- a/gfx/tests/gtest/moz.build
+++ b/gfx/tests/gtest/moz.build
@@ -16,16 +16,17 @@ GTEST_CPP_SOURCES += [
     #'gfxTextRunPerfTest.cpp',
     'gfxWordCacheTest.cpp',
     'TestAsyncPanZoomController.cpp',
     'TestLayers.cpp',
     'TestTiledLayerBuffer.cpp',
     'TestRegion.cpp',
     'TestColorNames.cpp',
     'TestTextures.cpp',
+    'TestBufferRotation.cpp',
 ]
 
 # Because of gkmedia on windows we wont find these
 # symbols in xul.dll.
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'windows':
     GTEST_CPP_SOURCES += [
         'TestBase.cpp',
         'TestMoz2D.cpp',
--- a/gfx/thebes/gfxPangoFonts.cpp
+++ b/gfx/thebes/gfxPangoFonts.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "mozilla/Util.h"
 
-#include "prtypes.h"
 #include "prlink.h"
 #include "gfxTypes.h"
 
 #include "nsTArray.h"
 
 #include "gfxContext.h"
 #ifdef MOZ_WIDGET_GTK
 #include "gfxPlatformGtk.h"
--- a/gfx/thebes/gfxScriptItemizer.h
+++ b/gfx/thebes/gfxScriptItemizer.h
@@ -46,17 +46,16 @@
  * All trademarks and registered trademarks mentioned herein are the property
  * of their respective owners. 
  */
 
 #ifndef GFX_SCRIPTITEMIZER_H
 #define GFX_SCRIPTITEMIZER_H
 
 #include <stdint.h>
-#include "prtypes.h"
 #include "nsUnicodeScriptCodes.h"
 
 #define PAREN_STACK_DEPTH 32
 
 class gfxScriptItemizer
 {
 public:
     gfxScriptItemizer(const PRUnichar *src, uint32_t length);
--- a/gfx/thebes/gfxUniscribeShaper.cpp
+++ b/gfx/thebes/gfxUniscribeShaper.cpp
@@ -1,14 +1,13 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "prtypes.h"
 #include "gfxTypes.h"
 
 #include "gfxContext.h"
 #include "gfxUniscribeShaper.h"
 #include "gfxWindowsPlatform.h"
 
 #include "gfxFontTest.h"
 
--- a/gfx/thebes/gfxUniscribeShaper.h
+++ b/gfx/thebes/gfxUniscribeShaper.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 GFX_UNISCRIBESHAPER_H
 #define GFX_UNISCRIBESHAPER_H
 
-#include "prtypes.h"
 #include "gfxTypes.h"
 #include "gfxGDIFont.h"
 
 #include <usp10.h>
 #include <cairo-win32.h>
 
 
 class gfxUniscribeShaper : public gfxFontShaper
--- a/ipc/chromium/src/chrome/common/mach_ipc_mac.mm
+++ b/ipc/chromium/src/chrome/common/mach_ipc_mac.mm
@@ -232,37 +232,41 @@ ReceivePort::~ReceivePort() {
   if (init_result_ == KERN_SUCCESS)
     mach_port_deallocate(mach_task_self(), port_);
 }
 
 //==============================================================================
 kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
                                           mach_msg_timeout_t timeout) {
   if (!out_message) {
+    printf("WaitForMessage failed because out_message was null\n");
     return KERN_INVALID_ARGUMENT;
   }
 
   // return any error condition encountered in constructor
-  if (init_result_ != KERN_SUCCESS)
+  if (init_result_ != KERN_SUCCESS) {
+    printf("WaitForMessage failed because init_result_ was %d\n", init_result_);
     return init_result_;
+  }
 
   out_message->Head()->msgh_bits = 0;
   out_message->Head()->msgh_local_port = port_;
   out_message->Head()->msgh_remote_port = MACH_PORT_NULL;
   out_message->Head()->msgh_reserved = 0;
   out_message->Head()->msgh_id = 0;
 
   kern_return_t result = mach_msg(out_message->Head(),
                                   MACH_RCV_MSG | MACH_RCV_TIMEOUT,
                                   0,
                                   out_message->MaxSize(),
                                   port_,
                                   timeout,              // timeout in ms
                                   MACH_PORT_NULL);
 
+  printf("WaitForMessage returned %d\n", result);
   return result;
 }
 
 #pragma mark -
 
 //==============================================================================
 // get a port with send rights corresponding to a named registered service
 MachPortSender::MachPortSender(const char *receive_port_name) {
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/regexp-clone.js
@@ -0,0 +1,8 @@
+var i=0;
+function f() {
+    assertEq(/^[a-z0-9\.]+$/gi.test("Foo.Bar"), true);
+    i++;
+    if (i < 100)
+	f();
+}
+f();
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -7449,17 +7449,19 @@ GetTemplateObjectForNative(JSContext *cx
         types::TypeObject *type = types::TypeScript::InitObject(cx, script, pc, JSProto_Array);
         if (!type)
             return false;
         res->setType(type);
         return true;
     }
 
     if (native == js::array_concat) {
-        if (args.thisv().isObject() && args.thisv().toObject().is<ArrayObject>()) {
+        if (args.thisv().isObject() && args.thisv().toObject().is<ArrayObject>() &&
+            !args.thisv().toObject().hasSingletonType())
+        {
             res.set(NewDenseEmptyArray(cx, args.thisv().toObject().getProto(), TenuredObject));
             if (!res)
                 return false;
             res->setType(args.thisv().toObject().type());
             return true;
         }
     }
 
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -18,16 +18,17 @@
 #include "jit/BaselineInspector.h"
 #include "jit/ExecutionModeInlines.h"
 #include "jit/Ion.h"
 #include "jit/IonSpewer.h"
 #include "jit/Lowering.h"
 #include "jit/MIRGraph.h"
 
 #include "vm/ArgumentsObject.h"
+#include "vm/RegExpStatics.h"
 
 #include "jsinferinlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "jit/CompileInfo-inl.h"
 
 using namespace js;
@@ -8868,26 +8869,51 @@ IonBuilder::jsop_delelem()
 
 bool
 IonBuilder::jsop_regexp(RegExpObject *reobj)
 {
     JSObject *prototype = script()->global().getOrCreateRegExpPrototype(cx);
     if (!prototype)
         return false;
 
-    MRegExp *regexp = MRegExp::New(reobj, prototype);
+    JS_ASSERT(&reobj->JSObject::global() == &script()->global());
+
+    // JS semantics require regular expression literals to create different
+    // objects every time they execute. We only need to do this cloning if the
+    // script could actually observe the effect of such cloning, for instance
+    // by getting or setting properties on it.
+    //
+    // First, make sure the regex is one we can safely optimize. Lowering can
+    // then check if this regex object only flows into known natives and can
+    // avoid cloning in this case.
+
+    bool mustClone = true;
+    types::TypeObjectKey *typeObj = types::TypeObjectKey::get(&script()->global());
+    if (!typeObj->hasFlags(constraints(), types::OBJECT_FLAG_REGEXP_FLAGS_SET)) {
+        RegExpStatics *res = script()->global().getRegExpStatics();
+
+        DebugOnly<uint32_t> origFlags = reobj->getFlags();
+        DebugOnly<uint32_t> staticsFlags = res->getFlags();
+        JS_ASSERT((origFlags & staticsFlags) == staticsFlags);
+
+        if (!reobj->global() && !reobj->sticky())
+            mustClone = false;
+    }
+
+    MRegExp *regexp = MRegExp::New(reobj, prototype, mustClone);
     current->add(regexp);
     current->push(regexp);
 
     regexp->setMovable();
 
     // The MRegExp is set to be movable.
     // That would be incorrect for global/sticky, because lastIndex could be wrong.
     // Therefore setting the lastIndex to 0. That is faster than removing the movable flag.
     if (reobj->sticky() || reobj->global()) {
+        JS_ASSERT(mustClone);
         MConstant *zero = MConstant::New(Int32Value(0));
         current->add(zero);
 
         MStoreFixedSlot *lastIndex =
             MStoreFixedSlot::New(regexp, RegExpObject::lastIndexSlot(), zero);
         current->add(lastIndex);
     }
 
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -1771,19 +1771,97 @@ LIRGenerator::visitToString(MToString *i
       }
 
       default:
         // Objects might be effectful. (see ToPrimitive)
         MOZ_ASSUME_UNREACHABLE("unexpected type");
     }
 }
 
+static bool
+MustCloneRegExpForCall(MPassArg *arg)
+{
+    // |arg| is a regex literal flowing into a call. Return |false| iff
+    // this is a native call that does not let the regex escape.
+
+    JS_ASSERT(arg->getArgument()->isRegExp());
+
+    for (MUseIterator iter(arg->usesBegin()); iter != arg->usesEnd(); iter++) {
+        MNode *node = iter->consumer();
+        if (!node->isDefinition())
+            return true;
+
+        MDefinition *def = node->toDefinition();
+        if (!def->isCall())
+            return true;
+
+        MCall *call = def->toCall();
+        JSFunction *target = call->getSingleTarget();
+        if (!target || !target->isNative())
+            return true;
+
+        if (iter->index() == MCall::IndexOfThis() &&
+            (target->native() == regexp_exec || target->native() == regexp_test))
+        {
+            continue;
+        }
+
+        if (iter->index() == MCall::IndexOfArgument(0) &&
+            (target->native() == str_split ||
+             target->native() == str_replace ||
+             target->native() == str_match ||
+             target->native() == str_search))
+        {
+            continue;
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+
+static bool
+MustCloneRegExp(MRegExp *regexp)
+{
+    if (regexp->mustClone())
+        return true;
+
+    // If this regex literal only flows into known natives that don't let
+    // it escape, we don't have to clone it.
+
+    for (MUseIterator iter(regexp->usesBegin()); iter != regexp->usesEnd(); iter++) {
+        MNode *node = iter->consumer();
+        if (!node->isDefinition())
+            return true;
+
+        MDefinition *def = node->toDefinition();
+        if (def->isRegExpTest() && iter->index() == 1) {
+            // Optimized RegExp.prototype.test.
+            JS_ASSERT(def->toRegExpTest()->regexp() == regexp);
+            continue;
+        }
+
+        if (def->isPassArg() && !MustCloneRegExpForCall(def->toPassArg()))
+            continue;
+
+        return true;
+    }
+    return false;
+}
+
 bool
 LIRGenerator::visitRegExp(MRegExp *ins)
 {
+    if (!MustCloneRegExp(ins)) {
+        RegExpObject *source = ins->source();
+        return define(new LPointer(source), ins);
+    }
+
     LRegExp *lir = new LRegExp();
     return defineReturn(lir, ins) && assignSafepoint(lir, ins);
 }
 
 bool
 LIRGenerator::visitRegExpTest(MRegExpTest *ins)
 {
     JS_ASSERT(ins->regexp()->type() == MIRType_Object);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1827,16 +1827,23 @@ class MCall
     MDefinition *getArg(uint32_t index) const {
         return getOperand(NumNonArgumentOperands + index);
     }
 
     void replaceArg(uint32_t index, MDefinition *def) {
         replaceOperand(NumNonArgumentOperands + index, def);
     }
 
+    static size_t IndexOfThis() {
+        return NumNonArgumentOperands;
+    }
+    static size_t IndexOfArgument(size_t index) {
+        return NumNonArgumentOperands + index + 1; // +1 to skip |this|.
+    }
+
     // For TI-informed monomorphic callsites.
     JSFunction *getSingleTarget() const {
         return target_;
     }
 
     bool isConstructing() const {
         return construct_;
     }
@@ -4476,34 +4483,39 @@ class MDefFun : public MUnaryInstruction
         return true;
     }
 };
 
 class MRegExp : public MNullaryInstruction
 {
     CompilerRoot<RegExpObject *> source_;
     CompilerRootObject prototype_;
-
-    MRegExp(RegExpObject *source, JSObject *prototype)
+    bool mustClone_;
+
+    MRegExp(RegExpObject *source, JSObject *prototype, bool mustClone)
       : source_(source),
-        prototype_(prototype)
+        prototype_(prototype),
+        mustClone_(mustClone)
     {
         setResultType(MIRType_Object);
 
         JS_ASSERT(source->getProto() == prototype);
         setResultTypeSet(MakeSingletonTypeSet(source));
     }
 
   public:
     INSTRUCTION_HEADER(RegExp)
 
-    static MRegExp *New(RegExpObject *source, JSObject *prototype) {
-        return new MRegExp(source, prototype);
-    }
-
+    static MRegExp *New(RegExpObject *source, JSObject *prototype, bool mustClone) {
+        return new MRegExp(source, prototype, mustClone);
+    }
+
+    bool mustClone() const {
+        return mustClone_;
+    }
     RegExpObject *source() const {
         return source_;
     }
     JSObject *getRegExpPrototype() const {
         return prototype_;
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
--- a/js/src/jit/x64/MacroAssembler-x64.h
+++ b/js/src/jit/x64/MacroAssembler-x64.h
@@ -1054,21 +1054,24 @@ class MacroAssemblerX64 : public MacroAs
     Condition testInt32Truthy(bool truthy, const ValueOperand &operand) {
         testl(operand.valueReg(), operand.valueReg());
         return truthy ? NonZero : Zero;
     }
     void branchTestBooleanTruthy(bool truthy, const ValueOperand &operand, Label *label) {
         testl(operand.valueReg(), operand.valueReg());
         j(truthy ? NonZero : Zero, label);
     }
+    // This returns the tag in ScratchReg.
     Condition testStringTruthy(bool truthy, const ValueOperand &value) {
         unboxString(value, ScratchReg);
 
         Operand lengthAndFlags(ScratchReg, JSString::offsetOfLengthAndFlags());
-        testq(lengthAndFlags, Imm32(-1 << JSString::LENGTH_SHIFT));
+        movq(lengthAndFlags, ScratchReg);
+        shrq(Imm32(JSString::LENGTH_SHIFT), ScratchReg);
+        testq(ScratchReg, ScratchReg);
         return truthy ? Assembler::NonZero : Assembler::Zero;
     }
 
 
     void loadInt32OrDouble(const Operand &operand, const FloatRegister &dest) {
         Label notInt32, end;
         branchTestInt32(Assembler::NotEqual, operand, &notInt32);
         convertInt32ToDouble(operand, dest);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -256,21 +256,21 @@ JS_ConvertArgumentsVA(JSContext *cx, uns
             if (!JS_ValueToECMAUint32(cx, *sp, va_arg(ap, uint32_t *)))
                 return false;
             break;
           case 'j':
             if (!JS_ValueToInt32(cx, *sp, va_arg(ap, int32_t *)))
                 return false;
             break;
           case 'd':
-            if (!JS_ValueToNumber(cx, *sp, va_arg(ap, double *)))
+            if (!ToNumber(cx, arg, va_arg(ap, double *)))
                 return false;
             break;
           case 'I':
-            if (!JS_ValueToNumber(cx, *sp, &d))
+            if (!ToNumber(cx, arg, &d))
                 return false;
             *va_arg(ap, double *) = ToInteger(d);
             break;
           case 'S':
           case 'W':
             val = *sp;
             str = ToString<CanGC>(cx, val);
             if (!str)
@@ -351,17 +351,17 @@ JS_ConvertValue(JSContext *cx, HandleVal
         break;
       case JSTYPE_STRING:
         str = ToString<CanGC>(cx, value);
         ok = (str != nullptr);
         if (ok)
             vp.setString(str);
         break;
       case JSTYPE_NUMBER:
-        ok = JS_ValueToNumber(cx, value, &d);
+        ok = ToNumber(cx, value, &d);
         if (ok)
             vp.setDouble(d);
         break;
       case JSTYPE_BOOLEAN:
         vp.setBoolean(ToBoolean(value));
         return true;
       default: {
         char numBuf[12];
@@ -425,23 +425,16 @@ JS_ValueToSource(JSContext *cx, jsval va
     RootedValue value(cx, valueArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, value);
     return ValueToSource(cx, value);
 }
 
 JS_PUBLIC_API(bool)
-JS_ValueToNumber(JSContext *cx, jsval valueArg, double *dp)
-{
-    RootedValue value(cx, valueArg);
-    return JS::ToNumber(cx, value, dp);
-}
-
-JS_PUBLIC_API(bool)
 JS_DoubleIsInt32(double d, int32_t *ip)
 {
     return mozilla::DoubleIsInt32(d, ip);
 }
 
 JS_PUBLIC_API(int32_t)
 JS_DoubleToInt32(double d)
 {
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1036,19 +1036,16 @@ extern JS_PUBLIC_API(JSFunction *)
 JS_ValueToConstructor(JSContext *cx, JS::HandleValue v);
 
 extern JS_PUBLIC_API(JSString *)
 JS_ValueToString(JSContext *cx, jsval v);
 
 extern JS_PUBLIC_API(JSString *)
 JS_ValueToSource(JSContext *cx, jsval v);
 
-extern JS_PUBLIC_API(bool)
-JS_ValueToNumber(JSContext *cx, jsval v, double *dp);
-
 namespace js {
 /*
  * DO NOT CALL THIS.  Use JS::ToNumber
  */
 extern JS_PUBLIC_API(bool)
 ToNumberSlow(JSContext *cx, JS::Value v, double *dp);
 
 /*
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2829,26 +2829,27 @@ Resolver(JSContext *cx, unsigned argc, j
  */
 static bool
 IsBefore(int64_t t1, int64_t t2)
 {
     return int32_t(t1 - t2) < 0;
 }
 
 static bool
-Sleep_fn(JSContext *cx, unsigned argc, jsval *vp)
+Sleep_fn(JSContext *cx, unsigned argc, Value *vp)
 {
+    CallArgs args = CallArgsFromVp(argc, vp);
     int64_t t_ticks;
 
-    if (argc == 0) {
+    if (args.length() == 0) {
         t_ticks = 0;
     } else {
         double t_secs;
 
-        if (!JS_ValueToNumber(cx, argc == 0 ? UndefinedValue() : vp[2], &t_secs))
+        if (!ToNumber(cx, args[0], &t_secs))
             return false;
 
         /* NB: The next condition also filter out NaNs. */
         if (!(t_secs <= MAX_TIMEOUT_INTERVAL)) {
             JS_ReportError(cx, "Excessive sleep interval");
             return false;
         }
         t_ticks = (t_secs <= 0.0)
@@ -3087,42 +3088,44 @@ SetTimeoutValue(JSContext *cx, double t)
     if (!ScheduleWatchdog(cx->runtime(), t)) {
         JS_ReportError(cx, "Failed to create the watchdog");
         return false;
     }
     return true;
 }
 
 static bool
-Timeout(JSContext *cx, unsigned argc, jsval *vp)
+Timeout(JSContext *cx, unsigned argc, Value *vp)
 {
-    if (argc == 0) {
-        JS_SET_RVAL(cx, vp, JS_NumberValue(gTimeoutInterval));
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (args.length() == 0) {
+        args.rval().setNumber(gTimeoutInterval);
         return true;
     }
 
-    if (argc > 2) {
+    if (args.length() > 2) {
         JS_ReportError(cx, "Wrong number of arguments");
         return false;
     }
 
     double t;
-    if (!JS_ValueToNumber(cx, JS_ARGV(cx, vp)[0], &t))
-        return false;
-
-    if (argc > 1) {
-        RootedValue value(cx, JS_ARGV(cx, vp)[1]);
+    if (!ToNumber(cx, args[0], &t))
+        return false;
+
+    if (args.length() > 1) {
+        RootedValue value(cx, args[1]);
         if (!value.isObject() || !value.toObject().is<JSFunction>()) {
             JS_ReportError(cx, "Second argument must be a timeout function");
             return false;
         }
         gTimeoutFunc = value;
     }
 
-    JS_SET_RVAL(cx, vp, UndefinedValue());
+    args.rval().setUndefined();
     return SetTimeoutValue(cx, t);
 }
 
 static bool
 Elapsed(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (argc == 0) {
         double d = 0.0;
@@ -4187,20 +4190,16 @@ static const JSFunctionSpecWithHelp shel
 "  dis and disfile take these options as preceeding string arguments:\n"
 "    \"-r\" (disassemble recursively)\n"
 "    \"-l\" (show line numbers)"),
 
     JS_FN_HELP("dissrc", DisassWithSrc, 1, 0,
 "dissrc([fun])",
 "  Disassemble functions with source lines."),
 
-    JS_FN_HELP("dumpHeap", DumpHeap, 0, 0,
-"dumpHeap([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])",
-"  Interface to JS_DumpHeap with output sent to file."),
-
     JS_FN_HELP("dumpObject", DumpObject, 1, 0,
 "dumpObject()",
 "  Dump an internal representation of an object."),
 
     JS_FN_HELP("notes", Notes, 1, 0,
 "notes([fun])",
 "  Show source notes for functions."),
 
@@ -4398,16 +4397,22 @@ static const JSFunctionSpecWithHelp shel
 };
 
 static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
     JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0,
 "getSelfHostedValue()",
 "  Get a self-hosted value by its name. Note that these values don't get \n"
 "  cached, so repeatedly getting the same value creates multiple distinct clones."),
 
+#ifdef DEBUG
+    JS_FN_HELP("dumpHeap", DumpHeap, 0, 0,
+"dumpHeap([fileName[, start[, toFind[, maxDepth[, toIgnore]]]]])",
+"  Interface to JS_DumpHeap with output sent to file."),
+#endif
+
     JS_FN_HELP("parent", Parent, 1, 0,
 "parent(obj)",
 "  Returns the parent of obj."),
 
     JS_FN_HELP("line2pc", LineToPC, 0, 0,
 "line2pc([fun,] line)",
 "  Map line number to PC."),
 
--- a/js/xpconnect/src/dictionary_helper_gen.py
+++ b/js/xpconnect/src/dictionary_helper_gen.py
@@ -297,20 +297,20 @@ def write_getter(a, iface, fd):
         fd.write("    NS_ENSURE_STATE(JS_ValueToECMAUint32(aCx, v, &aDict.%s));\n" % a.name)
     elif realtype.count("int32_t"):
         fd.write("    NS_ENSURE_STATE(JS::ToInt32(aCx, v, &aDict.%s));\n" % a.name)
     elif realtype.count("uint64_t"):
         fd.write("    NS_ENSURE_STATE(JS::ToUint64(aCx, v, &aDict.%s));\n" % a.name)
     elif realtype.count("int64_t"):
         fd.write("    NS_ENSURE_STATE(JS::ToInt64(aCx, v, &aDict.%s));\n" % a.name)
     elif realtype.count("double"):
-        fd.write("    NS_ENSURE_STATE(JS_ValueToNumber(aCx, v, &aDict.%s));\n" % a.name)
+        fd.write("    NS_ENSURE_STATE(JS::ToNumber(aCx, v, &aDict.%s));\n" % a.name)
     elif realtype.count("float"):
         fd.write("    double d;\n")
-        fd.write("    NS_ENSURE_STATE(JS_ValueToNumber(aCx, v, &d));")
+        fd.write("    NS_ENSURE_STATE(JS::ToNumber(aCx, v, &d));")
         fd.write("    aDict.%s = (float) d;\n" % a.name)
     elif realtype.count("nsAString"):
         if a.nullable:
             fd.write("    xpc_qsDOMString d(aCx, v, &v, false, xpc_qsDOMString::eNull, xpc_qsDOMString::eNull);\n")
         else:
             fd.write("    xpc_qsDOMString d(aCx, v, &v, false, xpc_qsDOMString::eStringify, xpc_qsDOMString::eStringify);\n")
         fd.write("    NS_ENSURE_STATE(d.IsValid());\n")
         fd.write("    aDict.%s = d;\n" % a.name)
--- a/js/xpconnect/src/qsgen.py
+++ b/js/xpconnect/src/qsgen.py
@@ -418,23 +418,23 @@ argumentUnboxingTemplates = {
 
     'unsigned long long':
         "    uint64_t ${name};\n"
         "    if (!JS::ToUint64(cx, ${argVal}, &${name}))\n"
         "        return false;\n",
 
     'float':
         "    double ${name}_dbl;\n"
-        "    if (!JS_ValueToNumber(cx, ${argVal}, &${name}_dbl))\n"
+        "    if (!JS::ToNumber(cx, ${argVal}, &${name}_dbl))\n"
         "        return false;\n"
         "    float ${name} = (float) ${name}_dbl;\n",
 
     'double':
         "    double ${name};\n"
-        "    if (!JS_ValueToNumber(cx, ${argVal}, &${name}))\n"
+        "    if (!JS::ToNumber(cx, ${argVal}, &${name}))\n"
         "        return false;\n",
 
     'boolean':
         "    bool ${name};\n"
         "    JS_ValueToBoolean(cx, ${argVal}, &${name});\n",
 
     '[astring]':
         "    xpc_qsAString ${name}(cx, ${argVal}, ${argPtr}, ${notPassed});\n"
--- a/layout/reftests/webm-video/reftest.list
+++ b/layout/reftests/webm-video/reftest.list
@@ -26,9 +26,9 @@ skip-if(Android||B2G) == poster-5.html p
 skip-if(Android||B2G) == poster-6.html poster-ref-black140x100.html
 skip-if(Android||B2G) == poster-7.html poster-ref-red140x100.html
 skip-if(Android||B2G) == poster-8.html poster-ref-black140x100.html
 random skip-if(Android||B2G) == poster-10.html poster-ref-blue125x100.html
 random skip-if(Android||B2G) == poster-11.html poster-ref-blue140x100.html
 random skip-if(Android||B2G) == poster-12.html poster-ref-blue140x100.html
 skip-if(Android||B2G) == poster-13.html poster-ref-blue400x300.html
 skip-if(Android||B2G) == poster-15.html poster-ref-green70x30.html
-skip-if(Android||B2G) == bug686957.html bug686957-ref.html
+random-if(cocoaWidget) skip-if(Android||B2G) == bug686957.html bug686957-ref.html # bug 922951 for OS X
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -650,17 +650,17 @@ PeerConnectionImpl::Initialize(PeerConne
   // Invariant: we receive configuration one way or the other but not both (XOR)
   MOZ_ASSERT(!aConfiguration != !aRTCConfiguration);
 #ifdef MOZILLA_INTERNAL_API
   MOZ_ASSERT(NS_IsMainThread());
 #endif
   MOZ_ASSERT(aThread);
   mThread = do_QueryInterface(aThread);
 
-  mPCObserver.Init(&aObserver);
+  mPCObserver.Set(&aObserver);
 
   // Find the STS thread
 
   mSTSThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &res);
   MOZ_ASSERT(mSTSThread);
 
 #ifdef MOZILLA_INTERNAL_API
   // This code interferes with the C++ unit test startup code.
@@ -1378,22 +1378,16 @@ PeerConnectionImpl::Close()
 }
 
 
 nsresult
 PeerConnectionImpl::CloseInt()
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
 
-  // Clear raw pointer to observer since PeerConnection.js does not guarantee
-  // the observer's existence past Close().
-  //
-  // Any outstanding runnables hold RefPtr<> references to observer.
-  mPCObserver.Close();
-
   if (mInternal->mCall) {
     CSFLogInfo(logTag, "%s: Closing PeerConnectionImpl %s; "
                "ending call", __FUNCTION__, mHandle.c_str());
     mInternal->mCall->endCall();
   }
 #ifdef MOZILLA_INTERNAL_API
   if (mDataConnection) {
     CSFLogInfo(logTag, "%s: Destroying DataChannelConnection %p for %s",
@@ -1757,10 +1751,35 @@ PeerConnectionImpl::GetRemoteStreams(nsT
     result.AppendElement(info->GetMediaStream());
   }
   return NS_OK;
 #else
   return NS_ERROR_FAILURE;
 #endif
 }
 
+// WeakConcretePtr gets around WeakPtr not working on concrete types by using
+// the attribute getWeakReferent, a member that supports weak refs, as a guard.
+
+void
+PeerConnectionImpl::WeakConcretePtr::Set(PeerConnectionObserver *aObserver) {
+  mObserver = aObserver;
+#ifdef MOZILLA_INTERNAL_API
+  MOZ_ASSERT(NS_IsMainThread());
+  JSErrorResult rv;
+  nsCOMPtr<nsISupports> tmp = aObserver->GetWeakReferent(rv);
+  MOZ_ASSERT(!rv.Failed());
+  mWeakPtr = do_GetWeakReference(tmp);
+#else
+  mWeakPtr = do_GetWeakReference(aObserver);
+#endif
+}
+
+PeerConnectionObserver *
+PeerConnectionImpl::WeakConcretePtr::MayGet() {
+#ifdef MOZILLA_INTERNAL_API
+  MOZ_ASSERT(NS_IsMainThread());
+#endif
+  nsCOMPtr<nsISupports> guard = do_QueryReferent(mWeakPtr);
+  return (!guard) ? nullptr : mObserver;
+}
 
 }  // end sipcc namespace
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -7,16 +7,19 @@
 
 #include <string>
 #include <vector>
 #include <map>
 #include <cmath>
 
 #include "prlock.h"
 #include "mozilla/RefPtr.h"
+#include "nsWeakPtr.h"
+#include "nsIWeakReferenceUtils.h" // for the definition of nsWeakPtr
+#include "IPeerConnection.h"
 #include "sigslot.h"
 #include "nricectx.h"
 #include "nricemediastream.h"
 #include "nsComponentManagerUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsIThread.h"
 
 #include "mozilla/ErrorResult.h"
@@ -497,39 +500,29 @@ private:
   mozilla::ScopedDeletePtr<Internal> mInternal;
   mozilla::dom::PCImplReadyState mReadyState;
   mozilla::dom::PCImplSignalingState mSignalingState;
 
   // ICE State
   mozilla::dom::PCImplIceState mIceState;
 
   nsCOMPtr<nsIThread> mThread;
-  // We hold a raw pointer to PeerConnectionObserver (no WeakRefs to concretes!)
-  // which is an invariant guaranteed to exist between Initialize() and Close().
-  // We explicitly clear it in Close(). We wrap it in a helper, to encourage
-  // testing against nullptr before use. Use in Runnables requires wrapping
-  // access in RefPtr<> since they may execute after close. This is only safe
-  // to use on the main thread
+  // WeakConcretePtr to PeerConnectionObserver. TODO: Remove after bug 928535
   //
+  // This is only safe to use on the main thread
   // TODO: Remove if we ever properly wire PeerConnection for cycle-collection.
-  class WeakReminder
+  class WeakConcretePtr
   {
   public:
-    WeakReminder() : mObserver(nullptr) {}
-    void Init(PeerConnectionObserver *aObserver) {
-      mObserver = aObserver;
-    }
-    void Close() {
-      mObserver = nullptr;
-    }
-    PeerConnectionObserver *MayGet() {
-      return mObserver;
-    }
+    WeakConcretePtr() : mObserver(nullptr) {}
+    void Set(PeerConnectionObserver *aObserver);
+    PeerConnectionObserver *MayGet();
   private:
     PeerConnectionObserver *mObserver;
+    nsWeakPtr mWeakPtr;
   } mPCObserver;
   nsCOMPtr<nsPIDOMWindow> mWindow;
 
   // The SDP sent in from JS - here for debugging.
   std::string mLocalRequestedSDP;
   std::string mRemoteRequestedSDP;
   // The SDP we are using.
   std::string mLocalSDP;
--- a/media/webrtc/signaling/test/FakePCObserver.h
+++ b/media/webrtc/signaling/test/FakePCObserver.h
@@ -16,28 +16,29 @@
 #include "MediaSegment.h"
 #include "StreamBuffer.h"
 #include "nsTArray.h"
 #include "nsIRunnable.h"
 #include "nsISupportsImpl.h"
 #include "nsIDOMMediaStream.h"
 #include "mozilla/dom/PeerConnectionObserverEnumsBinding.h"
 #include "PeerConnectionImpl.h"
+#include "nsWeakReference.h"
 
 namespace sipcc {
 class PeerConnectionImpl;
 }
 
 class nsIDOMWindow;
 class nsIDOMDataChannel;
 
 namespace test {
 using namespace mozilla::dom;
 
-class AFakePCObserver : public nsISupports
+class AFakePCObserver : public nsSupportsWeakReference
 {
 protected:
   typedef mozilla::ErrorResult ER;
 public:
   enum Action {
     OFFER,
     ANSWER
   };
--- a/media/webrtc/signaling/test/signaling_unittests.cpp
+++ b/media/webrtc/signaling/test/signaling_unittests.cpp
@@ -268,17 +268,17 @@ public:
   NS_IMETHODIMP OnRemoveStream(ER&);
   NS_IMETHODIMP OnAddTrack(ER&);
   NS_IMETHODIMP OnRemoveTrack(ER&);
   NS_IMETHODIMP OnAddIceCandidateSuccess(ER&);
   NS_IMETHODIMP OnAddIceCandidateError(uint32_t code, const char *msg, ER&);
   NS_IMETHODIMP OnIceCandidate(uint16_t level, const char *mid, const char *cand, ER&);
 };
 
-NS_IMPL_ISUPPORTS0(TestObserver)
+NS_IMPL_ISUPPORTS1(TestObserver, nsISupportsWeakReference)
 
 NS_IMETHODIMP
 TestObserver::OnCreateOfferSuccess(const char* offer, ER&)
 {
   lastString = strdup(offer);
   state = stateSuccess;
   std::cout << name << ": onCreateOfferSuccess = " << std::endl << indent(offer)
             << std::endl;
--- a/mfbt/Char16.h
+++ b/mfbt/Char16.h
@@ -17,17 +17,17 @@
  */
 
 #ifdef _MSC_VER
    /*
     * C++11 says char16_t is a distinct builtin type, but Windows's yvals.h
     * typedefs char16_t as an unsigned short. We would like to alias char16_t
     * to Windows's 16-bit wchar_t so we can declare UTF-16 literals as constant
     * expressions (and pass char16_t pointers to Windows APIs). We #define
-    * _CHAR16T here in order to prevent yvals.h to override our char16_t
+    * _CHAR16T here in order to prevent yvals.h from overriding our char16_t
     * typedefs, which we set to wchar_t for C++ code and to unsigned short for
     * C code.
     *
     * In addition, #defining _CHAR16T will prevent yvals.h from defining a
     * char32_t type, so we have to undo that damage here and provide our own,
     * which is identical to the yvals.h type.
     */
 #  define MOZ_UTF16_HELPER(s) L##s
--- a/netwerk/base/src/nsIncrementalDownload.cpp
+++ b/netwerk/base/src/nsIncrementalDownload.cpp
@@ -151,32 +151,35 @@ private:
   uint32_t                                 mLoadFlags;
   int32_t                                  mNonPartialCount;
   nsresult                                 mStatus;
   bool                                     mIsPending;
   bool                                     mDidOnStartRequest;
   PRTime                                   mLastProgressUpdate;
   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
   nsCOMPtr<nsIChannel>                     mNewRedirectChannel;
+  nsCString                                mPartialValidator;
+  bool                                     mCacheBust;
 };
 
 nsIncrementalDownload::nsIncrementalDownload()
   : mChunkLen(0)
   , mChunkSize(DEFAULT_CHUNK_SIZE)
   , mInterval(DEFAULT_INTERVAL)
   , mTotalSize(-1)
   , mCurrentSize(-1)
   , mLoadFlags(LOAD_NORMAL)
   , mNonPartialCount(0)
   , mStatus(NS_OK)
   , mIsPending(false)
   , mDidOnStartRequest(false)
   , mLastProgressUpdate(0)
   , mRedirectCallback(nullptr)
   , mNewRedirectChannel(nullptr)
+  , mCacheBust(false)  
 {
 }
 
 nsresult
 nsIncrementalDownload::FlushChunk()
 {
   NS_ASSERTION(mTotalSize != int64_t(-1), "total size should be known");
 
@@ -277,16 +280,27 @@ nsIncrementalDownload::ProcessTimeout()
   // entire document.
   if (mInterval || mCurrentSize != int64_t(0)) {
     nsAutoCString range;
     MakeRangeSpec(mCurrentSize, mTotalSize, mChunkSize, mInterval == 0, range);
 
     rv = http->SetRequestHeader(NS_LITERAL_CSTRING("Range"), range, false);
     if (NS_FAILED(rv))
       return rv;
+
+    if (!mPartialValidator.IsEmpty())
+      http->SetRequestHeader(NS_LITERAL_CSTRING("If-Range"),
+                             mPartialValidator, false);
+
+    if (mCacheBust) {
+      http->SetRequestHeader(NS_LITERAL_CSTRING("Cache-Control"),
+                             NS_LITERAL_CSTRING("no-cache"), false);
+      http->SetRequestHeader(NS_LITERAL_CSTRING("Pragma"),
+                             NS_LITERAL_CSTRING("no-cache"), false);
+    }
   }
 
   rv = channel->AsyncOpen(this, nullptr);
   if (NS_FAILED(rv))
     return rv;
 
   // Wait to assign mChannel when we know we are going to succeed.  This is
   // important because we don't want to introduce a reference cycle between
@@ -560,24 +574,88 @@ nsIncrementalDownload::OnStartRequest(ns
     } else {
       NS_WARNING("server response was unexpected");
       return NS_ERROR_UNEXPECTED;
     }
   } else {
     // We got a partial response, so clear this counter in case the next chunk
     // results in a 200 response.
     mNonPartialCount = 0;
+
+    // confirm that the content-range response header is consistent with
+    // expectations on each 206. If it is not then drop this response and
+    // retry with no-cache set.
+    if (!mCacheBust) {
+      nsAutoCString buf;
+      int64_t startByte = 0;
+      bool confirmedOK = false;
+
+      rv = http->GetResponseHeader(NS_LITERAL_CSTRING("Content-Range"), buf);
+      if (NS_FAILED(rv))
+        return rv; // it isn't a useful 206 without a CONTENT-RANGE of some sort
+
+      // Content-Range: bytes 0-299999/25604694
+      int32_t p = buf.Find("bytes ");
+
+      // first look for the starting point of the content-range
+      // to make sure it is what we expect
+      if (p != -1) {
+        char *endptr = nullptr;
+        const char *s = buf.get() + p + 6;
+        while (*s && *s == ' ')
+          s++;
+        startByte = strtol(s, &endptr, 10);
+
+        if (*s && endptr && (endptr != s) &&
+            (mCurrentSize == startByte)) {
+
+          // ok the starting point is confirmed. We still need to check the
+          // total size of the range for consistency if this isn't
+          // the first chunk
+          if (mTotalSize == int64_t(-1)) {
+            // first chunk
+            confirmedOK = true;
+          } else {
+            int32_t slash = buf.FindChar('/');
+            int64_t rangeSize = 0;
+            if (slash != kNotFound &&
+                (PR_sscanf(buf.get() + slash + 1, "%lld", (int64_t *) &rangeSize) == 1) &&
+                rangeSize == mTotalSize) {
+              confirmedOK = true;
+            }
+          }
+        }
+      }
+
+      if (!confirmedOK) {
+        NS_WARNING("unexpected content-range");
+        mCacheBust = true;
+        mChannel = nullptr;
+        if (++mNonPartialCount > MAX_RETRY_COUNT) {
+          NS_WARNING("unable to fetch a byte range; giving up");
+          return NS_ERROR_FAILURE;
+        }
+        // Increase delay with each failure.
+        StartTimer(mInterval * mNonPartialCount);
+        return NS_ERROR_DOWNLOAD_NOT_PARTIAL;
+      }
+    }
   }
 
   // Do special processing after the first response.
   if (mTotalSize == int64_t(-1)) {
     // Update knowledge of mFinalURI
     rv = http->GetURI(getter_AddRefs(mFinalURI));
     if (NS_FAILED(rv))
       return rv;
+    http->GetResponseHeader(NS_LITERAL_CSTRING("Etag"), mPartialValidator);
+    if (StringBeginsWith(mPartialValidator, NS_LITERAL_CSTRING("W/")))
+      mPartialValidator.Truncate(); // don't use weak validators
+    if (mPartialValidator.IsEmpty())
+      http->GetResponseHeader(NS_LITERAL_CSTRING("Last-Modified"), mPartialValidator);
 
     if (code == 206) {
       // OK, read the Content-Range header to determine the total size of this
       // download file.
       nsAutoCString buf;
       rv = http->GetResponseHeader(NS_LITERAL_CSTRING("Content-Range"), buf);
       if (NS_FAILED(rv))
         return rv;
@@ -773,16 +851,26 @@ nsIncrementalDownload::AsyncOnChannelRed
   // If we didn't have a Range header, then we must be doing a full download.
   nsAutoCString rangeVal;
   http->GetRequestHeader(rangeHdr, rangeVal);
   if (!rangeVal.IsEmpty()) {
     rv = newHttpChannel->SetRequestHeader(rangeHdr, rangeVal, false);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
+  // A redirection changes the validator
+  mPartialValidator.Truncate();
+
+  if (mCacheBust) {
+    newHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Cache-Control"),
+                                     NS_LITERAL_CSTRING("no-cache"), false);
+    newHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Pragma"),
+                                     NS_LITERAL_CSTRING("no-cache"), false);
+  }
+
   // Prepare to receive callback
   mRedirectCallback = cb;
   mNewRedirectChannel = newChannel;
 
   // Give the observer a chance to see this redirect notification.
   nsCOMPtr<nsIChannelEventSink> sink = do_GetInterface(mObserver);
   if (sink) {
     rv = sink->AsyncOnChannelRedirect(oldChannel, newChannel, flags, this);
--- a/parser/html/nsHtml5ArrayCopy.h
+++ b/parser/html/nsHtml5ArrayCopy.h
@@ -18,17 +18,16 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  */
 
 #ifndef nsHtml5ArrayCopy_h
 #define nsHtml5ArrayCopy_h
 
-#include "prtypes.h"
 
 class nsString;
 class nsHtml5StackNode;
 class nsHtml5AttributeName;
 
 // Unfortunately, these don't work as template functions because the arguments
 // would need coercion from a template class, which complicates things.
 class nsHtml5ArrayCopy {
--- a/parser/html/nsHtml5Highlighter.h
+++ b/parser/html/nsHtml5Highlighter.h
@@ -1,15 +1,14 @@
 /* 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 nsHtml5Highlighter_h
 #define nsHtml5Highlighter_h
 
-#include "prtypes.h"
 #include "nsCOMPtr.h"
 #include "nsHtml5TreeOperation.h"
 #include "nsHtml5UTF16Buffer.h"
 #include "nsHtml5TreeOperation.h"
 #include "nsAHtml5TreeOpSink.h"
 
 #define NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH 512
 
--- a/parser/html/nsHtml5NamedCharacters.cpp
+++ b/parser/html/nsHtml5NamedCharacters.cpp
@@ -16,17 +16,16 @@
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
  * DEALINGS IN THE SOFTWARE.
  */
 
 #define nsHtml5NamedCharacters_cpp_
-#include "prtypes.h"
 #include "jArray.h"
 #include "nscore.h"
 #include "nsDebug.h"
 #include "prlog.h"
 #include "nsMemory.h"
 
 #include "nsHtml5NamedCharacters.h"
 
--- a/parser/html/nsHtml5NamedCharacters.h
+++ b/parser/html/nsHtml5NamedCharacters.h
@@ -18,17 +18,16 @@
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
  * DEALINGS IN THE SOFTWARE.
  */
 
 #ifndef nsHtml5NamedCharacters_h
 #define nsHtml5NamedCharacters_h
 
-#include "prtypes.h"
 #include "jArray.h"
 #include "nscore.h"
 #include "nsDebug.h"
 #include "prlog.h"
 #include "nsMemory.h"
 
 struct nsHtml5CharacterName {
   uint16_t nameStart;
--- a/parser/html/nsHtml5NamedCharactersAccel.h
+++ b/parser/html/nsHtml5NamedCharactersAccel.h
@@ -4,17 +4,16 @@
  * 
  * You are granted a license to use, reproduce and create derivative works of 
  * this document.
  */
 
 #ifndef nsHtml5NamedCharactersAccel_h
 #define nsHtml5NamedCharactersAccel_h
 
-#include "prtypes.h"
 #include "jArray.h"
 #include "nscore.h"
 #include "nsDebug.h"
 #include "prlog.h"
 #include "nsMemory.h"
 
 class nsHtml5NamedCharactersAccel
 {
--- a/parser/html/nsHtml5Portability.cpp
+++ b/parser/html/nsHtml5Portability.cpp
@@ -1,13 +1,12 @@
 /* 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 "prtypes.h"
 #include "nsIAtom.h"
 #include "nsString.h"
 #include "jArray.h"
 #include "nsHtml5Portability.h"
 
 nsIAtom*
 nsHtml5Portability::newLocalNameFromBuffer(PRUnichar* buf, int32_t offset, int32_t length, nsHtml5AtomTable* interner)
 {
--- a/parser/htmlparser/src/nsHTMLEntities.cpp
+++ b/parser/htmlparser/src/nsHTMLEntities.cpp
@@ -6,17 +6,16 @@
 #include "mozilla/Util.h"
 
 #include "nsHTMLEntities.h"
 
 
 
 #include "nsString.h"
 #include "nsCRT.h"
-#include "prtypes.h"
 #include "pldhash.h"
 
 using namespace mozilla;
 
 struct EntityNode {
   const char* mStr; // never owns buffer
   int32_t       mUnicode;
 };
--- a/parser/htmlparser/src/nsScanner.h
+++ b/parser/htmlparser/src/nsScanner.h
@@ -17,17 +17,16 @@
 
 
 #ifndef SCANNER
 #define SCANNER
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIParser.h"
-#include "prtypes.h"
 #include "nsIUnicodeDecoder.h"
 #include "nsScannerString.h"
 
 class nsParser;
 
 class nsReadEndCondition {
 public:
   const PRUnichar *mChars;
--- a/rdf/base/src/rdfutil.h
+++ b/rdf/base/src/rdfutil.h
@@ -17,17 +17,16 @@
   2) All that's left is rdf_PossiblyMakeRelative() and
      -Absolute(). Maybe those go on nsIRDFService, too.
 
  */
 
 #ifndef rdfutil_h__
 #define rdfutil_h__
 
-#include "prtypes.h"
 
 class nsACString;
 class nsCString;
 class nsString;
 class nsIURI;
 
 nsresult
 rdf_MakeRelativeRef(const nsCSubstring& aBaseURI, nsCString& aURI);
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "prio.h"
-#include "prtypes.h"
 #include "pldhash.h"
 #include "nsXPCOMStrings.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/scache/StartupCache.h"
 
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
 #include "nsComponentManagerUtils.h"
--- a/testing/mochitest/ssltunnel/ssltunnel.cpp
+++ b/testing/mochitest/ssltunnel/ssltunnel.cpp
@@ -19,17 +19,16 @@
 #include <vector>
 #include <algorithm>
 #include <stdarg.h>
 #include "prinit.h"
 #include "prerror.h"
 #include "prenv.h"
 #include "prnetdb.h"
 #include "prtpool.h"
-#include "prtypes.h"
 #include "nsAlgorithm.h"
 #include "nss.h"
 #include "key.h"
 #include "ssl.h"
 #include "plhash.h"
 
 using namespace mozilla;
 using namespace mozilla::psm;
--- a/toolkit/components/ctypes/tests/jsctypes-test-errno.h
+++ b/toolkit/components/ctypes/tests/jsctypes-test-errno.h
@@ -1,15 +1,14 @@
 /* -*-  Mode: C++; 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/. */
 
 #include "nscore.h"
-#include "prtypes.h"
 
 #define EXPORT_CDECL(type)   NS_EXPORT type
 #define EXPORT_STDCALL(type) NS_EXPORT type NS_STDCALL
 
 NS_EXTERN_C
 {
   EXPORT_CDECL(void) set_errno(int status);
   EXPORT_CDECL(int) get_errno();
--- a/toolkit/components/ctypes/tests/jsctypes-test.h
+++ b/toolkit/components/ctypes/tests/jsctypes-test.h
@@ -1,15 +1,14 @@
 /* -*-  Mode: C++; 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/. */
 
 #include "nscore.h"
-#include "prtypes.h"
 #include "jspubtd.h"
 
 #define EXPORT_CDECL(type)   NS_EXPORT type
 #define EXPORT_STDCALL(type) NS_EXPORT type NS_STDCALL
 
 NS_EXTERN_C
 {
   EXPORT_CDECL(void) test_void_t_cdecl();
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -390,17 +390,17 @@ GetIntFromJSObject(JSContext* aCtx,
   NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
   if (JSVAL_IS_VOID(value)) {
     return NS_ERROR_INVALID_ARG;
   }
   NS_ENSURE_ARG(JSVAL_IS_PRIMITIVE(value));
   NS_ENSURE_ARG(JSVAL_IS_NUMBER(value));
 
   double num;
-  rc = JS_ValueToNumber(aCtx, value, &num);
+  rc = JS::ToNumber(aCtx, value, &num);
   NS_ENSURE_TRUE(rc, NS_ERROR_UNEXPECTED);
   NS_ENSURE_ARG(IntType(num) == num);
 
   *_int = IntType(num);
   return NS_OK;
 }
 
 /**
--- a/toolkit/components/places/nsPlacesMacros.h
+++ b/toolkit/components/places/nsPlacesMacros.h
@@ -1,14 +1,13 @@
 /* -*- Mode: C++; tab-width: 8; 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/. */
 
-#include "prtypes.h"
 #include "nsIConsoleService.h"
 #include "nsIScriptError.h"
 
 #ifndef __FUNCTION__
 #define __FUNCTION__ __func__
 #endif
 
 // Call a method on each observer in a category cache, then call the same
--- a/xpcom/base/nsMemoryImpl.cpp
+++ b/xpcom/base/nsMemoryImpl.cpp
@@ -69,17 +69,17 @@ nsMemoryImpl::IsLowMemoryPlatform(bool *
         *result = false;
 
         // check if MemTotal from /proc/meminfo is less than LOW_MEMORY_THRESHOLD_KB
         FILE* fd = fopen("/proc/meminfo", "r");
         if (!fd) {
             return NS_OK;
         }
         uint64_t mem = 0;
-        int rv = fscanf(fd, "MemTotal: %lu kB", &mem);
+        int rv = fscanf(fd, "MemTotal: %llu kB", &mem);
         if (fclose(fd)) {
             return NS_OK;
         }
         if (rv != 1) {
             return NS_OK;
         }
         sLowMemory = (mem < LOW_MEMORY_THRESHOLD_KB) ? 1 : 0;
     }
--- a/xpcom/glue/MainThreadUtils.h
+++ b/xpcom/glue/MainThreadUtils.h
@@ -24,24 +24,24 @@ NS_GetMainThread(nsIThread **result);
 #if defined(MOZILLA_INTERNAL_API) && defined(XP_WIN)
 bool NS_IsMainThread();
 #elif defined(MOZILLA_INTERNAL_API) && defined(NS_TLS)
 // This is defined in nsThreadManager.cpp and initialized to `Main` for the
 // main thread by nsThreadManager::Init.
 extern NS_TLS mozilla::threads::ID gTLSThreadID;
 #ifdef MOZ_ASAN
 // Temporary workaround, see bug 895845
-MOZ_ASAN_BLACKLIST static
+MOZ_ASAN_BLACKLIST bool NS_IsMainThread();
 #else
 inline
-#endif
 bool NS_IsMainThread()
 {
   return gTLSThreadID == mozilla::threads::Main;
 }
+#endif
 #else
 /**
  * Test to see if the current thread is the main thread.
  *
  * @returns true if the current thread is the main thread, and false
  * otherwise.
  */
 extern NS_COM_GLUE bool NS_IsMainThread();
--- a/xpcom/glue/nsTextFormatter.h
+++ b/xpcom/glue/nsTextFormatter.h
@@ -24,17 +24,16 @@
  **	%lld, %llu, %llx, %llX, %llo - 64 bit versions of above
  **	%s - utf8 string
  **	%S - PRUnichar string
  **	%c - character
  **	%p - pointer (deals with machine dependent pointer size)
  **	%f - float
  **	%g - float
  */
-#include "prtypes.h"
 #include "prio.h"
 #include <stdio.h>
 #include <stdarg.h>
 #include "nscore.h"
 #include "nsStringGlue.h"
 
 #ifdef XPCOM_GLUE
 #error "nsTextFormatter is not available in the standalone glue due to NSPR dependencies."
--- a/xpcom/glue/nsThreadUtils.cpp
+++ b/xpcom/glue/nsThreadUtils.cpp
@@ -109,40 +109,52 @@ NS_GetMainThread(nsIThread **result)
   nsresult rv;
   nsCOMPtr<nsIThreadManager> mgr =
       do_GetService(NS_THREADMANAGER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
   return mgr->GetMainThread(result);
 #endif
 }
 
-#ifndef MOZILLA_INTERNAL_API
+#if defined(MOZILLA_INTERNAL_API) && defined(XP_WIN)
+extern DWORD gTLSThreadIDIndex;
+bool
+NS_IsMainThread()
+{
+  return TlsGetValue(gTLSThreadIDIndex) == (void*) mozilla::threads::Main;
+}
+#elif defined(MOZILLA_INTERNAL_API) && defined(NS_TLS)
+#ifdef MOZ_ASAN
+// Temporary workaround, see bug 895845
+bool NS_IsMainThread()
+{
+  return gTLSThreadID == mozilla::threads::Main;
+}
+#else
+// NS_IsMainThread() is defined inline in MainThreadUtils.h
+#endif
+#else
+#ifdef MOZILLA_INTERNAL_API
+bool NS_IsMainThread()
+{
+  bool result = false;
+  nsThreadManager::get()->nsThreadManager::GetIsMainThread(&result);
+  return bool(result);
+}
+#else
 bool NS_IsMainThread()
 {
   bool result = false;
   nsCOMPtr<nsIThreadManager> mgr =
     do_GetService(NS_THREADMANAGER_CONTRACTID);
   if (mgr)
     mgr->GetIsMainThread(&result);
   return bool(result);
 }
-#elif defined(XP_WIN)
-extern DWORD gTLSThreadIDIndex;
-bool
-NS_IsMainThread()
-{
-  return TlsGetValue(gTLSThreadIDIndex) == (void*) mozilla::threads::Main;
-}
-#elif !defined(NS_TLS)
-bool NS_IsMainThread()
-{
-  bool result = false;
-  nsThreadManager::get()->nsThreadManager::GetIsMainThread(&result);
-  return bool(result);
-}
+#endif
 #endif
 
 NS_METHOD
 NS_DispatchToCurrentThread(nsIRunnable *event)
 {
 #ifdef MOZILLA_INTERNAL_API
   nsIThread *thread = NS_GetCurrentThread();
   if (!thread) { return NS_ERROR_UNEXPECTED; }
--- a/xpcom/io/nsEscape.h
+++ b/xpcom/io/nsEscape.h
@@ -3,17 +3,16 @@
  * 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/. */
 
 /*	First checked in on 98/12/03 by John R. McMullen, derived from net.h/mkparse.c. */
 
 #ifndef _ESCAPE_H_
 #define _ESCAPE_H_
 
-#include "prtypes.h"
 #include "nscore.h"
 #include "nsError.h"
 #include "nsString.h"
 
 /**
  * Valid mask values for nsEscape
  * Note: these values are copied in nsINetUtil.idl. Any changes should be kept
  * in sync.
--- a/xpcom/io/nsWildCard.h
+++ b/xpcom/io/nsWildCard.h
@@ -15,17 +15,16 @@
  * features and interactions this code must support, the easier it is to
  * ensure it works.
  *
  */
 
 #ifndef nsWildCard_h__
 #define nsWildCard_h__
 
-#include "prtypes.h"
 #include "nscore.h"
 
 /* --------------------------- Public routines ---------------------------- */
 
 
 /*
  * NS_WildCardValid takes a shell expression exp as input. It returns:
  *
--- a/xpcom/tests/TestPRIntN.cpp
+++ b/xpcom/tests/TestPRIntN.cpp
@@ -1,14 +1,13 @@
 /* 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 <stdint.h>
- 
 #include "prtypes.h"
 
 // This test is NOT intended to be run.  It's a test to make sure
 // PRInt{N} matches int{N}_t. If they don't match, we should get a
 // compiler warning or error in main().
 
 static void
 ClearNSPRIntTypes(PRInt8 *a, PRInt16 *b, PRInt32 *c, PRInt64 *d)
--- a/xpcom/threads/nsProcessCommon.cpp
+++ b/xpcom/threads/nsProcessCommon.cpp
@@ -12,17 +12,16 @@
  */
 
 #include "mozilla/Util.h"
 
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsMemory.h"
 #include "nsProcess.h"
-#include "prtypes.h"
 #include "prio.h"
 #include "prenv.h"
 #include "nsCRT.h"
 #include "nsThreadUtils.h"
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 
 #include <stdlib.h>
--- a/xulrunner/stub/nsXULStub.cpp
+++ b/xulrunner/stub/nsXULStub.cpp
@@ -1,15 +1,14 @@
 /* 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 "nsXPCOMGlue.h"
 #include "nsINIParser.h"
-#include "prtypes.h"
 #include "nsXPCOMPrivate.h" // for XP MAXPATHLEN
 #include "nsMemory.h" // for NS_ARRAY_LENGTH
 #include "nsXULAppAPI.h"
 #include "nsIFile.h"
 
 #include <stdarg.h>
 
 #ifdef XP_WIN