merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 05 Oct 2016 15:42:48 +0200
changeset 359425 e8fa13708c070d1fadf488ed9d951464745b4e17
parent 359361 cb48a92d0427b50fd18801f9a7f6607b46a7d38a (current diff)
parent 359424 7cedca0e724800f47dc7d0b3ed31683f18829537 (diff)
child 359426 c7d62e6d052c5d2638b08d480a720254ea09ff2d
child 359466 f6c226e793e4bc00c5afe358c860b7e5cd24517f
child 359515 4f41a594f88d17e25bbfd362f2e45e6dc891bfc6
child 359549 c52dec387187a918627d39b733dff7314b2f7c52
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
merge mozilla-inbound to mozilla-central a=merge
js/src/old-configure.in
moz.configure
--- a/accessible/base/EventTree.cpp
+++ b/accessible/base/EventTree.cpp
@@ -389,16 +389,17 @@ void
 EventTree::Clear()
 {
   mFirst = nullptr;
   mNext = nullptr;
   mContainer = nullptr;
 
   uint32_t eventsCount = mDependentEvents.Length();
   for (uint32_t jdx = 0; jdx < eventsCount; jdx++) {
+    mDependentEvents[jdx]->mEventType = AccEvent::eDoNotEmit;
     AccHideEvent* ev = downcast_accEvent(mDependentEvents[jdx]);
     if (ev && ev->NeedsShutdown()) {
       ev->Document()->ShutdownChildrenInSubtree(ev->mAccessible);
     }
   }
   mDependentEvents.Clear();
 }
 
--- a/accessible/ipc/other/PDocAccessible.ipdl
+++ b/accessible/ipc/other/PDocAccessible.ipdl
@@ -38,17 +38,17 @@ struct Attribute
 };
 
 struct RelationTargets
 {
   uint32_t Type;
   uint64_t[] Targets;
 };
 
-prio(normal upto high) sync protocol PDocAccessible
+nested(upto inside_sync) sync protocol PDocAccessible
 {
   manager PBrowser;
 
 parent:
   async Shutdown();
 
   /*
    * Notify the parent process the document in the child process is firing an
@@ -69,193 +69,193 @@ parent:
    * document.
    */
   async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
 
 child:
   async __delete__();
 
   // Accessible
-  prio(high) sync State(uint64_t aID) returns(uint64_t states);
-  prio(high) sync NativeState(uint64_t aID) returns(uint64_t states);
-  prio(high) sync Name(uint64_t aID) returns(nsString name);
-  prio(high) sync Value(uint64_t aID) returns(nsString value);
-  prio(high) sync Help(uint64_t aID) returns(nsString help);
-  prio(high) sync Description(uint64_t aID) returns(nsString desc);
-  prio(high) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
-  prio(high) sync RelationByType(uint64_t aID, uint32_t aRelationType)
+  nested(inside_sync) sync State(uint64_t aID) returns(uint64_t states);
+  nested(inside_sync) sync NativeState(uint64_t aID) returns(uint64_t states);
+  nested(inside_sync) sync Name(uint64_t aID) returns(nsString name);
+  nested(inside_sync) sync Value(uint64_t aID) returns(nsString value);
+  nested(inside_sync) sync Help(uint64_t aID) returns(nsString help);
+  nested(inside_sync) sync Description(uint64_t aID) returns(nsString desc);
+  nested(inside_sync) sync Attributes(uint64_t aID) returns(Attribute[] attributes);
+  nested(inside_sync) sync RelationByType(uint64_t aID, uint32_t aRelationType)
     returns(uint64_t[] targets);
-  prio(high) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
-  prio(high) sync IsSearchbox(uint64_t aID) returns(bool retval);
-  prio(high) sync LandmarkRole(uint64_t aID) returns(nsString landmark);
-  prio(high) sync ARIARoleAtom(uint64_t aID) returns(nsString role);
-  prio(high) sync GetLevelInternal(uint64_t aID) returns(int32_t aLevel);
+  nested(inside_sync) sync Relations(uint64_t aID) returns(RelationTargets[] relations);
+  nested(inside_sync) sync IsSearchbox(uint64_t aID) returns(bool retval);
+  nested(inside_sync) sync LandmarkRole(uint64_t aID) returns(nsString landmark);
+  nested(inside_sync) sync ARIARoleAtom(uint64_t aID) returns(nsString role);
+  nested(inside_sync) sync GetLevelInternal(uint64_t aID) returns(int32_t aLevel);
   async ScrollTo(uint64_t aID, uint32_t aScrollType);
   async ScrollToPoint(uint64_t aID, uint32_t aScrollType, int32_t aX,
                       int32_t aY);
 
   // AccessibleText
 
   // TextSubstring is getText in IDL.
-  prio(high) sync CaretLineNumber(uint64_t aID) returns(int32_t aLineNumber);
-  prio(high) sync CaretOffset(uint64_t aID) returns(int32_t aOffset);
+  nested(inside_sync) sync CaretLineNumber(uint64_t aID) returns(int32_t aLineNumber);
+  nested(inside_sync) sync CaretOffset(uint64_t aID) returns(int32_t aOffset);
    async SetCaretOffset(uint64_t aID, int32_t aOffset);
-  prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
-  prio(high) sync SelectionCount(uint64_t aID) returns(int32_t aCount);
-  prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t
-                                aEndOffset) returns(nsString aText, bool aValid);
-  prio(high) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
+  nested(inside_sync) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
+  nested(inside_sync) sync SelectionCount(uint64_t aID) returns(int32_t aCount);
+  nested(inside_sync) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t
+                                         aEndOffset) returns(nsString aText, bool aValid);
+  nested(inside_sync) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
-  prio(high) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
+  nested(inside_sync) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
 
-  prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
+  nested(inside_sync) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
-  prio(high) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar);
+  nested(inside_sync) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar);
 
-  prio(high) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset)
+  nested(inside_sync) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset)
     returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset);
-  prio(high) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes);
+  nested(inside_sync) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes);
 
-  prio(high) sync TextBounds(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
+  nested(inside_sync) sync TextBounds(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
                              uint32_t aCoordType)
     returns(nsIntRect aRetVal);
-  prio(high) sync CharBounds(uint64_t aID, int32_t aOffset, uint32_t aCoordType)
+  nested(inside_sync) sync CharBounds(uint64_t aID, int32_t aOffset, uint32_t aCoordType)
     returns(nsIntRect aRetVal);
 
-  prio(high) sync OffsetAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aCoordType)
+  nested(inside_sync) sync OffsetAtPoint(uint64_t aID, int32_t aX, int32_t aY, uint32_t aCoordType)
     returns(int32_t aRetVal);
 
-  prio(high) sync SelectionBoundsAt(uint64_t aID, int32_t aSelectionNum)
+  nested(inside_sync) sync SelectionBoundsAt(uint64_t aID, int32_t aSelectionNum)
     returns(bool aSucceeded, nsString aData, int32_t aStartOffset, int32_t aEndOffset);
-  prio(high) sync SetSelectionBoundsAt(uint64_t aID, int32_t aSelectionNum,
+  nested(inside_sync) sync SetSelectionBoundsAt(uint64_t aID, int32_t aSelectionNum,
                                        int32_t aStartOffset, int32_t aEndOffset)
     returns(bool aSucceeded);
-  prio(high) sync AddToSelection(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset)
+  nested(inside_sync) sync AddToSelection(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset)
     returns(bool aSucceeded);
-  prio(high) sync RemoveFromSelection(uint64_t aID, int32_t aSelectionNum)
+  nested(inside_sync) sync RemoveFromSelection(uint64_t aID, int32_t aSelectionNum)
     returns(bool aSucceeded);
 
   async ScrollSubstringTo(uint64_t aID, int32_t aStartOffset, int32_t aEndOffset,
                           uint32_t aScrollType);
   async ScrollSubstringToPoint(uint64_t aID,
                                int32_t aStartOffset,
                                int32_t aEndOffset,
                                uint32_t aCoordinateType,
                                int32_t aX, int32_t aY);
 
-  prio(high) sync Text(uint64_t aID) returns(nsString aText);
-  prio(high) sync ReplaceText(uint64_t aID, nsString aText);
-  prio(high) sync InsertText(uint64_t aID, nsString aText, int32_t aPosition)
+  nested(inside_sync) sync Text(uint64_t aID) returns(nsString aText);
+  nested(inside_sync) sync ReplaceText(uint64_t aID, nsString aText);
+  nested(inside_sync) sync InsertText(uint64_t aID, nsString aText, int32_t aPosition)
     returns(bool aValid);
-  prio(high) sync CopyText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
+  nested(inside_sync) sync CopyText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
     returns(bool aValid);
-  prio(high) sync CutText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
+  nested(inside_sync) sync CutText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
     returns(bool aValid);
-  prio(high) sync DeleteText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
+  nested(inside_sync) sync DeleteText(uint64_t aID, int32_t aStartPos, int32_t aEndPos)
     returns(bool aValid);
-  prio(high) sync PasteText(uint64_t aID, int32_t aPosition)
+  nested(inside_sync) sync PasteText(uint64_t aID, int32_t aPosition)
     returns(bool aValid);
 
-  prio(high) sync ImagePosition(uint64_t aID, uint32_t aCoordType) returns(IntPoint aRetVal);
-  prio(high) sync ImageSize(uint64_t aID) returns(IntSize aRetVal);
+  nested(inside_sync) sync ImagePosition(uint64_t aID, uint32_t aCoordType) returns(IntPoint aRetVal);
+  nested(inside_sync) sync ImageSize(uint64_t aID) returns(IntSize aRetVal);
 
-  prio(high) sync StartOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
-  prio(high) sync EndOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
-  prio(high) sync IsLinkValid(uint64_t aID) returns(bool aRetVal);
-  prio(high) sync AnchorCount(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
-  prio(high) sync AnchorURIAt(uint64_t aID, uint32_t aIndex) returns(nsCString aURI, bool aOk);
-  prio(high) sync AnchorAt(uint64_t aID, uint32_t aIndex) returns(uint64_t aIDOfAnchor, bool aOk);
+  nested(inside_sync) sync StartOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
+  nested(inside_sync) sync EndOffset(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
+  nested(inside_sync) sync IsLinkValid(uint64_t aID) returns(bool aRetVal);
+  nested(inside_sync) sync AnchorCount(uint64_t aID) returns(uint32_t aRetVal, bool aOk);
+  nested(inside_sync) sync AnchorURIAt(uint64_t aID, uint32_t aIndex) returns(nsCString aURI, bool aOk);
+  nested(inside_sync) sync AnchorAt(uint64_t aID, uint32_t aIndex) returns(uint64_t aIDOfAnchor, bool aOk);
 
-  prio(high) sync LinkCount(uint64_t aID) returns(uint32_t aCount);
-  prio(high) sync LinkAt(uint64_t aID, uint32_t aIndex) returns(uint64_t aIDOfLink, bool aOk);
-  prio(high) sync LinkIndexOf(uint64_t aID, uint64_t aLinkID) returns(int32_t aIndex);
-  prio(high) sync LinkIndexAtOffset(uint64_t aID, uint32_t aOffset) returns(int32_t aIndex);
+  nested(inside_sync) sync LinkCount(uint64_t aID) returns(uint32_t aCount);
+  nested(inside_sync) sync LinkAt(uint64_t aID, uint32_t aIndex) returns(uint64_t aIDOfLink, bool aOk);
+  nested(inside_sync) sync LinkIndexOf(uint64_t aID, uint64_t aLinkID) returns(int32_t aIndex);
+  nested(inside_sync) sync LinkIndexAtOffset(uint64_t aID, uint32_t aOffset) returns(int32_t aIndex);
 
-  prio(high) sync TableOfACell(uint64_t aID) returns(uint64_t aTableID, bool aOk);
-  prio(high) sync ColIdx(uint64_t aID) returns(uint32_t aIndex);
-  prio(high) sync RowIdx(uint64_t aID) returns(uint32_t aIndex);
-  prio(high) sync ColExtent(uint64_t aID) returns(uint32_t aExtent);
-  prio(high) sync RowExtent(uint64_t aID) returns(uint32_t aExtent);
-  prio(high) sync ColHeaderCells(uint64_t aID) returns(uint64_t[] aCells);
-  prio(high) sync RowHeaderCells(uint64_t aID) returns(uint64_t[] aCells);
-  prio(high) sync IsCellSelected(uint64_t aID) returns(bool aSelected);
+  nested(inside_sync) sync TableOfACell(uint64_t aID) returns(uint64_t aTableID, bool aOk);
+  nested(inside_sync) sync ColIdx(uint64_t aID) returns(uint32_t aIndex);
+  nested(inside_sync) sync RowIdx(uint64_t aID) returns(uint32_t aIndex);
+  nested(inside_sync) sync ColExtent(uint64_t aID) returns(uint32_t aExtent);
+  nested(inside_sync) sync RowExtent(uint64_t aID) returns(uint32_t aExtent);
+  nested(inside_sync) sync ColHeaderCells(uint64_t aID) returns(uint64_t[] aCells);
+  nested(inside_sync) sync RowHeaderCells(uint64_t aID) returns(uint64_t[] aCells);
+  nested(inside_sync) sync IsCellSelected(uint64_t aID) returns(bool aSelected);
 
-  prio(high) sync TableCaption(uint64_t aID) returns(uint64_t aCaptionID, bool aOk);
-  prio(high) sync TableSummary(uint64_t aID) returns(nsString aSummary);
-  prio(high) sync TableColumnCount(uint64_t aID) returns(uint32_t aColCount);
-  prio(high) sync TableRowCount(uint64_t aID) returns(uint32_t aRowCount);
-  prio(high) sync TableCellAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint64_t aCellID, bool aOk);
-  prio(high) sync TableCellIndexAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(int32_t aIndex);
-  prio(high) sync TableColumnIndexAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aCol);
-  prio(high) sync TableRowIndexAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aRow);
-  prio(high) sync TableRowAndColumnIndicesAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aRow, int32_t aCol);
-  prio(high) sync TableColumnExtentAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint32_t aExtent);
-  prio(high) sync TableRowExtentAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint32_t aExtent);
-  prio(high) sync TableColumnDescription(uint64_t aID, uint32_t aCol) returns(nsString aDescription);
-  prio(high) sync TableRowDescription(uint64_t aID, uint32_t aRow) returns(nsString aDescription);
-  prio(high) sync TableColumnSelected(uint64_t aID, uint32_t aCol) returns(bool aSelected);
-  prio(high) sync TableRowSelected(uint64_t aID, uint32_t aRow) returns(bool aSelected);
-  prio(high) sync TableCellSelected(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(bool aSelected);
-  prio(high) sync TableSelectedCellCount(uint64_t aID) returns(uint32_t aSelectedCells);
-  prio(high) sync TableSelectedColumnCount(uint64_t aID) returns(uint32_t aSelectedColumns);
-  prio(high) sync TableSelectedRowCount(uint64_t aID) returns(uint32_t aSelectedRows);
-  prio(high) sync TableSelectedCells(uint64_t aID) returns(uint64_t[] aCellIDs);
-  prio(high) sync TableSelectedCellIndices(uint64_t aID) returns(uint32_t[] aCellIndeces);
-  prio(high) sync TableSelectedColumnIndices(uint64_t aID) returns(uint32_t[] aColumnIndeces);
-  prio(high) sync TableSelectedRowIndices(uint64_t aID) returns(uint32_t[] aRowIndeces);
-  prio(high) sync TableSelectColumn(uint64_t aID, uint32_t aCol);
-  prio(high) sync TableSelectRow(uint64_t aID, uint32_t aRow);
-  prio(high) sync TableUnselectColumn(uint64_t aID, uint32_t aCol);
-  prio(high) sync TableUnselectRow(uint64_t aID, uint32_t aRow);
-  prio(high) sync TableIsProbablyForLayout(uint64_t aID) returns(bool aForLayout);
-  prio(high) sync AtkTableColumnHeader(uint64_t aID, int32_t aCol)
+  nested(inside_sync) sync TableCaption(uint64_t aID) returns(uint64_t aCaptionID, bool aOk);
+  nested(inside_sync) sync TableSummary(uint64_t aID) returns(nsString aSummary);
+  nested(inside_sync) sync TableColumnCount(uint64_t aID) returns(uint32_t aColCount);
+  nested(inside_sync) sync TableRowCount(uint64_t aID) returns(uint32_t aRowCount);
+  nested(inside_sync) sync TableCellAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint64_t aCellID, bool aOk);
+  nested(inside_sync) sync TableCellIndexAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(int32_t aIndex);
+  nested(inside_sync) sync TableColumnIndexAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aCol);
+  nested(inside_sync) sync TableRowIndexAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aRow);
+  nested(inside_sync) sync TableRowAndColumnIndicesAt(uint64_t aID, uint32_t aCellIndex) returns(int32_t aRow, int32_t aCol);
+  nested(inside_sync) sync TableColumnExtentAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint32_t aExtent);
+  nested(inside_sync) sync TableRowExtentAt(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(uint32_t aExtent);
+  nested(inside_sync) sync TableColumnDescription(uint64_t aID, uint32_t aCol) returns(nsString aDescription);
+  nested(inside_sync) sync TableRowDescription(uint64_t aID, uint32_t aRow) returns(nsString aDescription);
+  nested(inside_sync) sync TableColumnSelected(uint64_t aID, uint32_t aCol) returns(bool aSelected);
+  nested(inside_sync) sync TableRowSelected(uint64_t aID, uint32_t aRow) returns(bool aSelected);
+  nested(inside_sync) sync TableCellSelected(uint64_t aID, uint32_t aRow, uint32_t aCol) returns(bool aSelected);
+  nested(inside_sync) sync TableSelectedCellCount(uint64_t aID) returns(uint32_t aSelectedCells);
+  nested(inside_sync) sync TableSelectedColumnCount(uint64_t aID) returns(uint32_t aSelectedColumns);
+  nested(inside_sync) sync TableSelectedRowCount(uint64_t aID) returns(uint32_t aSelectedRows);
+  nested(inside_sync) sync TableSelectedCells(uint64_t aID) returns(uint64_t[] aCellIDs);
+  nested(inside_sync) sync TableSelectedCellIndices(uint64_t aID) returns(uint32_t[] aCellIndeces);
+  nested(inside_sync) sync TableSelectedColumnIndices(uint64_t aID) returns(uint32_t[] aColumnIndeces);
+  nested(inside_sync) sync TableSelectedRowIndices(uint64_t aID) returns(uint32_t[] aRowIndeces);
+  nested(inside_sync) sync TableSelectColumn(uint64_t aID, uint32_t aCol);
+  nested(inside_sync) sync TableSelectRow(uint64_t aID, uint32_t aRow);
+  nested(inside_sync) sync TableUnselectColumn(uint64_t aID, uint32_t aCol);
+  nested(inside_sync) sync TableUnselectRow(uint64_t aID, uint32_t aRow);
+  nested(inside_sync) sync TableIsProbablyForLayout(uint64_t aID) returns(bool aForLayout);
+  nested(inside_sync) sync AtkTableColumnHeader(uint64_t aID, int32_t aCol)
     returns(uint64_t aHeaderID, bool aOk);
-  prio(high) sync AtkTableRowHeader(uint64_t aID, int32_t aRow)
+  nested(inside_sync) sync AtkTableRowHeader(uint64_t aID, int32_t aRow)
     returns(uint64_t aHeaderID, bool aOk);
 
-  prio(high) sync SelectedItems(uint64_t aID) returns(uint64_t[] aSelectedItemIDs);
-  prio(high) sync SelectedItemCount(uint64_t aID) returns(uint32_t aCount);
-  prio(high) sync GetSelectedItem(uint64_t aID, uint32_t aIndex) returns(uint64_t aSelected, bool aOk);
-  prio(high) sync IsItemSelected(uint64_t aID, uint32_t aIndex) returns(bool aSelected);
-  prio(high) sync AddItemToSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
-  prio(high) sync RemoveItemFromSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
-  prio(high) sync SelectAll(uint64_t aID) returns(bool aSuccess);
-  prio(high) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
+  nested(inside_sync) sync SelectedItems(uint64_t aID) returns(uint64_t[] aSelectedItemIDs);
+  nested(inside_sync) sync SelectedItemCount(uint64_t aID) returns(uint32_t aCount);
+  nested(inside_sync) sync GetSelectedItem(uint64_t aID, uint32_t aIndex) returns(uint64_t aSelected, bool aOk);
+  nested(inside_sync) sync IsItemSelected(uint64_t aID, uint32_t aIndex) returns(bool aSelected);
+  nested(inside_sync) sync AddItemToSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
+  nested(inside_sync) sync RemoveItemFromSelection(uint64_t aID, uint32_t aIndex) returns(bool aSuccess);
+  nested(inside_sync) sync SelectAll(uint64_t aID) returns(bool aSuccess);
+  nested(inside_sync) sync UnselectAll(uint64_t aID) returns(bool aSuccess);
 
   async TakeSelection(uint64_t aID);
   async SetSelected(uint64_t aID, bool aSelected);
 
-  prio(high) sync DoAction(uint64_t aID, uint8_t aIndex) returns(bool aSuccess);
-  prio(high) sync ActionCount(uint64_t aID) returns(uint8_t aCount);
-  prio(high) sync ActionDescriptionAt(uint64_t aID, uint8_t aIndex) returns(nsString aDescription);
-  prio(high) sync ActionNameAt(uint64_t aID, uint8_t aIndex) returns(nsString aName);
-  prio(high) sync AccessKey(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
-  prio(high) sync KeyboardShortcut(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
-  prio(high) sync AtkKeyBinding(uint64_t aID) returns(nsString aResult);
+  nested(inside_sync) sync DoAction(uint64_t aID, uint8_t aIndex) returns(bool aSuccess);
+  nested(inside_sync) sync ActionCount(uint64_t aID) returns(uint8_t aCount);
+  nested(inside_sync) sync ActionDescriptionAt(uint64_t aID, uint8_t aIndex) returns(nsString aDescription);
+  nested(inside_sync) sync ActionNameAt(uint64_t aID, uint8_t aIndex) returns(nsString aName);
+  nested(inside_sync) sync AccessKey(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
+  nested(inside_sync) sync KeyboardShortcut(uint64_t aID) returns(uint32_t aKey, uint32_t aModifierMask);
+  nested(inside_sync) sync AtkKeyBinding(uint64_t aID) returns(nsString aResult);
 
-  prio(high) sync CurValue(uint64_t aID) returns(double aValue);
-  prio(high) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);
-  prio(high) sync MinValue(uint64_t aID) returns(double aValue);
-  prio(high) sync MaxValue(uint64_t aID) returns(double aValue);
-  prio(high) sync Step(uint64_t aID) returns(double aStep);
+  nested(inside_sync) sync CurValue(uint64_t aID) returns(double aValue);
+  nested(inside_sync) sync SetCurValue(uint64_t aID, double aValue) returns(bool aRetVal);
+  nested(inside_sync) sync MinValue(uint64_t aID) returns(double aValue);
+  nested(inside_sync) sync MaxValue(uint64_t aID) returns(double aValue);
+  nested(inside_sync) sync Step(uint64_t aID) returns(double aStep);
 
   async TakeFocus(uint64_t aID);
-  prio(high) sync FocusedChild(uint64_t aID)
+  nested(inside_sync) sync FocusedChild(uint64_t aID)
     returns(uint64_t aChild, bool aOk);
 
-  prio(high) sync Language(uint64_t aID) returns(nsString aLocale);
-  prio(high) sync DocType(uint64_t aID) returns(nsString aType);
-  prio(high) sync Title(uint64_t aID) returns(nsString aTitle);
-  prio(high) sync URL(uint64_t aID) returns(nsString aURL);
-  prio(high) sync MimeType(uint64_t aID) returns(nsString aMime);
-  prio(high) sync URLDocTypeMimeType(uint64_t aID) returns(nsString aURL, nsString aDocType, nsString aMimeType);
+  nested(inside_sync) sync Language(uint64_t aID) returns(nsString aLocale);
+  nested(inside_sync) sync DocType(uint64_t aID) returns(nsString aType);
+  nested(inside_sync) sync Title(uint64_t aID) returns(nsString aTitle);
+  nested(inside_sync) sync URL(uint64_t aID) returns(nsString aURL);
+  nested(inside_sync) sync MimeType(uint64_t aID) returns(nsString aMime);
+  nested(inside_sync) sync URLDocTypeMimeType(uint64_t aID) returns(nsString aURL, nsString aDocType, nsString aMimeType);
 
-  prio(high) sync AccessibleAtPoint(uint64_t aID, int32_t aX, int32_t aY, bool aNeedsScreenCoords, uint32_t aWhich)
+  nested(inside_sync) sync AccessibleAtPoint(uint64_t aID, int32_t aX, int32_t aY, bool aNeedsScreenCoords, uint32_t aWhich)
     returns(uint64_t aResult, bool aOk);
 
-  prio(high) sync Extents(uint64_t aID, bool aNeedsScreenCoords)
+  nested(inside_sync) sync Extents(uint64_t aID, bool aNeedsScreenCoords)
     returns(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight);
-  prio(high) sync DOMNodeID(uint64_t aID) returns(nsString aDOMNodeID);
+  nested(inside_sync) sync DOMNodeID(uint64_t aID) returns(nsString aDOMNodeID);
 };
 
 }
 }
--- a/accessible/tests/mochitest/events/test_coalescence.html
+++ b/accessible/tests/mochitest/events/test_coalescence.html
@@ -645,16 +645,52 @@
         getNode('t10_c2_moved').setAttribute('aria-owns', 't10_c3_moved');
       };
 
       this.getID = function test10_getID() {
         return "Move a node by aria-owns into a node moved by aria-owns to left within the tree";
       };
     }
 
+    /**
+     * Move a node by aria-owns from right to left in the tree, and then
+     * move its parent too by aria-owns. No hide event should be fired for
+     * original node.
+     */
+    function test11()
+    {
+      this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, getNode('t11_c1_child')),
+        new invokerChecker(EVENT_SHOW, 't11_c2_child'),
+        new invokerChecker(EVENT_HIDE, getNode('t11_c2')),
+        new invokerChecker(EVENT_SHOW, 't11_c2'),
+        new invokerChecker(EVENT_REORDER, 't11'),
+        new unexpectedInvokerChecker(EVENT_HIDE, 't11_c2_child'),
+        new unexpectedInvokerChecker(EVENT_REORDER, 't11_c1'),
+        new unexpectedInvokerChecker(EVENT_REORDER, 't11_c2'),
+        new unexpectedInvokerChecker(EVENT_REORDER, 't11_c3')
+      ];
+
+      this.invoke = function test11_invoke()
+      {
+        // Remove a node from 't11_c1' container to give the event tree a
+        // desired structure (the 't11_c1' container node goes first in
+        // the event tree),
+        getNode('t11_c1_child').remove();
+        // then move 't11_c2_moved' from 't11_c2' to 't11_c1', and then move
+        // 't11_c2' to 't11_c3'.
+        getNode('t11_c1').setAttribute('aria-owns', 't11_c2_child');
+        getNode('t11_c3').setAttribute('aria-owns', 't11_c2');
+      };
+
+      this.getID = function test11_getID() {
+        return "Move a node by aria-owns to left within the tree";
+      };
+    }
+
     ////////////////////////////////////////////////////////////////////////////
     // Do tests.
 
     //gA11yEventDumpToConsole = true; // debug stuff
     //enableLogging("eventTree");
 
     var gQueue = null;
     function doTests()
@@ -681,16 +717,17 @@
       gQueue.push(new test3());
       gQueue.push(new test4());
       gQueue.push(new test5());
       gQueue.push(new test6());
       gQueue.push(new test7());
       gQueue.push(new test8());
       gQueue.push(new test9());
       gQueue.push(new test10());
+      gQueue.push(new test11());
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
@@ -810,10 +847,16 @@
     <div id="t10_c2">
       <div id="t10_c2_child"></div>
       <div id="t10_c2_moved"></div>
     </div>
     <div id="t10_c3">
       <div id="t10_c3_moved"></div>
     </div>
   </div>
+
+  <div id="t11">
+    <div id="t11_c1"><div id="t11_c1_child"></div></div>
+    <div id="t11_c2"><div id="t11_c2_child"></div></div>
+    <div id="t11_c3"></div>
+  </div>
 </body>
 </html>
--- a/build/autoconf/jemalloc.m4
+++ b/build/autoconf/jemalloc.m4
@@ -71,16 +71,25 @@ if test "$MOZ_BUILD_APP" != js -o -n "$J
     unset CONFIG_FILES
     if test -z "$MOZ_TLS"; then
       ac_configure_args="$ac_configure_args --disable-tls"
     fi
     EXTRA_CFLAGS="$CFLAGS"
     for var in AS CC CXX CPP LD AR RANLIB STRIP CPPFLAGS EXTRA_CFLAGS LDFLAGS; do
       ac_configure_args="$ac_configure_args $var='`eval echo \\${${var}}`'"
     done
+
+    # jemalloc's configure assumes that if you have CFLAGS set at all, you set
+    # all the flags necessary to configure jemalloc, which is not likely to be
+    # the case on Windows if someone is building Firefox with flags set in
+    # their mozconfig.
+    if test "$_MSC_VER"; then
+       ac_configure_args="$ac_configure_args CFLAGS="
+    fi
+
     # Force disable DSS support in jemalloc.
     ac_configure_args="$ac_configure_args ac_cv_func_sbrk=false"
 
     # Make Linux builds munmap freed chunks instead of recycling them.
     ac_configure_args="$ac_configure_args --enable-munmap"
 
     # Disable cache oblivious behavior that appears to have a performance
     # impact on Firefox.
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -877,10 +877,31 @@ add_old_configure_assignment('MOZ_DEBUG_
 @depends(c_compiler, target)
 def libcxx_inline_visibility(c_compiler, target):
     if c_compiler.type == 'clang' and target.os == 'Android':
         return ''
 
 set_define('_LIBCPP_INLINE_VISIBILITY', libcxx_inline_visibility)
 set_define('_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49', libcxx_inline_visibility)
 
+@depends(c_compiler, target, check_build_environment)
+def visibility_flags(c_compiler, target, env):
+    if target.os != 'WINNT':
+        if target.kernel == 'Darwin':
+            return ('-fvisibility=hidden', '-fvisibility-inlines-hidden')
+        return ('-I%s/system_wrappers' % os.path.join(env.dist),
+                '-include',
+                '%s/config/gcc_hidden.h' % env.topsrcdir)
+
+@depends(target, visibility_flags)
+def wrap_system_includes(target, visibility_flags):
+    if visibility_flags and target.kernel != 'Darwin':
+        return True
+
+set_define('HAVE_VISIBILITY_HIDDEN_ATTRIBUTE',
+           depends(visibility_flags)(lambda v: bool(v) or None))
+set_define('HAVE_VISIBILITY_ATTRIBUTE',
+           depends(visibility_flags)(lambda v: bool(v) or None))
+set_config('WRAP_SYSTEM_INCLUDES', wrap_system_includes)
+set_config('VISIBILITY_FLAGS', visibility_flags)
+
 include('windows.configure')
 include('rust.configure')
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -291,17 +291,20 @@ KeyframeEffectReadOnly::UpdateProperties
 
   for (AnimationProperty& property : mProperties) {
     property.mWinsInCascade =
       winningInCascadeProperties.HasProperty(property.mProperty);
     property.mIsRunningOnCompositor =
       runningOnCompositorProperties.HasProperty(property.mProperty);
   }
 
-  CalculateCumulativeChangeHint(aStyleContext);
+  // FIXME (bug 1303235): Do this for Servo too
+  if (aStyleContext->PresContext()->StyleSet()->IsGecko()) {
+    CalculateCumulativeChangeHint(aStyleContext);
+  }
 
   MarkCascadeNeedsUpdate();
 
   RequestRestyle(EffectCompositor::RestyleType::Layer);
 }
 
 void
 KeyframeEffectReadOnly::ComposeStyle(RefPtr<AnimValuesStyleRule>& aStyleRule,
@@ -854,18 +857,23 @@ KeyframeEffectReadOnly::GetKeyframes(JSC
       // works with token stream values if we pass eCSSProperty_UNKNOWN as
       // the property.
       nsCSSPropertyID propertyForSerializing =
         nsCSSProps::IsShorthand(propertyValue.mProperty)
         ? eCSSProperty_UNKNOWN
         : propertyValue.mProperty;
 
       nsAutoString stringValue;
-      propertyValue.mValue.AppendToString(
-        propertyForSerializing, stringValue, nsCSSValue::eNormalized);
+      if (propertyValue.mServoDeclarationBlock) {
+        Servo_DeclarationBlock_SerializeOneValue(
+          propertyValue.mServoDeclarationBlock, &stringValue);
+      } else {
+        propertyValue.mValue.AppendToString(
+          propertyForSerializing, stringValue, nsCSSValue::eNormalized);
+      }
 
       JS::Rooted<JS::Value> value(aCx);
       if (!ToJSValue(aCx, stringValue, &value) ||
           !JS_DefineProperty(aCx, keyframeObject, name, value,
                              JSPROP_ENUMERATE)) {
         aRv.Throw(NS_ERROR_FAILURE);
         return;
       }
@@ -1265,16 +1273,23 @@ KeyframeEffectReadOnly::SetAnimation(Ani
 
 bool
 KeyframeEffectReadOnly::CanIgnoreIfNotVisible() const
 {
   if (!AnimationUtils::IsOffscreenThrottlingEnabled()) {
     return false;
   }
 
+  // FIXME (bug 1303235): We don't calculate mCumulativeChangeHint for
+  // the Servo backend yet
+  nsPresContext* presContext = GetPresContext();
+  if (!presContext || presContext->StyleSet()->IsServo()) {
+    return false;
+  }
+
   // FIXME: For further sophisticated optimization we need to check
   // change hint on the segment corresponding to computedTiming.progress.
   return NS_IsHintSubset(
     mCumulativeChangeHint, nsChangeHint_Hints_CanIgnoreIfNotVisible);
 }
 
 void
 KeyframeEffectReadOnly::MaybeUpdateFrameForCompositor()
--- a/dom/animation/KeyframeEffectReadOnly.h
+++ b/dom/animation/KeyframeEffectReadOnly.h
@@ -15,16 +15,18 @@
 #include "nsWrapperCache.h"
 #include "mozilla/AnimationPerformanceWarning.h"
 #include "mozilla/AnimationTarget.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ComputedTimingFunction.h"
 #include "mozilla/EffectCompositor.h"
 #include "mozilla/KeyframeEffectParams.h"
 #include "mozilla/LayerAnimationInfo.h" // LayerAnimations::kRecords
+#include "mozilla/ServoBindingHelpers.h" // ServoDeclarationBlock and
+                                         // associated RefPtrTraits
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/dom/AnimationEffectReadOnly.h"
 #include "mozilla/dom/Element.h"
 
 struct JSContext;
 class JSObject;
 class nsCSSPropertyIDSet;
 class nsIContent;
@@ -55,21 +57,30 @@ struct AnimationPropertyDetails;
  * A property-value pair specified on a keyframe.
  */
 struct PropertyValuePair
 {
   nsCSSPropertyID mProperty;
   // The specified value for the property. For shorthand properties or invalid
   // property values, we store the specified property value as a token stream
   // (string).
-  nsCSSValue    mValue;
+  nsCSSValue mValue;
+
+  // The specified value when using the Servo backend. However, even when
+  // using the Servo backend, we still fill in |mValue| in the case where we
+  // fail to parse the value since we use it to store the original string.
+  RefPtr<ServoDeclarationBlock> mServoDeclarationBlock;
 
   bool operator==(const PropertyValuePair& aOther) const {
     return mProperty == aOther.mProperty &&
-           mValue == aOther.mValue;
+           mValue == aOther.mValue &&
+           !mServoDeclarationBlock == !aOther.mServoDeclarationBlock &&
+           (!mServoDeclarationBlock ||
+            Servo_DeclarationBlock_Equals(mServoDeclarationBlock,
+                                          aOther.mServoDeclarationBlock));
   }
 };
 
 /**
  * A single keyframe.
  *
  * This is the canonical form in which keyframe effects are stored and
  * corresponds closely to the type of objects returned via the getKeyframes()
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -312,18 +312,22 @@ public:
 
 // ------------------------------------------------------------------
 //
 // Inlined helper methods
 //
 // ------------------------------------------------------------------
 
 inline bool
-IsInvalidValuePair(const PropertyValuePair& aPair)
+IsInvalidValuePair(const PropertyValuePair& aPair, StyleBackendType aBackend)
 {
+  if (aBackend == StyleBackendType::Servo) {
+    return !aPair.mServoDeclarationBlock;
+  }
+
   // There are three types of values we store as token streams:
   //
   // * Shorthand values (where we manually extract the token stream's string
   //   value) and pass that along to various parsing methods
   // * Longhand values with variable references
   // * Invalid values
   //
   // We can distinguish between the last two cases because for invalid values
@@ -584,51 +588,66 @@ KeyframeUtils::ApplyDistributeSpacing(ns
 /* static */ nsTArray<ComputedKeyframeValues>
 KeyframeUtils::GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
                                          dom::Element* aElement,
                                          nsStyleContext* aStyleContext)
 {
   MOZ_ASSERT(aStyleContext);
   MOZ_ASSERT(aElement);
 
+  StyleBackendType styleBackend = aElement->OwnerDoc()->GetStyleBackendType();
+
   const size_t len = aKeyframes.Length();
   nsTArray<ComputedKeyframeValues> result(len);
 
   for (const Keyframe& frame : aKeyframes) {
     nsCSSPropertyIDSet propertiesOnThisKeyframe;
     ComputedKeyframeValues* computedValues = result.AppendElement();
     for (const PropertyValuePair& pair :
            PropertyPriorityIterator(frame.mPropertyValues)) {
-      if (IsInvalidValuePair(pair)) {
+      MOZ_ASSERT(!pair.mServoDeclarationBlock ||
+                 styleBackend == StyleBackendType::Servo,
+                 "Animation values were parsed using Servo backend but target"
+                 " element is not using Servo backend?");
+
+      if (IsInvalidValuePair(pair, styleBackend)) {
         continue;
       }
 
       // Expand each value into the set of longhands and produce
       // a KeyframeValueEntry for each value.
       nsTArray<PropertyStyleAnimationValuePair> values;
 
-      // For shorthands, we store the string as a token stream so we need to
-      // extract that first.
-      if (nsCSSProps::IsShorthand(pair.mProperty)) {
-        nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
+      if (styleBackend == StyleBackendType::Servo) {
         if (!StyleAnimationValue::ComputeValues(pair.mProperty,
-              CSSEnabledState::eForAllContent, aElement, aStyleContext,
-              tokenStream->mTokenStream, /* aUseSVGMode */ false, values) ||
-            IsComputeValuesFailureKey(pair)) {
+              CSSEnabledState::eForAllContent, aStyleContext,
+              *pair.mServoDeclarationBlock, values)) {
           continue;
         }
       } else {
-        if (!StyleAnimationValue::ComputeValues(pair.mProperty,
-              CSSEnabledState::eForAllContent, aElement, aStyleContext,
-              pair.mValue, /* aUseSVGMode */ false, values)) {
-          continue;
+        // For shorthands, we store the string as a token stream so we need to
+        // extract that first.
+        if (nsCSSProps::IsShorthand(pair.mProperty)) {
+          nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
+          if (!StyleAnimationValue::ComputeValues(pair.mProperty,
+                CSSEnabledState::eForAllContent, aElement, aStyleContext,
+                tokenStream->mTokenStream, /* aUseSVGMode */ false, values) ||
+              IsComputeValuesFailureKey(pair)) {
+            continue;
+          }
+        } else {
+          if (!StyleAnimationValue::ComputeValues(pair.mProperty,
+                CSSEnabledState::eForAllContent, aElement, aStyleContext,
+                pair.mValue, /* aUseSVGMode */ false, values)) {
+            continue;
+          }
+          MOZ_ASSERT(values.Length() == 1,
+                    "Longhand properties should produce a single"
+                    " StyleAnimationValue");
         }
-        MOZ_ASSERT(values.Length() == 1,
-                   "Longhand properties should produce a single"
-                   " StyleAnimationValue");
       }
 
       for (auto& value : values) {
         // If we already got a value for this property on the keyframe,
         // skip this one.
         if (propertiesOnThisKeyframe.HasProperty(value.mProperty)) {
           continue;
         }
@@ -964,16 +983,46 @@ AppendValueAsString(JSContext* aCx,
  * @param aDocument The document to use when parsing.
  * @return The constructed PropertyValuePair object.
  */
 static PropertyValuePair
 MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
                       nsCSSParser& aParser, nsIDocument* aDocument)
 {
   MOZ_ASSERT(aDocument);
+  PropertyValuePair result;
+
+  result.mProperty = aProperty;
+
+  if (aDocument->GetStyleBackendType() == StyleBackendType::Servo) {
+    nsCString name = nsCSSProps::GetStringValue(aProperty);
+
+    NS_ConvertUTF16toUTF8 value(aStringValue);
+    RefPtr<ThreadSafeURIHolder> base =
+      new ThreadSafeURIHolder(aDocument->GetDocumentURI());
+    RefPtr<ThreadSafeURIHolder> referrer =
+      new ThreadSafeURIHolder(aDocument->GetDocumentURI());
+    RefPtr<ThreadSafePrincipalHolder> principal =
+      new ThreadSafePrincipalHolder(aDocument->NodePrincipal());
+
+    nsCString baseString;
+    aDocument->GetDocumentURI()->GetSpec(baseString);
+
+    RefPtr<ServoDeclarationBlock> servoDeclarationBlock =
+      Servo_ParseProperty(
+        reinterpret_cast<const uint8_t*>(name.get()), name.Length(),
+        reinterpret_cast<const uint8_t*>(value.get()), value.Length(),
+        reinterpret_cast<const uint8_t*>(baseString.get()), baseString.Length(),
+        base, referrer, principal).Consume();
+
+    if (servoDeclarationBlock) {
+      result.mServoDeclarationBlock = servoDeclarationBlock.forget();
+      return result;
+    }
+  }
 
   nsCSSValue value;
   if (!nsCSSProps::IsShorthand(aProperty)) {
     aParser.ParseLonghandProperty(aProperty,
                                   aStringValue,
                                   aDocument->GetDocumentURI(),
                                   aDocument->GetDocumentURI(),
                                   aDocument->NodePrincipal(),
@@ -996,19 +1045,28 @@ MakePropertyValuePair(nsCSSPropertyID aP
 
     // By leaving mShorthandPropertyID as unknown, we ensure that when
     // we call nsCSSValue::AppendToString we get back the string stored
     // in mTokenStream.
     MOZ_ASSERT(tokenStream->mShorthandPropertyID == eCSSProperty_UNKNOWN,
                "The shorthand property of a token stream should be initialized"
                " to unknown");
     value.SetTokenStreamValue(tokenStream);
+  } else {
+    // If we succeeded in parsing with Gecko, but not Servo the animation is
+    // not going to work since, for the purposes of animation, we're going to
+    // ignore |mValue| when the backend is Servo.
+    NS_WARNING_ASSERTION(aDocument->GetStyleBackendType() !=
+                           StyleBackendType::Servo,
+                         "Gecko succeeded in parsing where Servo failed");
   }
 
-  return { aProperty, value };
+  result.mValue = value;
+
+  return result;
 }
 
 /**
  * Checks that the given keyframes are loosely ordered (each keyframe's
  * offset that is not null is greater than or equal to the previous
  * non-null offset) and that all values are within the range [0.0, 1.0].
  *
  * @return true if the keyframes' offsets are correctly ordered and
@@ -1339,42 +1397,52 @@ RequiresAdditiveAnimation(const nsTArray
     properties.AddProperty(aProperty);
     if (aOffset == 0.0) {
       propertiesWithFromValue.AddProperty(aProperty);
     } else if (aOffset == 1.0) {
       propertiesWithToValue.AddProperty(aProperty);
     }
   };
 
+  StyleBackendType styleBackend = aDocument->GetStyleBackendType();
+
   for (size_t i = 0, len = aKeyframes.Length(); i < len; i++) {
     const Keyframe& frame = aKeyframes[i];
 
     // We won't have called ApplySpacing when this is called so
     // we can't use frame.mComputedOffset. Instead we do a rough version
     // of that algorithm that substitutes null offsets with 0.0 for the first
     // frame, 1.0 for the last frame, and 0.5 for everything else.
     double computedOffset = i == len - 1
                             ? 1.0
                             : i == 0 ? 0.0 : 0.5;
     double offsetToUse = frame.mOffset
                          ? frame.mOffset.value()
                          : computedOffset;
 
     for (const PropertyValuePair& pair : frame.mPropertyValues) {
-      if (IsInvalidValuePair(pair)) {
+      if (IsInvalidValuePair(pair, styleBackend)) {
         continue;
       }
 
       if (nsCSSProps::IsShorthand(pair.mProperty)) {
-        nsCSSValueTokenStream* tokenStream = pair.mValue.GetTokenStreamValue();
-        nsCSSParser parser(aDocument->CSSLoader());
-        if (!parser.IsValueValidForProperty(pair.mProperty,
-                                            tokenStream->mTokenStream)) {
-          continue;
+        if (styleBackend == StyleBackendType::Gecko) {
+          nsCSSValueTokenStream* tokenStream =
+            pair.mValue.GetTokenStreamValue();
+          nsCSSParser parser(aDocument->CSSLoader());
+          if (!parser.IsValueValidForProperty(pair.mProperty,
+                                              tokenStream->mTokenStream)) {
+            continue;
+          }
         }
+        // For the Servo backend, invalid shorthand values are represented by
+        // a null mServoDeclarationBlock member which we skip above in
+        // IsInvalidValuePair.
+        MOZ_ASSERT(styleBackend != StyleBackendType::Servo ||
+                   pair.mServoDeclarationBlock);
         CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(
             prop, pair.mProperty, CSSEnabledState::eForAllContent) {
           addToPropertySets(*prop, offsetToUse);
         }
       } else {
         addToPropertySets(pair.mProperty, offsetToUse);
       }
     }
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -479,17 +479,17 @@ nsAttrAndChildArray::RemoveAttrAt(uint32
   RefPtr<nsMappedAttributes> mapped =
     GetModifiableMapped(nullptr, nullptr, false);
 
   mapped->RemoveAttrAt(aPos - nonmapped, aValue);
 
   return MakeMappedUnique(mapped);
 }
 
-BorrowedAttrInfo
+mozilla::dom::BorrowedAttrInfo
 nsAttrAndChildArray::AttrInfoAt(uint32_t aPos) const
 {
   NS_ASSERTION(aPos < AttrCount(),
                "out-of-bounds access in nsAttrAndChildArray");
 
   uint32_t nonmapped = NonMappedAttrCount();
   if (aPos < nonmapped) {
     return BorrowedAttrInfo(&ATTRS(mImpl)[aPos].mName, &ATTRS(mImpl)[aPos].mValue);
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -886,17 +886,17 @@ nsDOMMutationObserver::HandleMutationsIn
     // after previous mutations are handled. But in case some
     // callback calls a sync API, which spins the eventloop, we need to still
     // process other mutations happening during that sync call.
     // This does *not* catch all cases, but should work for stuff running
     // in separate tabs.
     return;
   }
 
-  AutoSlowOperation aso;
+  mozilla::AutoSlowOperation aso;
 
   nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
 
   while (sScheduledMutationObservers) {
     AutoTArray<RefPtr<nsDOMMutationObserver>, 4>* observers =
       sScheduledMutationObservers;
     sScheduledMutationObservers = nullptr;
     for (uint32_t i = 0; i < observers->Length(); ++i) {
--- a/dom/base/nsHostObjectProtocolHandler.cpp
+++ b/dom/base/nsHostObjectProtocolHandler.cpp
@@ -3,16 +3,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/. */
 
 #include "nsHostObjectProtocolHandler.h"
 
 #include "DOMMediaStream.h"
 #include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/Exceptions.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/ipc/BlobChild.h"
 #include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/dom/MediaSource.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/ModuleUtils.h"
 #include "mozilla/Preferences.h"
@@ -124,43 +125,43 @@ void
 BroadcastBlobURLRegistration(const nsACString& aURI,
                              BlobImpl* aBlobImpl,
                              nsIPrincipal* aPrincipal)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBlobImpl);
 
   if (XRE_IsParentProcess()) {
-    ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
-                                                aPrincipal);
+    dom::ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
+                                                     aPrincipal);
     return;
   }
 
-  ContentChild* cc = ContentChild::GetSingleton();
-  BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl);
+  dom::ContentChild* cc = dom::ContentChild::GetSingleton();
+  dom::BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl);
   if (NS_WARN_IF(!actor)) {
     return;
   }
 
   Unused << NS_WARN_IF(!cc->SendStoreAndBroadcastBlobURLRegistration(
     nsCString(aURI), actor, IPC::Principal(aPrincipal)));
 }
 
 void
 BroadcastBlobURLUnregistration(const nsACString& aURI, DataInfo* aInfo)
 {
   MOZ_ASSERT(aInfo);
   MOZ_ASSERT(NS_IsMainThread());
 
   if (XRE_IsParentProcess()) {
-    ContentParent::BroadcastBlobURLUnregistration(aURI);
+    dom::ContentParent::BroadcastBlobURLUnregistration(aURI);
     return;
   }
 
-  ContentChild* cc = ContentChild::GetSingleton();
+  dom::ContentChild* cc = dom::ContentChild::GetSingleton();
   Unused << NS_WARN_IF(!cc->SendUnstoreAndBroadcastBlobURLUnregistration(
     nsCString(aURI)));
 }
 
 class HostObjectURLsReporter final : public nsIMemoryReporter
 {
   ~HostObjectURLsReporter() {}
 
@@ -459,17 +460,17 @@ nsHostObjectProtocolHandler::AddDataEntr
   Init();
 
   nsresult rv = GenerateURIStringForBlobURL(aPrincipal, aUri);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = AddDataEntryInternal(aUri, aBlobImpl, aPrincipal);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal);
+  mozilla::BroadcastBlobURLRegistration(aUri, aBlobImpl, aPrincipal);
   return NS_OK;
 }
 
 /* static */ nsresult
 nsHostObjectProtocolHandler::AddDataEntry(DOMMediaStream* aMediaStream,
                                           nsIPrincipal* aPrincipal,
                                           nsACString& aUri)
 {
@@ -504,42 +505,44 @@ nsHostObjectProtocolHandler::AddDataEntr
 nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aURI,
                                           nsIPrincipal* aPrincipal,
                                           mozilla::dom::BlobImpl* aBlobImpl)
 {
   return AddDataEntryInternal(aURI, aBlobImpl, aPrincipal);
 }
 
 /* static */ bool
-nsHostObjectProtocolHandler::GetAllBlobURLEntries(nsTArray<BlobURLRegistrationData>& aRegistrations,
-                                                  ContentParent* aCP)
+nsHostObjectProtocolHandler::GetAllBlobURLEntries(
+  nsTArray<mozilla::dom::BlobURLRegistrationData>& aRegistrations,
+  mozilla::dom::ContentParent* aCP)
 {
   MOZ_ASSERT(aCP);
 
   if (!gDataTable) {
     return true;
   }
 
   for (auto iter = gDataTable->ConstIter(); !iter.Done(); iter.Next()) {
     DataInfo* info = iter.UserData();
     MOZ_ASSERT(info);
 
     if (info->mObjectType != DataInfo::eBlobImpl) {
       continue;
     }
 
     MOZ_ASSERT(info->mBlobImpl);
-    PBlobParent* blobParent = aCP->GetOrCreateActorForBlobImpl(info->mBlobImpl);
+    mozilla::dom::PBlobParent* blobParent =
+      aCP->GetOrCreateActorForBlobImpl(info->mBlobImpl);
     if (!blobParent) {
       return false;
     }
 
-    aRegistrations.AppendElement(
-      BlobURLRegistrationData(nsCString(iter.Key()), blobParent, nullptr,
-                              IPC::Principal(info->mPrincipal)));
+    aRegistrations.AppendElement(mozilla::dom::BlobURLRegistrationData(
+      nsCString(iter.Key()), blobParent, nullptr,
+      IPC::Principal(info->mPrincipal)));
   }
 
   return true;
 }
 
 void
 nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri,
                                              bool aBroadcastToOtherProcesses)
@@ -549,17 +552,17 @@ nsHostObjectProtocolHandler::RemoveDataE
   }
 
   DataInfo* info = GetDataInfo(aUri);
   if (!info) {
     return;
   }
 
   if (aBroadcastToOtherProcesses && info->mObjectType == DataInfo::eBlobImpl) {
-    BroadcastBlobURLUnregistration(aUri, info);
+    mozilla::BroadcastBlobURLUnregistration(aUri, info);
   }
 
   gDataTable->Remove(aUri);
   if (gDataTable->Count() == 0) {
     delete gDataTable;
     gDataTable = nullptr;
   }
 }
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -121,17 +121,17 @@ public:
 
   /*
    * If the callback is known to be non-gray, then this method can be
    * used instead of Callback() to avoid the overhead of
    * ExposeObjectToActiveJS().
    */
   JS::Handle<JSObject*> CallbackKnownNotGray() const
   {
-    MOZ_ASSERT(!JS::ObjectIsMarkedGray(mCallback.get()));
+    MOZ_ASSERT(!JS::ObjectIsMarkedGray(mCallback));
     return CallbackPreserveColor();
   }
 
   nsIGlobalObject* IncumbentGlobalOrNull() const
   {
     return mIncumbentGlobal;
   }
 
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -300,18 +300,18 @@ class IDLScope(IDLObject):
                 "identifier '%s'.\n%s\n%s"
                 % (identifier.name,
                    originalObject.location, newObject.location), [])
 
         # We do the merging of overloads here as opposed to in IDLInterface
         # because we need to merge overloads of NamedConstructors and we need to
         # detect conflicts in those across interfaces. See also the comment in
         # IDLInterface.addExtendedAttributes for "NamedConstructor".
-        if (originalObject.tag == IDLInterfaceMember.Tags.Method and
-           newObject.tag == IDLInterfaceMember.Tags.Method):
+        if (isinstance(originalObject, IDLMethod) and
+            isinstance(newObject, IDLMethod)):
             return originalObject.addOverload(newObject)
 
         # Default to throwing, derived classes can override.
         conflictdesc = "\n\t%s at %s\n\t%s at %s" % (originalObject,
                                                      originalObject.location,
                                                      newObject,
                                                      newObject.location)
 
new file mode 100644
--- /dev/null
+++ b/dom/bindings/parser/tests/test_identifier_conflict.py
@@ -0,0 +1,39 @@
+# Import the WebIDL module, so we can do isinstance checks and whatnot
+import WebIDL
+
+def WebIDLTest(parser, harness):
+    try:
+        parser.parse("""
+            enum Foo { "a" };
+            interface Foo;
+        """)
+        results = parser.finish()
+        harness.ok(False, "Should fail to parse")
+    except Exception, e:
+        harness.ok("Name collision" in e.message,
+                   "Should have name collision for interface")
+
+    parser = parser.reset()
+    try:
+        parser.parse("""
+            dictionary Foo { long x; };
+            enum Foo { "a" };
+        """)
+        results = parser.finish()
+        harness.ok(False, "Should fail to parse")
+    except Exception, e:
+        harness.ok("Name collision" in e.message,
+                   "Should have name collision for dictionary")
+
+    parser = parser.reset()
+    try:
+        parser.parse("""
+            enum Foo { "a" };
+            enum Foo { "b" };
+        """)
+        results = parser.finish()
+        harness.ok(False, "Should fail to parse")
+    except Exception, e:
+        harness.ok("Multiple unresolvable definitions" in e.message,
+                   "Should have name collision for dictionary")
+
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -7354,18 +7354,17 @@ HTMLInputElement::HasPatternMismatch() c
   nsIDocument* doc = OwnerDoc();
 
   return !nsContentUtils::IsPatternMatching(value, pattern, doc);
 }
 
 bool
 HTMLInputElement::IsRangeOverflow() const
 {
-  // TODO: this is temporary until bug 888316 is fixed.
-  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_WEEK) {
+  if (!DoesMinMaxApply()) {
     return false;
   }
 
   Decimal maximum = GetMaximum();
   if (maximum.isNaN()) {
     return false;
   }
 
@@ -7375,18 +7374,17 @@ HTMLInputElement::IsRangeOverflow() cons
   }
 
   return value > maximum;
 }
 
 bool
 HTMLInputElement::IsRangeUnderflow() const
 {
-  // TODO: this is temporary until bug 888316 is fixed.
-  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_WEEK) {
+  if (!DoesMinMaxApply()) {
     return false;
   }
 
   Decimal minimum = GetMinimum();
   if (minimum.isNaN()) {
     return false;
   }
 
@@ -8381,18 +8379,17 @@ HTMLInputElement::UpdateHasRange()
 {
   /*
    * There is a range if min/max applies for the type and if the element
    * currently have a valid min or max.
    */
 
   mHasRange = false;
 
-  // TODO: this is temporary until bug 888316 is fixed.
-  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_WEEK) {
+  if (!DoesMinMaxApply()) {
     return;
   }
 
   Decimal minimum = GetMinimum();
   if (!minimum.isNaN()) {
     mHasRange = true;
     return;
   }
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1612,28 +1612,16 @@ nsresult HTMLMediaElement::LoadResource(
   nsCOMPtr<nsIDocShell> docShell = OwnerDoc()->GetDocShell();
   if (docShell && !docShell->GetAllowMedia()) {
     return NS_ERROR_FAILURE;
   }
 
   // Set the media element's CORS mode only when loading a resource
   mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
 
-  bool isBlob = false;
-  if (mMediaKeys &&
-      Preferences::GetBool("media.eme.mse-only", true) &&
-      // We only want mediaSource URLs, but they are BlobURL, so we have to
-      // check the schema and if they are not MediaStream or real Blob.
-      (NS_FAILED(mLoadingSrc->SchemeIs(BLOBURI_SCHEME, &isBlob)) ||
-       !isBlob ||
-       IsMediaStreamURI(mLoadingSrc) ||
-       IsBlobURI(mLoadingSrc))) {
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
-
   HTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
   if (other && other->mDecoder) {
     // Clone it.
     nsresult rv = InitializeDecoderAsClone(other->mDecoder);
     if (NS_SUCCEEDED(rv))
       return rv;
   }
 
--- a/dom/html/test/forms/test_max_attribute.html
+++ b/dom/html/test/forms/test_max_attribute.html
@@ -25,18 +25,17 @@ var data = [
   { type: 'search', apply: false },
   { type: 'tel', apply: false },
   { type: 'url', apply: false },
   { type: 'email', apply: false },
   { type: 'password', apply: false },
   { type: 'datetime', apply: true, todo: true },
   { type: 'date', apply: true },
   { type: 'month', apply: true },
-  // TODO: temporary set to false until bug 888316 is fixed.
-  { type: 'week', apply: false },
+  { type: 'week', apply: true },
   { type: 'time', apply: true },
   { type: 'datetime-local', apply: true, todo: true },
   { type: 'number', apply: true },
   { type: 'range', apply: true },
   { type: 'color', apply: false },
   { type: 'checkbox', apply: false },
   { type: 'radio', apply: false },
   { type: 'file', apply: false },
@@ -67,17 +66,17 @@ function checkValidity(aElement, aValidi
   aValidity = aApply ? aValidity : true;
 
   is(aElement.validity.valid, aValidity,
      "element validity should be " + aValidity);
   is(aElement.validity.rangeOverflow, !aValidity,
      "element overflow status should be " + !aValidity);
   var overflowMsg =
         (aElement.type == "date" || aElement.type == "time" ||
-         aElement.type == "month") ?
+         aElement.type == "month" || aElement.type == "week") ?
         ("Please select a value that is no later than " + aElement.max + ".") :
         ("Please select a value that is no more than " + aElement.max + ".");
   is(aElement.validationMessage,
      aValidity ? "" : overflowMsg, "Checking range overflow validation message");
 
   is(aElement.matches(":valid"), aElement.willValidate && aValidity,
      (aElement.willValidate && aValidity) ? ":valid should apply" : "valid shouldn't apply");
   is(aElement.matches(":invalid"), aElement.willValidate && !aValidity,
@@ -146,17 +145,17 @@ for (var test of data) {
       checkValidity(input, false, apply, apply);
       // Now make it something that won't cause an error below:
       input.max = '10';
       break;
     case 'month':
       input.max = '2016-12';
       break;
     case 'week':
-      // TODO: this is temporary until bug 888316 is fixed.
+      input.max = '2016-W39';
       break;
     default:
       ok(false, 'please, add a case for this new type (' + input.type + ')');
   }
 
   checkValidity(input, true, apply, apply);
 
   switch (input.type) {
@@ -378,18 +377,55 @@ for (var test of data) {
       input.value = '0049-12';
       checkValidity(input, true, apply, apply);
 
       input.max = '';
       checkValidity(input, true, apply, false);
 
       input.max = 'foo';
       checkValidity(input, true, apply, false);
+
+      break;
     case 'week':
-      // TODO: this is temporary until bug 888316 is fixed.
+      input.value = '2016-W01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2016-W39';
+      checkValidity(input, true, apply, apply);
+
+      input.value = 'foo';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2017-W01';
+      checkValidity(input, false, apply, apply);
+
+      input.max = '2017-W01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2017-W52';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '1000-W01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2100-W01';
+      checkValidity(input, false, apply, apply);
+
+      input.max = '0050-W01';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '0049-W52';
+      checkValidity(input, true, apply, apply);
+
+      input.max = '';
+      checkValidity(input, true, apply, false);
+
+      input.max = 'foo';
+      checkValidity(input, true, apply, false);
+
       break;
   }
 
   // Cleaning up,
   input.removeAttribute('max');
   input.value = '';
 }
 
--- a/dom/html/test/forms/test_min_attribute.html
+++ b/dom/html/test/forms/test_min_attribute.html
@@ -25,18 +25,17 @@ var data = [
   { type: 'search', apply: false },
   { type: 'tel', apply: false },
   { type: 'url', apply: false },
   { type: 'email', apply: false },
   { type: 'password', apply: false },
   { type: 'datetime', apply: true, todo: true },
   { type: 'date', apply: true },
   { type: 'month', apply: true },
-  // TODO: temporary set to false until bug 888316 is fixed.
-  { type: 'week', apply: false },
+  { type: 'week', apply: true },
   { type: 'time', apply: true },
   { type: 'datetime-local', apply: true, todo: true },
   { type: 'number', apply: true },
   { type: 'range', apply: true },
   { type: 'color', apply: false },
   { type: 'checkbox', apply: false },
   { type: 'radio', apply: false },
   { type: 'file', apply: false },
@@ -67,17 +66,17 @@ function checkValidity(aElement, aValidi
   aValidity = aApply ? aValidity : true;
 
   is(aElement.validity.valid, aValidity,
      "element validity should be " + aValidity);
   is(aElement.validity.rangeUnderflow, !aValidity,
      "element underflow status should be " + !aValidity);
   var underflowMsg =
         (aElement.type == "date" || aElement.type == "time" ||
-         aElement.type == "month") ?
+         aElement.type == "month" || aElement.type == "week") ?
         ("Please select a value that is no earlier than " + aElement.min + ".") :
         ("Please select a value that is no less than " + aElement.min + ".");
   is(aElement.validationMessage,
      aValidity ? "" : underflowMsg, "Checking range underflow validation message");
 
   is(aElement.matches(":valid"), aElement.willValidate && aValidity,
      (aElement.willValidate && aValidity) ? ":valid should apply" : "valid shouldn't apply");
   is(aElement.matches(":invalid"), aElement.willValidate && !aValidity,
@@ -142,17 +141,17 @@ for (var test of data) {
       // range is special, since setting min to 999 will make it invalid since
       // it's default maximum is 100, its value would be 999, and it would
       // suffer from overflow.
       break;
     case 'month':
       input.min = '2016-06';
       break;
     case 'week':
-      // TODO: this is temporary until bug 888316 is fixed.
+      input.min = "2016-W39";
       break;
     default:
       ok(false, 'please, add a case for this new type (' + input.type + ')');
   }
 
   // The element should still be valid and range should apply if it can.
   checkValidity(input, true, apply, apply);
 
@@ -376,17 +375,51 @@ for (var test of data) {
 
       input.min = '';
       checkValidity(input, true, apply, false);
 
       input.min = 'foo';
       checkValidity(input, true, apply, false);
       break;
     case 'week':
-      // TODO: this is temporary until bug 888316 is fixed.
+      input.value = '2016-W40';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2016-W39';
+      checkValidity(input, true, apply, apply);
+
+      input.value = 'foo';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2016-W38';
+      checkValidity(input, false, apply, apply);
+
+      input.min = '2016-W01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2015-W53';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '1000-W01';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '10000-01';
+      checkValidity(input, true, apply, apply);
+
+      input.min = '0010-W01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '0001-W01';
+      checkValidity(input, false, apply, apply);
+
+      input.min = '';
+      checkValidity(input, true, apply, false);
+
+      input.min = 'foo';
+      checkValidity(input, true, apply, false);
       break;
     default:
       ok(false, 'write tests for ' + input.type);
   }
 
   // Cleaning up,
   input.removeAttribute('min');
   input.value = '';
--- a/dom/indexedDB/IDBTransaction.cpp
+++ b/dom/indexedDB/IDBTransaction.cpp
@@ -634,17 +634,17 @@ IDBTransaction::AbortInternal(nsresult a
   AssertIsOnOwningThread();
   MOZ_ASSERT(NS_FAILED(aAbortCode));
   MOZ_ASSERT(!IsCommittingOrDone());
 
   RefPtr<DOMError> error = aError;
 
   const bool isVersionChange = mMode == VERSION_CHANGE;
   const bool isInvalidated = mDatabase->IsInvalidated();
-  bool needToSendAbort = mReadyState == INITIAL && !isInvalidated;
+  bool needToSendAbort = mReadyState == INITIAL;
 
   mAbortCode = aAbortCode;
   mReadyState = DONE;
   mError = error.forget();
 
   if (isVersionChange) {
     // If a version change transaction is aborted, we must revert the world
     // back to its previous state unless we're being invalidated after the
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -106,17 +106,17 @@ struct ShowInfo
 };
 
 union OptionalShmem
 {
   void_t;
   Shmem;
 };
 
-prio(normal upto urgent) sync protocol PBrowser
+nested(upto inside_cpow) sync protocol PBrowser
 {
     manager PContent or PContentBridge;
 
     manages PColorPicker;
     manages PDatePicker;
     manages PDocAccessible;
     manages PDocumentRenderer;
     manages PFilePicker;
@@ -199,145 +199,145 @@ parent:
     async DropLinks(nsString[] aLinks);
 
     async Event(RemoteDOMEvent aEvent);
 
     sync SyncMessage(nsString aMessage, ClonedMessageData aData,
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
-    prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
-                               CpowEntry[] aCpows, Principal aPrincipal)
+    nested(inside_sync) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
+                                        CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
     /**
      * Notifies chrome that there is a focus change involving an editable
      * object (input, textarea, document, contentEditable. etc.)
      *
      *  contentCache Cache of content
      *  notification Whole data of the notification
      *  preference   Native widget preference for IME updates
      */
-    prio(urgent) sync NotifyIMEFocus(ContentCache contentCache,
-                                     IMENotification notification)
+    nested(inside_cpow) sync NotifyIMEFocus(ContentCache contentCache,
+                                            IMENotification notification)
       returns (nsIMEUpdatePreference preference);
 
     /**
      * Notifies chrome that there has been a change in text content
      * One call can encompass both a delete and an insert operation
      * Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
      *
      *  contentCache Cache of content
      *  notification Whole data of the notification
      */
-    prio(urgent) async NotifyIMETextChange(ContentCache contentCache,
-                                           IMENotification notification);
+    nested(inside_cpow) async NotifyIMETextChange(ContentCache contentCache,
+                                                  IMENotification notification);
 
     /**
      * Notifies chrome that there is a IME compostion rect updated
      *
      *  contentCache Cache of content
      */
-    prio(urgent) async NotifyIMECompositionUpdate(ContentCache contentCache,
-                                                  IMENotification notification);
+    nested(inside_cpow) async NotifyIMECompositionUpdate(ContentCache contentCache,
+                                                         IMENotification notification);
 
     /**
      * Notifies chrome that there has been a change in selection
      * Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
      *
      *  contentCache Cache of content
      *  notification Whole data of the notification
      */
-    prio(urgent) async NotifyIMESelection(ContentCache contentCache,
-                                          IMENotification notification);
+    nested(inside_cpow) async NotifyIMESelection(ContentCache contentCache,
+                                                 IMENotification notification);
 
     /**
      * Notifies chrome of updating its content cache.
      * This is useful if content is modified but we don't need to notify IME.
      *
      *  contentCache Cache of content
      */
-    prio(urgent) async UpdateContentCache(ContentCache contentCache);
+    nested(inside_cpow) async UpdateContentCache(ContentCache contentCache);
 
     /**
      * Notifies IME of mouse button event on a character in focused editor.
      *
      * Returns true if the mouse button event is consumd by IME.
      */
-    prio(urgent) sync NotifyIMEMouseButtonEvent(IMENotification notification)
+    nested(inside_cpow) sync NotifyIMEMouseButtonEvent(IMENotification notification)
       returns (bool consumedByIME);
 
     /**
      * Notifies chrome to position change
      *
      *  contentCache Cache of content
      */
-    prio(urgent) async NotifyIMEPositionChange(ContentCache contentCache,
-                                               IMENotification notification);
+    nested(inside_cpow) async NotifyIMEPositionChange(ContentCache contentCache,
+                                                      IMENotification notification);
 
     /**
      * Requests chrome to commit or cancel composition of IME.
      *
      *  cancel                Set true if composition should be cancelled.
      *
      *  isCommitted           Returns true if the request causes composition
      *                        being committed synchronously.
      *  committedString       Returns committed string.  The may be non-empty
      *                        string even if cancel is true because IME may
      *                        try to restore selected string which was
      *                        replaced with the composition.
      */
-    prio(urgent) sync RequestIMEToCommitComposition(bool cancel)
+    nested(inside_cpow) sync RequestIMEToCommitComposition(bool cancel)
                         returns (bool isCommitted, nsString committedString);
 
     /**
      * OnEventNeedingAckHandled() is called after a child process dispatches a
      * composition event or a selection event which is sent from the parent
      * process.
      *
      * message      The message value of the handled event.
      */
-    prio(urgent) async OnEventNeedingAckHandled(EventMessage message);
+    nested(inside_cpow) async OnEventNeedingAckHandled(EventMessage message);
 
     /**
      * Tells chrome to start plugin IME.  If this results in a string getting
      * committed, the result is in aCommitted (otherwise aCommitted is empty).
      *
      * aKeyboardEvent     The event with which plugin IME is to be started
      * panelX and panelY  Location in screen coordinates of the IME input panel
      *                    (should be just under the plugin)
      * aCommitted         The string committed during IME -- otherwise empty
      */
-    prio(urgent) sync StartPluginIME(WidgetKeyboardEvent aKeyboardEvent,
-                                     int32_t panelX, int32_t panelY)
-                                     returns (nsString aCommitted);
+    nested(inside_cpow) sync StartPluginIME(WidgetKeyboardEvent aKeyboardEvent,
+                                            int32_t panelX, int32_t panelY)
+        returns (nsString aCommitted);
 
     /**
      * Tells chrome (and specifically the appropriate widget) whether or not
      * a plugin (inside the widget) has the keyboard focus.  Should be sent
      * when the keyboard focus changes too or from a plugin.
      *
      * aFocused  Whether or not a plugin is focused
      */
-    prio(urgent) async SetPluginFocused(bool aFocused);
+    nested(inside_cpow) async SetPluginFocused(bool aFocused);
 
     /**
      * Set IME candidate window by windowless plugin if plugin has focus.
      */
     async SetCandidateWindowForPlugin(CandidateWindowPosition aPosition);
 
     /**
      * Notifies the parent process of native key event data received in a
      * plugin process directly.
      *
      * aKeyEventData    The native key event data.  The actual type copied into
      *                  NativeEventData depending on the caller.  Please check
      *                  PluginInstanceChild.
      */
-    prio(urgent) async OnWindowedPluginKeyEvent(NativeEventData aKeyEventData);
+    nested(inside_cpow) async OnWindowedPluginKeyEvent(NativeEventData aKeyEventData);
 
     /**
      *  When plugin event isn't consumed, call this
      */
     async DefaultProcOfPluginEvent(WidgetPluginEvent aEvent);
 
     /**
      * Request that the parent process move focus to the browser's frame. If
@@ -348,26 +348,26 @@ parent:
     /**
      * Indicate, based on the current state, that some commands are enabled and
      * some are disabled.
      */
     async EnableDisableCommands(nsString action,
                                 nsCString[] enabledCommands,
                                 nsCString[] disabledCommands);
 
-    prio(urgent) sync GetInputContext() returns (int32_t IMEEnabled,
-                                                 int32_t IMEOpen);
+    nested(inside_cpow) sync GetInputContext() returns (int32_t IMEEnabled,
+                                                        int32_t IMEOpen);
 
-    prio(urgent) async SetInputContext(int32_t IMEEnabled,
-                                       int32_t IMEOpen,
-                                       nsString type,
-                                       nsString inputmode,
-                                       nsString actionHint,
-                                       int32_t cause,
-                                       int32_t focusChange);
+    nested(inside_cpow) async SetInputContext(int32_t IMEEnabled,
+                                              int32_t IMEOpen,
+                                              nsString type,
+                                              nsString inputmode,
+                                              nsString actionHint,
+                                              int32_t cause,
+                                              int32_t focusChange);
 
     sync IsParentWindowMainWidgetVisible() returns (bool visible);
 
     /**
      * Gets the DPI of the screen corresponding to this browser.
      */
     sync GetDPI() returns (float value);
 
@@ -574,19 +574,19 @@ parent:
     async ForcePaintNoOp(uint64_t aLayerObserverEpoch);
 
     /**
      * Sent by the child to the parent to inform it that an update to the
      * dimensions has been requested, likely through win.moveTo or resizeTo
      */
     async SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, int32_t aCx, int32_t aCy);
 
-    prio(high) sync DispatchWheelEvent(WidgetWheelEvent event);
-    prio(high) sync DispatchMouseEvent(WidgetMouseEvent event);
-    prio(high) sync DispatchKeyboardEvent(WidgetKeyboardEvent event);
+    nested(inside_sync) sync DispatchWheelEvent(WidgetWheelEvent event);
+    nested(inside_sync) sync DispatchMouseEvent(WidgetMouseEvent event);
+    nested(inside_sync) sync DispatchKeyboardEvent(WidgetKeyboardEvent event);
 
     async InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action,
                             OptionalShmem visualData,
                             uint32_t width, uint32_t height,
                             uint32_t stride, uint8_t format,
                             int32_t dragAreaX, int32_t dragAreaY);
 
     async AudioChannelActivityNotification(uint32_t aAudioChannel,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -372,17 +372,17 @@ union GetFilesResponseResult
 
 struct BlobURLRegistrationData
 {
     nsCString url;
     PBlob blob;
     Principal principal;
 };
 
-prio(normal upto urgent) sync protocol PContent
+nested(upto inside_cpow) sync protocol PContent
 {
     parent spawns PPluginModule;
 
     parent opens PProcessHangMonitor;
     parent opens PSharedBufferManager;
     parent opens PGMPService;
     child opens PBackground;
 
@@ -838,42 +838,42 @@ parent:
     sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
         returns (bool isSecureURI);
 
     async AccumulateMixedContentHSTS(URIParams uri, bool active, bool hasHSTSPriming);
 
     sync GetLookAndFeelCache()
         returns (LookAndFeelInt[] lookAndFeelIntCache);
 
-    prio(urgent) async PHal();
+    nested(inside_cpow) async PHal();
 
     async PHeapSnapshotTempFileHelper();
 
     async PIcc(uint32_t serviceId);
 
     async PMobileConnection(uint32_t clientId);
 
     async PNecko();
 
     async PPrinting();
 
     async PSendStream();
 
-    prio(high) sync PScreenManager()
+    nested(inside_sync) sync PScreenManager()
         returns (uint32_t numberOfScreens,
                  float systemDefaultScale,
                  bool success);
 
     async PCellBroadcast();
 
     async PSms();
 
     async PSpeechSynthesis();
 
-    prio(urgent) async PStorage();
+    nested(inside_cpow) async PStorage();
 
     async PTelephony();
 
     async PVoicemail();
 
     async PMedia();
 
     async PBluetooth();
@@ -903,18 +903,18 @@ parent:
 
     sync ReadDataStorageArray(nsString aFilename)
       returns (DataStorageItem[] retValue);
 
     sync SyncMessage(nsString aMessage, ClonedMessageData aData,
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
-    prio(high) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
-                               CpowEntry[] aCpows, Principal aPrincipal)
+    nested(inside_sync) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
+                                        CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
     async ShowAlert(AlertNotificationType alert);
 
     async CloseAlert(nsString name, Principal principal);
 
     async DisableNotifications(Principal principal);
 
@@ -1052,20 +1052,20 @@ parent:
 
     sync OpenAnonymousTemporaryFile() returns (FileDescOrError aFD);
 
     /**
      * Keygen requires us to call it after a <keygen> element is parsed and
      * before one is submitted. This is urgent because an extension might use
      * a CPOW to synchronously submit a keygen element.
      */
-    prio(urgent) sync KeygenProcessValue(nsString oldValue,
-                                         nsString challenge,
-                                         nsString keytype,
-                                         nsString keyparams)
+    nested(inside_cpow) sync KeygenProcessValue(nsString oldValue,
+                                                nsString challenge,
+                                                nsString keytype,
+                                                nsString keyparams)
         returns (nsString newValue);
 
     /**
      * Called to provide the options for <keygen> elements.
      */
     sync KeygenProvideContent()
         returns (nsString aAttribute, nsString[] aContent);
 
--- a/dom/ipc/PContentBridge.ipdl
+++ b/dom/ipc/PContentBridge.ipdl
@@ -27,17 +27,17 @@ namespace dom {
 /*
  * PContentBridge allows us to represent a parent/child relationship between two
  * child processes.  When a child process wants to open its own child, it asks
  * the root process to create a new process and then bridge them.  The first
  * child will allocate the PContentBridgeParent, and the newly opened child will
  * allocate the PContentBridgeChild.  This protocol allows these processes to
  * share PBrowsers and send messages to each other.
  */
-prio(normal upto urgent) sync protocol PContentBridge
+nested(upto inside_cpow) sync protocol PContentBridge
 {
     bridges PContent, PContent;
 
     manages PBlob;
     manages PBrowser;
     manages PFileDescriptorSet;
     manages PJavaScript;
     manages PSendStream;
--- a/dom/ipc/PScreenManager.ipdl
+++ b/dom/ipc/PScreenManager.ipdl
@@ -20,42 +20,42 @@ struct ScreenDetails {
   nsIntRect rectDisplayPix;
   nsIntRect availRect;
   nsIntRect availRectDisplayPix;
   int32_t pixelDepth;
   int32_t colorDepth;
   double contentsScaleFactor;
 };
 
-prio(normal upto high) sync protocol PScreenManager
+nested(upto inside_sync) sync protocol PScreenManager
 {
   manager PContent;
 
 parent:
-    prio(high) sync Refresh()
+    nested(inside_sync) sync Refresh()
       returns (uint32_t numberOfScreens,
                float systemDefaultScale,
                bool success);
 
-    prio(high) sync ScreenRefresh(uint32_t aId)
+    nested(inside_sync) sync ScreenRefresh(uint32_t aId)
       returns (ScreenDetails screen,
                bool success);
 
-    prio(high) sync GetPrimaryScreen()
+    nested(inside_sync) sync GetPrimaryScreen()
       returns (ScreenDetails screen,
                bool success);
 
-    prio(high) sync ScreenForRect(int32_t aLeft,
-                       int32_t aTop,
-                       int32_t aWidth,
-                       int32_t aHeight)
+    nested(inside_sync) sync ScreenForRect(int32_t aLeft,
+                                           int32_t aTop,
+                                           int32_t aWidth,
+                                           int32_t aHeight)
       returns (ScreenDetails screen,
                bool success);
 
-    prio(high) sync ScreenForBrowser(TabId aTabId)
+    nested(inside_sync) sync ScreenForBrowser(TabId aTabId)
       returns (ScreenDetails screen,
                bool success);
 
 child:
     async __delete__();
 };
 
 } // namespace dom
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -729,17 +729,16 @@ PluginModuleChromeParent::PluginModuleCh
                                                    uint32_t aPluginId,
                                                    int32_t aSandboxLevel,
                                                    bool aAllowAsyncInit)
     : PluginModuleParent(true, aAllowAsyncInit)
     , mSubprocess(new PluginProcessParent(aFilePath))
     , mPluginId(aPluginId)
     , mChromeTaskFactory(this)
     , mHangAnnotationFlags(0)
-    , mProtocolCallStackMutex("PluginModuleChromeParent::mProtocolCallStackMutex")
 #ifdef XP_WIN
     , mPluginCpuUsageOnHang()
     , mHangUIParent(nullptr)
     , mHangUIEnabled(true)
     , mIsTimerReset(true)
 #ifdef MOZ_CRASHREPORTER
     , mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex")
     , mCrashReporter(nullptr)
@@ -1001,50 +1000,16 @@ GetProcessCpuUsage(const InfallibleTArra
 
   return true;
 }
 
 } // namespace
 
 #endif // #ifdef XP_WIN
 
-void
-PluginModuleChromeParent::OnEnteredCall()
-{
-    mozilla::ipc::IProtocol* protocol = GetInvokingProtocol();
-    MOZ_ASSERT(protocol);
-    mozilla::MutexAutoLock lock(mProtocolCallStackMutex);
-    mProtocolCallStack.AppendElement(protocol);
-}
-
-void
-PluginModuleChromeParent::OnExitedCall()
-{
-    mozilla::MutexAutoLock lock(mProtocolCallStackMutex);
-    MOZ_ASSERT(!mProtocolCallStack.IsEmpty());
-    mProtocolCallStack.RemoveElementAt(mProtocolCallStack.Length() - 1);
-}
-
-void
-PluginModuleChromeParent::OnEnteredSyncSend()
-{
-    mozilla::ipc::IProtocol* protocol = GetInvokingProtocol();
-    MOZ_ASSERT(protocol);
-    mozilla::MutexAutoLock lock(mProtocolCallStackMutex);
-    mProtocolCallStack.AppendElement(protocol);
-}
-
-void
-PluginModuleChromeParent::OnExitedSyncSend()
-{
-    mozilla::MutexAutoLock lock(mProtocolCallStackMutex);
-    MOZ_ASSERT(!mProtocolCallStack.IsEmpty());
-    mProtocolCallStack.RemoveElementAt(mProtocolCallStack.Length() - 1);
-}
-
 /**
  * This function converts the topmost routing id on the call stack (as recorded
  * by the MessageChannel) into a pointer to a IProtocol object.
  */
 mozilla::ipc::IProtocol*
 PluginModuleChromeParent::GetInvokingProtocol()
 {
     int32_t routingId = GetIPCChannel()->GetTopmostMessageRoutingId();
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -487,21 +487,16 @@ class PluginModuleChromeParent
     void
     SetContentParent(dom::ContentParent* aContentParent);
 
     bool
     SendAssociatePluginId();
 
     void CachedSettingChanged();
 
-    void OnEnteredCall() override;
-    void OnExitedCall() override;
-    void OnEnteredSyncSend() override;
-    void OnExitedSyncSend() override;
-
 #ifdef  MOZ_ENABLE_PROFILER_SPS
     void GatherAsyncProfile();
     void GatheredAsyncProfile(nsIProfileSaveEvent* aSaveEvent);
     void StartProfiler(nsIProfilerStartParams* aParams);
     void StopProfiler();
 #endif
 
     virtual bool
@@ -587,18 +582,16 @@ private:
     enum HangAnnotationFlags
     {
         kInPluginCall = (1u << 0),
         kHangUIShown = (1u << 1),
         kHangUIContinued = (1u << 2),
         kHangUIDontShow = (1u << 3)
     };
     Atomic<uint32_t> mHangAnnotationFlags;
-    mozilla::Mutex mProtocolCallStackMutex;
-    InfallibleTArray<mozilla::ipc::IProtocol*> mProtocolCallStack;
 #ifdef XP_WIN
     InfallibleTArray<float> mPluginCpuUsageOnHang;
     PluginHangUIParent *mHangUIParent;
     bool mHangUIEnabled;
     bool mIsTimerReset;
 #ifdef MOZ_CRASHREPORTER
     /**
      * This mutex protects the crash reporter when the Plugin Hang UI event
--- a/dom/storage/PStorage.ipdl
+++ b/dom/storage/PStorage.ipdl
@@ -7,24 +7,24 @@
 include protocol PContent;
 
 namespace mozilla {
 namespace dom {
 
 /* This protocol bridges async access to the database thread running on the parent process
  * and caches running on the child process.
  */
-prio(normal upto urgent) sync protocol PStorage
+nested(upto inside_cpow) sync protocol PStorage
 {
   manager PContent;
 
 parent:
   async __delete__();
 
-  prio(urgent) sync Preload(nsCString originSuffix, nsCString originNoSuffix, uint32_t alreadyLoadedCount)
+  nested(inside_cpow) sync Preload(nsCString originSuffix, nsCString originNoSuffix, uint32_t alreadyLoadedCount)
     returns (nsString[] keys, nsString[] values, nsresult rv);
 
   async AsyncPreload(nsCString originSuffix, nsCString originNoSuffix, bool priority);
   async AsyncGetUsage(nsCString scope);
   async AsyncAddItem(nsCString originSuffix, nsCString originNoSuffix, nsString key, nsString value);
   async AsyncUpdateItem(nsCString originSuffix, nsCString originNoSuffix, nsString key, nsString value);
   async AsyncRemoveItem(nsCString originSuffix, nsCString originNoSuffix, nsString key);
   async AsyncClear(nsCString originSuffix, nsCString originNoSuffix);
--- a/dom/tests/mochitest/geolocation/geolocation_common.js
+++ b/dom/tests/mochitest/geolocation/geolocation_common.js
@@ -1,9 +1,10 @@
-var BASE_URL = "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs";
+var harness = SimpleTest.harnessParameters.testRoot == "chrome" ? "chrome" : "tests";
+var BASE_URL = "http://mochi.test:8888/" + harness + "/dom/tests/mochitest/geolocation/network_geolocation.sjs";
 
 function sleep(delay)
 {
     var start = Date.now();
     while (Date.now() < start + delay);
 }
 
 function force_prompt(allow, callback) {
--- a/dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html
+++ b/dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html
@@ -35,23 +35,30 @@ resume_geolocationProvider(function() {
 
 var successCallbackCalled = false;
 function successCallback(position) {
   successCallbackCalled = true;
   check_geolocation(position);
   while (!timeoutPassed) {
     SpecialPowers.spinEventLoop(window);
   }
-  ok(successCallbackCalled != errorCallbackCalled, "Ensure only one callback is called");
-  SimpleTest.finish();
+  info("TEST-INFO | successCallback called");
+  check();
 }
 
 var errorCallbackCalled = false;
 function errorCallback(error) {
   errorCallbackCalled = true;
+  info("TEST-INFO | errorCallback called");
+  check();
+}
+
+function check() {
+  ok(successCallbackCalled != errorCallbackCalled, "Ensure only one callback is called");
+  SimpleTest.finish();
 }
 
 var timeoutPassed = false;
 var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 function test1() {
   SpecialPowers.pushPrefEnv({"set": [["geo.wifi.timeToWaitBeforeSending", 10]]}, function() {
     navigator.geolocation.getCurrentPosition(successCallback, errorCallback, {timeout: 500});
     timer.initWithCallback(timer => {
--- a/dom/tests/moz.build
+++ b/dom/tests/moz.build
@@ -29,16 +29,17 @@ MOCHITEST_MANIFESTS += [
     'mochitest/webcomponents/mochitest.ini',
     'mochitest/whatwg/mochitest.ini',
 ]
 
 MOCHITEST_CHROME_MANIFESTS += [
     'mochitest/beacon/chrome.ini',
     'mochitest/chrome/chrome.ini',
     'mochitest/general/chrome.ini',
+    'mochitest/geolocation/chrome.ini',
     'mochitest/localstorage/chrome.ini',
     'mochitest/notification/chrome.ini',
     'mochitest/sessionstorage/chrome.ini',
     'mochitest/whatwg/chrome.ini',
 ]
 
 if CONFIG['MOZ_GAMEPAD']:
     MOCHITEST_MANIFESTS += [
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -44,16 +44,31 @@ RemoteContentController::RequestContentR
   MOZ_ASSERT(IsRepaintThread());
 
   if (mCanSend) {
     Unused << SendRequestContentRepaint(aFrameMetrics);
   }
 }
 
 void
+RemoteContentController::HandleTapOnMainThread(TapType aTapType,
+                                               const LayoutDevicePoint& aPoint,
+                                               Modifiers aModifiers,
+                                               const ScrollableLayerGuid& aGuid,
+                                               uint64_t aInputBlockId)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  dom::TabParent* tab = dom::TabParent::GetTabParentFromLayersId(aGuid.mLayersId);
+  if (tab) {
+    tab->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
+  }
+}
+
+void
 RemoteContentController::HandleTap(TapType aTapType,
                                    const LayoutDevicePoint& aPoint,
                                    Modifiers aModifiers,
                                    const ScrollableLayerGuid& aGuid,
                                    uint64_t aInputBlockId)
 {
   APZThreadUtils::AssertOnControllerThread();
 
@@ -61,38 +76,30 @@ RemoteContentController::HandleTap(TapTy
     MOZ_ASSERT(MessageLoop::current() == mCompositorThread);
 
     // The raw pointer to APZCTreeManagerParent is ok here because we are on the
     // compositor thread.
     APZCTreeManagerParent* apzctmp =
         CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId);
     if (apzctmp) {
       Unused << apzctmp->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
-      return;
     }
+
+    return;
   }
 
-  // If we get here we're probably in the parent process, but we might be in
-  // the GPU process in some shutdown phase where the LayerTreeState or
-  // APZCTreeManagerParent structures are torn down. In that case we'll just get
-  // a null TabParent.
-  dom::TabParent* tab = dom::TabParent::GetTabParentFromLayersId(aGuid.mLayersId);
-  if (tab) {
-    // If we got a TabParent we're definitely in the parent process, and the
-    // message is going to a child process.
-    //
-    // On desktop, we're already on the main thread, so we can call TabParent::SendHandleTap directly.
-    // On Android, we're on the UI thread, so proxy the SendHandleTap call to the main thread.
-    MOZ_ASSERT(XRE_IsParentProcess());
-    if (NS_IsMainThread()) {
-      tab->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
-    } else {
-      NS_DispatchToMainThread(NewRunnableMethod<TapType, const LayoutDevicePoint&, Modifiers, const ScrollableLayerGuid&, uint64_t>
-        (tab, &dom::TabParent::SendHandleTap, aTapType, aPoint, aModifiers, aGuid, aInputBlockId));
-    }
+  MOZ_ASSERT(XRE_IsParentProcess());
+
+  if (NS_IsMainThread()) {
+    HandleTapOnMainThread(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
+  } else {
+    // We don't want to get the TabParent or call TabParent::SendHandleTap() from a non-main thread (this might happen
+    // on Android, where this is called from the Java UI thread)
+    NS_DispatchToMainThread(NewRunnableMethod<TapType, const LayoutDevicePoint&, Modifiers, const ScrollableLayerGuid&, uint64_t>
+        (this, &RemoteContentController::HandleTapOnMainThread, aTapType, aPoint, aModifiers, aGuid, aInputBlockId));
   }
 }
 
 void
 RemoteContentController::NotifyPinchGesture(PinchGestureInput::PinchGestureType aType,
                                             const ScrollableLayerGuid& aGuid,
                                             LayoutDeviceCoord aSpanChange,
                                             Modifiers aModifiers)
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -81,16 +81,22 @@ public:
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   virtual void Destroy() override;
 
 private:
   MessageLoop* mCompositorThread;
   bool mCanSend;
 
+  void HandleTapOnMainThread(TapType aType,
+                             const LayoutDevicePoint& aPoint,
+                             Modifiers aModifiers,
+                             const ScrollableLayerGuid& aGuid,
+                             uint64_t aInputBlockId);
+
   // Mutex protecting members below accessed from multiple threads.
   mozilla::Mutex mMutex;
   nsRegion mTouchSensitiveRegion;
 };
 
 } // namespace layers
 
 } // namespace mozilla
--- a/hal/sandbox/PHal.ipdl
+++ b/hal/sandbox/PHal.ipdl
@@ -91,17 +91,17 @@ struct SystemTimezoneChangeInformation {
   int32_t oldTimezoneOffsetMinutes;
   int32_t newTimezoneOffsetMinutes;
 };
 
 } // namespace hal
 
 namespace hal_sandbox {
 
-prio(normal upto urgent) sync protocol PHal {
+nested(upto inside_cpow) sync protocol PHal {
     manager PContent;
 
 child:
     async NotifyBatteryChange(BatteryInformation aBatteryInfo);
     async NotifyNetworkChange(NetworkInformation aNetworkInfo);
     async NotifyWakeLockChange(WakeLockInformation aWakeLockInfo);
     async NotifyScreenConfigurationChange(ScreenConfiguration aScreenOrientation);
     async NotifySwitchChange(SwitchEvent aEvent);
@@ -151,17 +151,17 @@ parent:
                          uint64_t aProcessID);
     async EnableWakeLockNotifications();
     async DisableWakeLockNotifications();
     sync GetWakeLockInfo(nsString aTopic)
       returns (WakeLockInformation aWakeLockInfo);
 
     async EnableScreenConfigurationNotifications();
     async DisableScreenConfigurationNotifications();
-    prio(urgent) sync GetCurrentScreenConfiguration()
+    nested(inside_cpow) sync GetCurrentScreenConfiguration()
       returns (ScreenConfiguration aScreenConfiguration);
     sync LockScreenOrientation(ScreenOrientationInternal aOrientation)
       returns (bool allowed);
     async UnlockScreenOrientation();
  
     async EnableSwitchNotifications(SwitchDevice aDevice);
     async DisableSwitchNotifications(SwitchDevice aDevice);
     sync GetCurrentSwitchState(SwitchDevice aDevice)
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -258,18 +258,17 @@ bool Channel::ChannelImpl::CreatePipe(co
 void Channel::ChannelImpl::ResetFileDescriptor(int fd) {
   NS_ASSERTION(fd > 0 && fd == pipe_, "Invalid file descriptor");
 
   EnqueueHelloMessage();
 }
 
 bool Channel::ChannelImpl::EnqueueHelloMessage() {
   mozilla::UniquePtr<Message> msg(new Message(MSG_ROUTING_NONE,
-                                              HELLO_MESSAGE_TYPE,
-                                              IPC::Message::PRIORITY_NORMAL));
+                                              HELLO_MESSAGE_TYPE));
   if (!msg->WriteInt(base::GetCurrentProcId())) {
     Close();
     return false;
   }
 
   OutputQueuePush(msg.release());
   return true;
 }
@@ -495,18 +494,17 @@ bool Channel::ChannelImpl::ProcessIncomi
           // abort the connection
           return false;
         }
 
 #if defined(OS_MACOSX)
         // Send a message to the other side, indicating that we are now
         // responsible for closing the descriptor.
         Message *fdAck = new Message(MSG_ROUTING_NONE,
-                                     RECEIVED_FDS_MESSAGE_TYPE,
-                                     IPC::Message::PRIORITY_NORMAL);
+                                     RECEIVED_FDS_MESSAGE_TYPE);
         DCHECK(m.fd_cookie() != 0);
         fdAck->set_fd_cookie(m.fd_cookie());
         OutputQueuePush(fdAck);
 #endif
 
         m.file_descriptor_set()->SetDescriptors(
                                                 &fds[fds_i], m.header()->num_fds);
         fds_i += m.header()->num_fds;
--- a/ipc/chromium/src/chrome/common/ipc_channel_win.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_win.cc
@@ -223,18 +223,17 @@ bool Channel::ChannelImpl::CreatePipe(co
   }
 
   // Create the Hello message to be sent when Connect is called
   return EnqueueHelloMessage();
 }
 
 bool Channel::ChannelImpl::EnqueueHelloMessage() {
   mozilla::UniquePtr<Message> m = mozilla::MakeUnique<Message>(MSG_ROUTING_NONE,
-                                                               HELLO_MESSAGE_TYPE,
-                                                               IPC::Message::PRIORITY_NORMAL);
+                                                               HELLO_MESSAGE_TYPE);
 
   // If we're waiting for our shared secret from the other end's hello message
   // then don't give the game away by sending it in ours.
   int32_t secret = waiting_for_shared_secret_ ? 0 : shared_secret_;
 
   // Also, don't send if the value is zero (for IPC backwards compatability).
   if (!m->WriteInt(GetCurrentProcessId()) ||
       (secret && !m->WriteUInt32(secret)))
--- a/ipc/chromium/src/chrome/common/ipc_message.cc
+++ b/ipc/chromium/src/chrome/common/ipc_message.cc
@@ -40,23 +40,25 @@ Message::Message()
 #ifdef MOZ_TASK_TRACER
   header()->source_event_id = 0;
   header()->parent_task_id = 0;
   header()->source_event_type = SourceEventType::Unknown;
 #endif
   InitLoggingVariables();
 }
 
-Message::Message(int32_t routing_id, msgid_t type, PriorityValue priority,
+Message::Message(int32_t routing_id, msgid_t type, NestedLevel nestedLevel, PriorityValue priority,
                  MessageCompression compression, const char* const aName)
     : Pickle(sizeof(Header)) {
   MOZ_COUNT_CTOR(IPC::Message);
   header()->routing = routing_id;
   header()->type = type;
-  header()->flags = priority;
+  header()->flags = nestedLevel;
+  if (priority == HIGH_PRIORITY)
+    header()->flags |= PRIO_BIT;
   if (compression == COMPRESSION_ENABLED)
     header()->flags |= COMPRESS_BIT;
   else if (compression == COMPRESSION_ALL)
     header()->flags |= COMPRESSALL_BIT;
 #if defined(OS_POSIX)
   header()->num_fds = 0;
 #endif
   header()->interrupt_remote_stack_depth_guess = static_cast<uint32_t>(-1);
--- a/ipc/chromium/src/chrome/common/ipc_message.h
+++ b/ipc/chromium/src/chrome/common/ipc_message.h
@@ -33,52 +33,74 @@ namespace IPC {
 class Channel;
 class Message;
 struct LogData;
 
 class Message : public Pickle {
  public:
   typedef uint32_t msgid_t;
 
+  enum NestedLevel {
+    NOT_NESTED = 1,
+    NESTED_INSIDE_SYNC = 2,
+    NESTED_INSIDE_CPOW = 3
+  };
+
   enum PriorityValue {
-    PRIORITY_NORMAL = 1,
-    PRIORITY_HIGH = 2,
-    PRIORITY_URGENT = 3
+    NORMAL_PRIORITY,
+    HIGH_PRIORITY,
   };
 
   enum MessageCompression {
     COMPRESSION_NONE,
     COMPRESSION_ENABLED,
     COMPRESSION_ALL
   };
 
   virtual ~Message();
 
   Message();
 
   // Initialize a message with a user-defined type, priority value, and
   // destination WebView ID.
-  Message(int32_t routing_id, msgid_t type, PriorityValue priority,
+  Message(int32_t routing_id,
+          msgid_t type,
+          NestedLevel nestedLevel = NOT_NESTED,
+          PriorityValue priority = NORMAL_PRIORITY,
           MessageCompression compression = COMPRESSION_NONE,
           const char* const name="???");
 
   Message(const char* data, int data_len);
 
   Message(const Message& other) = delete;
   Message(Message&& other);
   Message& operator=(const Message& other) = delete;
   Message& operator=(Message&& other);
 
-  PriorityValue priority() const {
-    return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
+  NestedLevel nested_level() const {
+    return static_cast<NestedLevel>(header()->flags & NESTED_MASK);
+  }
+
+  void set_nested_level(NestedLevel nestedLevel) {
+    DCHECK((nestedLevel & ~NESTED_MASK) == 0);
+    header()->flags = (header()->flags & ~NESTED_MASK) | nestedLevel;
   }
 
-  void set_priority(int prio) {
-    DCHECK((prio & ~PRIORITY_MASK) == 0);
-    header()->flags = (header()->flags & ~PRIORITY_MASK) | prio;
+  PriorityValue priority() const {
+    if (header()->flags & PRIO_BIT) {
+      return HIGH_PRIORITY;
+    }
+    return NORMAL_PRIORITY;
+  }
+
+  void set_priority(PriorityValue prio) {
+    header()->flags &= ~PRIO_BIT;
+    if (prio == HIGH_PRIORITY) {
+      header()->flags |= PRIO_BIT;
+    }
   }
 
   // True if this is a synchronous message.
   bool is_sync() const {
     return (header()->flags & SYNC_BIT) != 0;
   }
 
   // True if this is a synchronous message.
@@ -109,37 +131,16 @@ class Message : public Pickle {
   void set_reply_error() {
     header()->flags |= REPLY_ERROR_BIT;
   }
 
   bool is_reply_error() const {
     return (header()->flags & REPLY_ERROR_BIT) != 0;
   }
 
-  // Normally when a receiver gets a message and they're blocked on a
-  // synchronous message Send, they buffer a message.  Setting this flag causes
-  // the receiver to be unblocked and the message to be dispatched immediately.
-  void set_unblock(bool unblock) {
-    if (unblock) {
-      header()->flags |= UNBLOCK_BIT;
-    } else {
-      header()->flags &= ~UNBLOCK_BIT;
-    }
-  }
-
-  bool should_unblock() const {
-    return (header()->flags & UNBLOCK_BIT) != 0;
-  }
-
-  // Tells the receiver that the caller is pumping messages while waiting
-  // for the result.
-  bool is_caller_pumping_messages() const {
-    return (header()->flags & PUMPING_MSGS_BIT) != 0;
-  }
-
   msgid_t type() const {
     return header()->type;
   }
 
   int32_t routing_id() const {
     return header()->routing;
   }
 
@@ -264,26 +265,24 @@ class Message : public Pickle {
   }
 
 #if !defined(OS_MACOSX)
  protected:
 #endif
 
   // flags
   enum {
-    PRIORITY_MASK   = 0x0003,
-    SYNC_BIT        = 0x0004,
-    REPLY_BIT       = 0x0008,
-    REPLY_ERROR_BIT = 0x0010,
-    UNBLOCK_BIT     = 0x0020,
-    PUMPING_MSGS_BIT= 0x0040,
-    HAS_SENT_TIME_BIT = 0x0080,
-    INTERRUPT_BIT   = 0x0100,
-    COMPRESS_BIT    = 0x0200,
-    COMPRESSALL_BIT = 0x0400,
+    NESTED_MASK     = 0x0003,
+    PRIO_BIT        = 0x0004,
+    SYNC_BIT        = 0x0008,
+    REPLY_BIT       = 0x0010,
+    REPLY_ERROR_BIT = 0x0020,
+    INTERRUPT_BIT   = 0x0040,
+    COMPRESS_BIT    = 0x0080,
+    COMPRESSALL_BIT = 0x0100,
   };
 
   struct Header : Pickle::Header {
     int32_t routing;  // ID of the view that this message is destined for
     msgid_t type;   // specifies the user-defined message type
     uint32_t flags;   // specifies control flags for the message
 #if defined(OS_POSIX)
     uint32_t num_fds; // the number of descriptors included with this message
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -34,62 +34,67 @@ using mozilla::Move;
 static mozilla::LazyLogModule sLogModule("ipc");
 #define IPC_LOG(...) MOZ_LOG(sLogModule, LogLevel::Debug, (__VA_ARGS__))
 #endif
 
 /*
  * IPC design:
  *
  * There are three kinds of messages: async, sync, and intr. Sync and intr
- * messages are blocking. Only intr and high-priority sync messages can nest.
+ * messages are blocking.
  *
  * Terminology: To dispatch a message Foo is to run the RecvFoo code for
  * it. This is also called "handling" the message.
  *
- * Sync and async messages have priorities while intr messages always have
- * normal priority. The three possible priorities are normal, high, and urgent.
- * The intended uses of these priorities are:
- *   NORMAL - most messages.
- *   HIGH   - CPOW-related messages, which can go in either direction.
- *   URGENT - messages where we don't want to dispatch
- *            incoming CPOWs while waiting for the response.
- * Async messages cannot have HIGH priority.
+ * Sync and async messages can sometimes "nest" inside other sync messages
+ * (i.e., while waiting for the sync reply, we can dispatch the inner
+ * message). Intr messages cannot nest.  The three possible nesting levels are
+ * NOT_NESTED, NESTED_INSIDE_SYNC, and NESTED_INSIDE_CPOW.  The intended uses
+ * are:
+ *   NOT_NESTED - most messages.
+ *   NESTED_INSIDE_SYNC - CPOW-related messages, which are always sync
+ *                        and can go in either direction.
+ *   NESTED_INSIDE_CPOW - messages where we don't want to dispatch
+ *                        incoming CPOWs while waiting for the response.
+ * These nesting levels are ordered: NOT_NESTED, NESTED_INSIDE_SYNC,
+ * NESTED_INSIDE_CPOW.  Async messages cannot be NESTED_INSIDE_SYNC but they can
+ * be NESTED_INSIDE_CPOW.
  *
- * To avoid jank, the parent process is not allowed to send sync messages of
- * normal priority. When a process is waiting for a response to a sync message
+ * To avoid jank, the parent process is not allowed to send NOT_NESTED sync messages.
+ * When a process is waiting for a response to a sync message
  * M0, it will dispatch an incoming message M if:
- *   1. M has a higher priority than M0, or
- *   2. if M has the same priority as M0 and we're in the child, or
- *   3. if M has the same priority as M0 and it was sent by the other side
- *      while dispatching M0 (nesting).
- * The idea is that higher priority messages should take precendence, and we
- * also want to allow nesting. The purpose of rule 2 is to handle a race where
- * both processes send to each other simultaneously. In this case, we resolve
- * the race in favor of the parent (so the child dispatches first).
+ *   1. M has a higher nesting level than M0, or
+ *   2. if M has the same nesting level as M0 and we're in the child, or
+ *   3. if M has the same nesting level as M0 and it was sent by the other side
+ *      while dispatching M0.
+ * The idea is that messages with higher nesting should take precendence. The
+ * purpose of rule 2 is to handle a race where both processes send to each other
+ * simultaneously. In this case, we resolve the race in favor of the parent (so
+ * the child dispatches first).
  *
  * Messages satisfy the following properties:
  *   A. When waiting for a response to a sync message, we won't dispatch any
- *      messages of lower priority.
- *   B. Messages of the same priority will be dispatched roughly in the
+ *      messages of nesting level.
+ *   B. Messages of the same nesting level will be dispatched roughly in the
  *      order they were sent. The exception is when the parent and child send
  *      sync messages to each other simulataneously. In this case, the parent's
  *      message is dispatched first. While it is dispatched, the child may send
  *      further nested messages, and these messages may be dispatched before the
  *      child's original message. We can consider ordering to be preserved here
  *      because we pretend that the child's original message wasn't sent until
  *      after the parent's message is finished being dispatched.
  *
  * When waiting for a sync message reply, we dispatch an async message only if
- * it has URGENT priority. Normally URGENT async messages are sent only from the
- * child. However, the parent can send URGENT async messages when it is creating
- * a bridged protocol.
+ * it is NESTED_INSIDE_CPOW. Normally NESTED_INSIDE_CPOW async
+ * messages are sent only from the child. However, the parent can send
+ * NESTED_INSIDE_CPOW async messages when it is creating a bridged protocol.
  *
- * Intr messages are blocking but not prioritized. While waiting for an intr
- * response, all incoming messages are dispatched until a response is
- * received. Intr messages also can be nested. When two intr messages race with
+ * Intr messages are blocking and can nest, but they don't participate in the
+ * nesting levels. While waiting for an intr response, all incoming messages are
+ * dispatched until a response is received. When two intr messages race with
  * each other, a similar scheme is used to ensure that one side wins. The
  * winning side is chosen based on the message type.
  *
  * Intr messages differ from sync messages in that, while sending an intr
  * message, we may dispatch an async message. This causes some additional
  * complexity. One issue is that replies can be received out of order. It's also
  * more difficult to determine whether one message is nested inside
  * another. Consequently, intr handling uses mOutOfTurnReplies and
@@ -282,34 +287,34 @@ private:
 };
 
 class AutoEnterTransaction
 {
 public:
     explicit AutoEnterTransaction(MessageChannel *aChan,
                                   int32_t aMsgSeqno,
                                   int32_t aTransactionID,
-                                  int aPriority)
+                                  int aNestedLevel)
       : mChan(aChan),
         mActive(true),
         mOutgoing(true),
-        mPriority(aPriority),
+        mNestedLevel(aNestedLevel),
         mSeqno(aMsgSeqno),
         mTransaction(aTransactionID),
         mNext(mChan->mTransactionStack)
     {
         mChan->mMonitor->AssertCurrentThreadOwns();
         mChan->mTransactionStack = this;
     }
 
     explicit AutoEnterTransaction(MessageChannel *aChan, const IPC::Message &aMessage)
       : mChan(aChan),
         mActive(true),
         mOutgoing(false),
-        mPriority(aMessage.priority()),
+        mNestedLevel(aMessage.nested_level()),
         mSeqno(aMessage.seqno()),
         mTransaction(aMessage.transaction_id()),
         mNext(mChan->mTransactionStack)
     {
         mChan->mMonitor->AssertCurrentThreadOwns();
 
         if (!aMessage.is_sync()) {
             mActive = false;
@@ -324,21 +329,21 @@ public:
         if (mActive) {
             mChan->mTransactionStack = mNext;
         }
     }
 
     void Cancel() {
         AutoEnterTransaction *cur = mChan->mTransactionStack;
         MOZ_RELEASE_ASSERT(cur == this);
-        while (cur && cur->mPriority != IPC::Message::PRIORITY_NORMAL) {
+        while (cur && cur->mNestedLevel != IPC::Message::NOT_NESTED) {
             // Note that, in the following situation, we will cancel multiple
             // transactions:
-            // 1. Parent sends high prio message P1 to child.
-            // 2. Child sends high prio message C1 to child.
+            // 1. Parent sends NESTED_INSIDE_SYNC message P1 to child.
+            // 2. Child sends NESTED_INSIDE_SYNC message C1 to child.
             // 3. Child dispatches P1, parent blocks.
             // 4. Child cancels.
             // In this case, both P1 and C1 are cancelled. The parent will
             // remove C1 from its queue when it gets the cancellation message.
             MOZ_RELEASE_ASSERT(cur->mActive);
             cur->mActive = false;
             cur = cur->mNext;
         }
@@ -351,43 +356,43 @@ public:
     bool AwaitingSyncReply() const {
         MOZ_RELEASE_ASSERT(mActive);
         if (mOutgoing) {
             return true;
         }
         return mNext ? mNext->AwaitingSyncReply() : false;
     }
 
-    int AwaitingSyncReplyPriority() const {
+    int AwaitingSyncReplyNestedLevel() const {
         MOZ_RELEASE_ASSERT(mActive);
         if (mOutgoing) {
-            return mPriority;
+            return mNestedLevel;
         }
-        return mNext ? mNext->AwaitingSyncReplyPriority() : 0;
+        return mNext ? mNext->AwaitingSyncReplyNestedLevel() : 0;
     }
 
     bool DispatchingSyncMessage() const {
         MOZ_RELEASE_ASSERT(mActive);
         if (!mOutgoing) {
             return true;
         }
         return mNext ? mNext->DispatchingSyncMessage() : false;
     }
 
-    int DispatchingSyncMessagePriority() const {
+    int DispatchingSyncMessageNestedLevel() const {
         MOZ_RELEASE_ASSERT(mActive);
         if (!mOutgoing) {
-            return mPriority;
+            return mNestedLevel;
         }
-        return mNext ? mNext->DispatchingSyncMessagePriority() : 0;
+        return mNext ? mNext->DispatchingSyncMessageNestedLevel() : 0;
     }
 
-    int Priority() const {
+    int NestedLevel() const {
         MOZ_RELEASE_ASSERT(mActive);
-        return mPriority;
+        return mNestedLevel;
     }
 
     int32_t SequenceNumber() const {
         MOZ_RELEASE_ASSERT(mActive);
         return mSeqno;
     }
 
     int32_t TransactionID() const {
@@ -451,17 +456,17 @@ private:
     // or if it was for a message that doesn't require transactions (an async
     // message).
     bool mActive;
 
     // Is this stack frame for an outgoing message?
     bool mOutgoing;
 
     // Properties of the message being sent/received.
-    int mPriority;
+    int mNestedLevel;
     int32_t mSeqno;
     int32_t mTransaction;
 
     // Next item in mChan->mTransactionStack.
     AutoEnterTransaction *mNext;
 
     // Pointer the a reply received for this message, if one was received.
     nsAutoPtr<IPC::Message> mReply;
@@ -475,20 +480,20 @@ MessageChannel::MessageChannel(MessageLi
     mWorkerLoop(nullptr),
     mChannelErrorTask(nullptr),
     mWorkerLoopID(-1),
     mTimeoutMs(kNoTimeout),
     mInTimeoutSecondHalf(false),
     mNextSeqno(0),
     mLastSendError(SyncSendError::SendSuccess),
     mDispatchingAsyncMessage(false),
-    mDispatchingAsyncMessagePriority(0),
+    mDispatchingAsyncMessageNestedLevel(0),
     mTransactionStack(nullptr),
     mTimedOutMessageSeqno(0),
-    mTimedOutMessagePriority(0),
+    mTimedOutMessageNestedLevel(0),
 #if defined(MOZ_CRASHREPORTER) && defined(OS_WIN)
     mPending(AnnotateAllocator<Message>(*this)),
 #endif
     mRemoteStackDepthGuess(false),
     mSawInterruptOutMsg(false),
     mIsWaitingForIncoming(false),
     mAbortOnError(false),
     mNotifiedChannelDone(false),
@@ -538,55 +543,55 @@ MessageChannel::~MessageChannel()
 #endif
     Clear();
 }
 
 // This function returns the current transaction ID. Since the notion of a
 // "current transaction" can be hard to define when messages race with each
 // other and one gets canceled and the other doesn't, we require that this
 // function is only called when the current transaction is known to be for a
-// high priority message. In that case, we know for sure what the caller is
+// NESTED_INSIDE_SYNC message. In that case, we know for sure what the caller is
 // looking for.
 int32_t
-MessageChannel::CurrentHighPriorityTransaction() const
+MessageChannel::CurrentNestedInsideSyncTransaction() const
 {
     mMonitor->AssertCurrentThreadOwns();
     if (!mTransactionStack) {
         return 0;
     }
-    MOZ_RELEASE_ASSERT(mTransactionStack->Priority() == IPC::Message::PRIORITY_HIGH);
+    MOZ_RELEASE_ASSERT(mTransactionStack->NestedLevel() == IPC::Message::NESTED_INSIDE_SYNC);
     return mTransactionStack->TransactionID();
 }
 
 bool
 MessageChannel::AwaitingSyncReply() const
 {
     mMonitor->AssertCurrentThreadOwns();
     return mTransactionStack ? mTransactionStack->AwaitingSyncReply() : false;
 }
 
 int
-MessageChannel::AwaitingSyncReplyPriority() const
+MessageChannel::AwaitingSyncReplyNestedLevel() const
 {
     mMonitor->AssertCurrentThreadOwns();
-    return mTransactionStack ? mTransactionStack->AwaitingSyncReplyPriority() : 0;
+    return mTransactionStack ? mTransactionStack->AwaitingSyncReplyNestedLevel() : 0;
 }
 
 bool
 MessageChannel::DispatchingSyncMessage() const
 {
     mMonitor->AssertCurrentThreadOwns();
     return mTransactionStack ? mTransactionStack->DispatchingSyncMessage() : false;
 }
 
 int
-MessageChannel::DispatchingSyncMessagePriority() const
+MessageChannel::DispatchingSyncMessageNestedLevel() const
 {
     mMonitor->AssertCurrentThreadOwns();
-    return mTransactionStack ? mTransactionStack->DispatchingSyncMessagePriority() : 0;
+    return mTransactionStack ? mTransactionStack->DispatchingSyncMessageNestedLevel() : 0;
 }
 
 static void
 PrintErrorMessage(Side side, const char* channelName, const char* msg)
 {
     const char *from = (side == ChildSide)
                        ? "Child"
                        : ((side == ParentSide) ? "Parent" : "Unknown");
@@ -766,18 +771,17 @@ bool
 MessageChannel::Send(Message* aMsg)
 {
     if (aMsg->size() >= kMinTelemetryMessageSize) {
         Telemetry::Accumulate(Telemetry::IPC_MESSAGE_SIZE,
                               nsDependentCString(aMsg->name()), aMsg->size());
     }
 
     MOZ_RELEASE_ASSERT(!aMsg->is_sync());
-    // We never send an async high priority message.
-    MOZ_RELEASE_ASSERT(aMsg->priority() != IPC::Message::PRIORITY_HIGH);
+    MOZ_RELEASE_ASSERT(aMsg->nested_level() != IPC::Message::NESTED_INSIDE_SYNC);
 
     CxxStackFrame frame(*this, OUT_MESSAGE, aMsg);
 
     nsAutoPtr<Message> msg(aMsg);
     AssertWorkerThread();
     mMonitor->AssertNotCurrentThreadOwns();
     if (MSG_ROUTING_NONE == msg->routing_id()) {
         ReportMessageRouteError("MessageChannel::Send");
@@ -792,17 +796,17 @@ MessageChannel::Send(Message* aMsg)
     mLink->SendMessage(msg.forget());
     return true;
 }
 
 class CancelMessage : public IPC::Message
 {
 public:
     explicit CancelMessage(int transaction) :
-        IPC::Message(MSG_ROUTING_NONE, CANCEL_MESSAGE_TYPE, PRIORITY_NORMAL)
+        IPC::Message(MSG_ROUTING_NONE, CANCEL_MESSAGE_TYPE)
     {
         set_transaction_id(transaction);
     }
     static bool Read(const Message* msg) {
         return true;
     }
     void Log(const std::string& aPrefix, FILE* aOutf) const {
         fputs("(special `Cancel' message)", aOutf);
@@ -833,51 +837,51 @@ MessageChannel::MaybeInterceptSpecialIOM
         }
     }
     return false;
 }
 
 bool
 MessageChannel::ShouldDeferMessage(const Message& aMsg)
 {
-    // Never defer messages that have the highest priority, even async
+    // Never defer messages that have the highest nested level, even async
     // ones. This is safe because only the child can send these messages, so
     // they can never nest.
-    if (aMsg.priority() == IPC::Message::PRIORITY_URGENT)
+    if (aMsg.nested_level() == IPC::Message::NESTED_INSIDE_CPOW)
         return false;
 
-    // Unless they're urgent, we always defer async messages.
-    // Note that we never send an async high priority message.
+    // Unless they're NESTED_INSIDE_CPOW, we always defer async messages.
+    // Note that we never send an async NESTED_INSIDE_SYNC message.
     if (!aMsg.is_sync()) {
-        MOZ_RELEASE_ASSERT(aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
+        MOZ_RELEASE_ASSERT(aMsg.nested_level() == IPC::Message::NOT_NESTED);
         return true;
     }
 
-    int msgPrio = aMsg.priority();
-    int waitingPrio = AwaitingSyncReplyPriority();
+    int msgNestedLevel = aMsg.nested_level();
+    int waitingNestedLevel = AwaitingSyncReplyNestedLevel();
 
-    // Always defer if the priority of the incoming message is less than the
-    // priority of the message we're awaiting.
-    if (msgPrio < waitingPrio)
+    // Always defer if the nested level of the incoming message is less than the
+    // nested level of the message we're awaiting.
+    if (msgNestedLevel < waitingNestedLevel)
         return true;
 
-    // Never defer if the message has strictly greater priority.
-    if (msgPrio > waitingPrio)
+    // Never defer if the message has strictly greater nested level.
+    if (msgNestedLevel > waitingNestedLevel)
         return false;
 
-    // When both sides send sync messages of the same priority, we resolve the
+    // When both sides send sync messages of the same nested level, we resolve the
     // race by dispatching in the child and deferring the incoming message in
     // the parent. However, the parent still needs to dispatch nested sync
     // messages.
     //
     // Deferring in the parent only sort of breaks message ordering. When the
     // child's message comes in, we can pretend the child hasn't quite
     // finished sending it yet. Since the message is sync, we know that the
     // child hasn't moved on yet.
-    return mSide == ParentSide && aMsg.transaction_id() != CurrentHighPriorityTransaction();
+    return mSide == ParentSide && aMsg.transaction_id() != CurrentNestedInsideSyncTransaction();
 }
 
 // Predicate that is true for messages that should be consolidated if 'compress' is set.
 class MatchingKinds {
     typedef IPC::Message Message;
     Message::msgid_t mType;
     int32_t mRoutingId;
 public:
@@ -912,19 +916,19 @@ MessageChannel::OnMessageReceivedFromLin
         MOZ_RELEASE_ASSERT(AwaitingSyncReply());
         MOZ_RELEASE_ASSERT(!mTimedOutMessageSeqno);
 
         mTransactionStack->HandleReply(Move(aMsg));
         NotifyWorkerThread();
         return;
     }
 
-    // Prioritized messages cannot be compressed.
+    // Nested messages cannot be compressed.
     MOZ_RELEASE_ASSERT(aMsg.compress_type() == IPC::Message::COMPRESSION_NONE ||
-                       aMsg.priority() == IPC::Message::PRIORITY_NORMAL);
+                       aMsg.nested_level() == IPC::Message::NOT_NESTED);
 
     bool compress = false;
     if (aMsg.compress_type() == IPC::Message::COMPRESSION_ENABLED) {
         compress = (!mPending.empty() &&
                     mPending.back().type() == aMsg.type() &&
                     mPending.back().routing_id() == aMsg.routing_id());
         if (compress) {
             // This message type has compression enabled, and the back of the
@@ -964,17 +968,17 @@ MessageChannel::OnMessageReceivedFromLin
     IPC_LOG("Receive on link thread; seqno=%d, xid=%d, shouldWakeUp=%d",
             aMsg.seqno(), aMsg.transaction_id(), shouldWakeUp);
 
     // There are three cases we're concerned about, relating to the state of the
     // main thread:
     //
     // (1) We are waiting on a sync reply - main thread is blocked on the
     //     IPC monitor.
-    //   - If the message is high priority, we wake up the main thread to
+    //   - If the message is NESTED_INSIDE_SYNC, we wake up the main thread to
     //     deliver the message depending on ShouldDeferMessage. Otherwise, we
     //     leave it in the mPending queue, posting a task to the main event
     //     loop, where it will be processed once the synchronous reply has been
     //     received.
     //
     // (2) We are waiting on an Interrupt reply - main thread is blocked on the
     //     IPC monitor.
     //   - Always notify and wake up the main thread.
@@ -1016,38 +1020,38 @@ MessageChannel::PeekMessages(mozilla::fu
 }
 
 void
 MessageChannel::ProcessPendingRequests(AutoEnterTransaction& aTransaction)
 {
     IPC_LOG("ProcessPendingRequests for seqno=%d, xid=%d",
             aTransaction.SequenceNumber(), aTransaction.TransactionID());
 
-    // Loop until there aren't any more priority messages to process.
+    // Loop until there aren't any more nested messages to process.
     for (;;) {
         // If we canceled during ProcessPendingRequest, then we need to leave
         // immediately because the results of ShouldDeferMessage will be
         // operating with weird state (as if no Send is in progress). That could
-        // cause even normal priority sync messages to be processed (but not
-        // normal priority async messages), which would break message ordering.
+        // cause even NOT_NESTED sync messages to be processed (but not
+        // NOT_NESTED async messages), which would break message ordering.
         if (aTransaction.IsCanceled()) {
             return;
         }
 
         mozilla::Vector<Message> toProcess;
 
         for (MessageQueue::iterator it = mPending.begin(); it != mPending.end(); ) {
             Message &msg = *it;
 
             MOZ_RELEASE_ASSERT(!aTransaction.IsCanceled(),
                                "Calling ShouldDeferMessage when cancelled");
             bool defer = ShouldDeferMessage(msg);
 
             // Only log the interesting messages.
-            if (msg.is_sync() || msg.priority() == IPC::Message::PRIORITY_URGENT) {
+            if (msg.is_sync() || msg.nested_level() == IPC::Message::NESTED_INSIDE_CPOW) {
                 IPC_LOG("ShouldDeferMessage(seqno=%d) = %d", msg.seqno(), defer);
             }
 
             if (!defer) {
                 if (!toProcess.append(Move(msg)))
                     MOZ_CRASH();
                 it = mPending.erase(it);
                 continue;
@@ -1096,84 +1100,84 @@ MessageChannel::Send(Message* aMsg, Mess
         // and we haven't received a reply for it. Once the original timed-out
         // message receives a reply, we'll be able to send more sync messages
         // again.
         IPC_LOG("Send() failed due to previous timeout");
         mLastSendError = SyncSendError::PreviousTimeout;
         return false;
     }
 
-    if (DispatchingSyncMessagePriority() == IPC::Message::PRIORITY_NORMAL &&
-        msg->priority() > IPC::Message::PRIORITY_NORMAL)
+    if (DispatchingSyncMessageNestedLevel() == IPC::Message::NOT_NESTED &&
+        msg->nested_level() > IPC::Message::NOT_NESTED)
     {
         // Don't allow sending CPOWs while we're dispatching a sync message.
         // If you want to do that, use sendRpcMessage instead.
-        IPC_LOG("Prio forbids send");
+        IPC_LOG("Nested level forbids send");
         mLastSendError = SyncSendError::SendingCPOWWhileDispatchingSync;
         return false;
     }
 
-    if (DispatchingSyncMessagePriority() == IPC::Message::PRIORITY_URGENT ||
-        DispatchingAsyncMessagePriority() == IPC::Message::PRIORITY_URGENT)
+    if (DispatchingSyncMessageNestedLevel() == IPC::Message::NESTED_INSIDE_CPOW ||
+        DispatchingAsyncMessageNestedLevel() == IPC::Message::NESTED_INSIDE_CPOW)
     {
         // Generally only the parent dispatches urgent messages. And the only
-        // sync messages it can send are high-priority. Mainly we want to ensure
+        // sync messages it can send are NESTED_INSIDE_SYNC. Mainly we want to ensure
         // here that we don't return false for non-CPOW messages.
-        MOZ_RELEASE_ASSERT(msg->priority() == IPC::Message::PRIORITY_HIGH);
+        MOZ_RELEASE_ASSERT(msg->nested_level() == IPC::Message::NESTED_INSIDE_SYNC);
         IPC_LOG("Sending while dispatching urgent message");
         mLastSendError = SyncSendError::SendingCPOWWhileDispatchingUrgent;
         return false;
     }
 
-    if (msg->priority() < DispatchingSyncMessagePriority() ||
-        msg->priority() < AwaitingSyncReplyPriority())
+    if (msg->nested_level() < DispatchingSyncMessageNestedLevel() ||
+        msg->nested_level() < AwaitingSyncReplyNestedLevel())
     {
         MOZ_RELEASE_ASSERT(DispatchingSyncMessage() || DispatchingAsyncMessage());
         IPC_LOG("Cancel from Send");
-        CancelMessage *cancel = new CancelMessage(CurrentHighPriorityTransaction());
-        CancelTransaction(CurrentHighPriorityTransaction());
+        CancelMessage *cancel = new CancelMessage(CurrentNestedInsideSyncTransaction());
+        CancelTransaction(CurrentNestedInsideSyncTransaction());
         mLink->SendMessage(cancel);
     }
 
     IPC_ASSERT(msg->is_sync(), "can only Send() sync messages here");
 
-    IPC_ASSERT(msg->priority() >= DispatchingSyncMessagePriority(),
-               "can't send sync message of a lesser priority than what's being dispatched");
-    IPC_ASSERT(AwaitingSyncReplyPriority() <= msg->priority(),
-               "nested sync message sends must be of increasing priority");
-    IPC_ASSERT(DispatchingSyncMessagePriority() != IPC::Message::PRIORITY_URGENT,
+    IPC_ASSERT(msg->nested_level() >= DispatchingSyncMessageNestedLevel(),
+               "can't send sync message of a lesser nested level than what's being dispatched");
+    IPC_ASSERT(AwaitingSyncReplyNestedLevel() <= msg->nested_level(),
+               "nested sync message sends must be of increasing nested level");
+    IPC_ASSERT(DispatchingSyncMessageNestedLevel() != IPC::Message::NESTED_INSIDE_CPOW,
                "not allowed to send messages while dispatching urgent messages");
 
-    IPC_ASSERT(DispatchingAsyncMessagePriority() != IPC::Message::PRIORITY_URGENT,
+    IPC_ASSERT(DispatchingAsyncMessageNestedLevel() != IPC::Message::NESTED_INSIDE_CPOW,
                "not allowed to send messages while dispatching urgent messages");
 
     if (!Connected()) {
         ReportConnectionError("MessageChannel::SendAndWait", msg);
         mLastSendError = SyncSendError::NotConnectedBeforeSend;
         return false;
     }
 
     msg->set_seqno(NextSeqno());
 
     int32_t seqno = msg->seqno();
-    int prio = msg->priority();
+    int nestedLevel = msg->nested_level();
     msgid_t replyType = msg->type() + 1;
 
     AutoEnterTransaction *stackTop = mTransactionStack;
 
-    // If the most recent message on the stack is high priority, then our
+    // If the most recent message on the stack is NESTED_INSIDE_SYNC, then our
     // message should nest inside that and we use the same transaction
     // ID. Otherwise we need a new transaction ID (so we use the seqno of the
     // message we're sending).
-    bool nest = stackTop && stackTop->Priority() == IPC::Message::PRIORITY_HIGH;
+    bool nest = stackTop && stackTop->NestedLevel() == IPC::Message::NESTED_INSIDE_SYNC;
     int32_t transaction = nest ? stackTop->TransactionID() : seqno;
     msg->set_transaction_id(transaction);
 
     bool handleWindowsMessages = mListener->HandleWindowsMessages(*aMsg);
-    AutoEnterTransaction transact(this, seqno, transaction, prio);
+    AutoEnterTransaction transact(this, seqno, transaction, nestedLevel);
 
     IPC_LOG("Send seqno=%d, xid=%d", seqno, transaction);
 
     // msg will be destroyed soon, but name() is not owned by msg.
     const char* msgName = msg->name();
 
     mLink->SendMessage(msg.forget());
 
@@ -1222,17 +1226,17 @@ MessageChannel::Send(Message* aMsg, Mess
             // out message in these cases.
             if (transact.IsComplete()) {
                 break;
             }
 
             IPC_LOG("Timing out Send: xid=%d", transaction);
 
             mTimedOutMessageSeqno = seqno;
-            mTimedOutMessagePriority = prio;
+            mTimedOutMessageNestedLevel = nestedLevel;
             mLastSendError = SyncSendError::TimedOut;
             return false;
         }
 
         if (transact.IsCanceled()) {
             break;
         }
     }
@@ -1510,34 +1514,34 @@ MessageChannel::DequeueOne(Message *recv
     }
 
     if (!mDeferred.empty())
         MaybeUndeferIncall();
 
     // If we've timed out a message and we're awaiting the reply to the timed
     // out message, we have to be careful what messages we process. Here's what
     // can go wrong:
-    // 1. child sends a normal priority sync message S
-    // 2. parent sends a high priority sync message H at the same time
+    // 1. child sends a NOT_NESTED sync message S
+    // 2. parent sends a NESTED_INSIDE_SYNC sync message H at the same time
     // 3. parent times out H
-    // 4. child starts processing H and sends a high priority message H' nested
+    // 4. child starts processing H and sends a NESTED_INSIDE_SYNC message H' nested
     //    within the same transaction
     // 5. parent dispatches S and sends reply
     // 6. child asserts because it instead expected a reply to H'.
     //
     // To solve this, we refuse to process S in the parent until we get a reply
     // to H. More generally, let the timed out message be M. We don't process a
     // message unless the child would need the response to that message in order
-    // to process M. Those messages are the ones that have a higher priority
+    // to process M. Those messages are the ones that have a higher nested level
     // than M or that are part of the same transaction as M.
     if (mTimedOutMessageSeqno) {
         for (MessageQueue::iterator it = mPending.begin(); it != mPending.end(); it++) {
             Message &msg = *it;
-            if (msg.priority() > mTimedOutMessagePriority ||
-                (msg.priority() == mTimedOutMessagePriority
+            if (msg.nested_level() > mTimedOutMessageNestedLevel ||
+                (msg.nested_level() == mTimedOutMessageNestedLevel
                  && msg.transaction_id() == mTimedOutMessageSeqno))
             {
                 *recvd = Move(msg);
                 mPending.erase(it);
                 return true;
             }
         }
         return false;
@@ -1621,33 +1625,33 @@ MessageChannel::DispatchMessage(Message 
     }
 }
 
 void
 MessageChannel::DispatchSyncMessage(const Message& aMsg, Message*& aReply)
 {
     AssertWorkerThread();
 
-    int prio = aMsg.priority();
+    int nestedLevel = aMsg.nested_level();
 
-    MOZ_RELEASE_ASSERT(prio == IPC::Message::PRIORITY_NORMAL || NS_IsMainThread());
+    MOZ_RELEASE_ASSERT(nestedLevel == IPC::Message::NOT_NESTED || NS_IsMainThread());
 
     MessageChannel* dummy;
     MessageChannel*& blockingVar = mSide == ChildSide && NS_IsMainThread() ? gParentProcessBlocker : dummy;
 
     Result rv;
     {
         AutoSetValue<MessageChannel*> blocked(blockingVar, this);
         rv = mListener->OnMessageReceived(aMsg, aReply);
     }
 
     if (!MaybeHandleError(rv, aMsg, "DispatchSyncMessage")) {
         aReply = new Message();
         aReply->set_sync();
-        aReply->set_priority(aMsg.priority());
+        aReply->set_nested_level(aMsg.nested_level());
         aReply->set_reply();
         aReply->set_reply_error();
     }
     aReply->set_seqno(aMsg.seqno());
     aReply->set_transaction_id(aMsg.transaction_id());
 }
 
 void
@@ -1657,19 +1661,19 @@ MessageChannel::DispatchAsyncMessage(con
     MOZ_RELEASE_ASSERT(!aMsg.is_interrupt() && !aMsg.is_sync());
 
     if (aMsg.routing_id() == MSG_ROUTING_NONE) {
         NS_RUNTIMEABORT("unhandled special message!");
     }
 
     Result rv;
     {
-        int prio = aMsg.priority();
+        int nestedLevel = aMsg.nested_level();
         AutoSetValue<bool> async(mDispatchingAsyncMessage, true);
-        AutoSetValue<int> prioSet(mDispatchingAsyncMessagePriority, prio);
+        AutoSetValue<int> nestedLevelSet(mDispatchingAsyncMessageNestedLevel, nestedLevel);
         rv = mListener->OnMessageReceived(aMsg);
     }
     MaybeHandleError(rv, aMsg, "DispatchAsyncMessage");
 }
 
 void
 MessageChannel::DispatchInterruptMessage(Message&& aMsg, size_t stackDepth)
 {
@@ -1770,17 +1774,17 @@ MessageChannel::MaybeUndeferIncall()
     // maybe time to process this message
     Message call(Move(mDeferred.top()));
     mDeferred.pop();
 
     // fix up fudge factor we added to account for race
     IPC_ASSERT(0 < mRemoteStackDepthGuess, "fatal logic error");
     --mRemoteStackDepthGuess;
 
-    MOZ_RELEASE_ASSERT(call.priority() == IPC::Message::PRIORITY_NORMAL);
+    MOZ_RELEASE_ASSERT(call.nested_level() == IPC::Message::NOT_NESTED);
     mPending.push_back(Move(call));
 }
 
 void
 MessageChannel::FlushPendingInterruptQueue()
 {
     AssertWorkerThread();
     mMonitor->AssertNotCurrentThreadOwns();
@@ -2144,17 +2148,17 @@ MessageChannel::PostErrorNotifyTask()
     mWorkerLoop->PostTask(task.forget());
 }
 
 // Special async message.
 class GoodbyeMessage : public IPC::Message
 {
 public:
     GoodbyeMessage() :
-        IPC::Message(MSG_ROUTING_NONE, GOODBYE_MESSAGE_TYPE, PRIORITY_NORMAL)
+        IPC::Message(MSG_ROUTING_NONE, GOODBYE_MESSAGE_TYPE)
     {
     }
     static bool Read(const Message* msg) {
         return true;
     }
     void Log(const std::string& aPrefix, FILE* aOutf) const {
         fputs("(special `Goodbye' message)", aOutf);
     }
@@ -2333,17 +2337,17 @@ MessageChannel::GetTopmostMessageRouting
 
 void
 MessageChannel::EndTimeout()
 {
     mMonitor->AssertCurrentThreadOwns();
 
     IPC_LOG("Ending timeout of seqno=%d", mTimedOutMessageSeqno);
     mTimedOutMessageSeqno = 0;
-    mTimedOutMessagePriority = 0;
+    mTimedOutMessageNestedLevel = 0;
 
     for (size_t i = 0; i < mPending.size(); i++) {
         // There may be messages in the queue that we expected to process from
         // OnMaybeDequeueOne. But during the timeout, that function will skip
         // some messages. Now they're ready to be processed, so we enqueue more
         // tasks.
         RefPtr<DequeueTask> task = new DequeueTask(mDequeueOneTask);
         mWorkerLoop->PostTask(task.forget());
@@ -2370,17 +2374,17 @@ MessageChannel::CancelTransaction(int tr
     // An unusual case: We timed out a transaction which the other side then
     // cancelled. In this case we just leave the timedout state and try to
     // forget this ever happened.
     if (transaction == mTimedOutMessageSeqno) {
         IPC_LOG("Cancelled timed out message %d", mTimedOutMessageSeqno);
         EndTimeout();
 
         // Normally mCurrentTransaction == 0 here. But it can be non-zero if:
-        // 1. Parent sends hi prio message H.
+        // 1. Parent sends NESTED_INSIDE_SYNC message H.
         // 2. Parent times out H.
         // 3. Child dispatches H and sends nested message H' (same transaction).
         // 4. Parent dispatches H' and cancels.
         MOZ_RELEASE_ASSERT(!mTransactionStack || mTransactionStack->TransactionID() == transaction);
         if (mTransactionStack) {
             mTransactionStack->Cancel();
         }
     } else {
@@ -2390,18 +2394,18 @@ MessageChannel::CancelTransaction(int tr
 
     bool foundSync = false;
     for (MessageQueue::iterator it = mPending.begin(); it != mPending.end(); ) {
         Message &msg = *it;
 
         // If there was a race between the parent and the child, then we may
         // have a queued sync message. We want to drop this message from the
         // queue since if will get cancelled along with the transaction being
-        // cancelled. This happens if the message in the queue is high priority.
-        if (msg.is_sync() && msg.priority() != IPC::Message::PRIORITY_NORMAL) {
+        // cancelled. This happens if the message in the queue is NESTED_INSIDE_SYNC.
+        if (msg.is_sync() && msg.nested_level() != IPC::Message::NOT_NESTED) {
             MOZ_RELEASE_ASSERT(!foundSync);
             MOZ_RELEASE_ASSERT(msg.transaction_id() != transaction);
             IPC_LOG("Removing msg from queue seqno=%d xid=%d", msg.seqno(), msg.transaction_id());
             foundSync = true;
             it = mPending.erase(it);
             continue;
         }
 
@@ -2415,27 +2419,27 @@ MessageChannel::IsInTransaction() const
     MonitorAutoLock lock(*mMonitor);
     return !!mTransactionStack;
 }
 
 void
 MessageChannel::CancelCurrentTransaction()
 {
     MonitorAutoLock lock(*mMonitor);
-    if (DispatchingSyncMessagePriority() >= IPC::Message::PRIORITY_HIGH) {
-        if (DispatchingSyncMessagePriority() == IPC::Message::PRIORITY_URGENT ||
-            DispatchingAsyncMessagePriority() == IPC::Message::PRIORITY_URGENT)
+    if (DispatchingSyncMessageNestedLevel() >= IPC::Message::NESTED_INSIDE_SYNC) {
+        if (DispatchingSyncMessageNestedLevel() == IPC::Message::NESTED_INSIDE_CPOW ||
+            DispatchingAsyncMessageNestedLevel() == IPC::Message::NESTED_INSIDE_CPOW)
         {
             mListener->IntentionalCrash();
         }
 
-        IPC_LOG("Cancel requested: current xid=%d", CurrentHighPriorityTransaction());
+        IPC_LOG("Cancel requested: current xid=%d", CurrentNestedInsideSyncTransaction());
         MOZ_RELEASE_ASSERT(DispatchingSyncMessage());
-        CancelMessage *cancel = new CancelMessage(CurrentHighPriorityTransaction());
-        CancelTransaction(CurrentHighPriorityTransaction());
+        CancelMessage *cancel = new CancelMessage(CurrentNestedInsideSyncTransaction());
+        CancelTransaction(CurrentNestedInsideSyncTransaction());
         mLink->SendMessage(cancel);
     }
 }
 
 void
 CancelCPOWs()
 {
     if (gParentProcessBlocker) {
--- a/ipc/glue/MessageChannel.h
+++ b/ipc/glue/MessageChannel.h
@@ -403,19 +403,19 @@ class MessageChannel : HasResultCodes
     friend class AutoEnterWaitForIncoming;
 
     // Returns true if we're dispatching an async message's callback.
     bool DispatchingAsyncMessage() const {
         AssertWorkerThread();
         return mDispatchingAsyncMessage;
     }
 
-    int DispatchingAsyncMessagePriority() const {
+    int DispatchingAsyncMessageNestedLevel() const {
         AssertWorkerThread();
-        return mDispatchingAsyncMessagePriority;
+        return mDispatchingAsyncMessageNestedLevel;
     }
 
     bool Connected() const;
 
   private:
     // Executed on the IO thread.
     void NotifyWorkerThread();
 
@@ -621,17 +621,17 @@ class MessageChannel : HasResultCodes
         }
       private:
         T& mVar;
         T mPrev;
         T mNew;
     };
 
     bool mDispatchingAsyncMessage;
-    int mDispatchingAsyncMessagePriority;
+    int mDispatchingAsyncMessageNestedLevel;
 
     // When we send an urgent request from the parent process, we could race
     // with an RPC message that was issued by the child beforehand. In this
     // case, if the parent were to wake up while waiting for the urgent reply,
     // and process the RPC, it could send an additional urgent message. The
     // child would wake up to process the urgent message (as it always will),
     // then send a reply, which could be received by the parent out-of-order
     // with respect to the first urgent reply.
@@ -644,39 +644,39 @@ class MessageChannel : HasResultCodes
     // transaction, the initiating transaction ID is used.
     //
     // To ensure IDs are unique, we use sequence numbers for transaction IDs,
     // which grow in opposite directions from child to parent.
 
     friend class AutoEnterTransaction;
     AutoEnterTransaction *mTransactionStack;
 
-    int32_t CurrentHighPriorityTransaction() const;
+    int32_t CurrentNestedInsideSyncTransaction() const;
 
     bool AwaitingSyncReply() const;
-    int AwaitingSyncReplyPriority() const;
+    int AwaitingSyncReplyNestedLevel() const;
 
     bool DispatchingSyncMessage() const;
-    int DispatchingSyncMessagePriority() const;
+    int DispatchingSyncMessageNestedLevel() const;
 
     // If a sync message times out, we store its sequence number here. Any
     // future sync messages will fail immediately. Once the reply for original
     // sync message is received, we allow sync messages again.
     //
     // When a message times out, nothing is done to inform the other side. The
     // other side will eventually dispatch the message and send a reply. Our
     // side is responsible for replying to all sync messages sent by the other
     // side when it dispatches the timed out message. The response is always an
     // error.
     //
     // A message is only timed out if it initiated a transaction. This avoids
     // hitting a lot of corner cases with message nesting that we don't really
     // care about.
     int32_t mTimedOutMessageSeqno;
-    int mTimedOutMessagePriority;
+    int mTimedOutMessageNestedLevel;
 
     // Queue of all incoming messages, except for replies to sync and urgent
     // messages, which are delivered directly to mRecvd, and any pending urgent
     // incall, which is stored in mPendingUrgentRequest.
     //
     // If both this side and the other side are functioning correctly, the queue
     // can only be in certain configurations.  Let
     //
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -78,20 +78,20 @@ IToplevelProtocol::~IToplevelProtocol()
 }
 
 class ChannelOpened : public IPC::Message
 {
 public:
   ChannelOpened(TransportDescriptor aDescriptor,
                 ProcessId aOtherProcess,
                 ProtocolId aProtocol,
-                PriorityValue aPriority = PRIORITY_NORMAL)
+                NestedLevel aNestedLevel = NOT_NESTED)
     : IPC::Message(MSG_ROUTING_CONTROL, // these only go to top-level actors
                    CHANNEL_OPENED_MESSAGE_TYPE,
-                   aPriority)
+                   aNestedLevel)
   {
     IPC::WriteParam(this, aDescriptor);
     IPC::WriteParam(this, aOtherProcess);
     IPC::WriteParam(this, static_cast<uint32_t>(aProtocol));
   }
 
   static bool Read(const IPC::Message& aMsg,
                    TransportDescriptor* aDescriptor,
@@ -123,26 +123,26 @@ Bridge(const PrivateIPDLInterface&,
   nsresult rv;
   if (NS_FAILED(rv = CreateTransport(aParentPid, &parentSide, &childSide))) {
     return rv;
   }
 
   if (!aParentChannel->Send(new ChannelOpened(parentSide,
                                               aChildPid,
                                               aProtocol,
-                                              IPC::Message::PRIORITY_URGENT))) {
+                                              IPC::Message::NESTED_INSIDE_CPOW))) {
     CloseDescriptor(parentSide);
     CloseDescriptor(childSide);
     return NS_ERROR_BRIDGE_OPEN_PARENT;
   }
 
   if (!aChildChannel->Send(new ChannelOpened(childSide,
                                             aParentPid,
                                             aChildProtocol,
-                                            IPC::Message::PRIORITY_URGENT))) {
+                                            IPC::Message::NESTED_INSIDE_CPOW))) {
     CloseDescriptor(parentSide);
     CloseDescriptor(childSide);
     return NS_ERROR_BRIDGE_OPEN_CHILD;
   }
 
   return NS_OK;
 }
 
--- a/ipc/glue/Shmem.cpp
+++ b/ipc/glue/Shmem.cpp
@@ -20,17 +20,17 @@ class ShmemCreated : public IPC::Message
 private:
   typedef Shmem::id_t id_t;
 
 public:
   ShmemCreated(int32_t routingId,
                id_t aIPDLId,
                size_t aSize,
                SharedMemory::SharedMemoryType aType) :
-    IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, PRIORITY_URGENT)
+    IPC::Message(routingId, SHMEM_CREATED_MESSAGE_TYPE, NESTED_INSIDE_CPOW)
   {
     IPC::WriteParam(this, aIPDLId);
     IPC::WriteParam(this, aSize);
     IPC::WriteParam(this, int32_t(aType));
   }
 
   static bool
   ReadInfo(const Message* msg, PickleIterator* iter,
@@ -55,17 +55,17 @@ public:
 class ShmemDestroyed : public IPC::Message
 {
 private:
   typedef Shmem::id_t id_t;
 
 public:
   ShmemDestroyed(int32_t routingId,
                  id_t aIPDLId) :
-    IPC::Message(routingId, SHMEM_DESTROYED_MESSAGE_TYPE, PRIORITY_NORMAL)
+    IPC::Message(routingId, SHMEM_DESTROYED_MESSAGE_TYPE)
   {
     IPC::WriteParam(this, aIPDLId);
   }
 };
 
 static SharedMemory*
 NewSegment(SharedMemory::SharedMemoryType aType)
 {
--- a/ipc/ipdl/ipdl/ast.py
+++ b/ipc/ipdl/ipdl/ast.py
@@ -1,17 +1,20 @@
 # 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/.
 
 import sys
 
+NOT_NESTED = 1
+INSIDE_SYNC_NESTED = 2
+INSIDE_CPOW_NESTED = 3
+
 NORMAL_PRIORITY = 1
 HIGH_PRIORITY = 2
-URGENT_PRIORITY = 3
 
 class Visitor:
     def defaultVisit(self, node):
         raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% (
             node.__class__.__name__)
 
     def visitTranslationUnit(self, tu):
         for cxxInc in tu.cxxIncludes:
@@ -231,17 +234,17 @@ class Namespace(Node):
     def __init__(self, loc, namespace):
         Node.__init__(self, loc)
         self.name = namespace
 
 class Protocol(NamespacedNode):
     def __init__(self, loc):
         NamespacedNode.__init__(self, loc)
         self.sendSemantics = ASYNC
-        self.priority = NORMAL_PRIORITY
+        self.nested = NOT_NESTED
         self.spawnsStmts = [ ]
         self.bridgesStmts = [ ]
         self.opensStmts = [ ]
         self.managers = [ ]
         self.managesStmts = [ ]
         self.messageDecls = [ ]
         self.transitionStmts = [ ]
         self.startStates = [ ]
@@ -291,17 +294,18 @@ class ManagesStmt(Node):
         Node.__init__(self, loc)
         self.name = managedName
 
 class MessageDecl(Node):
     def __init__(self, loc):
         Node.__init__(self, loc)
         self.name = None
         self.sendSemantics = ASYNC
-        self.priority = NORMAL_PRIORITY
+        self.nested = NOT_NESTED
+        self.prio = NORMAL_PRIORITY
         self.direction = None
         self.inParams = [ ]
         self.outParams = [ ]
         self.compress = ''
         self.verify = ''
 
     def addInParams(self, inParamsList):
         self.inParams += inParamsList
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1680,27 +1680,29 @@ class _GenerateProtocolCode(ipdl.ast.Vis
         ns.addstmts([ tfDecl, Whitespace.NL ])
         self.funcDefns.append(tfDefn)
 
         for md in p.messageDecls:
             decls = []
 
             mfDecl, mfDefn = _splitFuncDeclDefn(
                 _generateMessageConstructor(md.msgCtorFunc(), md.msgId(),
-                                            md.decl.type.priority,
+                                            md.decl.type.nested,
+                                            md.decl.type.prio,
                                             md.prettyMsgName(p.name+'::'),
                                             md.decl.type.compress))
             decls.append(mfDecl)
             self.funcDefns.append(mfDefn)
 
             if md.hasReply():
                 rfDecl, rfDefn = _splitFuncDeclDefn(
                     _generateMessageConstructor(
                         md.replyCtorFunc(), md.replyId(),
-                        md.decl.type.priority,
+                        md.decl.type.nested,
+                        md.decl.type.prio,
                         md.prettyReplyName(p.name+'::'),
                         md.decl.type.compress))
                 decls.append(rfDecl)
                 self.funcDefns.append(rfDefn)
 
             decls.append(Whitespace.NL)
             ns.addstmts(decls)
 
@@ -1921,44 +1923,52 @@ class _GenerateProtocolCode(ipdl.ast.Vis
                 StmtExpr(ExprAssn(ExprDeref(nextvar), _errorState())),
                 StmtReturn(ExprLiteral.FALSE),
             ])
 
         return transitionfunc
 
 ##--------------------------------------------------
 
-def _generateMessageConstructor(clsname, msgid, priority, prettyName, compress):
+def _generateMessageConstructor(clsname, msgid, nested, prio, prettyName, compress):
     routingId = ExprVar('routingId')
 
     func = FunctionDefn(FunctionDecl(
         clsname,
         params=[ Decl(Type('int32_t'), routingId.name) ],
         ret=Type('IPC::Message', ptr=1)))
 
     if compress == 'compress':
         compression = ExprVar('IPC::Message::COMPRESSION_ENABLED')
     elif compress:
         assert compress == 'compressall'
         compression = ExprVar('IPC::Message::COMPRESSION_ALL')
     else:
         compression = ExprVar('IPC::Message::COMPRESSION_NONE')
-    if priority == ipdl.ast.NORMAL_PRIORITY:
-        priorityEnum = 'IPC::Message::PRIORITY_NORMAL'
-    elif priority == ipdl.ast.HIGH_PRIORITY:
-        priorityEnum = 'IPC::Message::PRIORITY_HIGH'
+
+    if nested == ipdl.ast.NOT_NESTED:
+        nestedEnum = 'IPC::Message::NOT_NESTED'
+    elif nested == ipdl.ast.INSIDE_SYNC_NESTED:
+        nestedEnum = 'IPC::Message::NESTED_INSIDE_SYNC'
     else:
-        assert priority == ipdl.ast.URGENT_PRIORITY
-        priorityEnum = 'IPC::Message::PRIORITY_URGENT'
+        assert nested == ipdl.ast.INSIDE_CPOW_NESTED
+        nestedEnum = 'IPC::Message::NESTED_INSIDE_CPOW'
+
+    if prio == ipdl.ast.NORMAL_PRIORITY:
+        prioEnum = 'IPC::Message::NORMAL_PRIORITY'
+    else:
+        assert prio == ipdl.ast.HIGH_PRIORITY
+        prioEnum = 'IPC::Message::HIGH_PRIORITY'
 
     func.addstmt(
         StmtReturn(ExprNew(Type('IPC::Message'),
                            args=[ routingId,
                                   ExprVar(msgid),
-                                  ExprVar(priorityEnum),
+                                  ExprVar(nestedEnum),
+                                  ExprVar(prioEnum),
                                   compression,
                                   ExprLiteral.String(prettyName) ])))
 
     return func
 
 ##--------------------------------------------------
 
 class _ComputeTypeDeps(TypeVisitor):
@@ -3917,25 +3927,31 @@ class _GenerateProtocolActorCode(ipdl.as
             switchontype = StmtSwitch(pvar)
             for managee in p.managesStmts:
                 case = StmtBlock()
                 actorvar = ExprVar('actor')
                 manageeipdltype = managee.decl.type
                 manageecxxtype = _cxxBareType(ipdl.type.ActorType(manageeipdltype),
                                               self.side)
                 manageearray = p.managedVar(manageeipdltype, self.side)
+                containervar = ExprVar('container')
 
                 case.addstmts([
                     StmtDecl(Decl(manageecxxtype, actorvar.name),
                              ExprCast(listenervar, manageecxxtype, static=1)),
+                    # Use a temporary variable here so all the assertion expressions
+                    # in the _abortIfFalse call below are textually identical; the
+                    # linker can then merge the strings from the assertion macro(s).
+                    StmtDecl(Decl(Type('auto', ref=1), containervar.name),
+                             manageearray),
                     _abortIfFalse(
-                        _callHasManagedActor(manageearray, actorvar),
+                        _callHasManagedActor(containervar, actorvar),
                         "actor not managed by this!"),
                     Whitespace.NL,
-                    StmtExpr(_callRemoveManagedActor(manageearray, actorvar)),
+                    StmtExpr(_callRemoveManagedActor(containervar, actorvar)),
                     StmtExpr(ExprCall(_deallocMethod(manageeipdltype, self.side),
                                       args=[ actorvar ])),
                     StmtReturn()
                 ])
                 switchontype.addcase(CaseLabel(_protocolId(manageeipdltype).name),
                                      case)
             default = StmtBlock()
             default.addstmts([ _fatalError('unreached'), StmtReturn() ])
--- a/ipc/ipdl/ipdl/parser.py
+++ b/ipc/ipdl/ipdl/parser.py
@@ -123,40 +123,38 @@ reserved = set((
         'child',
         'class',
         'compress',
         'compressall',
         '__delete__',
         'delete',                       # reserve 'delete' to prevent its use
         'from',
         'goto',
-        'high',
         'include',
         'intr',
         'manager',
         'manages',
         'namespace',
-        'normal',
+        'nested',
         'nullable',
         'opens',
         'or',
         'parent',
         'prio',
         'protocol',
         'recv',
         'returns',
         'send',
         'spawns',
         'start',
         'state',
         'struct',
         'sync',
         'union',
         'upto',
-        'urgent',
         'using',
         'verify'))
 tokens = [
     'COLONCOLON', 'ID', 'STRING',
 ] + [ r.upper() for r in reserved ]
 
 t_COLONCOLON = '::'
 
@@ -354,17 +352,17 @@ def p_ComponentTypes(p):
         p[1].append(p[2])
         p[0] = p[1]
 
 def p_ProtocolDefn(p):
     """ProtocolDefn : OptionalProtocolSendSemanticsQual PROTOCOL ID '{' ProtocolBody '}' ';'"""
     protocol = p[5]
     protocol.loc = locFromTok(p, 2)
     protocol.name = p[3]
-    protocol.priorityRange = p[1][0]
+    protocol.nestedRange = p[1][0]
     protocol.sendSemantics = p[1][1]
     p[0] = protocol
 
     if Parser.current.type == 'header':
         _error(protocol.loc, 'can\'t define a protocol in a header.  Do it in a protocol spec instead.')
 
 
 def p_ProtocolBody(p):
@@ -497,18 +495,19 @@ def p_MessageDirectionLabel(p):
     elif p[1] == 'both':
         Parser.current.direction = INOUT
     else:
         assert 0
 
 def p_MessageDecl(p):
     """MessageDecl : SendSemanticsQual MessageBody"""
     msg = p[2]
-    msg.priority = p[1][0]
-    msg.sendSemantics = p[1][1]
+    msg.nested = p[1][0]
+    msg.prio = p[1][1]
+    msg.sendSemantics = p[1][2]
 
     if Parser.current.direction is None:
         _error(msg.loc, 'missing message direction')
     msg.direction = Parser.current.direction
 
     p[0] = msg
 
 def p_MessageBody(p):
@@ -636,71 +635,92 @@ def p_StateList(p):
         p[0] = p[1]
 
 def p_State(p):
     """State : ID"""
     p[0] = State(locFromTok(p, 1), p[1])
 
 ##--------------------
 ## Minor stuff
+def p_Nested(p):
+    """Nested : ID"""
+    kinds = {'not': 1,
+             'inside_sync': 2,
+             'inside_cpow': 3}
+    if p[1] not in kinds:
+        _error(locFromTok(p, 1), "Expected not, inside_sync, or inside_cpow for nested()")
+
+    p[0] = { 'nested': kinds[p[1]] }
+
 def p_Priority(p):
-    """Priority : NORMAL
-                | HIGH
-                | URGENT"""
-    prios = {'normal': 1,
-             'high': 2,
-             'urgent': 3}
-    p[0] = prios[p[1]]
+    """Priority : ID"""
+    kinds = {'normal': 1,
+             'high': 2}
+    if p[1] not in kinds:
+        _error(locFromTok(p, 1), "Expected normal or high for prio()")
+
+    p[0] = { 'prio': kinds[p[1]] }
+
+def p_SendQualifier(p):
+    """SendQualifier : NESTED '(' Nested ')'
+                     | PRIO '(' Priority ')'"""
+    p[0] = p[3]
+
+def p_SendQualifierList(p):
+    """SendQualifierList : SendQualifier SendQualifierList
+                         | """
+    if len(p) > 1:
+        p[0] = p[1]
+        p[0].update(p[2])
+    else:
+        p[0] = {}
 
 def p_SendSemanticsQual(p):
-    """SendSemanticsQual : ASYNC
-                         | SYNC
-                         | PRIO '(' Priority ')' ASYNC
-                         | PRIO '(' Priority ')' SYNC
+    """SendSemanticsQual : SendQualifierList ASYNC
+                         | SendQualifierList SYNC
                          | INTR"""
-    if p[1] == 'prio':
-        mtype = p[5]
-        prio = p[3]
+    quals = {}
+    if len(p) == 3:
+        quals = p[1]
+        mtype = p[2]
     else:
-        mtype = p[1]
-        prio = NORMAL_PRIORITY
+        mtype = 'intr'
 
     if mtype == 'async': mtype = ASYNC
     elif mtype == 'sync': mtype = SYNC
     elif mtype == 'intr': mtype = INTR
     else: assert 0
 
-    p[0] = [ prio, mtype ]
+    p[0] = [ quals.get('nested', NOT_NESTED), quals.get('prio', NORMAL_PRIORITY), mtype ]
 
 def p_OptionalProtocolSendSemanticsQual(p):
     """OptionalProtocolSendSemanticsQual : ProtocolSendSemanticsQual
                                          | """
     if 2 == len(p): p[0] = p[1]
-    else:           p[0] = [ (NORMAL_PRIORITY, NORMAL_PRIORITY), ASYNC ]
+    else:           p[0] = [ (NOT_NESTED, NOT_NESTED), ASYNC ]
 
 def p_ProtocolSendSemanticsQual(p):
     """ProtocolSendSemanticsQual : ASYNC
                                  | SYNC
-                                 | PRIO '(' Priority UPTO Priority ')' ASYNC
-                                 | PRIO '(' Priority UPTO Priority ')' SYNC
-                                 | PRIO '(' Priority UPTO Priority ')' INTR
+                                 | NESTED '(' UPTO Nested ')' ASYNC
+                                 | NESTED '(' UPTO Nested ')' SYNC
                                  | INTR"""
-    if p[1] == 'prio':
-        mtype = p[7]
-        prio = (p[3], p[5])
+    if p[1] == 'nested':
+        mtype = p[6]
+        nested = (NOT_NESTED, p[4])
     else:
         mtype = p[1]
-        prio = (NORMAL_PRIORITY, NORMAL_PRIORITY)
+        nested = (NOT_NESTED, NOT_NESTED)
 
     if mtype == 'async': mtype = ASYNC
     elif mtype == 'sync': mtype = SYNC
     elif mtype == 'intr': mtype = INTR
     else: assert 0
 
-    p[0] = [ prio, mtype ]
+    p[0] = [ nested, mtype ]
 
 def p_ParamList(p):
     """ParamList : ParamList ',' Param
                  | Param
                  | """
     if 1 == len(p):
         p[0] = [ ]
     elif 2 == len(p):
--- a/ipc/ipdl/ipdl/type.py
+++ b/ipc/ipdl/ipdl/type.py
@@ -4,17 +4,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os, sys
 
 from ipdl.ast import CxxInclude, Decl, Loc, QualifiedId, State, StructDecl, TransitionStmt
 from ipdl.ast import TypeSpec, UnionDecl, UsingStmt, Visitor
 from ipdl.ast import ASYNC, SYNC, INTR
 from ipdl.ast import IN, OUT, INOUT, ANSWER, CALL, RECV, SEND
-from ipdl.ast import NORMAL_PRIORITY, HIGH_PRIORITY, URGENT_PRIORITY
+from ipdl.ast import NOT_NESTED, INSIDE_SYNC_NESTED, INSIDE_CPOW_NESTED
 import ipdl.builtin as builtin
 
 _DELETE_MSG = '__delete__'
 
 
 def _otherside(side):
     if side == 'parent':  return 'child'
     elif side == 'child': return 'parent'
@@ -212,24 +212,24 @@ class IPDLType(Type):
     def isAsync(self): return self.sendSemantics == ASYNC
     def isSync(self): return self.sendSemantics == SYNC
     def isInterrupt(self): return self.sendSemantics is INTR
 
     def hasReply(self):  return (self.isSync() or self.isInterrupt())
 
     @classmethod
     def convertsTo(cls, lesser, greater):
-        if (lesser.priorityRange[0] < greater.priorityRange[0] or
-            lesser.priorityRange[1] > greater.priorityRange[1]):
+        if (lesser.nestedRange[0] < greater.nestedRange[0] or
+            lesser.nestedRange[1] > greater.nestedRange[1]):
             return False
 
         # Protocols that use intr semantics are not allowed to use
-        # message priorities.
+        # message nesting.
         if (greater.isInterrupt() and
-            lesser.priorityRange != (NORMAL_PRIORITY, NORMAL_PRIORITY)):
+            lesser.nestedRange != (NOT_NESTED, NOT_NESTED)):
             return False
 
         if lesser.isAsync():
             return True
         elif lesser.isSync() and not greater.isAsync():
             return True
         elif greater.isInterrupt():
             return True
@@ -246,24 +246,25 @@ class StateType(IPDLType):
         self.start = start
     def isState(self): return True
     def name(self):
         return self.name
     def fullname(self):
         return self.name()
 
 class MessageType(IPDLType):
-    def __init__(self, priority, sendSemantics, direction,
+    def __init__(self, nested, prio, sendSemantics, direction,
                  ctor=False, dtor=False, cdtype=None, compress=False,
                  verify=False):
         assert not (ctor and dtor)
         assert not (ctor or dtor) or type is not None
 
-        self.priority = priority
-        self.priorityRange = (priority, priority)
+        self.nested = nested
+        self.prio = prio
+        self.nestedRange = (nested, nested)
         self.sendSemantics = sendSemantics
         self.direction = direction
         self.params = [ ]
         self.returns = [ ]
         self.ctor = ctor
         self.dtor = dtor
         self.cdtype = cdtype
         self.compress = compress
@@ -290,19 +291,19 @@ class Bridge:
     def __cmp__(self, o):
         return cmp(self.parent, o.parent) or cmp(self.child, o.child)
     def __eq__(self, o):
         return self.parent == o.parent and self.child == o.child
     def __hash__(self):
         return hash(self.parent) + hash(self.child)
 
 class ProtocolType(IPDLType):
-    def __init__(self, qname, priorityRange, sendSemantics, stateless=False):
+    def __init__(self, qname, nestedRange, sendSemantics, stateless=False):
         self.qname = qname
-        self.priorityRange = priorityRange
+        self.nestedRange = nestedRange
         self.sendSemantics = sendSemantics
         self.spawns = set()             # ProtocolType
         self.opens = set()              # ProtocolType
         self.managers = []           # ProtocolType
         self.manages = [ ]
         self.stateless = stateless
         self.hasDelete = False
         self.hasReentrantDelete = False
@@ -710,17 +711,17 @@ class GatherDecls(TcheckVisitor):
             # types?
             qname = p.qname()
             if 0 == len(qname.quals):
                 fullname = None
             else:
                 fullname = str(qname)
             p.decl = self.declare(
                 loc=p.loc,
-                type=ProtocolType(qname, p.priorityRange, p.sendSemantics,
+                type=ProtocolType(qname, p.nestedRange, p.sendSemantics,
                                   stateless=(0 == len(p.transitionStmts))),
                 shortname=p.name,
                 fullname=fullname)
 
             p.parentEndpointDecl = self.declare(
                 loc=p.loc,
                 type=EndpointType(QualifiedId(p.loc, 'Endpoint<' + fullname + 'Parent>', ['mozilla', 'ipc'])),
                 shortname='Endpoint<' + p.name + 'Parent>')
@@ -1120,17 +1121,17 @@ class GatherDecls(TcheckVisitor):
         if _DELETE_MSG == msgname:
             isdtor = True
             cdtype = self.currentProtocolDecl.type
 
 
         # enter message scope
         self.symtab.enterScope(md)
 
-        msgtype = MessageType(md.priority, md.sendSemantics, md.direction,
+        msgtype = MessageType(md.nested, md.prio, md.sendSemantics, md.direction,
                               ctor=isctor, dtor=isdtor, cdtype=cdtype,
                               compress=md.compress, verify=md.verify)
 
         # replace inparam Param nodes with proper Decls
         def paramToDecl(param):
             ptname = param.typespec.basename()
             ploc = param.typespec.loc
 
@@ -1494,32 +1495,32 @@ class CheckTypes(TcheckVisitor):
 
 
     def visitMessageDecl(self, md):
         mtype, mname = md.decl.type, md.decl.progname
         ptype, pname = md.protocolDecl.type, md.protocolDecl.shortname
 
         loc = md.decl.loc
 
-        if mtype.priority == HIGH_PRIORITY and not mtype.isSync():
+        if mtype.nested == INSIDE_SYNC_NESTED and not mtype.isSync():
             self.error(
                 loc,
-                "high priority messages must be sync (here, message `%s' in protocol `%s')",
+                "inside_sync nested messages must be sync (here, message `%s' in protocol `%s')",
                 mname, pname)
 
-        if mtype.priority == URGENT_PRIORITY and (mtype.isOut() or mtype.isInout()):
+        if mtype.nested == INSIDE_CPOW_NESTED and (mtype.isOut() or mtype.isInout()):
             self.error(
                 loc,
-                "urgent parent-to-child messages are verboten (here, message `%s' in protocol `%s')",
+                "inside_cpow nested parent-to-child messages are verboten (here, message `%s' in protocol `%s')",
                 mname, pname)
 
-        # We allow high priority sync messages to be sent from the
-        # parent. Normal and urgent sync messages can only come from
+        # We allow inside_sync messages that are themselves sync to be sent from the
+        # parent. Normal and inside_cpow nested messages that are sync can only come from
         # the child.
-        if mtype.isSync() and mtype.priority == NORMAL_PRIORITY and (mtype.isOut() or mtype.isInout()):
+        if mtype.isSync() and mtype.nested == NOT_NESTED and (mtype.isOut() or mtype.isInout()):
             self.error(
                 loc,
                 "sync parent-to-child messages are verboten (here, message `%s' in protocol `%s')",
                 mname, pname)
 
         if mtype.needsMoreJuiceThan(ptype):
             self.error(
                 loc,
--- a/ipc/ipdl/test/cxx/PTestCancel.ipdl
+++ b/ipc/ipdl/test/cxx/PTestCancel.ipdl
@@ -1,36 +1,36 @@
 namespace mozilla {
 namespace _ipdltest {
 
-prio(normal upto high) sync protocol PTestCancel
+nested(upto inside_sync) sync protocol PTestCancel
 {
 // Test1
 child:
-    prio(high) sync Test1_1();
+    nested(inside_sync) sync Test1_1();
 parent:
     async Done1();
 
 // Test2
 child:
     async Start2();
-    prio(high) sync Test2_2();
+    nested(inside_sync) sync Test2_2();
 parent:
     sync Test2_1();
 
 // Test3
 child:
-    prio(high) sync Test3_1();
+    nested(inside_sync) sync Test3_1();
 parent:
     async Start3();
-    prio(high) sync Test3_2();
+    nested(inside_sync) sync Test3_2();
 
 parent:
     async Done();
 
 child:
-    prio(high) sync CheckChild() returns (uint32_t reply);
+    nested(inside_sync) sync CheckChild() returns (uint32_t reply);
 parent:
-    prio(high) sync CheckParent() returns (uint32_t reply);
+    nested(inside_sync) sync CheckParent() returns (uint32_t reply);
 };
 
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/PTestDemon.ipdl
+++ b/ipc/ipdl/test/cxx/PTestDemon.ipdl
@@ -1,21 +1,21 @@
 namespace mozilla {
 namespace _ipdltest {
 
-prio(normal upto urgent) sync protocol PTestDemon
+nested(upto inside_cpow) sync protocol PTestDemon
 {
 child:
     async Start();
 
 both:
     async AsyncMessage(int n);
-    prio(high) sync HiPrioSyncMessage();
+    nested(inside_sync) sync HiPrioSyncMessage();
 
 parent:
     sync SyncMessage(int n);
 
-    prio(urgent) async UrgentAsyncMessage(int n);
-    prio(urgent) sync UrgentSyncMessage(int n);
+    nested(inside_cpow) async UrgentAsyncMessage(int n);
+    nested(inside_cpow) sync UrgentSyncMessage(int n);
 };
 
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/PTestHighestPrio.ipdl
+++ b/ipc/ipdl/test/cxx/PTestHighestPrio.ipdl
@@ -1,18 +1,18 @@
 namespace mozilla {
 namespace _ipdltest {
 
-prio(normal upto urgent) sync protocol PTestHighestPrio
+nested(upto inside_cpow) sync protocol PTestHighestPrio
 {
 parent:
-  prio(urgent) async Msg1();
-  prio(high) sync Msg2();
-  prio(urgent) async Msg3();
-  prio(urgent) sync Msg4();
+  nested(inside_cpow) async Msg1();
+  nested(inside_sync) sync Msg2();
+  nested(inside_cpow) async Msg3();
+  nested(inside_cpow) sync Msg4();
 
 child:
   async Start();
-  prio(high) sync StartInner();
+  nested(inside_sync) sync StartInner();
 };
 
 }
 }
new file mode 100644
--- /dev/null
+++ b/ipc/ipdl/test/cxx/PTestPriority.ipdl
@@ -0,0 +1,14 @@
+namespace mozilla {
+namespace _ipdltest {
+
+sync protocol PTestPriority {
+parent:
+    prio(high) async Msg1();
+    prio(high) sync Msg2();
+
+child:
+    prio(high) async Msg3();
+};
+
+} // namespace _ipdltest
+} // namespace mozilla
--- a/ipc/ipdl/test/cxx/PTestRPC.ipdl
+++ b/ipc/ipdl/test/cxx/PTestRPC.ipdl
@@ -1,21 +1,21 @@
 namespace mozilla {
 namespace _ipdltest {
 
-prio(normal upto high) sync protocol PTestRPC
+nested(upto inside_sync) sync protocol PTestRPC
 {
 parent:
-    prio(high) sync Test1_Start() returns (uint32_t result);
-    prio(high) sync Test1_InnerEvent() returns (uint32_t result);
+    nested(inside_sync) sync Test1_Start() returns (uint32_t result);
+    nested(inside_sync) sync Test1_InnerEvent() returns (uint32_t result);
     async Test2_Start();
-    prio(high) sync Test2_OutOfOrder();
+    nested(inside_sync) sync Test2_OutOfOrder();
 
 child:
     async Start();
-    prio(high) sync Test1_InnerQuery() returns (uint32_t result);
-    prio(high) sync Test1_NoReenter() returns (uint32_t result);
-    prio(high) sync Test2_FirstUrgent();
-    prio(high) sync Test2_SecondUrgent();
+    nested(inside_sync) sync Test1_InnerQuery() returns (uint32_t result);
+    nested(inside_sync) sync Test1_NoReenter() returns (uint32_t result);
+    nested(inside_sync) sync Test2_FirstUrgent();
+    nested(inside_sync) sync Test2_SecondUrgent();
 };
 
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/PTestUrgency.ipdl
+++ b/ipc/ipdl/test/cxx/PTestUrgency.ipdl
@@ -1,19 +1,19 @@
 namespace mozilla {
 namespace _ipdltest {
 
-prio(normal upto high) sync protocol PTestUrgency
+nested(upto inside_cpow) sync protocol PTestUrgency
 {
 parent:
-    prio(high) sync Test1() returns (uint32_t result);
+    nested(inside_sync) sync Test1() returns (uint32_t result);
     async Test2();
     sync Test3() returns (uint32_t result);
     sync FinalTest_Begin();
 
 child:
     async Start();
-    prio(high) sync Reply1() returns (uint32_t result);
-    prio(high) sync Reply2() returns (uint32_t result);
+    nested(inside_sync) sync Reply1() returns (uint32_t result);
+    nested(inside_sync) sync Reply2() returns (uint32_t result);
 };
 
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/PTestUrgentHangs.ipdl
+++ b/ipc/ipdl/test/cxx/PTestUrgentHangs.ipdl
@@ -1,28 +1,28 @@
 namespace mozilla {
 namespace _ipdltest {
 
-prio(normal upto urgent) sync protocol PTestUrgentHangs
+nested(upto inside_cpow) sync protocol PTestUrgentHangs
 {
 parent:
-    prio(high) sync Test1_2();
+    nested(inside_sync) sync Test1_2();
 
-    prio(high) sync TestInner();
-    prio(urgent) sync TestInnerUrgent();
+    nested(inside_sync) sync TestInner();
+    nested(inside_cpow) sync TestInnerUrgent();
 
 child:
-    prio(high) sync Test1_1();
-    prio(high) sync Test1_3();
+    nested(inside_sync) sync Test1_1();
+    nested(inside_sync) sync Test1_3();
 
-    prio(high) sync Test2();
+    nested(inside_sync) sync Test2();
 
-    prio(high) sync Test3();
+    nested(inside_sync) sync Test3();
 
     async Test4();
-    prio(high) sync Test4_1();
+    nested(inside_sync) sync Test4_1();
 
     async Test5();
-    prio(high) sync Test5_1();
+    nested(inside_sync) sync Test5_1();
 };
 
 } // namespace _ipdltest
 } // namespace mozilla
--- a/ipc/ipdl/test/cxx/moz.build
+++ b/ipc/ipdl/test/cxx/moz.build
@@ -102,16 +102,17 @@ IPDL_SOURCES += [
     'PTestManyChildAllocsSub.ipdl',
     'PTestMultiMgrs.ipdl',
     'PTestMultiMgrsBottom.ipdl',
     'PTestMultiMgrsLeft.ipdl',
     'PTestMultiMgrsRight.ipdl',
     'PTestNestedLoops.ipdl',
     'PTestOpens.ipdl',
     'PTestOpensOpened.ipdl',
+    'PTestPriority.ipdl',
     'PTestRaceDeadlock.ipdl',
     'PTestRaceDeferral.ipdl',
     'PTestRacyInterruptReplies.ipdl',
     'PTestRacyReentry.ipdl',
     'PTestRacyUndefer.ipdl',
     'PTestRPC.ipdl',
     'PTestSanity.ipdl',
     'PTestSelfManage.ipdl',
--- a/js/ipc/PJavaScript.ipdl
+++ b/js/ipc/PJavaScript.ipdl
@@ -10,48 +10,48 @@ include protocol PContentBridge;
 include DOMTypes;
 include JavaScriptTypes;
 
 using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
 
 namespace mozilla {
 namespace jsipc {
 
-prio(normal upto high) sync protocol PJavaScript
+nested(upto inside_sync) sync protocol PJavaScript
 {
     manager PContent or PContentBridge;
 
 both:
     // Sent when a CPOW has been finalized and table entries can be freed up.
     async DropObject(uint64_t objId);
 
     // These roughly map to the ProxyHandler hooks that CPOWs need.
-    prio(high) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
-    prio(high) sync GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
-    prio(high) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
-    prio(high) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
-    prio(high) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs);
+    nested(inside_sync) sync PreventExtensions(uint64_t objId) returns (ReturnStatus rs);
+    nested(inside_sync) sync GetPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
+    nested(inside_sync) sync GetOwnPropertyDescriptor(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, PPropertyDescriptor result);
+    nested(inside_sync) sync DefineProperty(uint64_t objId, JSIDVariant id, PPropertyDescriptor descriptor) returns (ReturnStatus rs);
+    nested(inside_sync) sync Delete(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs);
 
-    prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
-    prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
-    prio(high) sync Get(uint64_t objId, JSVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
-    prio(high) sync Set(uint64_t objId, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs);
+    nested(inside_sync) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
+    nested(inside_sync) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
+    nested(inside_sync) sync Get(uint64_t objId, JSVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
+    nested(inside_sync) sync Set(uint64_t objId, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs);
 
-    prio(high) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
-    prio(high) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
-    prio(high) sync HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
-    prio(high) sync GetBuiltinClass(uint64_t objId) returns (ReturnStatus rs, uint32_t classValue);
-    prio(high) sync IsArray(uint64_t objId) returns (ReturnStatus rs, uint32_t ans);
-    prio(high) sync ClassName(uint64_t objId) returns (nsCString name);
-    prio(high) sync GetPrototype(uint64_t objId) returns (ReturnStatus rs, ObjectOrNullVariant result);
-    prio(high) sync GetPrototypeIfOrdinary(uint64_t objId) returns (ReturnStatus rs, bool isOrdinary, ObjectOrNullVariant result);
-    prio(high) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
+    nested(inside_sync) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
+    nested(inside_sync) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
+    nested(inside_sync) sync HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
+    nested(inside_sync) sync GetBuiltinClass(uint64_t objId) returns (ReturnStatus rs, uint32_t classValue);
+    nested(inside_sync) sync IsArray(uint64_t objId) returns (ReturnStatus rs, uint32_t ans);
+    nested(inside_sync) sync ClassName(uint64_t objId) returns (nsCString name);
+    nested(inside_sync) sync GetPrototype(uint64_t objId) returns (ReturnStatus rs, ObjectOrNullVariant result);
+    nested(inside_sync) sync GetPrototypeIfOrdinary(uint64_t objId) returns (ReturnStatus rs, bool isOrdinary, ObjectOrNullVariant result);
+    nested(inside_sync) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);
 
-    prio(high) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, JSIDVariant[] ids);
-    prio(high) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
-    prio(high) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);
+    nested(inside_sync) sync GetPropertyKeys(uint64_t objId, uint32_t flags) returns (ReturnStatus rs, JSIDVariant[] ids);
+    nested(inside_sync) sync InstanceOf(uint64_t objId, JSIID iid) returns (ReturnStatus rs, bool instanceof);
+    nested(inside_sync) sync DOMInstanceOf(uint64_t objId, int prototypeID, int depth) returns (ReturnStatus rs, bool instanceof);
 
 parent:
     async __delete__();
 };
 
 }
 }
--- a/js/src/ds/MemoryProtectionExceptionHandler.cpp
+++ b/js/src/ds/MemoryProtectionExceptionHandler.cpp
@@ -6,17 +6,17 @@
 
 #include "ds/MemoryProtectionExceptionHandler.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Atomics.h"
 
 #if defined(XP_WIN)
 # include "jswin.h"
-#elif defined(XP_LINUX)
+#elif defined(XP_UNIX) && !defined(XP_DARWIN)
 # include <signal.h>
 # include <sys/types.h>
 # include <unistd.h>
 #elif defined(XP_DARWIN)
 # include <mach/mach.h>
 # include <unistd.h>
 #endif
 
@@ -205,17 +205,17 @@ MemoryProtectionExceptionHandler::uninst
 
         // Restore the previous exception handler.
         MOZ_ALWAYS_TRUE(RemoveVectoredExceptionHandler(sVectoredExceptionHandler));
 
         sExceptionHandlerInstalled = false;
     }
 }
 
-#elif defined(XP_LINUX)
+#elif defined(XP_UNIX) && !defined(XP_DARWIN)
 
 static struct sigaction sPrevSEGVHandler = {};
 
 /*
  * We can only handle one exception. To guard against races and reentrancy,
  * we set this value the first time we enter the exception handler and never
  * touch it again.
  */
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -2477,16 +2477,24 @@ js::TenuringTracer::traceObjectSlots(Nat
 
 void
 js::TenuringTracer::traceSlots(Value* vp, Value* end)
 {
     for (; vp != end; ++vp)
         traverse(vp);
 }
 
+#ifdef DEBUG
+static inline ptrdiff_t
+OffsetToChunkEnd(void* p)
+{
+    return ChunkLocationOffset - (uintptr_t(p) & gc::ChunkMask);
+}
+#endif
+
 size_t
 js::TenuringTracer::moveObjectToTenured(JSObject* dst, JSObject* src, AllocKind dstKind)
 {
     size_t srcSize = Arena::thingSize(dstKind);
     size_t tenuredSize = srcSize;
 
     /*
      * Arrays do not necessarily have the same AllocKind between src and dst.
@@ -2496,16 +2504,17 @@ js::TenuringTracer::moveObjectToTenured(
      * For Arrays we're reducing tenuredSize to the smaller srcSize
      * because moveElementsToTenured() accounts for all Array elements,
      * even if they are inlined.
      */
     if (src->is<ArrayObject>())
         tenuredSize = srcSize = sizeof(NativeObject);
 
     // Copy the Cell contents.
+    MOZ_ASSERT(OffsetToChunkEnd(src) >= ptrdiff_t(srcSize));
     js_memcpy(dst, src, srcSize);
 
     // Move any hash code attached to the object.
     src->zone()->transferUniqueId(dst, src);
 
     // Move the slots and elements, if we need to.
     if (src->isNative()) {
         NativeObject* ndst = &dst->as<NativeObject>();
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -193,20 +193,34 @@ static const PhaseInfo phases[] = {
 
 static ExtraPhaseInfo phaseExtra[PHASE_LIMIT] = { { 0, 0 } };
 
 // Mapping from all nodes with a multi-parented child to a Vector of all
 // multi-parented children and their descendants. (Single-parented children will
 // not show up in this list.)
 static mozilla::Vector<Phase, 0, SystemAllocPolicy> dagDescendants[Statistics::NumTimingArrays];
 
+// Preorder iterator over all phases in the expanded tree. Positions are
+// returned as <phase,dagSlot> pairs (dagSlot will be zero aka PHASE_DAG_NONE
+// for the top nodes with a single path from the parent, and 1 or more for
+// nodes in multiparented subtrees).
 struct AllPhaseIterator {
+    // If 'descendants' is empty, the current Phase position.
     int current;
+
+    // The depth of the current multiparented node that we are processing, or
+    // zero if we are pointing to the top portion of the tree.
     int baseLevel;
+
+    // When looking at multiparented descendants, the dag slot (index into
+    // PhaseTimeTables) containing the entries for the current parent.
     size_t activeSlot;
+
+    // When iterating over a multiparented subtree, the list of (remaining)
+    // subtree nodes.
     mozilla::Vector<Phase, 0, SystemAllocPolicy>::Range descendants;
 
     explicit AllPhaseIterator(const Statistics::PhaseTimeTable table)
       : current(0)
       , baseLevel(0)
       , activeSlot(PHASE_DAG_NONE)
       , descendants(dagDescendants[PHASE_DAG_NONE].all()) /* empty range */
     {
@@ -219,27 +233,33 @@ struct AllPhaseIterator {
         if (level)
             *level = phaseExtra[*phase].depth + baseLevel;
     }
 
     void advance() {
         MOZ_ASSERT(!done());
 
         if (!descendants.empty()) {
+            // Currently iterating over a multiparented subtree.
             descendants.popFront();
             if (!descendants.empty())
                 return;
 
+            // Just before leaving the last child, reset the iterator to look
+            // at "main" phases (in PHASE_DAG_NONE) instead of multiparented
+            // subtree phases.
             ++current;
             activeSlot = PHASE_DAG_NONE;
             baseLevel = 0;
             return;
         }
 
         if (phaseExtra[current].dagSlot != PHASE_DAG_NONE) {
+            // The current phase has a shared subtree. Load them up into
+            // 'descendants' and advance to the first child.
             activeSlot = phaseExtra[current].dagSlot;
             descendants = dagDescendants[activeSlot].all();
             MOZ_ASSERT(!descendants.empty());
             baseLevel += phaseExtra[current].depth + 1;
             return;
         }
 
         ++current;
@@ -303,29 +323,28 @@ Join(const FragmentVector& fragments, co
     return UniqueChars(joined);
 }
 
 static int64_t
 SumChildTimes(size_t phaseSlot, Phase phase, const Statistics::PhaseTimeTable phaseTimes)
 {
     // Sum the contributions from single-parented children.
     int64_t total = 0;
-    for (unsigned i = 0; i < PHASE_LIMIT; i++) {
+    size_t depth = phaseExtra[phase].depth;
+    for (unsigned i = phase + 1; i < PHASE_LIMIT && phaseExtra[i].depth > depth; i++) {
         if (phases[i].parent == phase)
             total += phaseTimes[phaseSlot][i];
     }
 
     // Sum the contributions from multi-parented children.
     size_t dagSlot = phaseExtra[phase].dagSlot;
     if (dagSlot != PHASE_DAG_NONE) {
-        for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
-            if (dagChildEdges[i].parent == phase) {
-                Phase child = dagChildEdges[i].child;
-                total += phaseTimes[dagSlot][child];
-            }
+        for (auto edge : dagChildEdges) {
+            if (edge.parent == phase)
+                total += phaseTimes[dagSlot][edge.child];
         }
     }
     return total;
 }
 
 UniqueChars
 Statistics::formatCompactSliceMessage() const
 {
@@ -882,16 +901,18 @@ Statistics::clearMaxGCPauseAccumulator()
 }
 
 int64_t
 Statistics::getMaxGCPauseSinceClear()
 {
     return maxPauseInInterval;
 }
 
+// Sum up the time for a phase, including instances of the phase with different
+// parents.
 static int64_t
 SumPhase(Phase phase, const Statistics::PhaseTimeTable times)
 {
     int64_t sum = 0;
     for (auto i : MakeRange(Statistics::NumTimingArrays))
         sum += times[i][phase];
     return sum;
 }
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -426,17 +426,17 @@ js::gc::GCRuntime::finishVerifier()
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 
 class CheckHeapTracer : public JS::CallbackTracer
 {
   public:
     explicit CheckHeapTracer(JSRuntime* rt);
     bool init();
-    bool check(AutoLockForExclusiveAccess& lock);
+    void check(AutoLockForExclusiveAccess& lock);
 
   private:
     void onChild(const JS::GCCellPtr& thing) override;
 
     struct WorkItem {
         WorkItem(JS::GCCellPtr thing, const char* name, int parentIndex)
           : thing(thing), name(name), parentIndex(parentIndex), processed(false)
         {}
@@ -507,17 +507,17 @@ CheckHeapTracer::onChild(const JS::GCCel
         return;
     }
 
     WorkItem item(thing, contextName(), parentIndex);
     if (!stack.append(item))
         oom = true;
 }
 
-bool
+void
 CheckHeapTracer::check(AutoLockForExclusiveAccess& lock)
 {
     // The analysis thinks that traceRuntime might GC by calling a GC callback.
     JS::AutoSuppressGCAnalysis nogc;
     if (!rt->isBeingDestroyed())
         rt->gc.traceRuntime(this, lock);
 
     while (!stack.empty()) {
@@ -527,29 +527,27 @@ CheckHeapTracer::check(AutoLockForExclus
         } else {
             parentIndex = stack.length() - 1;
             TraceChildren(this, item.thing);
             stack.back().processed = true;
         }
     }
 
     if (oom)
-        return false;
+        return;
 
     if (failures) {
         fprintf(stderr, "Heap check: %zu failure(s) out of %" PRIu32 " pointers checked\n",
                 failures, visited.count());
     }
     MOZ_RELEASE_ASSERT(failures == 0);
-
-    return true;
 }
 
 void
 js::gc::CheckHeapAfterGC(JSRuntime* rt)
 {
     AutoTraceSession session(rt, JS::HeapState::Tracing);
     CheckHeapTracer tracer(rt);
-    if (!tracer.init() || !tracer.check(session.lock))
-        fprintf(stderr, "OOM checking heap\n");
+    if (!tracer.init())
+        tracer.check(session.lock);
 }
 
 #endif /* JSGC_HASH_TABLE_CHECKS */
--- a/js/src/old-configure.in
+++ b/js/src/old-configure.in
@@ -998,45 +998,25 @@ if test "$ac_cv_type_ssize_t" = true ; t
 else
   AC_MSG_RESULT(no)
 fi
 
 AC_LANG_CPLUSPLUS
 
 MOZ_CXX11
 
-dnl Check for .hidden assembler directive and visibility attribute.
-dnl Borrowed from glibc configure.in
-dnl ===============================================================
-if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
-  AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
-  AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
-  case "$OS_TARGET" in
-  Darwin)
-    VISIBILITY_FLAGS='-fvisibility=hidden -fvisibility-inlines-hidden'
-    ;;
-  *)
-    VISIBILITY_FLAGS="-I${DIST}/system_wrappers -include ${_topsrcdir}/config/gcc_hidden.h"
-    WRAP_SYSTEM_INCLUDES=1
-    ;;
-  esac
-fi         # GNU_CC
-
 case "${OS_TARGET}" in
 WINNT|Darwin|Android)
   ;;
 *)
   STL_FLAGS="-I${DIST}/stl_wrappers"
   WRAP_STL_INCLUDES=1
   ;;
 esac
 
-AC_SUBST(WRAP_SYSTEM_INCLUDES)
-AC_SUBST_LIST(VISIBILITY_FLAGS)
-
 dnl Checks for header files.
 dnl ========================================================
 AC_HEADER_DIRENT
 case "$target_os" in
 freebsd*)
 # for stuff like -lXshm
     CPPFLAGS="${CPPFLAGS} ${X_CFLAGS}"
     ;;
--- a/layout/base/RestyleManagerBase.cpp
+++ b/layout/base/RestyleManagerBase.cpp
@@ -673,26 +673,24 @@ FrameHasPositionedPlaceholderDescendants
         // they ignore their position style ... but they can't.
         NS_ASSERTION(!outOfFlow->IsSVGText(),
                      "SVG text frames can't be out of flow");
         if (aPositionMask & (1 << outOfFlow->StyleDisplay()->mPosition)) {
           return true;
         }
       }
       uint32_t positionMask = aPositionMask;
-      // Is it faster to check aPositionMask & (1 << NS_STYLE_POSITION_ABSOLUTE)
-      // before we check IsAbsPosContainingBlock?  Not clear....
-      if (f->IsAbsPosContainingBlock()) {
-        if (f->IsFixedPosContainingBlock()) {
-          continue;
-        }
-        // We don't care about absolutely positioned things inside f, because
-        // they will still use f as their containing block.
-        positionMask = (1 << NS_STYLE_POSITION_FIXED);
-      }
+      // NOTE:  It's tempting to check f->IsAbsPosContainingBlock() or
+      // f->IsFixedPosContainingBlock() here.  However, that would only
+      // be testing the *new* style of the frame, which might exclude
+      // descendants that currently have this frame as an abs-pos
+      // containing block.  Taking the codepath where we don't reframe
+      // could lead to an unsafe call to
+      // cont->MarkAsNotAbsoluteContainingBlock() before we've reframed
+      // the descendant and taken it off the absolute list.
       if (FrameHasPositionedPlaceholderDescendants(f, positionMask)) {
         return true;
       }
     }
   }
   return false;
 }
 
@@ -1130,17 +1128,27 @@ RestyleManagerBase::ProcessRestyledFrame
           // descendants).
           if (cont->IsAbsPosContainingBlock()) {
             if (!cont->IsAbsoluteContainer() &&
                 (cont->GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN)) {
               cont->MarkAsAbsoluteContainingBlock();
             }
           } else {
             if (cont->IsAbsoluteContainer()) {
-              cont->MarkAsNotAbsoluteContainingBlock();
+              if (cont->HasAbsolutelyPositionedChildren()) {
+                // If |cont| still has absolutely positioned children,
+                // we can't call MarkAsNotAbsoluteContainingBlock.  This
+                // will remove a frame list that still has children in
+                // it that we need to keep track of.
+                // The optimization of removing it isn't particularly
+                // important, although it does mean we skip some tests.
+                NS_WARNING("skipping removal of absolute containing block");
+              } else {
+                cont->MarkAsNotAbsoluteContainingBlock();
+              }
             }
           }
         }
       }
     }
 
     if ((hint & nsChangeHint_AddOrRemoveTransform) && frame &&
         !(hint & nsChangeHint_ReconstructFrame)) {
new file mode 100644
--- /dev/null
+++ b/layout/base/crashtests/1299736-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<title>Testcase, bug 1299736</title>
+
+<div id="A" style="transform: translateX(50px)">
+  <div id="B">
+    <div id="C" style="position: fixed">
+    </div>
+  </div>
+</div>
+
+<script>
+  document.getElementById("C").offsetLeft; // flush
+  document.getElementById("B").style.transform = "translateX(50px)";
+  document.getElementById("A").style.transform = "";
+</script>
--- a/layout/base/crashtests/crashtests.list
+++ b/layout/base/crashtests/crashtests.list
@@ -473,8 +473,9 @@ load 1163583.html
 load 1234622-1.html
 load 1235467-1.html
 pref(dom.webcomponents.enabled,true) load 1261351.html
 load 1270797-1.html
 load 1278455-1.html
 load 1286889.html
 load 1297835.html
 load 1288608.html
+load 1299736-1.html
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3556,26 +3556,17 @@ nsCSSFrameConstructor::FindHTMLData(Elem
     // <legend> is only special inside fieldset, we only check the frame tree
     // parent because the content tree parent may not be a <fieldset> due to
     // display:contents, Shadow DOM, or XBL. For floated or absolutely
     // positioned legends we want to construct by display type and
     // not do special legend stuff.
     return nullptr;
   }
 
-  if (aTag == nsGkAtoms::details || aTag == nsGkAtoms::summary) {
-    if (!HTMLDetailsElement::IsDetailsEnabled()) {
-      return nullptr;
-    }
-  }
-
-  if (aTag == nsGkAtoms::summary &&
-      (!aParentFrame || aParentFrame->GetType() != nsGkAtoms::detailsFrame)) {
-    // <summary> is special only if it is a direct child of <details>. If it
-    // isn't, construct it as a normal block frame instead of a summary frame.
+  if (aTag == nsGkAtoms::details && !HTMLDetailsElement::IsDetailsEnabled()) {
     return nullptr;
   }
 
   static const FrameConstructionDataByTag sHTMLData[] = {
     SIMPLE_TAG_CHAIN(img, nsCSSFrameConstructor::FindImgData),
     SIMPLE_TAG_CHAIN(mozgeneratedcontentimage,
                      nsCSSFrameConstructor::FindImgData),
     { &nsGkAtoms::br,
@@ -5900,20 +5891,33 @@ nsCSSFrameConstructor::AddFrameConstruct
     CreateGeneratedContentItem(aState, aParentFrame, aContent, styleContext,
                                CSSPseudoElementType::after, aItems);
     if (canHavePageBreak && display->mBreakAfter) {
       AddPageBreakItem(aContent, aStyleContext, aItems);
     }
     return;
   }
 
-  FrameConstructionItem* item =
-    aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
-                      pendingBinding, styleContext.forget(),
-                      aSuppressWhiteSpaceOptimizations, aAnonChildren);
+  FrameConstructionItem* item = nullptr;
+  if (details && details->IsDetailsEnabled() && details->Open()) {
+    auto* summary = HTMLSummaryElement::FromContentOrNull(aContent);
+    if (summary && summary->IsMainSummary()) {
+      // If details is open, the main summary needs to be rendered as if it is
+      // the first child, so add the item to the front of the item list.
+      item = aItems.PrependItem(data, aContent, aTag, aNameSpaceID,
+                                pendingBinding, styleContext.forget(),
+                                aSuppressWhiteSpaceOptimizations, aAnonChildren);
+    }
+  }
+
+  if (!item) {
+    item = aItems.AppendItem(data, aContent, aTag, aNameSpaceID,
+                             pendingBinding, styleContext.forget(),
+                             aSuppressWhiteSpaceOptimizations, aAnonChildren);
+  }
   item->mIsText = isText;
   item->mIsGeneratedContent = isGeneratedContent;
   item->mIsAnonymousContentCreatorContent =
     aFlags & ITEM_IS_ANONYMOUSCONTENTCREATOR_CONTENT;
   if (isGeneratedContent) {
     NS_ADDREF(item->mContent);
   }
   item->mIsRootPopupgroup =
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -857,16 +857,37 @@ private:
                                   aSuppressWhiteSpaceOptimizations,
                                   aAnonChildren);
       PR_APPEND_LINK(item, &mItems);
       ++mItemCount;
       ++mDesiredParentCounts[item->DesiredParentType()];
       return item;
     }
 
+    // Arguments are the same as AppendItem().
+    FrameConstructionItem* PrependItem(const FrameConstructionData* aFCData,
+                                       nsIContent* aContent,
+                                       nsIAtom* aTag,
+                                       int32_t aNameSpaceID,
+                                       PendingBinding* aPendingBinding,
+                                       already_AddRefed<nsStyleContext>&& aStyleContext,
+                                       bool aSuppressWhiteSpaceOptimizations,
+                                       nsTArray<nsIAnonymousContentCreator::ContentInfo>* aAnonChildren)
+    {
+      FrameConstructionItem* item =
+        new FrameConstructionItem(aFCData, aContent, aTag, aNameSpaceID,
+                                  aPendingBinding, aStyleContext,
+                                  aSuppressWhiteSpaceOptimizations,
+                                  aAnonChildren);
+      PR_INSERT_LINK(item, &mItems);
+      ++mItemCount;
+      ++mDesiredParentCounts[item->DesiredParentType()];
+      return item;
+    }
+
     void AppendUndisplayedItem(nsIContent* aContent,
                                nsStyleContext* aStyleContext) {
       mUndisplayedItems.AppendElement(UndisplayedItem(aContent, aStyleContext));
     }
 
     void InlineItemAdded() { ++mInlineCount; }
     void BlockItemAdded() { ++mBlockCount; }
     void LineParticipantItemAdded() { ++mLineParticipantCount; }
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -2134,19 +2134,22 @@ nsListControlFrame::KeyDown(nsIDOMEvent*
 #ifdef XP_MACOSX
   dropDownMenuOnUpDown = IsInDropDownMode() && !mComboboxFrame->IsDroppedDown();
   dropDownMenuOnSpace = !keyEvent->IsAlt() && !keyEvent->IsControl() &&
     !keyEvent->IsMeta();
 #else
   dropDownMenuOnUpDown = keyEvent->IsAlt();
   dropDownMenuOnSpace = IsInDropDownMode() && !mComboboxFrame->IsDroppedDown();
 #endif
+  bool withinIncrementalSearchTime =
+    keyEvent->mTime - gLastKeyTime <= INCREMENTAL_SEARCH_KEYPRESS_TIME;
   if ((dropDownMenuOnUpDown &&
        (keyEvent->mKeyCode == NS_VK_UP || keyEvent->mKeyCode == NS_VK_DOWN)) ||
-      (dropDownMenuOnSpace && keyEvent->mKeyCode == NS_VK_SPACE)) {
+      (dropDownMenuOnSpace && keyEvent->mKeyCode == NS_VK_SPACE &&
+       !withinIncrementalSearchTime)) {
     DropDownToggleKey(aKeyEvent);
     if (keyEvent->DefaultPrevented()) {
       return NS_OK;
     }
   }
   if (keyEvent->IsAlt()) {
     return NS_OK;
   }
--- a/layout/forms/test/mochitest.ini
+++ b/layout/forms/test/mochitest.ini
@@ -60,8 +60,9 @@ skip-if = (buildapp == 'b2g' && (toolkit
 [test_textarea_resize.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # b2g(resizing textarea not available in b2g) b2g-debug(resizing textarea not available in b2g) b2g-desktop(resizing textarea not available in b2g)
 [test_bug961363.html]
 skip-if = toolkit == 'android' # Bug 1021644 - Fails when pushed into a different chunk on Android
 [test_bug1111995.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g'
 [test_select_vertical.html]
 skip-if = e10s || buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # Bug 1170129 - vertical <select> popup not implemented for e10s # <select> elements don't use an in-page popup on B2G/Android
+[test_bug1305282.html]
new file mode 100644
--- /dev/null
+++ b/layout/forms/test/test_bug1305282.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=615697
+-->
+<head>
+  <title>Test for Bug 1305282</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1305282">Mozilla Bug 1305282</a>
+<p id="display"></p>
+<div id="content">
+  <select>
+    <option>f o o</option>
+    <option>b a r</option>
+    <option>b o o</option>
+  </select>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1305282 **/
+
+var select = document.getElementsByTagName('select')[0];
+
+select.addEventListener("change", function(aEvent) {
+  select.removeEventListener("change", arguments.callee, false);
+  is(select.selectedIndex, 1, "'b a r' option is selected");
+  SimpleTest.finish();
+}, false);
+
+select.addEventListener("focus", function() {
+  select.removeEventListener("focus", arguments.callee, false);
+  SimpleTest.executeSoon(function () {
+    synthesizeKey("VK_DOWN", {});
+    SimpleTest.executeSoon(function () {
+      synthesizeKey('b', {});
+      SimpleTest.executeSoon(function () {
+        synthesizeKey(' ', {});
+        SimpleTest.executeSoon(function () {
+          synthesizeKey("VK_RETURN", {});
+        });
+      });
+    });
+  });
+}, false);
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+  select.focus();
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/layout/generic/DetailsFrame.cpp
+++ b/layout/generic/DetailsFrame.cpp
@@ -41,59 +41,54 @@ nsIAtom*
 DetailsFrame::GetType() const
 {
   return nsGkAtoms::detailsFrame;
 }
 
 void
 DetailsFrame::SetInitialChildList(ChildListID aListID, nsFrameList& aChildList)
 {
+#ifdef DEBUG
   if (aListID == kPrincipalList) {
-    HTMLDetailsElement* details = HTMLDetailsElement::FromContent(GetContent());
-    bool isOpen = details->Open();
-
-    if (isOpen) {
-      // If details is open, the first summary needs to be rendered as if it is
-      // the first child.
-      for (nsIFrame* child : aChildList) {
-        HTMLSummaryElement* summary =
-          HTMLSummaryElement::FromContent(child->GetContent());
-
-        if (summary && summary->IsMainSummary()) {
-          // Take out the first summary frame and insert it to the beginning of
-          // the list.
-          aChildList.RemoveFrame(child);
-          aChildList.InsertFrame(nullptr, nullptr, child);
-          break;
-        }
-      }
-    }
-
-#ifdef DEBUG
-    for (nsIFrame* child : aChildList) {
-      HTMLSummaryElement* summary =
-        HTMLSummaryElement::FromContent(child->GetContent());
-
-      if (child == aChildList.FirstChild()) {
-        if (summary && summary->IsMainSummary()) {
-          break;
-        }
-      } else {
-        MOZ_ASSERT(!summary || !summary->IsMainSummary(),
-                   "Rest of the children are neither summary elements nor"
-                   "the main summary!");
-      }
-    }
+    CheckValidMainSummary(aChildList);
+  }
 #endif
 
-  }
-
   nsBlockFrame::SetInitialChildList(aListID, aChildList);
 }
 
+#ifdef DEBUG
+bool
+DetailsFrame::CheckValidMainSummary(const nsFrameList& aFrameList) const
+{
+  for (nsIFrame* child : aFrameList) {
+    HTMLSummaryElement* summary =
+      HTMLSummaryElement::FromContent(child->GetContent());
+
+    if (child == aFrameList.FirstChild()) {
+      if (summary && summary->IsMainSummary()) {
+        return true;
+      } else if (child->GetContent() == GetContent()) {
+        // The child frame's content is the same as our content, which means
+        // it's a kind of wrapper frame. Descend into its child list to find
+        // main summary.
+        if (CheckValidMainSummary(child->PrincipalChildList())) {
+          return true;
+        }
+      }
+    } else {
+      NS_ASSERTION(!summary || !summary->IsMainSummary(),
+                   "Rest of the children are either not summary element "
+                   "or are not the main summary!");
+    }
+  }
+  return false;
+}
+#endif
+
 void
 DetailsFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   nsContentUtils::DestroyAnonymousContent(&mDefaultSummary);
   nsBlockFrame::DestroyFrom(aDestructRoot);
 }
 
 nsresult
--- a/layout/generic/DetailsFrame.h
+++ b/layout/generic/DetailsFrame.h
@@ -33,16 +33,22 @@ public:
 
 #ifdef DEBUG_FRAME_DUMP
   nsresult GetFrameName(nsAString& aResult) const override
   {
     return MakeFrameName(NS_LITERAL_STRING("Details"), aResult);
   }
 #endif
 
+#ifdef DEBUG
+  // Check the frame of the main summary element is the first child in the frame
+  // list. Returns true if we found the main summary frame; false otherwise.
+  bool CheckValidMainSummary(const nsFrameList& aFrameList) const;
+#endif
+
   void SetInitialChildList(ChildListID aListID,
                            nsFrameList& aChildList) override;
 
   void DestroyFrom(nsIFrame* aDestructRoot) override;
 
   // nsIAnonymousContentCreator
   nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
 
new file mode 100644
--- /dev/null
+++ b/layout/generic/crashtests/1304441.html
@@ -0,0 +1,9 @@
+<details>
+<summary>
+<li>
+<style>
+summary{
+all:initial
+}
+:first-child::first-line
+{}
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -634,8 +634,9 @@ load 1278007.html
 load 1279814.html
 load large-border-radius-dashed.html
 load large-border-radius-dashed2.html
 load large-border-radius-dotted.html
 load large-border-radius-dotted2.html
 load 1297427-non-equal-centers.html
 load 1278461-1.html
 load 1278461-2.html
+load 1304441.html
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -4056,21 +4056,21 @@ nsGridContainerFrame::Tracks::Initialize
       // [align|justify]-self:[last-]baseline.
       auto selfAlignment = isOrthogonal ?
         child->StylePosition()->UsedJustifySelf(containerSC) :
         child->StylePosition()->UsedAlignSelf(containerSC);
       selfAlignment &= ~NS_STYLE_ALIGN_FLAG_BITS;
       if (selfAlignment == NS_STYLE_ALIGN_BASELINE) {
         state |= ItemState::eFirstBaseline | ItemState::eSelfBaseline;
         const GridArea& area = gridItem.mArea;
-        baselineTrack = isOrthogonal ? area.mCols.mStart : area.mRows.mStart;
+        baselineTrack = isInlineAxis ? area.mCols.mStart : area.mRows.mStart;
       } else if (selfAlignment == NS_STYLE_ALIGN_LAST_BASELINE) {
         state |= ItemState::eLastBaseline | ItemState::eSelfBaseline;
         const GridArea& area = gridItem.mArea;
-        baselineTrack = (isOrthogonal ? area.mCols.mEnd : area.mRows.mEnd) - 1;
+        baselineTrack = (isInlineAxis ? area.mCols.mEnd : area.mRows.mEnd) - 1;
       }
 
       // [align|justify]-content:[last-]baseline.
       // https://drafts.csswg.org/css-align-3/#baseline-align-content
       // "[...] and its computed 'align-self' or 'justify-self' (whichever
       // affects its block axis) is 'stretch' or 'self-start' ('self-end').
       // For this purpose, the 'start', 'end', 'flex-start', and 'flex-end'
       // values of 'align-self' are treated as either 'self-start' or
@@ -4118,20 +4118,20 @@ nsGridContainerFrame::Tracks::Initialize
                            (alignContent == NS_STYLE_ALIGN_LAST_BASELINE);
               break;
           }
         }
         if (validCombo) {
           const GridArea& area = gridItem.mArea;
           if (alignContent == NS_STYLE_ALIGN_BASELINE) {
             state |= ItemState::eFirstBaseline | ItemState::eContentBaseline;
-            baselineTrack = isOrthogonal ? area.mCols.mStart : area.mRows.mStart;
+            baselineTrack = isInlineAxis ? area.mCols.mStart : area.mRows.mStart;
           } else if (alignContent == NS_STYLE_ALIGN_LAST_BASELINE) {
             state |= ItemState::eLastBaseline | ItemState::eContentBaseline;
-            baselineTrack = (isOrthogonal ? area.mCols.mEnd : area.mRows.mEnd) - 1;
+            baselineTrack = (isInlineAxis ? area.mCols.mEnd : area.mRows.mEnd) - 1;
           }
         }
       }
     }
 
     if (state & ItemState::eIsBaselineAligned) {
       // XXX available size issue
       LogicalSize avail(childWM, INFINITE_ISIZE_COORD, NS_UNCONSTRAINEDSIZE);
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/details-first-line-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  div#details::first-line {
+    color: blue;
+  }
+  </style>
+  <body>
+    <div id="details">
+      <span>Summary
+        <div>Block in summary</div>
+      </span>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/details-first-line.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  summary {
+    display: inline; /* ::first-line appiles only to inline element. */
+  }
+
+  details::first-line {
+    color: blue;
+  }
+  </style>
+  <body>
+    <details>
+      <summary>Summary
+        <!-- Need ib-split so that the summary has multiple frames. -->
+        <div>Block in summary</div>
+      </summary>
+      <p>This is the details.</p>
+    </details>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-first-line-1.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  summary {
+    display: inline; /* ::first-line appiles only to inline element. */
+  }
+
+  details::first-line {
+    color: blue;
+  }
+  </style>
+  <body>
+    <details open>
+      <summary>Summary
+        <!-- Need ib-split so that the summary has multiple frames. -->
+        <div>Block in summary</div>
+      </summary>
+      <span>This is the details.</span>
+    </details>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-first-line-2.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  summary {
+    display: inline; /* ::first-line appiles only to inline element. */
+  }
+
+  details::first-line {
+    color: blue;
+  }
+  </style>
+  <body>
+    <details open>
+      <span>This is the details.</span>
+      <summary>Summary
+        <!-- Need ib-split so that the summary has multiple frames. -->
+        <div>Block in summary</div>
+      </summary>
+    </details>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-details-first-line-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  div#details::first-line {
+    color: blue;
+  }
+  </style>
+  <body>
+    <div id="details">
+      <span>Summary
+        <div>Block in summary</div>
+      </span>
+      <span>This is the details.</span>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-inline-style-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <body>
+    <div>
+      <span>Summary
+        <div>Block in summary</div>
+      </span>
+      <p>This is the details.</p>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-inline-style.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  summary {
+    display: inline;
+  }
+  </style>
+  <body>
+    <details open>
+      <p>This is the details.</p>
+      <!-- Make summary the second element child so that layout will try to
+           render it as the first child. -->
+      <summary>Summary
+        <!-- Need ib-split so that the summary has multiple frames. -->
+        <div>Block in summary</div>
+      </summary>
+    </details>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-table-cell-style-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <body>
+    <div>
+      <span style="display: table-cell;">Summary
+        <div>Block in summary</div>
+      </span>
+      <p>This is the details.</p>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/details-summary/open-summary-table-cell-style.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+   - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+  <style>
+  summary {
+    display: table-cell;
+  }
+  </style>
+  <body>
+    <details open>
+      <p>This is the details.</p>
+      <!-- Make summary the second element child so that layout will try to
+           render it as the first child. -->
+      <summary>Summary
+        <div>Block in summary</div>
+      </summary>
+    </details>
+  </body>
+</html>
--- a/layout/reftests/details-summary/reftest.list
+++ b/layout/reftests/details-summary/reftest.list
@@ -6,16 +6,18 @@ pref(dom.details_element.enabled,false) 
 pref(dom.details_element.enabled,false) == no-summary.html disabled-no-summary-ref.html
 
 # Basic <summary> handling
 == multiple-summary.html single-summary.html
 == open-multiple-summary.html open-multiple-summary-ref.html
 == summary-not-first-child.html single-summary.html
 == open-summary-not-first-child.html open-single-summary.html
 == open-summary-block-style.html open-summary-block-style-ref.html
+== open-summary-inline-style.html open-summary-inline-style-ref.html
+== open-summary-table-cell-style.html open-summary-table-cell-style-ref.html
 == no-summary.html no-summary-ref.html
 == open-no-summary.html open-no-summary-ref.html
 == summary-not-in-details.html summary-not-in-details-ref.html
 == summary-not-direct-child.html summary-not-direct-child-ref.html
 == float-in-summary.html float-in-summary-ref.html
 
 # Add elements dynamically
 == dynamic-add-single-summary.html open-single-summary.html
@@ -65,16 +67,19 @@ pref(dom.details_element.enabled,false) 
 # Various properties on details or summary
 == details-display-inline.html details-display-inline-ref.html
 == details-percentage-height-children.html details-percentage-height-children-ref.html
 == details-absolute-children.html details-absolute-children-ref.html
 == details-three-columns.html details-three-columns-ref.html
 == details-writing-mode.html details-writing-mode-ref.html
 == details-in-ol.html details-in-ol-ref.html
 == summary-three-columns.html summary-three-columns-ref.html
+== details-first-line.html details-first-line-ref.html
+== open-details-first-line-1.html open-details-first-line-ref.html
+== open-details-first-line-2.html open-details-first-line-ref.html
 
 # Dispatch mouse click to summary
 == mouse-click-single-summary.html open-single-summary.html
 == mouse-click-twice-single-summary.html single-summary.html
 == mouse-click-open-single-summary.html single-summary.html
 == mouse-click-twice-open-single-summary.html open-single-summary.html
 == mouse-click-open-second-summary.html open-multiple-summary.html
 == mouse-click-overflow-hidden-details.html overflow-hidden-open-details.html
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -42,30 +42,53 @@ SERVO_BINDING_FUNC(Servo_StyleSet_Append
 SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
                    RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
                    RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
                    RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet,
                    RawServoStyleSheetBorrowed reference)
 
+// Animations API
+SERVO_BINDING_FUNC(Servo_ParseProperty,
+                   ServoDeclarationBlockStrong,
+                   const uint8_t* property_bytes,
+                   uint32_t property_length,
+                   const uint8_t* value_bytes,
+                   uint32_t value_length,
+                   const uint8_t* base_bytes,
+                   uint32_t base_length,
+                   ThreadSafeURIHolder* base,
+                   ThreadSafeURIHolder* referrer,
+                   ThreadSafePrincipalHolder* principal)
+SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
+                   ServoComputedValuesStrong,
+                   ServoDeclarationBlockBorrowed declarations,
+                   ServoComputedValuesBorrowed previous_style)
+
 // Style attribute
 SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, ServoDeclarationBlockStrong,
                    const uint8_t* bytes, uint32_t length,
                    nsHTMLCSSStyleSheet* cache)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_AddRef, void,
                    ServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Release, void,
                    ServoDeclarationBlockBorrowed declarations)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
+                   ServoDeclarationBlockBorrowed a,
+                   ServoDeclarationBlockBorrowed b)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetCache, nsHTMLCSSStyleSheet*,
                    ServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SetImmutable, void,
                    ServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_ClearCachePointer, void,
                    ServoDeclarationBlockBorrowed declarations)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_SerializeOneValue, void,
+                   ServoDeclarationBlockBorrowed declarations,
+                   nsString* buffer)
 
 // CSS supports()
 SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
                    const uint8_t* name, uint32_t name_length,
                    const uint8_t* value, uint32_t value_length)
 
 // Computed style data
 SERVO_BINDING_FUNC(Servo_ComputedValues_Get, ServoComputedValuesStrong,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -615,16 +615,29 @@ Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* 
   // XXXbholley: We should be able to do this without converting, I just can't
   // find the right thing to call.
   nsDependentAtomString atomStr(aAtom);
   NS_ConvertUTF8toUTF16 inStr(nsDependentCSubstring(aString, aLength));
   return nsContentUtils::EqualsIgnoreASCIICase(atomStr, inStr);
 }
 
 void
+Gecko_Utf8SliceToString(nsString* aString,
+                        const uint8_t* aBuffer,
+                        size_t aBufferLen)
+{
+  MOZ_ASSERT(aString);
+  MOZ_ASSERT(aBuffer);
+
+  aString->Truncate();
+  AppendUTF8toUTF16(Substring(reinterpret_cast<const char*>(aBuffer),
+                              aBufferLen), *aString);
+}
+
+void
 Gecko_FontFamilyList_Clear(FontFamilyList* aList) {
   aList->Clear();
 }
 
 void
 Gecko_FontFamilyList_AppendNamed(FontFamilyList* aList, nsIAtom* aName)
 {
   // Servo doesn't record whether the name was quoted or unquoted, so just
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -221,16 +221,21 @@ ServoDeclarationBlockBorrowedOrNull Geck
 // Atoms.
 nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength);
 void Gecko_AddRefAtom(nsIAtom* aAtom);
 void Gecko_ReleaseAtom(nsIAtom* aAtom);
 const uint16_t* Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength);
 bool Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength);
 bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength);
 
+// Strings (temporary until bug 1294742)
+void Gecko_Utf8SliceToString(nsString* aString,
+                             const uint8_t* aBuffer,
+                             size_t aBufferLen);
+
 // Font style
 void Gecko_FontFamilyList_Clear(FontFamilyList* aList);
 void Gecko_FontFamilyList_AppendNamed(FontFamilyList* aList, nsIAtom* aName);
 void Gecko_FontFamilyList_AppendGeneric(FontFamilyList* list, FontFamilyType familyType);
 void Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src);
 
 // Counter style.
 void Gecko_SetListStyleType(nsStyleList* style_struct, uint32_t type);
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -22,16 +22,17 @@
 #include "nsStyleSet.h"
 #include "nsComputedDOMStyle.h"
 #include "nsCSSParser.h"
 #include "nsCSSPseudoElements.h"
 #include "mozilla/css/Declaration.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/Likely.h"
+#include "mozilla/ServoBindings.h" // ServoDeclarationBlock
 #include "gfxMatrix.h"
 #include "gfxQuaternion.h"
 #include "nsIDocument.h"
 #include "nsIFrame.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
@@ -3032,19 +3033,49 @@ BuildStyleRule(nsCSSPropertyID aProperty
   declaration->ValueAppended(aProperty);
   declaration->CompressFrom(&block);
 
   RefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration, 0, 0);
   return rule.forget();
 }
 
 static bool
+ComputeValuesFromStyleContext(
+  nsCSSPropertyID aProperty,
+  CSSEnabledState aEnabledState,
+  nsStyleContext* aStyleContext,
+  nsTArray<PropertyStyleAnimationValuePair>& aValues)
+{
+  // Extract computed value of our property (or all longhand components, if
+  // aProperty is a shorthand) from the temporary style context
+  if (nsCSSProps::IsShorthand(aProperty)) {
+    CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty, aEnabledState) {
+      if (nsCSSProps::kAnimTypeTable[*p] == eStyleAnimType_None) {
+        // Skip non-animatable component longhands.
+        continue;
+      }
+      PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
+      pair->mProperty = *p;
+      if (!StyleAnimationValue::ExtractComputedValue(*p, aStyleContext,
+                                                     pair->mValue)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
+  pair->mProperty = aProperty;
+  return StyleAnimationValue::ExtractComputedValue(aProperty, aStyleContext,
+                                                   pair->mValue);
+}
+
+static bool
 ComputeValuesFromStyleRule(nsCSSPropertyID aProperty,
                            CSSEnabledState aEnabledState,
-                           dom::Element* aTargetElement,
                            nsStyleContext* aStyleContext,
                            css::StyleRule* aStyleRule,
                            nsTArray<PropertyStyleAnimationValuePair>& aValues,
                            bool* aIsContextSensitive)
 {
   MOZ_ASSERT(aStyleContext);
   if (!nsCSSProps::IsEnabled(aProperty, aEnabledState)) {
     return false;
@@ -3095,38 +3126,18 @@ ComputeValuesFromStyleRule(nsCSSProperty
     declaration->SetImmutable();
     tmpStyleContext =
       styleSet->ResolveStyleByAddingRules(aStyleContext, ruleArray);
     if (!tmpStyleContext) {
       return false;
     }
   }
 
-  // Extract computed value of our property (or all longhand components, if
-  // aProperty is a shorthand) from the temporary style rule
-  if (nsCSSProps::IsShorthand(aProperty)) {
-    CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aProperty, aEnabledState) {
-      if (nsCSSProps::kAnimTypeTable[*p] == eStyleAnimType_None) {
-        // Skip non-animatable component longhands.
-        continue;
-      }
-      PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
-      pair->mProperty = *p;
-      if (!StyleAnimationValue::ExtractComputedValue(*p, tmpStyleContext,
-                                                     pair->mValue)) {
-        return false;
-      }
-    }
-    return true;
-  } else {
-    PropertyStyleAnimationValuePair* pair = aValues.AppendElement();
-    pair->mProperty = aProperty;
-    return StyleAnimationValue::ExtractComputedValue(aProperty, tmpStyleContext,
-                                                     pair->mValue);
-  }
+  return ComputeValuesFromStyleContext(aProperty, aEnabledState,
+                                       tmpStyleContext, aValues);
 }
 
 /* static */ bool
 StyleAnimationValue::ComputeValue(nsCSSPropertyID aProperty,
                                   dom::Element* aTargetElement,
                                   nsStyleContext* aStyleContext,
                                   const nsAString& aSpecifiedValue,
                                   bool aUseSVGMode,
@@ -3155,17 +3166,17 @@ StyleAnimationValue::ComputeValue(nsCSSP
       *aIsContextSensitive = false;
     }
     return true;
   }
 
   AutoTArray<PropertyStyleAnimationValuePair,1> values;
   bool ok = ComputeValuesFromStyleRule(aProperty,
                                        CSSEnabledState::eIgnoreEnabledState,
-                                       aTargetElement, aStyleContext, styleRule,
+                                       aStyleContext, styleRule,
                                        values, aIsContextSensitive);
   if (!ok) {
     return false;
   }
 
   MOZ_ASSERT(values.Length() == 1);
   MOZ_ASSERT(values[0].mProperty == aProperty);
 
@@ -3192,17 +3203,17 @@ ComputeValuesFromSpecifiedValue(
   // and Principal.
   RefPtr<css::StyleRule> styleRule =
     BuildStyleRule(aProperty, aTargetElement, aSpecifiedValue, aUseSVGMode);
   if (!styleRule) {
     return false;
   }
 
   aResult.Clear();
-  return ComputeValuesFromStyleRule(aProperty, aEnabledState, aTargetElement,
+  return ComputeValuesFromStyleRule(aProperty, aEnabledState,
                                     aStyleContext, styleRule, aResult,
                                     /* aIsContextSensitive */ nullptr);
 }
 
 /* static */ bool
 StyleAnimationValue::ComputeValues(
     nsCSSPropertyID aProperty,
     CSSEnabledState aEnabledState,
@@ -3229,16 +3240,55 @@ StyleAnimationValue::ComputeValues(
     nsTArray<PropertyStyleAnimationValuePair>& aResult)
 {
   return ComputeValuesFromSpecifiedValue(aProperty, aEnabledState,
                                          aTargetElement, aStyleContext,
                                          aSpecifiedValue, aUseSVGMode,
                                          aResult);
 }
 
+/* static */ bool
+StyleAnimationValue::ComputeValues(
+  nsCSSPropertyID aProperty,
+  CSSEnabledState aEnabledState,
+  nsStyleContext* aStyleContext,
+  const ServoDeclarationBlock& aDeclarations,
+  nsTArray<PropertyStyleAnimationValuePair>& aValues)
+{
+  MOZ_ASSERT(aStyleContext->PresContext()->StyleSet()->IsServo(),
+             "Should be using ServoStyleSet if we have a"
+             " ServoDeclarationBlock");
+
+  if (!nsCSSProps::IsEnabled(aProperty, aEnabledState)) {
+    return false;
+  }
+
+  RefPtr<ServoComputedValues> previousStyle =
+    aStyleContext->StyleSource().AsServoComputedValues();
+
+  // FIXME: Servo bindings don't yet represent const-ness so we just
+  // cast it away for now.
+  auto declarations = const_cast<ServoDeclarationBlock*>(&aDeclarations);
+  RefPtr<ServoComputedValues> computedValues =
+    Servo_RestyleWithAddedDeclaration(declarations, previousStyle).Consume();
+  if (!computedValues) {
+    return false;
+  }
+
+  RefPtr<nsStyleContext> tmpStyleContext =
+    NS_NewStyleContext(aStyleContext, aStyleContext->PresContext(),
+                       aStyleContext->GetPseudo(),
+                       aStyleContext->GetPseudoType(),
+                       computedValues.forget(),
+                       false /* skipFixup */);
+
+  return ComputeValuesFromStyleContext(aProperty, aEnabledState,
+                                       tmpStyleContext, aValues);
+}
+
 bool
 StyleAnimationValue::UncomputeValue(nsCSSPropertyID aProperty,
                                     const StyleAnimationValue& aComputedValue,
                                     nsCSSValue& aSpecifiedValue)
 {
   Unit unit = aComputedValue.GetUnit();
   switch (unit) {
     case eUnit_Normal:
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -15,16 +15,17 @@
 #include "nsCoord.h"
 #include "nsColor.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 
 class nsIFrame;
 class nsStyleContext;
 class gfx3DMatrix;
+struct ServoDeclarationBlock;
 
 namespace mozilla {
 
 namespace css {
 class StyleRule;
 } // namespace css
 
 namespace dom {
@@ -231,16 +232,27 @@ public:
                 mozilla::CSSEnabledState aEnabledState,
                 mozilla::dom::Element* aTargetElement,
                 nsStyleContext* aStyleContext,
                 const nsCSSValue& aSpecifiedValue,
                 bool aUseSVGMode,
                 nsTArray<PropertyStyleAnimationValuePair>& aResult);
 
   /**
+   * A variant of ComputeValues that takes a ServoDeclarationBlock as the
+   * specified value.
+   */
+  static MOZ_MUST_USE bool
+  ComputeValues(nsCSSPropertyID aProperty,
+                mozilla::CSSEnabledState aEnabledState,
+                nsStyleContext* aStyleContext,
+                const ServoDeclarationBlock& aDeclarations,
+                nsTArray<PropertyStyleAnimationValuePair>& aValues);
+
+  /**
    * Creates a specified value for the given computed value.
    *
    * The first two overloads fill in an nsCSSValue object; the third
    * produces a string.  For the overload that takes a const
    * StyleAnimationValue& reference, the nsCSSValue result may depend on
    * objects owned by the |aComputedValue| object, so users of that variant
    * must keep |aComputedValue| alive longer than |aSpecifiedValue|.
    * The overload that takes an rvalue StyleAnimationValue reference
--- a/mobile/android/chrome/content/WebrtcUI.js
+++ b/mobile/android/chrome/content/WebrtcUI.js
@@ -161,17 +161,17 @@ var WebrtcUI = {
         let videoId = 0;
         if (inputs && inputs.videoSource != undefined)
           videoId = inputs.videoSource;
         if (videoDevices[videoId]) {
           allowedDevices.AppendElement(videoDevices[videoId]);
           let perms = Services.perms;
           // Although the lifetime is "session" it will be removed upon
           // use so it's more of a one-shot.
-          perms.add(aUri, "camera", perms.ALLOW_ACTION, perms.EXPIRE_SESSION);
+          perms.add(aUri, "MediaManagerVideo", perms.ALLOW_ACTION, perms.EXPIRE_SESSION);
         }
 
         Services.obs.notifyObservers(allowedDevices, "getUserMedia:response:allow", aCallID);
       },
       positive: true
     }];
   },
 
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -14,16 +14,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Messaging", "resource://gre/modules/Messaging.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "FormData", "resource://gre/modules/FormData.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "ScrollPosition", "resource://gre/modules/ScrollPosition.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm");
 XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/AndroidLog.jsm", "AndroidLog");
 XPCOMUtils.defineLazyModuleGetter(this, "SharedPreferences", "resource://gre/modules/SharedPreferences.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "Utils", "resource:///modules/sessionstore/Utils.jsm");
 XPCOMUtils.defineLazyServiceGetter(this, "serializationHelper",
                                    "@mozilla.org/network/serialization-helper;1",
                                    "nsISerializationHelper");
 
 function dump(a) {
   Services.console.logStringMessage(a);
 }
 
--- a/moz.configure
+++ b/moz.configure
@@ -30,16 +30,26 @@ option('--enable-artifact-builds', env='
 
 @depends('--enable-artifact-builds')
 def artifact_builds(value):
     if value:
         return True
 
 set_config('MOZ_ARTIFACT_BUILDS', artifact_builds)
 
+imply_option('--enable-artifact-build-symbols',
+             depends(artifact_builds)(lambda v: False if v is None else None),
+             reason='--disable-artifact-builds')
+
+option('--enable-artifact-build-symbols',
+       help='Download symbols when artifact builds are enabled.')
+
+set_config('MOZ_ARTIFACT_BUILD_SYMBOLS',
+           depends_if('--enable-artifact-build-symbols')(lambda _: True))
+
 @depends('--enable-artifact-builds')
 def imply_disable_compile_environment(value):
     if value:
         return False
 
 imply_option('--enable-compile-environment', imply_disable_compile_environment)
 
 option('--disable-compile-environment',
--- a/netwerk/cookie/PCookieService.ipdl
+++ b/netwerk/cookie/PCookieService.ipdl
@@ -21,17 +21,17 @@ namespace net {
  * all cookie operations. Lower-level programmatic operations (i.e. those
  * provided by the nsICookieManager and nsICookieManager2 interfaces) are not
  * currently implemented and requesting these interfaces in the child will fail.
  *
  * @see nsICookieService
  * @see nsICookiePermission
  */
 
-prio(normal upto urgent) sync protocol PCookieService
+nested(upto inside_cpow) sync protocol PCookieService
 {
   manager PNecko;
 
 parent:
 
   /*
    * Get the complete cookie string associated with the URI. This is a sync
    * call in order to avoid race conditions -- for instance, an HTTP response
@@ -54,20 +54,20 @@ parent:
    *        cookie is being set on.
    *
    * @see nsICookieService.getCookieString
    * @see nsICookieService.getCookieStringFromHttp
    * @see mozIThirdPartyUtil.isThirdPartyChannel
    *
    * @return the resulting cookie string.
    */
-  prio(urgent) sync GetCookieString(URIParams host,
-                                    bool isForeign,
-                                    bool fromHttp,
-                                    NeckoOriginAttributes attrs)
+  nested(inside_cpow) sync GetCookieString(URIParams host,
+                                           bool isForeign,
+                                           bool fromHttp,
+                                           NeckoOriginAttributes attrs)
        returns (nsCString result);
 
   /*
    * Set a cookie string.
    *
    * @param host
    *        Same as the 'aURI' argument to nsICookieService.setCookieString.
    * @param isForeign
@@ -89,21 +89,21 @@ parent:
    * @param attrs
    *        The origin attributes from the HTTP channel or document that the
    *        cookie is being set on.
    *
    * @see nsICookieService.setCookieString
    * @see nsICookieService.setCookieStringFromHttp
    * @see mozIThirdPartyUtil.isThirdPartyChannel
    */
-  prio(urgent) async SetCookieString(URIParams host,
-                                     bool isForeign,
-                                     nsCString cookieString,
-                                     nsCString serverTime,
-                                     bool fromHttp,
-                                     NeckoOriginAttributes attrs);
+  nested(inside_cpow) async SetCookieString(URIParams host,
+                                            bool isForeign,
+                                            nsCString cookieString,
+                                            nsCString serverTime,
+                                            bool fromHttp,
+                                            NeckoOriginAttributes attrs);
 
   async __delete__();
 };
 
 }
 }
 
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -35,17 +35,17 @@ include protocol PAltDataOutputStream;
 using class IPC::SerializedLoadContext from "SerializedLoadContext.h";
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
-prio(normal upto urgent) sync protocol PNecko
+nested(upto inside_cpow) sync protocol PNecko
 {
   manager PContent;
   manages PHttpChannel;
   manages PCookieService;
   manages PWyciwygChannel;
   manages PFTPChannel;
   manages PWebSocket;
   manages PWebSocketEventListener;
@@ -59,17 +59,17 @@ prio(normal upto urgent) sync protocol P
   manages PRtspChannel;
   manages PChannelDiverter;
   manages PTransportProvider;
   manages PAltDataOutputStream;
 
 parent:
   async __delete__();
 
-  prio(urgent) async PCookieService();
+  nested(inside_cpow) async PCookieService();
   async PHttpChannel(PBrowserOrId browser,
                      SerializedLoadContext loadContext,
                      HttpChannelCreationArgs args);
   async PWyciwygChannel();
   async PFTPChannel(PBrowserOrId browser, SerializedLoadContext loadContext,
                     FTPChannelCreationArgs args);
 
   async PWebSocket(PBrowserOrId browser, SerializedLoadContext loadContext,
--- a/old-configure.in
+++ b/old-configure.in
@@ -1355,45 +1355,25 @@ AC_LANG_CPLUSPLUS
 AC_LANG_C
 
 AC_LANG_CPLUSPLUS
 
 MOZ_CXX11
 
 AC_LANG_C
 
-dnl Check for .hidden assembler directive and visibility attribute.
-dnl Borrowed from glibc configure.in
-dnl ===============================================================
-if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
-  AC_DEFINE(HAVE_VISIBILITY_HIDDEN_ATTRIBUTE)
-  AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
-  case "$OS_TARGET" in
-  Darwin)
-    VISIBILITY_FLAGS='-fvisibility=hidden -fvisibility-inlines-hidden'
-    ;;
-  *)
-    VISIBILITY_FLAGS="-I${DIST}/system_wrappers -include ${_topsrcdir}/config/gcc_hidden.h"
-    WRAP_SYSTEM_INCLUDES=1
-    ;;
-  esac
-fi         # GNU_CC
-
 case "${OS_TARGET}" in
 Darwin)
   ;;
 *)
   STL_FLAGS="-I${DIST}/stl_wrappers"
   WRAP_STL_INCLUDES=1
   ;;
 esac
 
-AC_SUBST(WRAP_SYSTEM_INCLUDES)
-AC_SUBST_LIST(VISIBILITY_FLAGS)
-
 dnl Checks for header files.
 dnl ========================================================
 AC_HEADER_DIRENT
 case "$target_os" in
 bitrig*|dragonfly*|freebsd*|openbsd*)
 # for stuff like -lXshm
     CPPFLAGS="${CPPFLAGS} ${X_CFLAGS}"
     ;;
--- a/python/mozbuild/mozbuild/artifacts.py
+++ b/python/mozbuild/mozbuild/artifacts.py
@@ -123,48 +123,55 @@ class ArtifactJob(object):
         ('bin/xpcshell', ('bin', 'bin')),
         ('bin/plugins/*', ('bin/plugins', 'plugins'))
     }
 
     # We can tell our input is a test archive by this suffix, which happens to
     # be the same across platforms.
     _test_archive_suffix = '.common.tests.zip'
 
-    def __init__(self, package_re, tests_re, log=None):
+    def __init__(self, package_re, tests_re, log=None, download_symbols=False):
         self._package_re = re.compile(package_re)
         self._tests_re = None
         if tests_re:
             self._tests_re = re.compile(tests_re)
         self._log = log
+        self._symbols_archive_suffix = None
+        if download_symbols:
+            self._symbols_archive_suffix = 'crashreporter-symbols.zip'
 
     def log(self, *args, **kwargs):
         if self._log:
             self._log(*args, **kwargs)
 
     def find_candidate_artifacts(self, artifacts):
         # TODO: Handle multiple artifacts, taking the latest one.
         tests_artifact = None
         for artifact in artifacts:
             name = artifact['name']
             if self._package_re and self._package_re.match(name):
                 yield name
             elif self._tests_re and self._tests_re.match(name):
                 tests_artifact = name
                 yield name
+            elif self._symbols_archive_suffix and name.endswith(self._symbols_archive_suffix):
+                yield name
             else:
                 self.log(logging.DEBUG, 'artifact',
                          {'name': name},
                          'Not yielding artifact named {name} as a candidate artifact')
         if self._tests_re and not tests_artifact:
             raise ValueError('Expected tests archive matching "{re}", but '
                              'found none!'.format(re=self._tests_re))
 
     def process_artifact(self, filename, processed_filename):
         if filename.endswith(ArtifactJob._test_archive_suffix) and self._tests_re:
             return self.process_tests_artifact(filename, processed_filename)
+        if self._symbols_archive_suffix and filename.endswith(self._symbols_archive_suffix):
+            return self.process_symbols_archive(filename, processed_filename)
         return self.process_package_artifact(filename, processed_filename)
 
     def process_package_artifact(self, filename, processed_filename):
         raise NotImplementedError("Subclasses must specialize process_package_artifact!")
 
     def process_tests_artifact(self, filename, processed_filename):
         added_entry = False
 
@@ -183,16 +190,25 @@ class ArtifactJob(object):
                     writer.add(destpath.encode('utf-8'), reader[filename], mode=mode)
                     added_entry = True
 
         if not added_entry:
             raise ValueError('Archive format changed! No pattern from "{patterns}"'
                              'matched an archive path.'.format(
                                  patterns=LinuxArtifactJob.test_artifact_patterns))
 
+    def process_symbols_archive(self, filename, processed_filename):
+        with JarWriter(file=processed_filename, optimize=False, compress_level=5) as writer:
+            reader = JarReader(filename)
+            for filename in reader.entries:
+                destpath = mozpath.join('crashreporter-symbols', filename)
+                self.log(logging.INFO, 'artifact',
+                         {'destpath': destpath},
+                         'Adding {destpath} to processed archive')
+                writer.add(destpath.encode('utf-8'), reader[filename])
 
 class AndroidArtifactJob(ArtifactJob):
 
     package_artifact_patterns = {
         'application.ini',
         'platform.ini',
         '**/*.so',
         '**/interfaces.xpt',
@@ -425,19 +441,19 @@ JOB_DETAILS = {
     'win64': (WinArtifactJob, ('public/build/firefox-(.*)\.win64.zip',
                                'public/build/firefox-(.*)\.common\.tests\.zip')),
     'win64-debug': (WinArtifactJob, ('public/build/firefox-(.*)\.win64.zip',
                                'public/build/firefox-(.*)\.common\.tests\.zip')),
 }
 
 
 
-def get_job_details(job, log=None):
+def get_job_details(job, log=None, download_symbols=False):
     cls, (package_re, tests_re) = JOB_DETAILS[job]
-    return cls(package_re, tests_re, log=log)
+    return cls(package_re, tests_re, log=log, download_symbols=download_symbols)
 
 def cachedmethod(cachefunc):
     '''Decorator to wrap a class or instance method with a memoizing callable that
     saves results in a (possibly shared) cache.
     '''
     def decorator(method):
         def wrapper(self, *args, **kwargs):
             mapping = cachefunc(self)
@@ -606,19 +622,19 @@ class TaskCache(CacheManager):
     '''Map candidate pushheads to Task Cluster task IDs and artifact URLs.'''
 
     def __init__(self, cache_dir, log=None, skip_cache=False):
         CacheManager.__init__(self, cache_dir, 'artifact_url', MAX_CACHED_TASKS, log=log, skip_cache=skip_cache)
         self._index = taskcluster.Index()
         self._queue = taskcluster.Queue()
 
     @cachedmethod(operator.attrgetter('_cache'))
-    def artifact_urls(self, tree, job, rev):
+    def artifact_urls(self, tree, job, rev, download_symbols):
         try:
-            artifact_job = get_job_details(job, log=self._log)
+            artifact_job = get_job_details(job, log=self._log, download_symbols=download_symbols)
         except KeyError:
             self.log(logging.INFO, 'artifact',
                 {'job': job},
                 'Unknown job {job}')
             raise KeyError("Unknown job")
 
         key = '{rev}.{tree}.{job}'.format(rev=rev, tree=tree, job=job)
         try:
@@ -743,28 +759,29 @@ class Artifacts(object):
 
     def __init__(self, tree, substs, defines, job=None, log=None,
                  cache_dir='.', hg=None, git=None, skip_cache=False,
                  topsrcdir=None):
         if (hg and git) or (not hg and not git):
             raise ValueError("Must provide path to exactly one of hg and git")
 
         self._substs = substs
+        self._download_symbols = self._substs.get('MOZ_ARTIFACT_BUILD_SYMBOLS', False)
         self._defines = defines
         self._tree = tree
         self._job = job or self._guess_artifact_job()
         self._log = log
         self._hg = hg
         self._git = git
         self._cache_dir = cache_dir
         self._skip_cache = skip_cache
         self._topsrcdir = topsrcdir
 
         try:
-            self._artifact_job = get_job_details(self._job, log=self._log)
+            self._artifact_job = get_job_details(self._job, log=self._log, download_symbols=self._download_symbols)
         except KeyError:
             self.log(logging.INFO, 'artifact',
                 {'job': self._job},
                 'Unknown job {job}')
             raise KeyError("Unknown job")
 
         self._task_cache = TaskCache(self._cache_dir, log=self._log, skip_cache=self._skip_cache)
         self._artifact_cache = ArtifactCache(self._cache_dir, log=self._log, skip_cache=self._skip_cache)
@@ -909,17 +926,17 @@ class Artifacts(object):
         try:
             trees = tree_cache.artifact_trees(pushhead)
         except ValueError:
             return None
         trees.sort()
 
         for tree in trees:
             try:
-                urls = task_cache.artifact_urls(tree, job, pushhead)
+                urls = task_cache.artifact_urls(tree, job, pushhead, self._download_symbols)
             except ValueError:
                 continue
             if urls:
                 self.log(logging.INFO, 'artifact',
                          {'pushhead': pushhead,
                           'tree': tree},
                          'Installing from remote pushhead {pushhead} on {tree}')
                 return urls
--- a/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
+++ b/security/sandbox/chromium-shim/sandbox/win/loggingCallbacks.h
@@ -5,25 +5,31 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef security_sandbox_loggingCallbacks_h__
 #define security_sandbox_loggingCallbacks_h__
 
 #include <sstream>
 #include <iostream>
 
+#include "mozilla/Logging.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/sandboxing/loggingTypes.h"
 #include "nsContentUtils.h"
 
 #ifdef MOZ_STACKWALKING
 #include "mozilla/StackWalk.h"
 #endif
 
 namespace mozilla {
+
+static LazyLogModule sSandboxTargetLog("SandboxTarget");
+
+#define LOG_D(...) MOZ_LOG(sSandboxTargetLog, LogLevel::Debug, (__VA_ARGS__))
+
 namespace sandboxing {
 
 #ifdef MOZ_STACKWALKING
 static uint32_t sStackTraceDepth = 0;
 
 // NS_WalkStackCallback to write a formatted stack frame to an ostringstream.
 static void
 StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
@@ -68,16 +74,19 @@ Log(const char* aMessageType,
   // Use NS_DebugBreak directly as we want child process prefix, but not source
   // file or line number.
   NS_DebugBreak(NS_DEBUG_WARNING, nullptr, msg.c_str(), nullptr, -1);
 #endif
 
   if (nsContentUtils::IsInitialized()) {
     nsContentUtils::LogMessageToConsole(msg.c_str());
   }
+
+  // As we don't always have the facility to log to console use MOZ_LOG as well.
+  LOG_D("%s", msg.c_str());
 }
 
 // Initialize sandbox logging if required.
 static void
 InitLoggingIfRequired(ProvideLogFunctionCb aProvideLogFunctionCb)
 {
   if (!aProvideLogFunctionCb) {
     return;
@@ -96,9 +105,9 @@ InitLoggingIfRequired(ProvideLogFunction
     }
 #endif
   }
 }
 
 } // sandboxing
 } // mozilla
 
-#endif // security_sandbox_loggingCallbacks_h__
\ No newline at end of file
+#endif // security_sandbox_loggingCallbacks_h__
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -1940,31 +1940,47 @@ SpecialPowersAPI.prototype = {
     this.notifyObserversInParentProcess(null, "browser:purge-domain-data", "example.com");
   },
 
   cleanUpSTSData: function(origin, flags) {
     return this._sendSyncMessage('SPCleanUpSTSData', {origin: origin, flags: flags || 0});
   },
 
   _nextExtensionID: 0,
+  _extensionListeners: null,
+
   loadExtension: function(ext, handler) {
+    if (this._extensionListeners == null) {
+      this._extensionListeners = new Set();
+
+      this._addMessageListener("SPExtensionMessage", msg => {
+        for (let listener of this._extensionListeners) {
+          try {
+            listener(msg);
+          } catch (e) {
+            Cu.reportError(e);
+          }
+        }
+      });
+    }
+
     // Note, this is not the addon is as used by the AddonManager etc,
     // this is just an identifier used for specialpowers messaging
     // between this content process and the chrome process.
     let id = this._nextExtensionID++;
 
     let resolveStartup, resolveUnload, rejectStartup;
     let startupPromise = new Promise((resolve, reject) => {
       resolveStartup = resolve;
       rejectStartup = reject;
     });
     let unloadPromise = new Promise(resolve => { resolveUnload = resolve; });
 
     startupPromise.catch(() => {
-      this._removeMessageListener("SPExtensionMessage", listener);
+      this._extensionListeners.delete(listener);
     });
 
     handler = Cu.waiveXrays(handler);
     ext = Cu.waiveXrays(ext);
 
     let sp = this;
     let state = "uninitialized";
     let extension = {
@@ -1995,28 +2011,28 @@ SpecialPowersAPI.prototype = {
           state = "running";
           resolveStartup();
         } else if (msg.data.type == "extensionSetId") {
           extension.id = msg.data.args[0];
         } else if (msg.data.type == "extensionFailed") {
           state = "failed";
           rejectStartup("startup failed");
         } else if (msg.data.type == "extensionUnloaded") {
-          this._removeMessageListener("SPExtensionMessage", listener);
+          this._extensionListeners.delete(listener);
           state = "unloaded";
           resolveUnload();
         } else if (msg.data.type in handler) {
           handler[msg.data.type](...msg.data.args);
         } else {
           dump(`Unexpected: ${msg.data.type}\n`);
         }
       }
     };
 
-    this._addMessageListener("SPExtensionMessage", listener);
+    this._extensionListeners.add(listener);
     return extension;
   },
 
   invalidateExtensionStorageCache: function() {
     this.notifyObserversInParentProcess(null, "extension-invalidate-storage-cache", "");
   },
 
   allowMedia: function(window, enable) {
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-checkValidity.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-checkValidity.html.ini
@@ -40,26 +40,14 @@
     expected: FAIL
 
   [[INPUT in MONTH status\] suffering from a step mismatch]
     expected: FAIL
 
   [[INPUT in MONTH status\] suffering from a step mismatch (in a form)]
     expected: FAIL
 
-  [[INPUT in WEEK status\] suffering from an overflow]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] suffering from an overflow (in a form)]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] suffering from an underflow]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] suffering from an underflow (in a form)]
-    expected: FAIL
-
   [[INPUT in WEEK status\] suffering from a step mismatch]
     expected: FAIL
 
   [[INPUT in WEEK status\] suffering from a step mismatch (in a form)]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-reportValidity.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-reportValidity.html.ini
@@ -40,26 +40,14 @@
     expected: FAIL
 
   [[INPUT in MONTH status\] suffering from a step mismatch]
     expected: FAIL
 
   [[INPUT in MONTH status\] suffering from a step mismatch (in a form)]
     expected: FAIL
 
-  [[INPUT in WEEK status\] suffering from an overflow]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] suffering from an overflow (in a form)]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] suffering from an underflow]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] suffering from an underflow (in a form)]
-    expected: FAIL
-
   [[INPUT in WEEK status\] suffering from a step mismatch]
     expected: FAIL
 
   [[INPUT in WEEK status\] suffering from a step mismatch (in a form)]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html.ini
@@ -1,11 +1,4 @@
 [form-validation-validity-rangeOverflow.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
-
-  [[INPUT in WEEK status\] The value attribute is greater than max attribute]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] The value attribute is greater than max attribute(Year is 10000 should be valid)]
-    expected: FAIL
-
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html.ini
@@ -1,11 +1,5 @@
 [form-validation-validity-rangeUnderflow.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in WEEK status\] The value attribute is less than min attribute]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] The value attribute is less than min attribute(Year is 10000 should be valid)]
-    expected: FAIL
-
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valid.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valid.html.ini
@@ -19,17 +19,11 @@
     expected: FAIL
 
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
   [[INPUT in MONTH status\] validity.valid must be false if validity.stepMismatch is true]
     expected: FAIL
 
-  [[INPUT in WEEK status\] validity.valid must be false if validity.rangeOverflow is true]
-    expected: FAIL
-
-  [[INPUT in WEEK status\] validity.valid must be false if validity.rangeUnderflow is true]
-    expected: FAIL
-
   [[INPUT in WEEK status\] validity.valid must be false if validity.stepMismatch is true]
     expected: FAIL
 
--- a/toolkit/components/extensions/.eslintrc
+++ b/toolkit/components/extensions/.eslintrc
@@ -221,17 +221,17 @@
 
     // Never use spaces before function parentheses
     "space-before-function-paren": [2, {"anonymous": "never", "named": "never"}],
 
     // Require spaces around operators, except for a|0.
     "space-infix-ops": [2, {"int32Hint": true}],
 
     // ++ and -- should not need spacing
-    "space-unary-ops": [1, {"nonwords": false}],
+    "space-unary-ops": [1, {"nonwords": false, "words": true, "overrides": {"typeof": false}}],
 
     // No comparisons to NaN
     "use-isnan": 2,
 
     // Only check typeof against valid results
     "valid-typeof": 2,
 
     // Disallow using variables outside the blocks they are defined (especially
--- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest.html
@@ -147,16 +147,17 @@ function backgroundScript() {
     browser.test.assertTrue(ids && ids.has(details.requestId), `correct requestId for ${details.url} in ${event} (${details.requestId} in [${ids && [...ids].join(", ")}])`);
     if (ids && idDisposalEvents.has(event)) {
       ids.delete(details.requestId);
     }
   }
 
   let frameIDs = new Map();
   let skippedRequests = new Set();
+  let redirectedRequests = new Set();
 
   let recorded = {requested: [],
                   beforeSendHeaders: [],
                   beforeRedirect: [],
                   sendHeaders: [],
                   responseStarted: [],
                   responseStarted2: [],
                   error: [],
@@ -363,16 +364,17 @@ function backgroundScript() {
 
       browser.test.assertEq(details.tabId, savedTabId, "correct tab ID");
       checkType(details);
 
       let id = frameIDs.get(details.url);
       browser.test.assertEq(id, details.frameId, "frame ID same in onBeforeSendHeaders as onBeforeRequest");
     }
     if (details.url.includes("_redirect.")) {
+      redirectedRequests.add(details.requestId);
       return {redirectUrl: details.url.replace("_redirect.", "_good.")};
     }
     return {requestHeaders: details.requestHeaders};
   }
 
   function onBeforeRedirect(details) {
     browser.test.log(`onBeforeRedirect ${details.url} -> ${details.redirectUrl}`);
     checkRequestId(details, "redirect");
@@ -444,18 +446,26 @@ function backgroundScript() {
   function onHeadersReceived(details) {
     checkIpAndRecord("headersReceived", details);
     processHeaders("response", details);
     browser.test.log(`After processing response headers: ${details.responseHeaders.toSource()}`);
     return {responseHeaders: details.responseHeaders};
   }
 
   function onErrorOccurred(details) {
-    onRecord("error", details);
-    browser.test.assertTrue(/^NS_ERROR_/.test(details.error), `onErrorOccurred reported for ${details.url} (${details.error})`);
+    if (details.url.endsWith("_good.png") && redirectedRequests.has(details.requestId)) {
+      // Redirected image requests sometimes result in multiple attempts to
+      // load the same image in parallel. In this case, the later request is
+      // canceled, and the same image loading context is shared by both images.
+      redirectedRequests.delete(details.requestId);
+      browser.test.assertEq("NS_BINDING_ABORTED", details.error, `onErrorOccurred reported for ${details.url}`);
+    } else {
+      onRecord("error", details);
+      browser.test.assertTrue(/^NS_ERROR_/.test(details.error), `onErrorOccurred reported for ${details.url} (${details.error})`);
+    }
   }
 
   function onCompleted(details) {
     checkFromCache("completed", details);
     checkHeaders("response", details);
   }
 
   browser.webRequest.onBeforeRequest.addListener(onBeforeRequest, {urls: ["<all_urls>"]}, ["blocking"]);
@@ -493,21 +503,22 @@ function backgroundScript() {
 function* test_once(skipCompleted) {
   let extensionData = {
     manifest: {
       permissions: [
         "webRequest",
         "webRequestBlocking",
       ],
     },
-    background: `const BASE = ${JSON.stringify(BASE)}; (${backgroundScript.toString()})()`,
+    background: `const BASE = ${JSON.stringify(BASE)}; (${backgroundScript})()`,
   };
 
   let extension = ExtensionTestUtils.loadExtension(extensionData);
-  let [, resourceTypes] = yield Promise.all([extension.startup(), extension.awaitMessage("ready")]);
+  yield extension.startup();
+  let resourceTypes = yield extension.awaitMessage("ready");
   info("webrequest extension loaded");
 
   if (skipCompleted) {
     extension.sendMessage("skipCompleted");
     yield extension.awaitMessage("ackSkipCompleted");
   }
 
   for (let key in resourceTypes) {
--- a/toolkit/xre/moz.build
+++ b/toolkit/xre/moz.build
@@ -122,19 +122,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     DEFINES['ANDROID_PACKAGE_NAME'] = '"%s"' % CONFIG['ANDROID_PACKAGE_NAME']
 
 if CONFIG['TARGET_XPCOM_ABI']:
     DEFINES['TARGET_OS_ABI'] = '"%s_%s"' % (CONFIG['OS_TARGET'],
                                             CONFIG['TARGET_XPCOM_ABI'])
 
-if CONFIG['WRAP_SYSTEM_INCLUDES']:
-    DEFINES['WRAP_SYSTEM_INCLUDES'] = True
-
 if CONFIG['OS_ARCH'] == 'Linux' and 'lib64' in CONFIG['libdir']:
     DEFINES['HAVE_USR_LIB64_DIR'] = True
 
 DEFINES['GRE_MILESTONE'] = CONFIG['GRE_MILESTONE']
 
 for var in ('APP_VERSION', 'APP_ID'):
     DEFINES[var] = CONFIG['MOZ_%s' % var]
 
--- a/tools/mercurial/eslintvalidate.py
+++ b/tools/mercurial/eslintvalidate.py
@@ -3,30 +3,33 @@
 
 import os
 import sys
 import re
 import json
 from subprocess import check_output, CalledProcessError
 
 lintable = re.compile(r'.+\.(?:js|jsm|jsx|xml|html)$')
-ignored = "File ignored because of your .eslintignore file. Use --no-ignore to override."
+ignored = 'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.'
 
 def is_lintable(filename):
     return lintable.match(filename)
 
 def display(ui, output):
     results = json.loads(output)
     for file in results:
         path = os.path.relpath(file["filePath"])
         for message in file["messages"]:
             if message["message"] == ignored:
                 continue
 
-            ui.warn("%s:%d:%d %s\n" % (path, message["line"], message["column"], message["message"]))
+            if "line" in message:
+                ui.warn("%s:%d:%d %s\n" % (path, message["line"], message["column"], message["message"]))
+            else:
+                ui.warn("%s: %s\n" % (path, message["message"]))
 
 def eslinthook(ui, repo, node=None, **opts):
     ctx = repo[node]
     if len(ctx.parents()) > 1:
         return 0
 
     deleted = repo.status(ctx.p1().node(), ctx.node()).deleted
     files = [f for f in ctx.files() if f not in deleted and is_lintable(f)]
--- a/xpcom/base/Logging.cpp
+++ b/xpcom/base/Logging.cpp
@@ -143,16 +143,25 @@ ExpandPIDMarker(const char* aFilename, c
     return buffer;
   }
 
   return aFilename;
 }
 
 } // detail
 
+namespace {
+  // Helper method that initializes an empty va_list to be empty.
+  void empty_va(va_list *va, ...)
+  {
+    va_start(*va, va);
+    va_end(*va);
+  }
+}
+
 class LogModuleManager
 {
 public:
   LogModuleManager()
     : mModulesLock("logmodules")
     , mModules(kInitialModuleCount)
     , mPrintEntryCount(0)
     , mOutFile(nullptr)
@@ -270,16 +279,24 @@ public:
     detail::LogFile* newFile = OpenFile(false, 0);
     detail::LogFile* oldFile = mOutFile.exchange(newFile);
 
     // Since we don't allow changing the logfile if MOZ_LOG_FILE is already set,
     // and we don't allow log rotation when setting it at runtime, mToReleaseFile
     // will be null, so we're not leaking.
     DebugOnly<detail::LogFile*> prevFile = mToReleaseFile.exchange(oldFile);
     MOZ_ASSERT(!prevFile, "Should be null because rotation is not allowed");
+
+    // If we just need to release a file, we must force print, in order to
+    // trigger the closing and release of mToReleaseFile.
+    if (oldFile) {
+      va_list va;
+      empty_va(&va);
+      Print("Logger", LogLevel::Info, "Flushing old log files\n", va);
+    }
   }
 
   uint32_t GetLogFile(char *aBuffer, size_t aLength)
   {
     uint32_t len = strlen(mOutFilePath.get());
     if (len + 1 > aLength) {
       return 0;
     }