Merge inbound to m-c. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Mon, 15 Jun 2015 15:55:28 -0400
changeset 279669 cd0d976e5f5c6389512cad8f2cae03526b0fb0f3
parent 279618 e14631051d8363cdc782c0fe2b31ed58d1d6d3b4 (current diff)
parent 279668 53a99d02925f98b41f0fc1b949254d513ceaed51 (diff)
child 279678 5a1e229e8bff26ddf482080b3cf15509b0b9eb7c
child 279685 9d4200cadeaf0cd4c65808cdd68b11ae534086d5
child 279744 2ab72a2aeca9e0951d86503d970c0184e2fcdf87
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone41.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 inbound to m-c. a=merge
build/pgo/certs/bug483440-attack2b.ca
build/pgo/certs/bug483440-attack7.ca
build/pgo/certs/bug483440-pk10oflo.ca
dom/base/MessageChannel.cpp
dom/base/MessageChannel.h
dom/base/MessagePort.cpp
dom/base/MessagePort.h
dom/base/MessagePortList.cpp
dom/base/MessagePortList.h
dom/base/moz.build
dom/base/test/iframe_messageChannel_chrome.html
dom/base/test/iframe_messageChannel_cloning.html
dom/base/test/iframe_messageChannel_pingpong.html
dom/base/test/iframe_messageChannel_post.html
dom/base/test/test_messageChannel.html
dom/base/test/test_messageChannel.xul
dom/base/test/test_messageChannel_cloning.html
dom/base/test/test_messageChannel_pingpong.html
dom/base/test/test_messageChannel_post.html
dom/base/test/test_messageChannel_pref.html
dom/base/test/test_messageChannel_start.html
dom/base/test/test_messageChannel_transferable.html
dom/base/test/test_messageChannel_unshipped.html
dom/inputmethod/mochitest/file_test_contenteditable.html
layout/mathml/MathJaxFonts.html
layout/mathml/mathfontMathJax_Main.properties
layout/mathml/mathfontStandardSymbolsL.properties
netwerk/test/TestSTSParser.cpp
security/manager/ssl/tests/mochitest/bugs/test_bug483440.html
testing/web-platform/meta/webmessaging/Channel_MessagePort_onmessage_start.htm.ini
testing/web-platform/meta/webmessaging/without-ports/023.html.ini
testing/web-platform/meta/webmessaging/without-ports/025.html.ini
testing/web-platform/meta/workers/MessagePort_initial_disabled.htm.ini
testing/web-platform/meta/workers/MessagePort_onmessage_start.htm.ini
testing/web-platform/meta/workers/postMessage_clone_port.htm.ini
testing/web-platform/meta/workers/postMessage_clone_port_error.htm.ini
testing/web-platform/meta/workers/postMessage_event_properties.htm.ini
testing/web-platform/meta/workers/postMessage_ports_readonly_array.htm.ini
testing/web-platform/meta/workers/postMessage_target_source.htm.ini
--- a/accessible/atk/nsMaiInterfaceText.cpp
+++ b/accessible/atk/nsMaiInterfaceText.cpp
@@ -27,23 +27,25 @@ ConvertTextAttributeToAtkAttribute(const
                                    const nsAString& aValue,
                                    AtkAttributeSet** aAttributeSet)
 {
   // Handle attributes where atk has its own name.
   const char* atkName = nullptr;
   nsAutoString atkValue;
   if (aName.EqualsLiteral("color")) {
     // The format of the atk attribute is r,g,b and the gecko one is
-    // rgb(r,g,b).
-    atkValue = Substring(aValue, 5, aValue.Length() - 1);
+    // rgb(r, g, b).
+    atkValue = Substring(aValue, 4, aValue.Length() - 5);
+    atkValue.StripWhitespace();
     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
   } else if (aName.EqualsLiteral("background-color")) {
     // The format of the atk attribute is r,g,b and the gecko one is
-    // rgb(r,g,b).
-    atkValue = Substring(aValue, 5, aValue.Length() - 1);
+    // rgb(r, g, b).
+    atkValue = Substring(aValue, 4, aValue.Length() - 5);
+    atkValue.StripWhitespace();
     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
   } else if (aName.EqualsLiteral("font-family")) {
     atkValue = aValue;
     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
   } else if (aName.EqualsLiteral("font-size")) {
     // ATK wants the number of pixels without px at the end.
     atkValue = StringHead(aValue, aValue.Length() - 2);
     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
--- a/browser/components/privatebrowsing/test/browser/browser.ini
+++ b/browser/components/privatebrowsing/test/browser/browser.ini
@@ -11,16 +11,17 @@ support-files =
   browser_privatebrowsing_placesTitleNoUpdate.html
   browser_privatebrowsing_protocolhandler_page.html
   browser_privatebrowsing_windowtitle_page.html
   head.js
   popup.html
   title.sjs
 
 [browser_privatebrowsing_DownloadLastDirWithCPS.js]
+skip-if = (os == "win" && os_version == "6.2") # bug 1173801
 [browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js]
 [browser_privatebrowsing_aboutSessionRestore.js]
 [browser_privatebrowsing_cache.js]
 [browser_privatebrowsing_certexceptionsui.js]
 [browser_privatebrowsing_concurrent.js]
 [browser_privatebrowsing_cookieacceptdialog.js]
 skip-if = e10s # Bug 1139953 - Accept cookie dialog shown in private window when e10s enabled
 [browser_privatebrowsing_crh.js]
--- a/dom/base/nsCCUncollectableMarker.cpp
+++ b/dom/base/nsCCUncollectableMarker.cpp
@@ -427,17 +427,17 @@ nsCCUncollectableMarker::Observe(nsISupp
     sFSState = eInitial;
     return NS_OK;
   } else {
     ++sFSState;
   }
 
   switch(sFSState) {
     case eUnmarkJSEventListeners: {
-      nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(sGeneration);
+      nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments();
       break;
     }
     case eUnmarkMessageManagers: {
       MarkMessageManagers();
       break;
     }
     case eUnmarkStrongObservers: {
       nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3980,39 +3980,32 @@ nsContentUtils::MaybeFireNodeRemoved(nsI
     InternalMutationEvent mutation(true, NS_MUTATION_NODEREMOVED);
     mutation.mRelatedNode = do_QueryInterface(aParent);
 
     mozAutoSubtreeModified subtree(aOwnerDoc, aParent);
     EventDispatcher::Dispatch(aChild, nullptr, &mutation);
   }
 }
 
-PLDHashOperator
-ListenerEnumerator(PLDHashTable* aTable, PLDHashEntryHdr* aEntry,
-                   uint32_t aNumber, void* aArg)
-{
-  EventListenerManagerMapEntry* entry =
-    static_cast<EventListenerManagerMapEntry*>(aEntry);
-  if (entry) {
+void
+nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments()
+{
+  if (!sEventListenerManagersHash) {
+    return;
+  }
+
+  PLDHashTable::Iterator iter(sEventListenerManagersHash);
+  while (iter.HasMoreEntries()) {
+    auto entry = static_cast<EventListenerManagerMapEntry*>(iter.NextEntry());
     nsINode* n = static_cast<nsINode*>(entry->mListenerManager->GetTarget());
     if (n && n->IsInDoc() &&
         nsCCUncollectableMarker::InGeneration(n->OwnerDoc()->GetMarkedCCGeneration())) {
       entry->mListenerManager->MarkForCC();
     }
   }
-  return PL_DHASH_NEXT;
-}
-
-void
-nsContentUtils::UnmarkGrayJSListenersInCCGenerationDocuments(uint32_t aGeneration)
-{
-  if (sEventListenerManagersHash) {
-    PL_DHashTableEnumerate(sEventListenerManagersHash, ListenerEnumerator,
-                           &aGeneration);
-  }
 }
 
 /* static */
 void
 nsContentUtils::TraverseListenerManager(nsINode *aNode,
                                         nsCycleCollectionTraversalCallback &cb)
 {
   if (!sEventListenerManagersHash) {
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1119,17 +1119,17 @@ public:
    * Get the eventlistener manager for aNode, returning null if it does not
    * already exist.
    *
    * @param aNode The node for which to get the eventlistener manager.
    */
   static mozilla::EventListenerManager*
     GetExistingListenerManagerForNode(const nsINode* aNode);
 
-  static void UnmarkGrayJSListenersInCCGenerationDocuments(uint32_t aGeneration);
+  static void UnmarkGrayJSListenersInCCGenerationDocuments();
 
   /**
    * Remove the eventlistener manager for aNode.
    *
    * @param aNode The node for which to remove the eventlistener manager.
    */
   static void RemoveListenerManager(nsINode *aNode);
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -529,17 +529,17 @@ AllocateProtoAndIfaceCache(JSObject* obj
 struct VerifyTraceProtoAndIfaceCacheCalledTracer : public JS::CallbackTracer
 {
   bool ok;
 
   explicit VerifyTraceProtoAndIfaceCacheCalledTracer(JSRuntime *rt)
     : JS::CallbackTracer(rt), ok(false)
   {}
 
-  void trace(void** thingp, JS::TraceKind kind) override {
+  void onChild(const JS::GCCellPtr&) override {
     // We don't do anything here, we only want to verify that
     // TraceProtoAndIfaceCache was called.
   }
 
   TracerKind getTracerKind() const override { return TracerKind::VerifyTraceProtoAndIface; }
 };
 #endif
 
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -218,16 +218,49 @@ typedef TypedArray<double, js::UnwrapFlo
                    js::GetFloat64ArrayLengthAndData, JS_NewFloat64Array>
         Float64Array;
 typedef TypedArray_base<uint8_t, js::UnwrapArrayBufferView, js::GetArrayBufferViewLengthAndData>
         ArrayBufferView;
 typedef TypedArray<uint8_t, js::UnwrapArrayBuffer, JS_GetArrayBufferData,
                    js::GetArrayBufferLengthAndData, JS_NewArrayBuffer>
         ArrayBuffer;
 
+typedef TypedArray<int8_t, js::UnwrapSharedInt8Array, JS_GetSharedInt8ArrayData,
+                   js::GetSharedInt8ArrayLengthAndData, JS_NewSharedInt8Array>
+        SharedInt8Array;
+typedef TypedArray<uint8_t, js::UnwrapSharedUint8Array, JS_GetSharedUint8ArrayData,
+                   js::GetSharedUint8ArrayLengthAndData, JS_NewSharedUint8Array>
+        SharedUint8Array;
+typedef TypedArray<uint8_t, js::UnwrapSharedUint8ClampedArray, JS_GetSharedUint8ClampedArrayData,
+                   js::GetSharedUint8ClampedArrayLengthAndData, JS_NewSharedUint8ClampedArray>
+        SharedUint8ClampedArray;
+typedef TypedArray<int16_t, js::UnwrapSharedInt16Array, JS_GetSharedInt16ArrayData,
+                   js::GetSharedInt16ArrayLengthAndData, JS_NewSharedInt16Array>
+        SharedInt16Array;
+typedef TypedArray<uint16_t, js::UnwrapSharedUint16Array, JS_GetSharedUint16ArrayData,
+                   js::GetSharedUint16ArrayLengthAndData, JS_NewSharedUint16Array>
+        SharedUint16Array;
+typedef TypedArray<int32_t, js::UnwrapSharedInt32Array, JS_GetSharedInt32ArrayData,
+                   js::GetSharedInt32ArrayLengthAndData, JS_NewSharedInt32Array>
+        SharedInt32Array;
+typedef TypedArray<uint32_t, js::UnwrapSharedUint32Array, JS_GetSharedUint32ArrayData,
+                   js::GetSharedUint32ArrayLengthAndData, JS_NewSharedUint32Array>
+        SharedUint32Array;
+typedef TypedArray<float, js::UnwrapSharedFloat32Array, JS_GetSharedFloat32ArrayData,
+                   js::GetSharedFloat32ArrayLengthAndData, JS_NewSharedFloat32Array>
+        SharedFloat32Array;
+typedef TypedArray<double, js::UnwrapSharedFloat64Array, JS_GetSharedFloat64ArrayData,
+                   js::GetSharedFloat64ArrayLengthAndData, JS_NewSharedFloat64Array>
+        SharedFloat64Array;
+typedef TypedArray_base<uint8_t, js::UnwrapSharedArrayBufferView, js::GetSharedArrayBufferViewLengthAndData>
+        SharedArrayBufferView;
+typedef TypedArray<uint8_t, js::UnwrapSharedArrayBuffer, JS_GetSharedArrayBufferData,
+                   js::GetSharedArrayBufferLengthAndData, JS_NewSharedArrayBuffer>
+        SharedArrayBuffer;
+
 // A class for converting an nsTArray to a TypedArray
 // Note: A TypedArrayCreator must not outlive the nsTArray it was created from.
 //       So this is best used to pass from things that understand nsTArray to
 //       things that understand TypedArray, as with Promise::ArgumentToJSValue.
 template<typename TypedArrayType>
 class TypedArrayCreator
 {
   typedef nsTArray<typename TypedArrayType::element_type> ArrayType;
--- a/dom/bindings/parser/WebIDL.py
+++ b/dom/bindings/parser/WebIDL.py
@@ -1724,19 +1724,28 @@ class IDLType(IDLObject):
         return False
 
     def isArrayBuffer(self):
         return False
 
     def isArrayBufferView(self):
         return False
 
+    def isSharedArrayBuffer(self):
+        return False
+
+    def isSharedArrayBufferView(self):
+        return False
+
     def isTypedArray(self):
         return False
 
+    def isSharedTypedArray(self):
+        return False
+
     def isCallbackInterface(self):
         return False
 
     def isNonCallbackInterface(self):
         return False
 
     def isGeckoInterface(self):
         """ Returns a boolean indicating whether this type is an 'interface'
@@ -1746,17 +1755,20 @@ class IDLType(IDLObject):
         return self.isInterface() and not self.isSpiderMonkeyInterface()
 
     def isSpiderMonkeyInterface(self):
         """ Returns a boolean indicating whether this type is an 'interface'
             type that is implemented in Spidermonkey.  At the moment, this
             only returns true for the types from the TypedArray spec. """
         return self.isInterface() and (self.isArrayBuffer() or \
                                        self.isArrayBufferView() or \
-                                       self.isTypedArray())
+                                       self.isSharedArrayBuffer() or \
+                                       self.isSharedArrayBufferView() or \
+                                       self.isTypedArray() or \
+                                       self.isSharedTypedArray())
 
     def isDictionary(self):
         return False
 
     def isInterface(self):
         return False
 
     def isAny(self):
@@ -1928,19 +1940,28 @@ class IDLNullableType(IDLType):
         return self.inner.isArray()
 
     def isArrayBuffer(self):
         return self.inner.isArrayBuffer()
 
     def isArrayBufferView(self):
         return self.inner.isArrayBufferView()
 
+    def isSharedArrayBuffer(self):
+        return self.inner.isSharedArrayBuffer()
+
+    def isSharedArrayBufferView(self):
+        return self.inner.isSharedArrayBufferView()
+
     def isTypedArray(self):
         return self.inner.isTypedArray()
 
+    def isSharedTypedArray(self):
+        return self.inner.isSharedTypedArray()
+
     def isDictionary(self):
         return self.inner.isDictionary()
 
     def isInterface(self):
         return self.inner.isInterface()
 
     def isCallbackInterface(self):
         return self.inner.isCallbackInterface()
@@ -2419,19 +2440,28 @@ class IDLTypedefType(IDLType):
         return self.inner.isDictionary()
 
     def isArrayBuffer(self):
         return self.inner.isArrayBuffer()
 
     def isArrayBufferView(self):
         return self.inner.isArrayBufferView()
 
+    def isSharedArrayBuffer(self):
+        return self.inner.isSharedArrayBuffer()
+
+    def isSharedArrayBufferView(self):
+        return self.inner.isSharedArrayBufferView()
+
     def isTypedArray(self):
         return self.inner.isTypedArray()
 
+    def isSharedTypedArray(self):
+        return self.inner.isSharedTypedArray()
+
     def isInterface(self):
         return self.inner.isInterface()
 
     def isCallbackInterface(self):
         return self.inner.isCallbackInterface()
 
     def isNonCallbackInterface(self):
         return self.inner.isNonCallbackInterface()
@@ -2679,25 +2709,36 @@ class IDLBuiltinType(IDLType):
         'bytestring',
         'usvstring',
         'object',
         'date',
         'void',
         # Funny stuff
         'ArrayBuffer',
         'ArrayBufferView',
+        'SharedArrayBuffer',
+        'SharedArrayBufferView',
         'Int8Array',
         'Uint8Array',
         'Uint8ClampedArray',
         'Int16Array',
         'Uint16Array',
         'Int32Array',
         'Uint32Array',
         'Float32Array',
-        'Float64Array'
+        'Float64Array',
+        'SharedInt8Array',
+        'SharedUint8Array',
+        'SharedUint8ClampedArray',
+        'SharedInt16Array',
+        'SharedUint16Array',
+        'SharedInt32Array',
+        'SharedUint32Array',
+        'SharedFloat32Array',
+        'SharedFloat64Array'
         )
 
     TagLookup = {
             Types.byte: IDLType.Tags.int8,
             Types.octet: IDLType.Tags.uint8,
             Types.short: IDLType.Tags.int16,
             Types.unsigned_short: IDLType.Tags.uint16,
             Types.long: IDLType.Tags.int32,
@@ -2713,25 +2754,36 @@ class IDLBuiltinType(IDLType):
             Types.domstring: IDLType.Tags.domstring,
             Types.bytestring: IDLType.Tags.bytestring,
             Types.usvstring: IDLType.Tags.usvstring,
             Types.object: IDLType.Tags.object,
             Types.date: IDLType.Tags.date,
             Types.void: IDLType.Tags.void,
             Types.ArrayBuffer: IDLType.Tags.interface,
             Types.ArrayBufferView: IDLType.Tags.interface,
+            Types.SharedArrayBuffer: IDLType.Tags.interface,
+            Types.SharedArrayBufferView: IDLType.Tags.interface,
             Types.Int8Array: IDLType.Tags.interface,
             Types.Uint8Array: IDLType.Tags.interface,
             Types.Uint8ClampedArray: IDLType.Tags.interface,
             Types.Int16Array: IDLType.Tags.interface,
             Types.Uint16Array: IDLType.Tags.interface,
             Types.Int32Array: IDLType.Tags.interface,
             Types.Uint32Array: IDLType.Tags.interface,
             Types.Float32Array: IDLType.Tags.interface,
-            Types.Float64Array: IDLType.Tags.interface
+            Types.Float64Array: IDLType.Tags.interface,
+            Types.SharedInt8Array: IDLType.Tags.interface,
+            Types.SharedUint8Array: IDLType.Tags.interface,
+            Types.SharedUint8ClampedArray: IDLType.Tags.interface,
+            Types.SharedInt16Array: IDLType.Tags.interface,
+            Types.SharedUint16Array: IDLType.Tags.interface,
+            Types.SharedInt32Array: IDLType.Tags.interface,
+            Types.SharedUint32Array: IDLType.Tags.interface,
+            Types.SharedFloat32Array: IDLType.Tags.interface,
+            Types.SharedFloat64Array: IDLType.Tags.interface
         }
 
     def __init__(self, location, name, type):
         IDLType.__init__(self, location, name)
         self.builtin = True
         self._typeTag = type
 
     def isPrimitive(self):
@@ -2761,27 +2813,40 @@ class IDLBuiltinType(IDLType):
         return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long
 
     def isArrayBuffer(self):
         return self._typeTag == IDLBuiltinType.Types.ArrayBuffer
 
     def isArrayBufferView(self):
         return self._typeTag == IDLBuiltinType.Types.ArrayBufferView
 
+    def isSharedArrayBuffer(self):
+        return self._typeTag == IDLBuiltinType.Types.SharedArrayBuffer
+
+    def isSharedArrayBufferView(self):
+        return self._typeTag == IDLBuiltinType.Types.SharedArrayBufferView
+
     def isTypedArray(self):
         return self._typeTag >= IDLBuiltinType.Types.Int8Array and \
                self._typeTag <= IDLBuiltinType.Types.Float64Array
 
+    def isSharedTypedArray(self):
+        return self._typeTag >= IDLBuiltinType.Types.SharedInt8Array and \
+               self._typeTag <= IDLBuiltinType.Types.SharedFloat64Array
+
     def isInterface(self):
         # TypedArray things are interface types per the TypedArray spec,
         # but we handle them as builtins because SpiderMonkey implements
         # all of it internally.
         return self.isArrayBuffer() or \
                self.isArrayBufferView() or \
-               self.isTypedArray()
+               self.isSharedArrayBuffer() or \
+               self.isSharedArrayBufferView() or \
+               self.isTypedArray() or \
+               self.isSharedTypedArray()
 
     def isNonCallbackInterface(self):
         # All the interfaces we can be are non-callback
         return self.isInterface()
 
     def isFloat(self):
         return self._typeTag == IDLBuiltinType.Types.float or \
                self._typeTag == IDLBuiltinType.Types.double or \
@@ -2842,25 +2907,30 @@ class IDLBuiltinType(IDLType):
         return (other.isPrimitive() or other.isString() or other.isEnum() or
                 other.isCallback() or other.isDictionary() or
                 other.isSequence() or other.isMozMap() or other.isArray() or
                 other.isDate() or
                 (other.isInterface() and (
                  # ArrayBuffer is distinguishable from everything
                  # that's not an ArrayBuffer or a callback interface
                  (self.isArrayBuffer() and not other.isArrayBuffer()) or
+                 (self.isSharedArrayBuffer() and not other.isSharedArrayBuffer()) or
                  # ArrayBufferView is distinguishable from everything
                  # that's not an ArrayBufferView or typed array.
                  (self.isArrayBufferView() and not other.isArrayBufferView() and
                   not other.isTypedArray()) or
+                 (self.isSharedArrayBufferView() and not other.isSharedArrayBufferView() and
+                  not other.isSharedTypedArray()) or
                  # Typed arrays are distinguishable from everything
                  # except ArrayBufferView and the same type of typed
                  # array
                  (self.isTypedArray() and not other.isArrayBufferView() and not
-                  (other.isTypedArray() and other.name == self.name)))))
+                  (other.isTypedArray() and other.name == self.name)) or
+                 (self.isSharedTypedArray() and not other.isSharedArrayBufferView() and not
+                  (other.isSharedTypedArray() and other.name == self.name)))))
 
     def _getDependentObjects(self):
         return set()
 
 BuiltinTypes = {
       IDLBuiltinType.Types.byte:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte",
                          IDLBuiltinType.Types.byte),
@@ -2922,16 +2992,22 @@ BuiltinTypes = {
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Void",
                          IDLBuiltinType.Types.void),
       IDLBuiltinType.Types.ArrayBuffer:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBuffer",
                          IDLBuiltinType.Types.ArrayBuffer),
       IDLBuiltinType.Types.ArrayBufferView:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView",
                          IDLBuiltinType.Types.ArrayBufferView),
+      IDLBuiltinType.Types.SharedArrayBuffer:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBuffer",
+                         IDLBuiltinType.Types.SharedArrayBuffer),
+      IDLBuiltinType.Types.SharedArrayBufferView:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedArrayBufferView",
+                         IDLBuiltinType.Types.SharedArrayBufferView),
       IDLBuiltinType.Types.Int8Array:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array",
                          IDLBuiltinType.Types.Int8Array),
       IDLBuiltinType.Types.Uint8Array:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8Array",
                          IDLBuiltinType.Types.Uint8Array),
       IDLBuiltinType.Types.Uint8ClampedArray:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8ClampedArray",
@@ -2948,17 +3024,44 @@ BuiltinTypes = {
       IDLBuiltinType.Types.Uint32Array:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint32Array",
                          IDLBuiltinType.Types.Uint32Array),
       IDLBuiltinType.Types.Float32Array:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float32Array",
                          IDLBuiltinType.Types.Float32Array),
       IDLBuiltinType.Types.Float64Array:
           IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array",
-                         IDLBuiltinType.Types.Float64Array)
+                         IDLBuiltinType.Types.Float64Array),
+      IDLBuiltinType.Types.SharedInt8Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt8Array",
+                         IDLBuiltinType.Types.SharedInt8Array),
+      IDLBuiltinType.Types.SharedUint8Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint8Array",
+                         IDLBuiltinType.Types.SharedUint8Array),
+      IDLBuiltinType.Types.SharedUint8ClampedArray:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint8ClampedArray",
+                         IDLBuiltinType.Types.SharedUint8ClampedArray),
+      IDLBuiltinType.Types.SharedInt16Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt16Array",
+                         IDLBuiltinType.Types.SharedInt16Array),
+      IDLBuiltinType.Types.SharedUint16Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint16Array",
+                         IDLBuiltinType.Types.SharedUint16Array),
+      IDLBuiltinType.Types.SharedInt32Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedInt32Array",
+                         IDLBuiltinType.Types.SharedInt32Array),
+      IDLBuiltinType.Types.SharedUint32Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedUint32Array",
+                         IDLBuiltinType.Types.SharedUint32Array),
+      IDLBuiltinType.Types.SharedFloat32Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedFloat32Array",
+                         IDLBuiltinType.Types.SharedFloat32Array),
+      IDLBuiltinType.Types.SharedFloat64Array:
+          IDLBuiltinType(BuiltinLocation("<builtin type>"), "SharedFloat64Array",
+                         IDLBuiltinType.Types.SharedFloat64Array)
     }
 
 
 integerTypeSizes = {
         IDLBuiltinType.Types.byte: (-128, 127),
         IDLBuiltinType.Types.octet:  (0, 255),
         IDLBuiltinType.Types.short: (-32768, 32767),
         IDLBuiltinType.Types.unsigned_short: (0, 65535),
@@ -4408,16 +4511,17 @@ class Tokenizer(object):
         "[": "LBRACKET",
         "]": "RBRACKET",
         "?": "QUESTIONMARK",
         ",": "COMMA",
         "=": "EQUALS",
         "<": "LT",
         ">": "GT",
         "ArrayBuffer": "ARRAYBUFFER",
+        "SharedArrayBuffer": "SHAREDARRAYBUFFER",
         "or": "OR"
         }
 
     tokens.extend(keywords.values())
 
     def t_error(self, t):
         raise WebIDLError("Unrecognized Input",
                [Location(lexer=self.lexer,
@@ -5455,22 +5559,25 @@ class Parser(Tokenizer):
             UnionMemberTypes :
         """
         p[0] = []
 
     def p_NonAnyType(self, p):
         """
             NonAnyType : PrimitiveOrStringType TypeSuffix
                        | ARRAYBUFFER TypeSuffix
+                       | SHAREDARRAYBUFFER TypeSuffix
                        | OBJECT TypeSuffix
         """
         if p[1] == "object":
             type = BuiltinTypes[IDLBuiltinType.Types.object]
         elif p[1] == "ArrayBuffer":
             type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer]
+        elif p[1] == "SharedArrayBuffer":
+            type = BuiltinTypes[IDLBuiltinType.Types.SharedArrayBuffer]
         else:
             type = BuiltinTypes[p[1]]
 
         p[0] = self.handleModifiers(type, p[2])
 
     def p_NonAnyTypeSequenceType(self, p):
         """
             NonAnyType : SEQUENCE LT Type GT Null
@@ -5854,17 +5961,17 @@ class Parser(Tokenizer):
         self._filename = None
 
         self.parser.parse(lexer=self.lexer,tracking=True)
 
     def _installBuiltins(self, scope):
         assert isinstance(scope, IDLScope)
 
         # xrange omits the last value.
-        for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1):
+        for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.SharedFloat64Array + 1):
             builtin = BuiltinTypes[x]
             name = builtin.name
             typedef = IDLTypedef(BuiltinLocation("<builtin type>"), scope, builtin, name)
 
     @ staticmethod
     def handleModifiers(type, modifiers):
         for (modifier, modifierLocation) in modifiers:
             assert modifier == IDLMethod.TypeSuffixModifier.QMark or \
@@ -5915,16 +6022,17 @@ class Parser(Tokenizer):
 
     def reset(self):
         return Parser(lexer=self.lexer)
 
     # Builtin IDL defined by WebIDL
     _builtins = """
         typedef unsigned long long DOMTimeStamp;
         typedef (ArrayBufferView or ArrayBuffer) BufferSource;
+        typedef (SharedArrayBufferView or SharedArrayBuffer) SharedBufferSource;
     """
 
 def main():
     # Parse arguments.
     from optparse import OptionParser
     usageString = "usage: %prog [options] files"
     o = OptionParser(usage=usageString)
     o.add_option("--cachedir", dest='cachedir', default=None,
--- a/dom/bindings/parser/tests/test_distinguishability.py
+++ b/dom/bindings/parser/tests/test_distinguishability.py
@@ -155,43 +155,46 @@ def WebIDLTest(parser, harness):
                  "Interface", "Interface?",
                  "AncestorInterface", "UnrelatedInterface",
                  "ImplementedInterface", "CallbackInterface",
                  "CallbackInterface?", "CallbackInterface2",
                  "object", "Callback", "Callback2", "optional Dict",
                  "optional Dict2", "sequence<long>", "sequence<short>",
                  "MozMap<object>", "MozMap<Dict>", "MozMap<long>",
                  "long[]", "short[]", "Date", "Date?", "any",
-                 "USVString" ]
+                 "USVString", "ArrayBuffer", "ArrayBufferView", "SharedArrayBuffer", "SharedArrayBufferView",
+                 "Uint8Array", "SharedUint8Array", "Uint16Array", "SharedUint16Array" ]
     # When we can parse Date and RegExp, we need to add them here.
 
     # Try to categorize things a bit to keep list lengths down
     def allBut(list1, list2):
         return [a for a in list1 if a not in list2 and a != "any"]
     numerics = [ "long", "short", "long?", "short?" ]
     booleans = [ "boolean", "boolean?" ]
     primitives = numerics + booleans
     nonNumerics = allBut(argTypes, numerics)
     nonBooleans = allBut(argTypes, booleans)
     strings = [ "DOMString", "ByteString", "Enum", "Enum2", "USVString" ]
     nonStrings = allBut(argTypes, strings)
     nonObjects = primitives + strings
     objects = allBut(argTypes, nonObjects )
+    bufferSourceTypes = ["ArrayBuffer", "ArrayBufferView", "Uint8Array", "Uint16Array"]
+    sharedBufferSourceTypes = ["SharedArrayBuffer", "SharedArrayBufferView", "SharedUint8Array", "SharedUint16Array"]
     interfaces = [ "Interface", "Interface?", "AncestorInterface",
-                   "UnrelatedInterface", "ImplementedInterface" ]
+                   "UnrelatedInterface", "ImplementedInterface" ] + bufferSourceTypes + sharedBufferSourceTypes
     nullables = ["long?", "short?", "boolean?", "Interface?",
                  "CallbackInterface?", "optional Dict", "optional Dict2",
                  "Date?", "any"]
     dates = [ "Date", "Date?" ]
     sequences = [ "sequence<long>", "sequence<short>" ]
     arrays = [ "long[]", "short[]" ]
     nonUserObjects = nonObjects + interfaces + dates + sequences
     otherObjects = allBut(argTypes, nonUserObjects + ["object"])
     notRelatedInterfaces = (nonObjects + ["UnrelatedInterface"] +
-                            otherObjects + dates + sequences)
+                            otherObjects + dates + sequences + bufferSourceTypes + sharedBufferSourceTypes)
     mozMaps = [ "MozMap<object>", "MozMap<Dict>", "MozMap<long>" ]
 
     # Build a representation of the distinguishability table as a dict
     # of dicts, holding True values where needed, holes elsewhere.
     data = dict();
     for type in argTypes:
         data[type] = dict()
     def setDistinguishable(type, types):
@@ -230,16 +233,24 @@ def WebIDLTest(parser, harness):
     setDistinguishable("MozMap<object>", nonUserObjects)
     setDistinguishable("MozMap<Dict>", nonUserObjects)
     setDistinguishable("MozMap<long>", nonUserObjects)
     setDistinguishable("long[]", allBut(nonUserObjects, sequences))
     setDistinguishable("short[]", allBut(nonUserObjects, sequences))
     setDistinguishable("Date", allBut(argTypes, dates + ["object"]))
     setDistinguishable("Date?", allBut(argTypes, dates + nullables + ["object"]))
     setDistinguishable("any", [])
+    setDistinguishable("ArrayBuffer", allBut(argTypes, ["ArrayBuffer", "object"]))
+    setDistinguishable("ArrayBufferView", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "Uint16Array", "object"]))
+    setDistinguishable("Uint8Array", allBut(argTypes, ["ArrayBufferView", "Uint8Array", "object"]))
+    setDistinguishable("Uint16Array", allBut(argTypes, ["ArrayBufferView", "Uint16Array", "object"]))
+    setDistinguishable("SharedArrayBuffer", allBut(argTypes, ["SharedArrayBuffer", "object"]))
+    setDistinguishable("SharedArrayBufferView", allBut(argTypes, ["SharedArrayBufferView", "SharedUint8Array", "SharedUint16Array", "object"]))
+    setDistinguishable("SharedUint8Array", allBut(argTypes, ["SharedArrayBufferView", "SharedUint8Array", "object"]))
+    setDistinguishable("SharedUint16Array", allBut(argTypes, ["SharedArrayBufferView", "SharedUint16Array", "object"]))
 
     def areDistinguishable(type1, type2):
         return data[type1].get(type2, False)
 
     def checkDistinguishability(parser, type1, type2):
         idlTemplate = """
           enum Enum { "a", "b" };
           enum Enum2 { "c", "d" };
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/capturestream.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset='UTF-8'>
+<!--
+Clear the canvas to green and capture it to a stream to test that we can get
+the stream to screen in a local video element.
+-->
+<html class="reftest-wait">
+
+<head>
+  <script type='text/javascript'>
+function finished() {
+  document.documentElement.removeAttribute("class");
+}
+
+function runTest() {
+  var canvas = document.getElementById('canvas');
+  var context = canvas.getContext('2d');
+  context.fillStyle = "rgba(0, 255, 0, 1)";
+  context.fillRect(0, 0, canvas.width, canvas.height);
+
+  var video = document.getElementById('video');
+  video.mozSrcObject = canvas.captureStream(0);
+  video.play();
+  video.onloadeddata = finished;
+  video.onerror = finished;
+}
+  </script>
+</head>
+
+<body onload='runTest();'>
+  <video id='video' width='256' height='256'></video>
+  <canvas id='canvas' width='256' height='256' style="display:none"></canvas>
+</body>
+
+</html>
--- a/dom/canvas/test/reftest/reftest.list
+++ b/dom/canvas/test/reftest/reftest.list
@@ -14,16 +14,19 @@ pref(webgl.force-layers-readback,true)  
 # Make sure that our choice of attribs doesn't break rendering.
 == webgl-clear-test.html?depth wrapper.html?green.png
 == webgl-clear-test.html?stencil wrapper.html?green.png
 == webgl-clear-test.html?depth&stencil wrapper.html?green.png
 
 # Check that resize works:
 == webgl-resize-test.html  wrapper.html?green.png
 
+# Check that captureStream() displays in a local video element
+pref(canvas.capturestream.enabled,true) skip-if(winWidget&&layersGPUAccelerated&&d2d) == webgl-capturestream-test.html?preserve wrapper.html?green.png
+
 # Some of the failure conditions are a little crazy. I'm (jgilbert) setting these based on
 # failures encountered when running on Try, and then targetting the Try config by
 # differences in the `sandbox` contents. That is, I'm labeling based on symptoms rather
 # than cause.
 # Lin-R-e10s: gtkWidget && browserIsRemote
 # WinXP-R: winWidget && layersGPUAccelerated && !d2d
 # Win7+-R: winWidget && layersGPUAccelerated && d2d
 # Win7+-Ru: winWidget && !layersGPUAccelerated
@@ -147,8 +150,11 @@ skip-if(!winWidget) pref(webgl.disable-a
 != clip-multiple-paths.html clip-multiple-paths-badref.html
 
 # Bug 815648
 == stroketext-shadow.html stroketext-shadow-ref.html
 
 # focus rings
 pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
 pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
+
+# Check that captureStream() displays in a local video element
+pref(canvas.capturestream.enabled,true) fails-if(B2G) skip-if(winWidget&&layersGPUAccelerated&&d2d) == capturestream.html wrapper.html?green.png
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/reftest/webgl-capturestream-test.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset='UTF-8'>
+<!--
+Clear the canvas to green and capture it to a stream to test that we can get
+the stream to screen in a local video element.
+-->
+<html class="reftest-wait">
+
+<head>
+  <script type='text/javascript' src='webgl-utils.js'></script>
+  <script type='text/javascript'>
+'use strict';
+
+function setStatus(text) {
+  var elem = document.getElementById('status');
+  elem.innerHTML = text;
+}
+
+function finished() {
+  document.documentElement.removeAttribute("class");
+}
+
+function runTest() {
+  var canvas = document.getElementById('canvas');
+
+  var gl = initGL(canvas);
+  if (!gl) {
+    setStatus('WebGL context creation failed.');
+    return;
+  }
+
+  gl.clearColor(0.0, 1.0, 0.0, 1.0);
+  gl.clear(gl.COLOR_BUFFER_BIT);
+
+  var video = document.getElementById('video');
+  video.mozSrcObject = canvas.captureStream(0);
+  video.play();
+  video.onloadeddata = finished;
+  video.onerror = finished;
+}
+  </script>
+</head>
+
+<body onload='runTest();'>
+  <video id='video' width='256' height='256'></video>
+  <canvas id='canvas' width='256' height='256' style="display:none"></canvas>
+  <div id='status'></div>
+</body>
+
+</html>
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3703,18 +3703,28 @@ public:
 /*static*/ bool
 EventStateManager::IsHandlingUserInput()
 {
   if (sUserInputEventDepth <= 0) {
     return false;
   }
 
   TimeDuration timeout = nsContentUtils::HandlingUserInputTimeout();
-  return timeout <= TimeDuration(0) ||
-         (TimeStamp::Now() - sHandlingInputStart) <= timeout;
+  TimeDuration elapsed = TimeStamp::Now() - sHandlingInputStart;
+  bool inTime = timeout <= TimeDuration(0) || elapsed <= timeout;
+
+  if (!inTime) {
+#ifdef DEBUG
+    printf("EventStateManager::IsHandlingUserInput() has timed out "
+           "(timeout: %f, elapsed: %f)\n",
+           timeout.ToMilliseconds(), elapsed.ToMilliseconds());
+#endif
+    return false;
+  }
+  return true;
 }
 
 static void
 CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
                                 uint32_t aMessage,
                                 nsIContent* aRelatedContent,
                                 nsAutoPtr<WidgetMouseEvent>& aNewEvent)
 {
--- a/dom/inputmethod/forms.js
+++ b/dom/inputmethod/forms.js
@@ -13,20 +13,16 @@ let Cc = Components.classes;
 let Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 XPCOMUtils.defineLazyServiceGetter(Services, "fm",
                                    "@mozilla.org/focus-manager;1",
                                    "nsIFocusManager");
 
-XPCOMUtils.defineLazyServiceGetter(Services, "threadManager",
-                                   "@mozilla.org/thread-manager;1",
-                                   "nsIThreadManager");
-
 XPCOMUtils.defineLazyGetter(this, "domWindowUtils", function () {
   return content.QueryInterface(Ci.nsIInterfaceRequestor)
                 .getInterface(Ci.nsIDOMWindowUtils);
 });
 
 const RESIZE_SCROLL_DELAY = 20;
 // In content editable node, when there are hidden elements such as <br>, it
 // may need more than one (usually less than 3 times) move/extend operations
@@ -456,23 +452,16 @@ let FormAssistant = {
           break;
         }
 
         CompositionManager.onCompositionEnd();
         break;
     }
   },
 
-  waitForNextTick: function(callback) {
-    var tm = Services.threadManager;
-    tm.mainThread.dispatch({
-      run: callback,
-    }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
-  },
-
   receiveMessage: function fa_receiveMessage(msg) {
     let target = this.focusedElement;
     let json = msg.json;
 
     // To not break mozKeyboard contextId is optional
     if ('contextId' in json &&
         json.contextId !== this._focusCounter &&
         json.requestId) {
@@ -677,45 +666,23 @@ let FormAssistant = {
   handleFocus: function fa_handleFocus(target) {
     if (this.focusedElement === target)
       return;
 
     if (target instanceof HTMLOptionElement)
       target = target.parentNode;
 
     this.setFocusedElement(target);
-
-    let count = this._focusCounter;
-    this.waitForNextTick(function fa_handleFocusSync() {
-      if (count !== this._focusCounter) {
-        return;
-      }
-
-      let isHandlingFocus = this.sendInputState(target);
-      this.isHandlingFocus = isHandlingFocus;
-    }.bind(this));
+    this.isHandlingFocus = this.sendInputState(target);
   },
 
   unhandleFocus: function fa_unhandleFocus() {
     this.setFocusedElement(null);
-
-    let count = this._focusCounter;
-
-    // Wait for the next tick before unset the focused element and etc.
-    // If the user move from one input from another,
-    // the remote process should get one Forms:Input message instead of two.
-    this.waitForNextTick(function fa_unhandleFocusSync() {
-      if (count !== this._focusCounter ||
-          !this.isHandlingFocus) {
-        return;
-      }
-
-      this.isHandlingFocus = false;
-      sendAsyncMessage("Forms:Input", { "type": "blur" });
-    }.bind(this));
+    this.isHandlingFocus = false;
+    sendAsyncMessage("Forms:Input", { "type": "blur" });
   },
 
   isFocusableElement: function fa_isFocusableElement(element) {
     if (element instanceof HTMLSelectElement ||
         element instanceof HTMLTextAreaElement)
       return true;
 
     if (element instanceof HTMLOptionElement &&
deleted file mode 100644
--- a/dom/inputmethod/mochitest/file_test_contenteditable.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<body>
-<div id="text" contenteditable>Jan Jongboom</div>
-<script type="application/javascript;version=1.7">
-  var t = document.querySelector('#text');
-
-  t.focus();
-  var range = document.createRange();
-  range.selectNodeContents(t);
-  range.collapse(false);
-  var selection = window.getSelection();
-  selection.removeAllRanges();
-  selection.addRange(range);
-</script>
-</body>
-</html>
--- a/dom/inputmethod/mochitest/mochitest.ini
+++ b/dom/inputmethod/mochitest/mochitest.ini
@@ -1,17 +1,16 @@
 [DEFAULT]
 # Not supported on Android, bug 983015 for B2G emulator
 skip-if = (toolkit == 'android' || toolkit == 'gonk') || e10s
 support-files =
   inputmethod_common.js
   file_inputmethod.html
   file_inputmethod_1043828.html
   file_test_app.html
-  file_test_contenteditable.html
   file_test_sendkey_cancel.html
   file_test_sms_app.html
   file_test_sms_app_1066515.html
 
 [test_basic.html]
 [test_bug944397.html]
 [test_bug949059.html]
 [test_bug953044.html]
--- a/dom/inputmethod/mochitest/test_bug1059163.html
+++ b/dom/inputmethod/mochitest/test_bug1059163.html
@@ -15,63 +15,69 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script class="testbody" type="application/javascript;version=1.7">
 inputmethod_setup(function() {
   runTest();
 });
 
 // The frame script running in the file
 function appFrameScript() {
+  let document = content.document;
+  let window = content.document.defaultView;
+
+  let t = document.getElementById('text');
+  t.focus();
+
+  let range = document.createRange();
+  range.selectNodeContents(t);
+  range.collapse(false);
+  let selection = window.getSelection();
+  selection.removeAllRanges();
+  selection.addRange(range);
+
   addMessageListener('test:InputMethod:clear', function() {
-    var t = content.document.getElementById('text');
     t.innerHTML = '';
   });
 }
 
 function runTest() {
   let im = navigator.mozInputMethod;
 
   // Set current page as an input method.
   SpecialPowers.wrap(im).setActive(true);
 
   // Create an app frame to recieve keyboard inputs.
   let app = document.createElement('iframe');
-  app.src = 'file_test_contenteditable.html';
+  app.src = 'data:text/html,<html><body><div id="text" contenteditable>Jan Jongboom</div></html>';
   app.setAttribute('mozbrowser', true);
   document.body.appendChild(app);
   app.addEventListener('mozbrowserloadend', function() {
     let mm = SpecialPowers.getBrowserFrameMessageManager(app);
+    mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false);
+
+    im.oninputcontextchange = function() {
+      if (im.inputcontext) {
+        im.oninputcontextchange = null;
+        register();
+      }
+    };
 
     function register() {
       im.inputcontext.onselectionchange = function() {
         im.inputcontext.onselectionchange = null;
 
         is(im.inputcontext.textBeforeCursor, '', 'textBeforeCursor');
-        is(im.inputcontext.textBeforeCursor, '', 'textAfterCursor');
+        is(im.inputcontext.textAfterCursor, '', 'textAfterCursor');
         is(im.inputcontext.selectionStart, 0, 'selectionStart');
         is(im.inputcontext.selectionEnd, 0, 'selectionEnd');
 
         inputmethod_cleanup();
       };
 
       mm.sendAsyncMessage('test:InputMethod:clear');
     }
-
-    if (im.inputcontext) {
-       register();
-    }
-    else {
-      im.oninputcontextchange = function() {
-        if (im.inputcontext) {
-          im.oninputcontextchange = null;
-          register();
-        }
-      };
-    }
-
-    mm.loadFrameScript('data:,(' + appFrameScript.toString() + ')();', false);
   });
 }
 </script>
 </pre>
 </body>
 </html>
 
--- a/dom/inputmethod/mochitest/test_sync_edit.html
+++ b/dom/inputmethod/mochitest/test_sync_edit.html
@@ -20,44 +20,60 @@ inputmethod_setup(function() {
 });
 
 let appFrameScript = function appFrameScript() {
   let input = content.document.body.firstElementChild;
 
   input.focus();
   input.value = 'First1';
   input.blur();
-
-  content.setTimeout(function() {
-    sendAsyncMessage('test:next', {});
-  });
 };
 
 function runTest() {
   let im = navigator.mozInputMethod;
 
   let i = 0;
   im.oninputcontextchange = function() {
-    ok(false, 'Should not receive any inputcontextchange events.');
+    let inputcontext = im.inputcontext;
+    i++;
+    switch (i) {
+      case 1:
+        ok(!!inputcontext, 'Should receive inputcontext from focus().');
+        is(inputcontext.textAfterCursor, 'First');
+
+        break;
+
+      case 2:
+        ok(!!inputcontext, 'Should receive inputcontext from value change.');
+        is(inputcontext.textBeforeCursor, 'First1');
+
+        break;
+
+      case 3:
+        ok(!inputcontext, 'Should lost inputcontext from blur().');
+
+        inputmethod_cleanup();
+        break;
+
+      default:
+        ok(false, 'Unknown event count.');
+
+        inputmethod_cleanup();
+    }
   };
 
   // Set current page as an input method.
   SpecialPowers.wrap(im).setActive(true);
 
   let iframe = document.createElement('iframe');
   iframe.src = 'data:text/html,<html><body><input value="First"></body></html>';
   iframe.setAttribute('mozbrowser', true);
   document.body.appendChild(iframe);
 
   let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
-  mm.addMessageListener('test:next', function() {
-    ok(true, '\\o/');
-    inputmethod_cleanup();
-  });
-
   iframe.addEventListener('mozbrowserloadend', function() {
     mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false);
   });
 }
 
 </script>
 </pre>
 </body>
--- a/dom/inputmethod/mochitest/test_two_inputs.html
+++ b/dom/inputmethod/mochitest/test_two_inputs.html
@@ -29,49 +29,47 @@ let appFrameScript = function appFrameSc
 
   input1.focus();
 
   addMessageListener('test:next', function() {
     i++;
     switch (i) {
       case 2:
         input2.focus();
-
-        break;
-
-      case 3:
-        input2.blur();
-        input2.focus();
+        i++; // keep the same count with the parent frame.
 
         break;
 
       case 4:
         input2.blur();
 
         break;
 
       case 5:
         input2.focus();
-        input2.blur();
-
-        input1.focus();
 
         break;
 
       case 6:
+        input1.focus();
+        i++; // keep the same count with the parent frame.
+
+        break;
+
+      case 8:
         content.document.body.removeChild(input1);
 
         break;
 
-      case 7:
+      case 9:
         input2.focus();
 
         break;
 
-      case 8:
+      case 10:
         content.document.body.removeChild(input2);
 
         break;
     }
   });
 };
 
 function runTest() {
@@ -80,75 +78,83 @@ function runTest() {
   let i = 0;
   im.oninputcontextchange = function(evt) {
     var inputcontext = navigator.mozInputMethod.inputcontext;
 
     i++;
     switch (i) {
       // focus on the first input receives the first input context.
       case 1:
-        ok(!!inputcontext, 'Receving the first input context');
+        ok(!!inputcontext, '1) Receving the first input context');
         is(inputcontext.textAfterCursor, 'First');
 
         mm.sendAsyncMessage('test:next');
         break;
 
-      // focus on the second input (implicitly blur the first input)
-      // results the second input context.
+      // focus on the second input should implicitly blur the first input
       case 2:
-        ok(!!inputcontext, 'Receving the second input context');
-        is(inputcontext.textAfterCursor, 'Second');
+        is(inputcontext, null, '2) Receving null inputcontext');
 
-
-        mm.sendAsyncMessage('test:next');
         break;
 
-      // blur and re-focus on the second input results updated
-      // input context for the second input.
+      // ... and results the second input context.
       case 3:
-        ok(!!inputcontext, 'Receving the second input context');
+        ok(!!inputcontext, '3) Receving the second input context');
         is(inputcontext.textAfterCursor, 'Second');
 
         mm.sendAsyncMessage('test:next');
         break;
 
       // blur on the second input results null input context
       case 4:
-        is(inputcontext, null, 'Receving null inputcontext');
+        is(inputcontext, null, '4) Receving null inputcontext');
 
         mm.sendAsyncMessage('test:next');
         break;
 
-      // focus and blur on the second input sends no message;
-      // focus on the first input receives the first input context.
+      // focus on the second input receives the second input context.
       case 5:
-        ok(!!inputcontext, 'Receving the first input context');
+        ok(!!inputcontext, '5) Receving the second input context');
+        is(inputcontext.textAfterCursor, 'Second');
+
+        mm.sendAsyncMessage('test:next');
+        break;
+
+      // focus on the second input should implicitly blur the first input
+      case 6:
+        is(inputcontext, null, '6) Receving null inputcontext');
+
+        break;
+
+      // ... and results the second input context.
+      case 7:
+        ok(!!inputcontext, '7) Receving the first input context');
         is(inputcontext.textAfterCursor, 'First');
 
         mm.sendAsyncMessage('test:next');
         break;
 
       // remove on the first focused input results null input context
-      case 6:
-        is(inputcontext, null, 'Receving null inputcontext');
+      case 8:
+        is(inputcontext, null, '8) Receving null inputcontext');
 
         mm.sendAsyncMessage('test:next');
         break;
 
       // input context for the second input.
-      case 7:
-        ok(!!inputcontext, 'Receving the second input context');
+      case 9:
+        ok(!!inputcontext, '9) Receving the second input context');
         is(inputcontext.textAfterCursor, 'Second');
 
         mm.sendAsyncMessage('test:next');
         break;
 
       // remove on the second focused input results null input context
-      case 8:
-        is(inputcontext, null, 'Receving null inputcontext');
+      case 10:
+        is(inputcontext, null, '10) Receving null inputcontext');
 
         inputmethod_cleanup();
         break;
 
       default:
         ok(false, 'Receving extra inputcontextchange calls');
         inputmethod_cleanup();
 
--- a/dom/inputmethod/mochitest/test_two_selects.html
+++ b/dom/inputmethod/mochitest/test_two_selects.html
@@ -27,40 +27,48 @@ let appFrameScript = function appFrameSc
 
   select1.focus();
 
   addMessageListener('test:next', function() {
     i++;
     switch (i) {
       case 2:
         select2.focus();
-
-        break;
-
-      case 3:
-        select2.blur();
-        select2.focus();
+        i++; // keep the same count with the parent frame.
 
         break;
 
       case 4:
         select2.blur();
 
         break;
 
       case 5:
         select2.focus();
-        select2.blur();
-
-        select1.focus();
 
         break;
 
       case 6:
-        select1.blur();
+        select1.focus();
+        i++; // keep the same count with the parent frame.
+
+        break;
+
+      case 8:
+        content.document.body.removeChild(select1);
+
+        break;
+
+      case 9:
+        select2.focus();
+
+        break;
+
+      case 10:
+        content.document.body.removeChild(select2);
 
         break;
     }
   });
 };
 
 function runTest() {
   let im = navigator.mozInputMethod;
@@ -68,60 +76,83 @@ function runTest() {
   let i = 0;
   im.oninputcontextchange = function(evt) {
     var inputcontext = navigator.mozInputMethod.inputcontext;
 
     i++;
     switch (i) {
       // focus on the first input receives the first input context.
       case 1:
-        ok(!!inputcontext, 'Receving the first input context');
+        ok(!!inputcontext, '1) Receving the first input context');
         is(inputcontext.textAfterCursor, 'First');
 
         mm.sendAsyncMessage('test:next');
         break;
 
-      // focus on the second input (implicitly blur the first input)
-      // results the second input context.
+      // focus on the second input should implicitly blur the first input
       case 2:
-        ok(!!inputcontext, 'Receving the second input context');
-        is(inputcontext.textAfterCursor, 'Second');
+        is(inputcontext, null, '2) Receving null inputcontext');
 
-
-        mm.sendAsyncMessage('test:next');
         break;
 
-      // blur and re-focus on the second input results updated
-      // input context for the second input.
+      // ... and results the second input context.
       case 3:
-        ok(!!inputcontext, 'Receving the second input context');
+        ok(!!inputcontext, '3) Receving the second input context');
         is(inputcontext.textAfterCursor, 'Second');
 
         mm.sendAsyncMessage('test:next');
         break;
 
       // blur on the second input results null input context
       case 4:
-        is(inputcontext, null, 'Receving null inputcontext');
+        is(inputcontext, null, '4) Receving null inputcontext');
 
         mm.sendAsyncMessage('test:next');
         break;
 
-      // focus and blur on the second input sends no message;
-      // focus on the first input receives the first input context.
+      // focus on the second input receives the second input context.
       case 5:
-        ok(!!inputcontext, 'Receving the first input context');
+        ok(!!inputcontext, '5) Receving the second input context');
+        is(inputcontext.textAfterCursor, 'Second');
+
+        mm.sendAsyncMessage('test:next');
+        break;
+
+      // focus on the second input should implicitly blur the first input
+      case 6:
+        is(inputcontext, null, '6) Receving null inputcontext');
+
+        break;
+
+      // ... and results the second input context.
+      case 7:
+        ok(!!inputcontext, '7) Receving the first input context');
         is(inputcontext.textAfterCursor, 'First');
 
         mm.sendAsyncMessage('test:next');
         break;
 
-      // blur on the first input results null input context
-      case 6:
-        is(inputcontext, null, 'Receving null inputcontext');
+      // remove on the first focused input results null input context
+      case 8:
+        is(inputcontext, null, '8) Receving null inputcontext');
+
+        mm.sendAsyncMessage('test:next');
+        break;
+
+      // input context for the second input.
+      case 9:
+        ok(!!inputcontext, '9) Receving the second input context');
+        is(inputcontext.textAfterCursor, 'Second');
+
+        mm.sendAsyncMessage('test:next');
+        break;
+
+      // remove on the second focused input results null input context
+      case 10:
+        is(inputcontext, null, '10) Receving null inputcontext');
 
         inputmethod_cleanup();
         break;
 
       default:
         ok(false, 'Receving extra inputcontextchange calls');
         inputmethod_cleanup();
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -74,17 +74,19 @@
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/layers/SharedBufferManagerParent.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/net/NeckoParent.h"
 #include "mozilla/plugins/PluginBridge.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/ProcessHangMonitor.h"
 #include "mozilla/ProcessHangMonitorIPC.h"
+#ifdef MOZ_ENABLE_PROFILER_SPS
 #include "mozilla/ProfileGatherer.h"
+#endif
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsAnonymousTemporaryFile.h"
 #include "nsAppRunner.h"
 #include "nsAutoPtr.h"
 #include "nsCDefaultURIFixup.h"
@@ -234,17 +236,19 @@ using namespace mozilla::system;
 #ifdef MOZ_GAMEPAD
 #include "mozilla/dom/GamepadMonitoring.h"
 #endif
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 
 using base::ChildPrivileges;
 using base::KillProcess;
+#ifdef MOZ_ENABLE_PROFILER_SPS
 using mozilla::ProfileGatherer;
+#endif
 
 #ifdef MOZ_CRASHREPORTER
 using namespace CrashReporter;
 #endif
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::cellbroadcast;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::icc;
@@ -5101,22 +5105,24 @@ ContentParent::RecvGamepadListenerRemove
     MaybeStopGamepadMonitoring();
 #endif
     return true;
 }
 
 bool
 ContentParent::RecvProfile(const nsCString& aProfile)
 {
+#ifdef MOZ_ENABLE_PROFILER_SPS
     if (NS_WARN_IF(!mGatherer)) {
         return true;
     }
     mProfile = aProfile;
     mGatherer->GatheredOOPProfile();
     mGatherer = nullptr;
+#endif
     return true;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 NS_IMPL_ISUPPORTS(ParentIdleListener, nsIObserver)
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -32,17 +32,19 @@ class nsConsoleService;
 class nsICycleCollectorLogSink;
 class nsIDumpGCAndCCLogsCallback;
 class nsITimer;
 class ParentIdleListener;
 class nsIWidget;
 
 namespace mozilla {
 class PRemoteSpellcheckEngineParent;
+#ifdef MOZ_ENABLE_PROFILER_SPS
 class ProfileGatherer;
+#endif
 
 namespace ipc {
 class OptionalURIParams;
 class PFileDescriptorSetParent;
 class URIParams;
 class TestShellParent;
 } // namespace ipc
 
@@ -928,17 +930,19 @@ private:
 #endif
 
 #ifdef MOZ_NUWA_PROCESS
     static int32_t sNuwaPid;
     static bool sNuwaReady;
 #endif
 
     PProcessHangMonitorParent* mHangMonitorActor;
+#ifdef MOZ_ENABLE_PROFILER_SPS
     nsRefPtr<mozilla::ProfileGatherer> mGatherer;
+#endif
     nsCString mProfile;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 class ParentIdleListener : public nsIObserver {
   friend class mozilla::dom::ContentParent;
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -305,17 +305,17 @@ parent:
     sync IsParentWindowMainWidgetVisible() returns (bool visible);
 
     /**
      * Returns the offset of this tab from the top level window
      * origin in device pixels.
      *
      * aPoint offset values in device pixels.
      */
-    sync GetTabOffset() returns (LayoutDeviceIntPoint aPoint);
+    prio(high) sync GetTabOffset() returns (LayoutDeviceIntPoint aPoint);
 
     /**
      * Gets the DPI of the screen corresponding to this browser.
      */
     sync GetDPI() returns (float value);
 
     /**
      * Gets the default scaling factor of the screen corresponding to this browser.
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -2697,16 +2697,23 @@ TabParent::ApzAwareEventRoutingToChild(S
     }
     if (aOutApzResponse) {
       *aOutApzResponse = InputAPZContext::GetApzResponse();
     }
 
     // Let the widget know that the event will be sent to the child process,
     // which will (hopefully) send a confirmation notice back to APZ.
     InputAPZContext::SetRoutedToChildProcess();
+  } else {
+    if (aOutInputBlockId) {
+      *aOutInputBlockId = 0;
+    }
+    if (aOutApzResponse) {
+      *aOutApzResponse = nsEventStatus_eIgnore;
+    }
   }
 }
 
 bool
 TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                       const nsString& aURL,
                                       const nsString& aName,
                                       const nsString& aFeatures,
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -485,27 +485,28 @@ VideoData::Create(const VideoInfo& aInfo
 
 #define RAW_DATA_DEFAULT_SIZE 4096
 
 MediaRawData::MediaRawData()
   : MediaData(RAW_DATA)
   , mData(nullptr)
   , mSize(0)
   , mCrypto(mCryptoInternal)
-  , mBuffer(new MediaLargeByteBuffer(RAW_DATA_DEFAULT_SIZE))
+  , mBuffer(new MediaByteBuffer())
   , mPadding(0)
 {
+  unused << mBuffer->SetCapacity(RAW_DATA_DEFAULT_SIZE, fallible);
 }
 
 MediaRawData::MediaRawData(const uint8_t* aData, size_t aSize)
   : MediaData(RAW_DATA)
   , mData(nullptr)
   , mSize(0)
   , mCrypto(mCryptoInternal)
-  , mBuffer(new MediaLargeByteBuffer(RAW_DATA_DEFAULT_SIZE))
+  , mBuffer(new MediaByteBuffer())
   , mPadding(0)
 {
   if (!EnsureCapacity(aSize)) {
     return;
   }
 
   // We ensure sufficient capacity above so this shouldn't fail.
   MOZ_ALWAYS_TRUE(mBuffer->AppendElements(aData, aSize, fallible));
--- a/dom/media/MediaData.h
+++ b/dom/media/MediaData.h
@@ -17,17 +17,16 @@
 
 namespace mozilla {
 
 namespace layers {
 class Image;
 class ImageContainer;
 }
 
-class MediaLargeByteBuffer;
 class MediaByteBuffer;
 
 // Container that holds media samples.
 class MediaData {
 public:
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaData)
 
@@ -364,17 +363,17 @@ public:
   // Clear the memory buffer. Will set mData and mSize to 0.
   void Clear();
 
 private:
   friend class MediaRawData;
   explicit MediaRawDataWriter(MediaRawData* aMediaRawData);
   bool EnsureSize(size_t aSize);
   MediaRawData* mTarget;
-  nsRefPtr<MediaLargeByteBuffer> mBuffer;
+  nsRefPtr<MediaByteBuffer> mBuffer;
 };
 
 class MediaRawData : public MediaData {
 public:
   MediaRawData();
   MediaRawData(const uint8_t* aData, size_t mSize);
 
   // Pointer to data or null if not-yet allocated
@@ -398,33 +397,22 @@ protected:
 private:
   friend class MediaRawDataWriter;
   // Ensure that the backend buffer can hold aSize data. Will update mData.
   // Will enforce that the start of allocated data is always 32 bytes
   // aligned and that it has sufficient end padding to allow for 32 bytes block
   // read as required by some data decoders.
   // Returns false if memory couldn't be allocated.
   bool EnsureCapacity(size_t aSize);
-  nsRefPtr<MediaLargeByteBuffer> mBuffer;
+  nsRefPtr<MediaByteBuffer> mBuffer;
   CryptoSample mCryptoInternal;
   uint32_t mPadding;
   MediaRawData(const MediaRawData&); // Not implemented
 };
 
-  // MediaLargeByteBuffer is a ref counted fallible TArray.
-  // It is designed to share potentially big byte arrays.
-class MediaLargeByteBuffer : public FallibleTArray<uint8_t> {
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaLargeByteBuffer);
-  MediaLargeByteBuffer() = default;
-  explicit MediaLargeByteBuffer(size_t aCapacity) : FallibleTArray<uint8_t>(aCapacity) {}
-
-private:
-  ~MediaLargeByteBuffer() {}
-};
-
   // MediaByteBuffer is a ref counted infallible TArray.
 class MediaByteBuffer : public nsTArray<uint8_t> {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaByteBuffer);
 
 private:
   ~MediaByteBuffer() {}
 };
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -2965,21 +2965,17 @@ void MediaDecoderStateMachine::AdvanceFr
   // the monitor and get a staled value from GetCurrentTimeUs() which hits the
   // assertion in GetClock().
 
   if (currentFrame) {
     // Decode one frame and display it.
     int64_t delta = currentFrame->mTime - clock_time;
     TimeStamp presTime = nowTime + TimeDuration::FromMicroseconds(delta / mPlaybackRate);
     NS_ASSERTION(currentFrame->mTime >= mStartTime, "Should have positive frame time");
-    // Filter out invalid frames by checking the frame time. FrameTime could be
-    // zero if it's a initial frame.
-    int64_t frameTime = currentFrame->mTime - mStartTime;
-    if (frameTime > 0  || (frameTime == 0 && mPlayDuration == 0) ||
-        IsRealTime()) {
+    {
       ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
       // If we have video, we want to increment the clock in steps of the frame
       // duration.
       RenderVideoFrame(currentFrame, presTime);
     }
     MOZ_ASSERT(IsPlaying());
     MediaDecoder::FrameStatistics& frameStats = mDecoder->GetFrameStatistics();
     frameStats.NotifyPresentedFrame();
--- a/dom/media/fmp4/MP4Demuxer.cpp
+++ b/dom/media/fmp4/MP4Demuxer.cpp
@@ -15,17 +15,17 @@
 #include "mp4_demuxer/ResourceStream.h"
 #include "mp4_demuxer/BufferStream.h"
 
 namespace mozilla {
 
 MP4Demuxer::MP4Demuxer(MediaResource* aResource)
   : mResource(aResource)
   , mStream(new mp4_demuxer::ResourceStream(aResource))
-  , mInitData(new MediaLargeByteBuffer)
+  , mInitData(new MediaByteBuffer)
 {
 }
 
 nsRefPtr<MP4Demuxer::InitPromise>
 MP4Demuxer::Init()
 {
   AutoPinned<mp4_demuxer::ResourceStream> stream(mStream);
 
--- a/dom/media/fmp4/MP4Demuxer.h
+++ b/dom/media/fmp4/MP4Demuxer.h
@@ -46,17 +46,17 @@ public:
   virtual void NotifyDataArrived(uint32_t aLength, int64_t aOffset) override;
 
   virtual void NotifyDataRemoved() override;
 
 private:
   friend class MP4TrackDemuxer;
   nsRefPtr<MediaResource> mResource;
   nsRefPtr<mp4_demuxer::ResourceStream> mStream;
-  nsRefPtr<MediaLargeByteBuffer> mInitData;
+  nsRefPtr<MediaByteBuffer> mInitData;
   UniquePtr<mp4_demuxer::MP4Metadata> mMetadata;
   nsTArray<nsRefPtr<MP4TrackDemuxer>> mDemuxers;
 };
 
 class MP4TrackDemuxer : public MediaTrackDemuxer
 {
 public:
   MP4TrackDemuxer(MP4Demuxer* aParent,
--- a/dom/media/mediasource/ContainerParser.cpp
+++ b/dom/media/mediasource/ContainerParser.cpp
@@ -32,41 +32,41 @@ namespace mozilla {
 
 ContainerParser::ContainerParser(const nsACString& aType)
   : mHasInitData(false)
   , mType(aType)
 {
 }
 
 bool
-ContainerParser::IsInitSegmentPresent(MediaLargeByteBuffer* aData)
+ContainerParser::IsInitSegmentPresent(MediaByteBuffer* aData)
 {
 MSE_DEBUG(ContainerParser, "aLength=%u [%x%x%x%x]",
             aData->Length(),
             aData->Length() > 0 ? (*aData)[0] : 0,
             aData->Length() > 1 ? (*aData)[1] : 0,
             aData->Length() > 2 ? (*aData)[2] : 0,
             aData->Length() > 3 ? (*aData)[3] : 0);
 return false;
 }
 
 bool
-ContainerParser::IsMediaSegmentPresent(MediaLargeByteBuffer* aData)
+ContainerParser::IsMediaSegmentPresent(MediaByteBuffer* aData)
 {
   MSE_DEBUG(ContainerParser, "aLength=%u [%x%x%x%x]",
             aData->Length(),
             aData->Length() > 0 ? (*aData)[0] : 0,
             aData->Length() > 1 ? (*aData)[1] : 0,
             aData->Length() > 2 ? (*aData)[2] : 0,
             aData->Length() > 3 ? (*aData)[3] : 0);
   return false;
 }
 
 bool
-ContainerParser::ParseStartAndEndTimestamps(MediaLargeByteBuffer* aData,
+ContainerParser::ParseStartAndEndTimestamps(MediaByteBuffer* aData,
                                             int64_t& aStart, int64_t& aEnd)
 {
   return false;
 }
 
 bool
 ContainerParser::TimestampsFuzzyEqual(int64_t aLhs, int64_t aRhs)
 {
@@ -81,17 +81,17 @@ ContainerParser::GetRoundingError()
 }
 
 bool
 ContainerParser::HasCompleteInitData()
 {
   return mHasInitData && !!mInitData->Length();
 }
 
-MediaLargeByteBuffer*
+MediaByteBuffer*
 ContainerParser::InitData()
 {
   return mInitData;
 }
 
 MediaByteRange
 ContainerParser::InitSegmentRange()
 {
@@ -116,17 +116,17 @@ public:
     : ContainerParser(aType)
     , mParser(0)
     , mOffset(0)
   {}
 
   static const unsigned NS_PER_USEC = 1000;
   static const unsigned USEC_PER_SEC = 1000000;
 
-  bool IsInitSegmentPresent(MediaLargeByteBuffer* aData) override
+  bool IsInitSegmentPresent(MediaByteBuffer* aData) override
   {
     ContainerParser::IsInitSegmentPresent(aData);
     // XXX: This is overly primitive, needs to collect data as it's appended
     // to the SB and handle, rather than assuming everything is present in a
     // single aData segment.
     // 0x1a45dfa3 // EBML
     // ...
     // DocType == "webm"
@@ -139,17 +139,17 @@ public:
     if (aData->Length() >= 4 &&
         (*aData)[0] == 0x1a && (*aData)[1] == 0x45 && (*aData)[2] == 0xdf &&
         (*aData)[3] == 0xa3) {
       return true;
     }
     return false;
   }
 
-  bool IsMediaSegmentPresent(MediaLargeByteBuffer* aData) override
+  bool IsMediaSegmentPresent(MediaByteBuffer* aData) override
   {
     ContainerParser::IsMediaSegmentPresent(aData);
     // XXX: This is overly primitive, needs to collect data as it's appended
     // to the SB and handle, rather than assuming everything is present in a
     // single aData segment.
     // 0x1a45dfa3 // EBML
     // ...
     // DocType == "webm"
@@ -160,25 +160,25 @@ public:
     if (aData->Length() >= 4 &&
         (*aData)[0] == 0x1f && (*aData)[1] == 0x43 && (*aData)[2] == 0xb6 &&
         (*aData)[3] == 0x75) {
       return true;
     }
     return false;
   }
 
-  bool ParseStartAndEndTimestamps(MediaLargeByteBuffer* aData,
+  bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
                                   int64_t& aStart, int64_t& aEnd) override
   {
     bool initSegment = IsInitSegmentPresent(aData);
     if (initSegment) {
       mOffset = 0;
       mParser = WebMBufferedParser(0);
       mOverlappedMapping.Clear();
-      mInitData = new MediaLargeByteBuffer();
+      mInitData = new MediaByteBuffer();
       mResource = new SourceBufferResource(NS_LITERAL_CSTRING("video/webm"));
     }
 
     // XXX if it only adds new mappings, overlapped but not available
     // (e.g. overlap < 0) frames are "lost" from the reported mappings here.
     nsTArray<WebMTimeDataOffset> mapping;
     mapping.AppendElements(mOverlappedMapping);
     mOverlappedMapping.Clear();
@@ -253,17 +253,17 @@ private:
 #ifdef MOZ_FMP4
 class MP4ContainerParser : public ContainerParser {
 public:
   explicit MP4ContainerParser(const nsACString& aType)
     : ContainerParser(aType)
     , mMonitor("MP4ContainerParser Index Monitor")
   {}
 
-  bool IsInitSegmentPresent(MediaLargeByteBuffer* aData) override
+  bool IsInitSegmentPresent(MediaByteBuffer* aData) override
   {
     ContainerParser::IsInitSegmentPresent(aData);
     // Each MP4 atom has a chunk size and chunk type. The root chunk in an MP4
     // file is the 'ftyp' atom followed by a file type. We just check for a
     // vaguely valid 'ftyp' atom.
 
     if (aData->Length() < 8) {
       return false;
@@ -273,17 +273,17 @@ public:
     if (chunk_size < 8) {
       return false;
     }
 
     return (*aData)[4] == 'f' && (*aData)[5] == 't' && (*aData)[6] == 'y' &&
            (*aData)[7] == 'p';
   }
 
-  bool IsMediaSegmentPresent(MediaLargeByteBuffer* aData) override
+  bool IsMediaSegmentPresent(MediaByteBuffer* aData) override
   {
     ContainerParser::IsMediaSegmentPresent(aData);
     if (aData->Length() < 8) {
       return false;
     }
 
     uint32_t chunk_size = BigEndian::readUint32(aData->Elements());
     if (chunk_size < 8) {
@@ -293,31 +293,31 @@ public:
     return ((*aData)[4] == 'm' && (*aData)[5] == 'o' && (*aData)[6] == 'o' &&
             (*aData)[7] == 'f') ||
            ((*aData)[4] == 's' && (*aData)[5] == 't' && (*aData)[6] == 'y' &&
             (*aData)[7] == 'p') ||
            ((*aData)[4] == 's' && (*aData)[5] == 'i' && (*aData)[6] == 'd' &&
             (*aData)[7] == 'x');
   }
 
-  bool ParseStartAndEndTimestamps(MediaLargeByteBuffer* aData,
+  bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
                                   int64_t& aStart, int64_t& aEnd) override
   {
     MonitorAutoLock mon(mMonitor); // We're not actually racing against anything,
                                    // but mParser requires us to hold a monitor.
     bool initSegment = IsInitSegmentPresent(aData);
     if (initSegment) {
       mResource = new SourceBufferResource(NS_LITERAL_CSTRING("video/mp4"));
       mStream = new MP4Stream(mResource);
       // We use a timestampOffset of 0 for ContainerParser, and require
       // consumers of ParseStartAndEndTimestamps to add their timestamp offset
       // manually. This allows the ContainerParser to be shared across different
       // timestampOffsets.
       mParser = new mp4_demuxer::MoofParser(mStream, 0, /* aIsAudio = */ false, &mMonitor);
-      mInitData = new MediaLargeByteBuffer();
+      mInitData = new MediaByteBuffer();
     } else if (!mStream || !mParser) {
       return false;
     }
 
     mResource->AppendData(aData);
     nsTArray<MediaByteRange> byteRanges;
     MediaByteRange mbr =
       MediaByteRange(mParser->mOffset, mResource->GetLength());
--- a/dom/media/mediasource/ContainerParser.h
+++ b/dom/media/mediasource/ContainerParser.h
@@ -8,48 +8,48 @@
 #define MOZILLA_CONTAINERPARSER_H_
 
 #include "nsRefPtr.h"
 #include "nsString.h"
 #include "MediaResource.h"
 
 namespace mozilla {
 
-class MediaLargeByteBuffer;
+class MediaByteBuffer;
 class SourceBufferResource;
 
 class ContainerParser {
 public:
   explicit ContainerParser(const nsACString& aType);
   virtual ~ContainerParser() {}
 
   // Return true if aData starts with an initialization segment.
   // The base implementation exists only for debug logging and is expected
   // to be called first from the overriding implementation.
-  virtual bool IsInitSegmentPresent(MediaLargeByteBuffer* aData);
+  virtual bool IsInitSegmentPresent(MediaByteBuffer* aData);
 
   // Return true if aData starts with a media segment.
   // The base implementation exists only for debug logging and is expected
   // to be called first from the overriding implementation.
-  virtual bool IsMediaSegmentPresent(MediaLargeByteBuffer* aData);
+  virtual bool IsMediaSegmentPresent(MediaByteBuffer* aData);
 
   // Parse aData to extract the start and end frame times from the media
   // segment.  aData may not start on a parser sync boundary.  Return true
   // if aStart and aEnd have been updated.
-  virtual bool ParseStartAndEndTimestamps(MediaLargeByteBuffer* aData,
+  virtual bool ParseStartAndEndTimestamps(MediaByteBuffer* aData,
                                           int64_t& aStart, int64_t& aEnd);
 
   // Compare aLhs and rHs, considering any error that may exist in the
   // timestamps from the format's base representation.  Return true if aLhs
   // == aRhs within the error epsilon.
   bool TimestampsFuzzyEqual(int64_t aLhs, int64_t aRhs);
 
   virtual int64_t GetRoundingError();
 
-  MediaLargeByteBuffer* InitData();
+  MediaByteBuffer* InitData();
 
   bool HasInitData()
   {
     return mHasInitData;
   }
 
   bool HasCompleteInitData();
   // Returns the byte range of the first complete init segment, or an empty
@@ -60,17 +60,17 @@ public:
   MediaByteRange MediaHeaderRange();
   // Returns the byte range of the first complete media segment or an empty
   // range if not complete.
   MediaByteRange MediaSegmentRange();
 
   static ContainerParser* CreateForMIMEType(const nsACString& aType);
 
 protected:
-  nsRefPtr<MediaLargeByteBuffer> mInitData;
+  nsRefPtr<MediaByteBuffer> mInitData;
   nsRefPtr<SourceBufferResource> mResource;
   bool mHasInitData;
   MediaByteRange mCompleteInitSegmentRange;
   MediaByteRange mCompleteMediaHeaderRange;
   MediaByteRange mCompleteMediaSegmentRange;
   const nsCString mType;
 };
 
--- a/dom/media/mediasource/ResourceQueue.cpp
+++ b/dom/media/mediasource/ResourceQueue.cpp
@@ -15,17 +15,17 @@ extern PRLogModuleInfo* GetSourceBufferR
 #define __func__ __FUNCTION__
 #endif
 
 #define SBR_DEBUG(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Debug, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 #define SBR_DEBUGV(arg, ...) MOZ_LOG(GetSourceBufferResourceLog(), mozilla::LogLevel::Verbose, ("ResourceQueue(%p)::%s: " arg, this, __func__, ##__VA_ARGS__))
 
 namespace mozilla {
 
-ResourceItem::ResourceItem(MediaLargeByteBuffer* aData)
+ResourceItem::ResourceItem(MediaByteBuffer* aData)
   : mData(aData)
 {
 }
 
 size_t
 ResourceItem::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   // size including this
@@ -77,17 +77,17 @@ ResourceQueue::CopyData(uint64_t aOffset
       offset = 0;
       aCount -= bytes;
       aDest += bytes;
     }
   }
 }
 
 void
-ResourceQueue::AppendItem(MediaLargeByteBuffer* aData)
+ResourceQueue::AppendItem(MediaByteBuffer* aData)
 {
   mLogicalLength += aData->Length();
   Push(new ResourceItem(aData));
 }
 
 uint32_t
 ResourceQueue::Evict(uint64_t aOffset, uint32_t aSizeToEvict,
                      ErrorResult& aRv)
@@ -106,17 +106,17 @@ uint32_t ResourceQueue::EvictBefore(uint
               item, item->mData->Length(), mOffset);
     if (item->mData->Length() + mOffset >= aOffset) {
       if (aOffset <= mOffset) {
         break;
       }
       uint32_t offset = aOffset - mOffset;
       mOffset += offset;
       evicted += offset;
-      nsRefPtr<MediaLargeByteBuffer> data = new MediaLargeByteBuffer;
+      nsRefPtr<MediaByteBuffer> data = new MediaByteBuffer;
       if (!data->AppendElements(item->mData->Elements() + offset,
                                 item->mData->Length() - offset,
                                 fallible)) {
         aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
         return 0;
       }
 
       item->mData = data;
--- a/dom/media/mediasource/ResourceQueue.h
+++ b/dom/media/mediasource/ResourceQueue.h
@@ -21,36 +21,36 @@ class ErrorResult;
 
 // Data is evicted once it reaches a size threshold. This pops the items off
 // the front of the queue and deletes it.  If an eviction happens then the
 // MediaSource is notified (done in SourceBuffer::AppendData) which then
 // requests all SourceBuffers to evict data up to approximately the same
 // timepoint.
 
 struct ResourceItem {
-  explicit ResourceItem(MediaLargeByteBuffer* aData);
+  explicit ResourceItem(MediaByteBuffer* aData);
   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
-  nsRefPtr<MediaLargeByteBuffer> mData;
+  nsRefPtr<MediaByteBuffer> mData;
 };
 
 class ResourceQueue : private nsDeque {
 public:
   ResourceQueue();
 
   // Returns the logical byte offset of the start of the data.
   uint64_t GetOffset();
 
   // Returns the length of all items in the queue plus the offset.
   // This is the logical length of the resource.
   uint64_t GetLength();
 
   // Copies aCount bytes from aOffset in the queue into aDest.
   void CopyData(uint64_t aOffset, uint32_t aCount, char* aDest);
 
-  void AppendItem(MediaLargeByteBuffer* aData);
+  void AppendItem(MediaByteBuffer* aData);
 
   // Tries to evict at least aSizeToEvict from the queue up until
   // aOffset. Returns amount evicted.
   uint32_t Evict(uint64_t aOffset, uint32_t aSizeToEvict,
                  ErrorResult& aRv);
 
   uint32_t EvictBefore(uint64_t aOffset, ErrorResult& aRv);
 
--- a/dom/media/mediasource/SourceBuffer.cpp
+++ b/dom/media/mediasource/SourceBuffer.cpp
@@ -428,17 +428,17 @@ SourceBuffer::CheckEndTime()
   }
 }
 
 void
 SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
 {
   MSE_DEBUG("AppendData(aLength=%u)", aLength);
 
-  nsRefPtr<MediaLargeByteBuffer> data = PrepareAppend(aData, aLength, aRv);
+  nsRefPtr<MediaByteBuffer> data = PrepareAppend(aData, aLength, aRv);
   if (!data) {
     return;
   }
   mContentManager->AppendData(data, mTimestampOffset);
 
   StartUpdating();
 
   MOZ_ASSERT(mAppendMode == SourceBufferAppendMode::Segments,
@@ -531,17 +531,17 @@ SourceBuffer::AppendError(bool aDecoderE
   if (aDecoderError) {
     Optional<MediaSourceEndOfStreamError> decodeError(
       MediaSourceEndOfStreamError::Decode);
     ErrorResult dummy;
     mMediaSource->EndOfStream(decodeError, dummy);
   }
 }
 
-already_AddRefed<MediaLargeByteBuffer>
+already_AddRefed<MediaByteBuffer>
 SourceBuffer::PrepareAppend(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
 {
   typedef SourceBufferContentManager::EvictDataResult Result;
 
   if (!IsAttached() || mUpdating) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
     return nullptr;
   }
@@ -579,17 +579,17 @@ SourceBuffer::PrepareAppend(const uint8_
   // to the DASH player to provide a complete media segment.
   if (aLength > mEvictionThreshold ||
       ((mContentManager->GetSize() > mEvictionThreshold - aLength) &&
        evicted != Result::CANT_EVICT)) {
     aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
     return nullptr;
   }
 
-  nsRefPtr<MediaLargeByteBuffer> data = new MediaLargeByteBuffer();
+  nsRefPtr<MediaByteBuffer> data = new MediaByteBuffer();
   if (!data->AppendElements(aData, aLength, fallible)) {
     aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
     return nullptr;
   }
   // TODO: Test buffer full flag.
   return data.forget();
 }
 
--- a/dom/media/mediasource/SourceBuffer.h
+++ b/dom/media/mediasource/SourceBuffer.h
@@ -27,17 +27,17 @@
 #include "SourceBufferContentManager.h"
 
 class JSObject;
 struct JSContext;
 
 namespace mozilla {
 
 class ErrorResult;
-class MediaLargeByteBuffer;
+class MediaByteBuffer;
 template <typename T> class AsyncEventRunner;
 class TrackBuffersManager;
 
 namespace dom {
 
 using media::TimeUnit;
 using media::TimeIntervals;
 
@@ -152,21 +152,21 @@ private:
   void BufferAppend(uint32_t aAppendID);
 
   // Implement the "Append Error Algorithm".
   // Will call endOfStream() with "decode" error if aDecodeError is true.
   // 3.5.3 Append Error Algorithm
   // http://w3c.github.io/media-source/#sourcebuffer-append-error
   void AppendError(bool aDecoderError);
 
-  // Implements the "Prepare Append Algorithm". Returns MediaLargeByteBuffer object
+  // Implements the "Prepare Append Algorithm". Returns MediaByteBuffer object
   // on success or nullptr (with aRv set) on error.
-  already_AddRefed<MediaLargeByteBuffer> PrepareAppend(const uint8_t* aData,
-                                                       uint32_t aLength,
-                                                       ErrorResult& aRv);
+  already_AddRefed<MediaByteBuffer> PrepareAppend(const uint8_t* aData,
+                                                  uint32_t aLength,
+                                                  ErrorResult& aRv);
 
   void AppendDataCompletedWithSuccess(bool aHasActiveTracks);
   void AppendDataErrored(nsresult aError);
 
   // Set timestampOffset, must be called on the main thread.
   void SetTimestampOffset(const TimeUnit& aTimestampOffset);
 
   nsRefPtr<MediaSource> mMediaSource;
--- a/dom/media/mediasource/SourceBufferContentManager.h
+++ b/dom/media/mediasource/SourceBufferContentManager.h
@@ -28,17 +28,17 @@ public:
 
   static already_AddRefed<SourceBufferContentManager>
   CreateManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder,
                 const nsACString& aType);
 
   // Add data to the end of the input buffer.
   // Returns false if the append failed.
   virtual bool
-  AppendData(MediaLargeByteBuffer* aData, TimeUnit aTimestampOffset) = 0;
+  AppendData(MediaByteBuffer* aData, TimeUnit aTimestampOffset) = 0;
 
   // Run MSE Buffer Append Algorithm
   // 3.5.5 Buffer Append Algorithm.
   // http://w3c.github.io/media-source/index.html#sourcebuffer-buffer-append
   virtual nsRefPtr<AppendPromise> BufferAppend() = 0;
 
   // Abort any pending AppendData.
   virtual void AbortAppendData() = 0;
--- a/dom/media/mediasource/SourceBufferResource.cpp
+++ b/dom/media/mediasource/SourceBufferResource.cpp
@@ -207,17 +207,17 @@ uint32_t
 SourceBufferResource::EvictAll()
 {
   SBR_DEBUG("EvictAll()");
   ReentrantMonitorAutoEnter mon(mMonitor);
   return mInputBuffer.EvictAll();
 }
 
 void
-SourceBufferResource::AppendData(MediaLargeByteBuffer* aData)
+SourceBufferResource::AppendData(MediaByteBuffer* aData)
 {
   SBR_DEBUG("AppendData(aData=%p, aLength=%u)",
             aData->Elements(), aData->Length());
   ReentrantMonitorAutoEnter mon(mMonitor);
   mInputBuffer.AppendItem(aData);
   mEnded = false;
   mon.NotifyAll();
 }
--- a/dom/media/mediasource/SourceBufferResource.h
+++ b/dom/media/mediasource/SourceBufferResource.h
@@ -22,17 +22,17 @@
 
 #define UNIMPLEMENTED() { /* Logging this is too spammy to do by default */ }
 
 class nsIStreamListener;
 
 namespace mozilla {
 
 class MediaDecoder;
-class MediaLargeByteBuffer;
+class MediaByteBuffer;
 
 namespace dom {
 
 class SourceBuffer;
 
 }  // namespace dom
 
 class SourceBufferResource final : public MediaResource
@@ -98,17 +98,17 @@ public:
 
   virtual size_t SizeOfIncludingThis(
                       MallocSizeOf aMallocSizeOf) const override
   {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
 
   // Used by SourceBuffer.
-  void AppendData(MediaLargeByteBuffer* aData);
+  void AppendData(MediaByteBuffer* aData);
   void Ended();
   bool IsEnded()
   {
     ReentrantMonitorAutoEnter mon(mMonitor);
     return mEnded;
   }
   // Remove data from resource if it holds more than the threshold
   // number of bytes. Returns amount evicted.
--- a/dom/media/mediasource/TrackBuffer.cpp
+++ b/dom/media/mediasource/TrackBuffer.cpp
@@ -134,17 +134,17 @@ TrackBuffer::ContinueShutdown()
   MOZ_ASSERT(!mCurrentDecoder, "Detach() should have been called");
   mInitializedDecoders.Clear();
   mParentDecoder = nullptr;
 
   mShutdownPromise.Resolve(true, __func__);
 }
 
 bool
-TrackBuffer::AppendData(MediaLargeByteBuffer* aData, TimeUnit aTimestampOffset)
+TrackBuffer::AppendData(MediaByteBuffer* aData, TimeUnit aTimestampOffset)
 {
   MOZ_ASSERT(NS_IsMainThread());
   mInputBuffer = aData;
   mTimestampOffset = aTimestampOffset;
   return true;
 }
 
 nsRefPtr<TrackBuffer::AppendPromise>
@@ -157,17 +157,17 @@ TrackBuffer::BufferAppend()
   if (mInputBuffer->IsEmpty()) {
     return AppendPromise::CreateAndResolve(false, __func__);
   }
 
   DecodersToInitialize decoders(this);
   nsRefPtr<AppendPromise> p = mInitializationPromise.Ensure(__func__);
   bool hadInitData = mParser->HasInitData();
   bool hadCompleteInitData = mParser->HasCompleteInitData();
-  nsRefPtr<MediaLargeByteBuffer> oldInit = mParser->InitData();
+  nsRefPtr<MediaByteBuffer> oldInit = mParser->InitData();
   bool newInitData = mParser->IsInitSegmentPresent(mInputBuffer);
 
   // TODO: Run more of the buffer append algorithm asynchronously.
   if (newInitData) {
     MSE_DEBUG("New initialization segment.");
   } else if (!hadInitData) {
     MSE_DEBUG("Non-init segment appended during initialization.");
     mInitializationPromise.Reject(NS_ERROR_FAILURE, __func__);
@@ -257,17 +257,17 @@ TrackBuffer::BufferAppend()
   // required when data is appended.
   NotifyTimeRangesChanged();
 
   mInitializationPromise.Resolve(HasInitSegment(), __func__);
   return p;
 }
 
 bool
-TrackBuffer::AppendDataToCurrentResource(MediaLargeByteBuffer* aData, uint32_t aDuration)
+TrackBuffer::AppendDataToCurrentResource(MediaByteBuffer* aData, uint32_t aDuration)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mCurrentDecoder) {
     return false;
   }
 
   SourceBufferResource* resource = mCurrentDecoder->GetResource();
   int64_t appendOffset = resource->GetLength();
@@ -719,17 +719,17 @@ TrackBuffer::OnMetadataRead(MetadataHold
   }
   if (mCurrentDecoder != aDecoder) {
     MSE_DEBUG("append was cancelled. Aborting initialization.");
     return;
   }
 
   // Adding an empty buffer will reopen the SourceBufferResource
   if (!aWasEnded) {
-    nsRefPtr<MediaLargeByteBuffer> emptyBuffer = new MediaLargeByteBuffer;
+    nsRefPtr<MediaByteBuffer> emptyBuffer = new MediaByteBuffer;
     aDecoder->GetResource()->AppendData(emptyBuffer);
   }
   // HACK END.
 
   MediaDecoderReader* reader = aDecoder->GetReader();
   reader->SetIdle();
 
   if (reader->IsWaitingOnCDMResource()) {
--- a/dom/media/mediasource/TrackBuffer.h
+++ b/dom/media/mediasource/TrackBuffer.h
@@ -17,25 +17,25 @@
 #include "nsString.h"
 #include "nscore.h"
 #include "TimeUnits.h"
 
 namespace mozilla {
 
 class ContainerParser;
 class MediaSourceDecoder;
-class MediaLargeByteBuffer;
+class MediaByteBuffer;
 
 class TrackBuffer final : public SourceBufferContentManager {
 public:
   TrackBuffer(MediaSourceDecoder* aParentDecoder, const nsACString& aType);
 
   nsRefPtr<ShutdownPromise> Shutdown();
 
-  bool AppendData(MediaLargeByteBuffer* aData, TimeUnit aTimestampOffset) override;
+  bool AppendData(MediaByteBuffer* aData, TimeUnit aTimestampOffset) override;
 
   // Append data to the current decoder.  Also responsible for calling
   // NotifyDataArrived on the decoder to keep buffered range computation up
   // to date.
   nsRefPtr<AppendPromise> BufferAppend() override;
 
   // Evicts data held in the current decoders SourceBufferResource from the
   // start of the buffer through to aPlaybackTime. aThreshold is used to
@@ -114,17 +114,17 @@ private:
   // returns it. The new decoder must be queued using QueueInitializeDecoder
   // for initialization.
   // The decoder is not considered initialized until it is added to
   // mInitializedDecoders.
   already_AddRefed<SourceBufferDecoder> NewDecoder(TimeUnit aTimestampOffset);
 
   // Helper for AppendData, ensures NotifyDataArrived is called whenever
   // data is appended to the current decoder's SourceBufferResource.
-  bool AppendDataToCurrentResource(MediaLargeByteBuffer* aData,
+  bool AppendDataToCurrentResource(MediaByteBuffer* aData,
                                    uint32_t aDuration /* microseconds */);
   // Queue on the parent's decoder task queue a call to NotifyTimeRangesChanged.
   void NotifyTimeRangesChanged();
 
   // Queue execution of InitializeDecoder on mTaskQueue.
   bool QueueInitializeDecoder(SourceBufferDecoder* aDecoder);
 
   // Runs decoder initialization including calling ReadMetadata.  Runs as an
@@ -158,17 +158,17 @@ private:
   void OnMetadataRead(MetadataHolder* aMetadata,
                       SourceBufferDecoder* aDecoder,
                       bool aWasEnded);
 
   void OnMetadataNotRead(ReadMetadataFailureReason aReason,
                          SourceBufferDecoder* aDecoder);
 
   nsAutoPtr<ContainerParser> mParser;
-  nsRefPtr<MediaLargeByteBuffer> mInputBuffer;
+  nsRefPtr<MediaByteBuffer> mInputBuffer;
 
   // A task queue using the shared media thread pool.  Used exclusively to
   // initialize (i.e. call ReadMetadata on) decoders as they are created via
   // NewDecoder.
   RefPtr<MediaTaskQueue> mTaskQueue;
 
   // All of the decoders managed by this TrackBuffer.  Access protected by
   // mParentDecoder's monitor.
--- a/dom/media/mediasource/TrackBuffersManager.cpp
+++ b/dom/media/mediasource/TrackBuffersManager.cpp
@@ -33,17 +33,17 @@ AppendStateToStr(TrackBuffersManager::Ap
     case TrackBuffersManager::AppendState::PARSING_MEDIA_SEGMENT:
       return "PARSING_MEDIA_SEGMENT";
     default:
       return "IMPOSSIBLE";
   }
 }
 
 TrackBuffersManager::TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType)
-  : mInputBuffer(new MediaLargeByteBuffer)
+  : mInputBuffer(new MediaByteBuffer)
   , mAppendState(AppendState::WAITING_FOR_SEGMENT)
   , mBufferFull(false)
   , mFirstInitializationSegmentReceived(false)
   , mActiveTrack(false)
   , mType(aType)
   , mParser(ContainerParser::CreateForMIMEType(aType))
   , mProcessedInput(0)
   , mAppendRunning(false)
@@ -60,17 +60,17 @@ TrackBuffersManager::TrackBuffersManager
   nsCOMPtr<nsIRunnable> task =
     NS_NewRunnableFunction([self] () {
       self->mMediaSourceDuration.Connect(self->mParentDecoder->CanonicalExplicitDuration());
     });
   GetTaskQueue()->Dispatch(task.forget());
 }
 
 bool
-TrackBuffersManager::AppendData(MediaLargeByteBuffer* aData,
+TrackBuffersManager::AppendData(MediaByteBuffer* aData,
                                 TimeUnit aTimestampOffset)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MSE_DEBUG("Appending %lld bytes", aData->Length());
 
   mEnded = false;
   nsCOMPtr<nsIRunnable> task =
     NS_NewRunnableMethodWithArg<IncomingBuffer>(
@@ -311,23 +311,23 @@ TrackBuffersManager::CompleteResetParser
     mCurrentInputBuffer = new SourceBufferResource(mType);
   }
 
   // We could be left with a demuxer in an unusable state. It needs to be
   // recreated. We store in the InputBuffer an init segment which will be parsed
   // during the next Segment Parser Loop and a new demuxer will be created and
   // initialized.
   if (mFirstInitializationSegmentReceived) {
-    nsRefPtr<MediaLargeByteBuffer> initData = mParser->InitData();
+    nsRefPtr<MediaByteBuffer> initData = mParser->InitData();
     MOZ_ASSERT(initData->Length(), "we must have an init segment");
     // The aim here is really to destroy our current demuxer.
     CreateDemuxerforMIMEType();
     // Recreate our input buffer. We can't directly assign the initData buffer
     // to mInputBuffer as it will get modified in the Segment Parser Loop.
-    mInputBuffer = new MediaLargeByteBuffer;
+    mInputBuffer = new MediaByteBuffer;
     MOZ_ALWAYS_TRUE(mInputBuffer->AppendElements(*initData, fallible));
   }
   RecreateParser();
 
   // 7. Set append state to WAITING_FOR_SEGMENT.
   SetAppendState(AppendState::WAITING_FOR_SEGMENT);
 }
 
@@ -922,17 +922,17 @@ TrackBuffersManager::CodedFrameProcessin
   uint32_t length;
   if (mediaRange.IsNull()) {
     length = mInputBuffer->Length();
     mCurrentInputBuffer->AppendData(mInputBuffer);
     mInputBuffer = nullptr;
   } else {
     // The mediaRange is offset by the init segment position previously added.
     length = mediaRange.mEnd - (mProcessedInput - mInputBuffer->Length());
-    nsRefPtr<MediaLargeByteBuffer> segment = new MediaLargeByteBuffer;
+    nsRefPtr<MediaByteBuffer> segment = new MediaByteBuffer;
     MOZ_ASSERT(mInputBuffer->Length() >= length);
     if (!segment->AppendElements(mInputBuffer->Elements(), length, fallible)) {
       return CodedFrameProcessingPromise::CreateAndReject(NS_ERROR_OUT_OF_MEMORY, __func__);
     }
     mCurrentInputBuffer->AppendData(segment);
     mInputBuffer->RemoveElementsAt(0, length);
   }
   mInputDemuxer->NotifyDataArrived(length, offset);
@@ -1375,17 +1375,17 @@ TrackBuffersManager::ProcessFrame(MediaR
 void
 TrackBuffersManager::RecreateParser()
 {
   MOZ_ASSERT(OnTaskQueue());
   // Recreate our parser for only the data remaining. This is required
   // as it has parsed the entire InputBuffer provided.
   // Once the old TrackBuffer/MediaSource implementation is removed
   // we can optimize this part. TODO
-  nsRefPtr<MediaLargeByteBuffer> initData = mParser->InitData();
+  nsRefPtr<MediaByteBuffer> initData = mParser->InitData();
   mParser = ContainerParser::CreateForMIMEType(mType);
   if (initData) {
     int64_t start, end;
     mParser->ParseStartAndEndTimestamps(initData, start, end);
     mProcessedInput = initData->Length();
   } else {
     mProcessedInput = 0;
   }
--- a/dom/media/mediasource/TrackBuffersManager.h
+++ b/dom/media/mediasource/TrackBuffersManager.h
@@ -15,17 +15,17 @@
 #include "mozilla/Pair.h"
 #include "nsProxyRelease.h"
 #include "nsTArray.h"
 #include "StateMirroring.h"
 
 namespace mozilla {
 
 class ContainerParser;
-class MediaLargeByteBuffer;
+class MediaByteBuffer;
 class MediaRawData;
 class MediaSourceDemuxer;
 class SourceBuffer;
 class SourceBufferResource;
 
 using media::TimeUnit;
 using media::TimeInterval;
 using media::TimeIntervals;
@@ -35,17 +35,17 @@ class TrackBuffersManager : public Sourc
 public:
   typedef MediaPromise<bool, nsresult, /* IsExclusive = */ true> CodedFrameProcessingPromise;
   typedef TrackInfo::TrackType TrackType;
   typedef MediaData::Type MediaType;
   typedef nsTArray<nsRefPtr<MediaRawData>> TrackBuffer;
 
   TrackBuffersManager(dom::SourceBuffer* aParent, MediaSourceDecoder* aParentDecoder, const nsACString& aType);
 
-  bool AppendData(MediaLargeByteBuffer* aData, TimeUnit aTimestampOffset) override;
+  bool AppendData(MediaByteBuffer* aData, TimeUnit aTimestampOffset) override;
 
   nsRefPtr<AppendPromise> BufferAppend() override;
 
   void AbortAppendData() override;
 
   void ResetParserState() override;
 
   nsRefPtr<RangeRemovalPromise> RangeRemoval(TimeUnit aStart, TimeUnit aEnd) override;
@@ -111,22 +111,22 @@ private:
   {
     return mVideoTracks.mNumTracks > 0;
   }
   bool HasAudio() const
   {
     return mAudioTracks.mNumTracks > 0;
   }
 
-  typedef Pair<nsRefPtr<MediaLargeByteBuffer>, TimeUnit> IncomingBuffer;
+  typedef Pair<nsRefPtr<MediaByteBuffer>, TimeUnit> IncomingBuffer;
   void AppendIncomingBuffer(IncomingBuffer aData);
   nsTArray<IncomingBuffer> mIncomingBuffers;
 
   // The input buffer as per http://w3c.github.io/media-source/index.html#sourcebuffer-input-buffer
-  nsRefPtr<MediaLargeByteBuffer> mInputBuffer;
+  nsRefPtr<MediaByteBuffer> mInputBuffer;
   // The current append state as per https://w3c.github.io/media-source/#sourcebuffer-append-state
   // Accessed on both the main thread and the task queue.
   Atomic<AppendState> mAppendState;
   // Buffer full flag as per https://w3c.github.io/media-source/#sourcebuffer-buffer-full-flag.
   // Accessed on both the main thread and the task queue.
   // TODO: Unused for now.
   Atomic<bool> mBufferFull;
   bool mFirstInitializationSegmentReceived;
--- a/dom/media/platforms/gonk/GonkDecoderModule.cpp
+++ b/dom/media/platforms/gonk/GonkDecoderModule.cpp
@@ -63,11 +63,12 @@ GonkDecoderModule::DecoderNeedsConversio
 bool
 GonkDecoderModule::SupportsMimeType(const nsACString& aMimeType)
 {
   return aMimeType.EqualsLiteral("audio/mp4a-latm") ||
     aMimeType.EqualsLiteral("audio/3gpp") ||
     aMimeType.EqualsLiteral("audio/amr-wb") ||
     aMimeType.EqualsLiteral("video/mp4") ||
     aMimeType.EqualsLiteral("video/mp4v-es") ||
-    aMimeType.EqualsLiteral("video/avc");
+    aMimeType.EqualsLiteral("video/avc") ||
+    aMimeType.EqualsLiteral("video/3gpp");
 }
 } // namespace mozilla
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -17,17 +17,19 @@
 #include "mozilla/dom/PCrashReporterParent.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/plugins/BrowserStreamParent.h"
 #include "mozilla/plugins/PluginAsyncSurrogate.h"
 #include "mozilla/plugins/PluginBridge.h"
 #include "mozilla/plugins/PluginInstanceParent.h"
 #include "mozilla/Preferences.h"
+#ifdef MOZ_ENABLE_PROFILER_SPS
 #include "mozilla/ProfileGatherer.h"
+#endif
 #include "mozilla/ProcessHangMonitor.h"
 #include "mozilla/Services.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/unused.h"
 #include "nsAutoPtr.h"
 #include "nsCRT.h"
 #include "nsIFile.h"
 #include "nsIObserverService.h"
@@ -54,17 +56,19 @@
 #elif XP_MACOSX
 #include "PluginInterposeOSX.h"
 #include "PluginUtilsOSX.h"
 #endif
 
 using base::KillProcess;
 
 using mozilla::PluginLibrary;
+#ifdef MOZ_ENABLE_PROFILER_SPS
 using mozilla::ProfileGatherer;
+#endif
 using mozilla::ipc::MessageChannel;
 using mozilla::ipc::GeckoChildProcessHost;
 using mozilla::dom::PCrashReporterParent;
 using mozilla::dom::CrashReporterParent;
 
 using namespace mozilla;
 using namespace mozilla::plugins;
 using namespace mozilla::plugins::parent;
@@ -3101,23 +3105,26 @@ PluginModuleChromeParent::GatherAsyncPro
 void
 PluginModuleChromeParent::GatheredAsyncProfile(nsIProfileSaveEvent* aSaveEvent)
 {
     if (aSaveEvent && !mProfile.IsEmpty()) {
         aSaveEvent->AddSubProfile(mProfile.get());
         mProfile.Truncate();
     }
 }
+#endif // MOZ_ENABLE_PROFILER_SPS
 
 bool
 PluginModuleChromeParent::RecvProfile(const nsCString& aProfile)
 {
+#ifdef MOZ_ENABLE_PROFILER_SPS
     if (NS_WARN_IF(!mGatherer)) {
         return true;
     }
 
     mProfile = aProfile;
     mGatherer->GatheredOOPProfile();
     mGatherer = nullptr;
+#endif
     return true;
 }
 
-#endif
+
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -30,17 +30,19 @@
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
 
 class nsIProfileSaveEvent;
 class nsPluginTag;
 
 namespace mozilla {
+#ifdef MOZ_ENABLE_PROFILER_SPS
 class ProfileGatherer;
+#endif
 namespace dom {
 class PCrashReporterParent;
 class CrashReporterParent;
 }
 
 namespace plugins {
 //-----------------------------------------------------------------------------
 
@@ -412,18 +414,20 @@ class PluginModuleChromeParent
 
     void CachedSettingChanged();
 
     void OnEnteredCall() override;
     void OnExitedCall() override;
     void OnEnteredSyncSend() override;
     void OnExitedSyncSend() override;
 
+#ifdef  MOZ_ENABLE_PROFILER_SPS
     void GatherAsyncProfile(mozilla::ProfileGatherer* aGatherer);
     void GatheredAsyncProfile(nsIProfileSaveEvent* aSaveEvent);
+#endif
 
     virtual bool
     RecvProfile(const nsCString& aProfile) override;
 
 private:
     virtual void
     EnteredCxxStack() override;
 
@@ -575,17 +579,19 @@ private:
 
     friend class LaunchedTask;
 
     bool                mInitOnAsyncConnect;
     nsresult            mAsyncInitRv;
     NPError             mAsyncInitError;
     dom::ContentParent* mContentParent;
     nsCOMPtr<nsIObserver> mOfflineObserver;
+#ifdef MOZ_ENABLE_PROFILER_SPS
     nsRefPtr<mozilla::ProfileGatherer> mGatherer;
+#endif
     nsCString mProfile;
     bool mIsBlocklisted;
     static bool sInstantiated;
 };
 
 } // namespace plugins
 } // namespace mozilla
 
--- a/editor/libeditor/nsHTMLCSSUtils.cpp
+++ b/editor/libeditor/nsHTMLCSSUtils.cpp
@@ -608,22 +608,29 @@ nsHTMLCSSUtils::GetDefaultLengthUnit(nsA
   nsresult rv =
     Preferences::GetString("editor.css.default_length_unit", &aLengthUnit);
   // XXX Why don't you validate the pref value?
   if (NS_FAILED(rv)) {
     aLengthUnit.AssignLiteral("px");
   }
 }
 
-// Unfortunately, CSSStyleDeclaration::GetPropertyCSSValue is not yet implemented...
-// We need then a way to determine the number part and the unit from aString, aString
-// being the result of a GetPropertyValue query...
+// Unfortunately, CSSStyleDeclaration::GetPropertyCSSValue is not yet
+// implemented... We need then a way to determine the number part and the unit
+// from aString, aString being the result of a GetPropertyValue query...
 void
-nsHTMLCSSUtils::ParseLength(const nsAString & aString, float * aValue, nsIAtom ** aUnit)
+nsHTMLCSSUtils::ParseLength(const nsAString& aString, float* aValue,
+                            nsIAtom** aUnit)
 {
+  if (aString.IsEmpty()) {
+    *aValue = 0;
+    *aUnit = NS_NewAtom(aString).take();
+    return;
+  }
+
   nsAString::const_iterator iter;
   aString.BeginReading(iter);
 
   float a = 10.0f , b = 1.0f, value = 0;
   int8_t sign = 1;
   int32_t i = 0, j = aString.Length();
   char16_t c;
   bool floatingPointFound = false;
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -1610,49 +1610,45 @@ DrawTargetCG::CopySurface(SourceSurface 
                           const IntPoint &aDestination)
 {
   if (MOZ2D_ERROR_IF(!mCg)) {
     return;
   }
 
   MarkChanged();
 
-  if (aSurface->GetType() == SurfaceType::COREGRAPHICS_IMAGE ||
-      aSurface->GetType() == SurfaceType::COREGRAPHICS_CGCONTEXT ||
-      aSurface->GetType() == SurfaceType::DATA) {
-    CGImageRef image = GetRetainedImageFromSourceSurface(aSurface);
+  CGImageRef image = GetRetainedImageFromSourceSurface(aSurface);
 
-    // XXX: it might be more efficient for us to do the copy directly if we have access to the bits
+  // XXX: it might be more efficient for us to do the copy directly if we have access to the bits
+
+  CGContextSaveGState(mCg);
+  CGContextSetCTM(mCg, mOriginalTransform);
 
-    CGContextSaveGState(mCg);
-    CGContextSetCTM(mCg, mOriginalTransform);
+  // CopySurface ignores the clip, so we need to use private API to temporarily reset it
+  CGContextResetClip(mCg);
+  CGRect destRect = CGRectMake(aDestination.x, aDestination.y,
+                               aSourceRect.width, aSourceRect.height);
+  CGContextClipToRect(mCg, destRect);
 
-    // CopySurface ignores the clip, so we need to use private API to temporarily reset it
-    CGContextResetClip(mCg);
-    CGRect destRect = CGRectMake(aDestination.x, aDestination.y,
-                                 aSourceRect.width, aSourceRect.height);
-    CGContextClipToRect(mCg, destRect);
+  CGContextSetBlendMode(mCg, kCGBlendModeCopy);
 
-    CGContextSetBlendMode(mCg, kCGBlendModeCopy);
+  CGContextScaleCTM(mCg, 1, -1);
 
-    CGContextScaleCTM(mCg, 1, -1);
-
-    CGRect flippedRect = CGRectMake(aDestination.x - aSourceRect.x, -(aDestination.y - aSourceRect.y + double(CGImageGetHeight(image))),
-                                    CGImageGetWidth(image), CGImageGetHeight(image));
+  CGRect flippedRect = CGRectMake(aDestination.x - aSourceRect.x, -(aDestination.y - aSourceRect.y + double(CGImageGetHeight(image))),
+                                  CGImageGetWidth(image), CGImageGetHeight(image));
 
-    // Quartz seems to copy A8 surfaces incorrectly if we don't initialize them
-    // to transparent first.
-    if (mFormat == SurfaceFormat::A8) {
-      CGContextClearRect(mCg, flippedRect);
-    }
-    CGContextDrawImage(mCg, flippedRect, image);
+  // Quartz seems to copy A8 surfaces incorrectly if we don't initialize them
+  // to transparent first.
+  if (mFormat == SurfaceFormat::A8) {
+    CGContextClearRect(mCg, flippedRect);
+  }
+  CGContextDrawImage(mCg, flippedRect, image);
 
-    CGContextRestoreGState(mCg);
-    CGImageRelease(image);
-  }
+  CGContextRestoreGState(mCg);
+  CGImageRelease(image);
 }
 
 void
 DrawTargetCG::DrawSurfaceWithShadow(SourceSurface *aSurface, const Point &aDest, const Color &aColor, const Point &aOffset, Float aSigma, CompositionOp aOperator)
 {
   if (MOZ2D_ERROR_IF(!mCg)) {
     return;
   }
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -1751,16 +1751,17 @@ BorrowedXlibDrawable::Init(DrawTarget* a
     return false;
   }
 
   DrawTargetCairo* cairoDT = static_cast<DrawTargetCairo*>(aDT);
   cairo_surface_t* surf = cairoDT->mSurface;
   if (cairo_surface_get_type(surf) != CAIRO_SURFACE_TYPE_XLIB) {
     return false;
   }
+  cairo_surface_flush(surf);
 
   cairoDT->WillChange();
 
   mDisplay = cairo_xlib_surface_get_display(surf);
   mDrawable = cairo_xlib_surface_get_drawable(surf);
   mScreen = cairo_xlib_surface_get_screen(surf);
   mVisual = cairo_xlib_surface_get_visual(surf);
   mXRenderFormat = cairo_xlib_surface_get_xrender_format(surf);
@@ -1769,16 +1770,19 @@ BorrowedXlibDrawable::Init(DrawTarget* a
 #else
   return false;
 #endif
 }
 
 void
 BorrowedXlibDrawable::Finish()
 {
+  DrawTargetCairo* cairoDT = static_cast<DrawTargetCairo*>(mDT);
+  cairo_surface_t* surf = cairoDT->mSurface;
+  cairo_surface_mark_dirty(surf);
   if (mDrawable) {
     mDrawable = None;
   }
 }
 #endif
 
 }
 }
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -1448,39 +1448,56 @@ DrawTargetD2D1::CreateBrushForPattern(co
     if (!pat->mSurface) {
       gfxDebug() << "No source surface specified for surface pattern";
       return CreateTransparentBlackBrush();
     }
 
     D2D1_RECT_F samplingBounds;
     Matrix mat = pat->mMatrix;
 
-    bool useSamplingRect = false;
-    if (!pat->mSamplingRect.IsEmpty() &&
-        (pat->mSurface->GetType() == SurfaceType::D2D1_1_IMAGE)) {
-      samplingBounds = D2DRect(pat->mSamplingRect);
-      mat.PreTranslate(pat->mSamplingRect.x, pat->mSamplingRect.y);
-    } else if (!pat->mSamplingRect.IsEmpty()) {
-      // We will do a partial upload of the sampling restricted area from GetImageForSurface.
-      samplingBounds = D2D1::RectF(0, 0, pat->mSamplingRect.width, pat->mSamplingRect.height);
-    } else {
-      samplingBounds = D2D1::RectF(0, 0,
-                                   Float(pat->mSurface->GetSize().width),
-                                   Float(pat->mSurface->GetSize().height));
-    }
-
     MOZ_ASSERT(pat->mSurface->IsValid());
 
-    RefPtr<ID2D1ImageBrush> imageBrush;
     RefPtr<ID2D1Image> image = GetImageForSurface(pat->mSurface, mat, pat->mExtendMode, !pat->mSamplingRect.IsEmpty() ? &pat->mSamplingRect : nullptr);
 
     if (!image) {
       return CreateTransparentBlackBrush();
     }
 
+    bool useSamplingRect = false;
+    if (pat->mSamplingRect.IsEmpty()) {
+      RefPtr<ID2D1Bitmap> bitmap;
+      image->QueryInterface((ID2D1Bitmap**)byRef(bitmap));
+      if (bitmap) {
+        RefPtr<ID2D1BitmapBrush> bitmapBrush;
+        mDC->CreateBitmapBrush(bitmap,
+                               D2D1::BitmapBrushProperties(D2DExtend(pat->mExtendMode),
+                                                           D2DExtend(pat->mExtendMode),
+                                                           D2DFilter(pat->mFilter)),
+                               D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
+                               byRef(bitmapBrush));
+        if (!bitmapBrush) {
+          gfxWarning() << "Couldn't create bitmap brush!";
+          return CreateTransparentBlackBrush();
+        }
+        return bitmapBrush.forget();
+      }
+    }
+
+    RefPtr<ID2D1ImageBrush> imageBrush;
+    if (pat->mSamplingRect.IsEmpty()) {
+      samplingBounds = D2D1::RectF(0, 0,
+                                   Float(pat->mSurface->GetSize().width),
+                                   Float(pat->mSurface->GetSize().height));
+    } else if (pat->mSurface->GetType() == SurfaceType::D2D1_1_IMAGE) {
+      samplingBounds = D2DRect(pat->mSamplingRect);
+      mat.PreTranslate(pat->mSamplingRect.x, pat->mSamplingRect.y);
+    } else {
+      // We will do a partial upload of the sampling restricted area from GetImageForSurface.
+      samplingBounds = D2D1::RectF(0, 0, pat->mSamplingRect.width, pat->mSamplingRect.height);
+    }
     mDC->CreateImageBrush(image,
                           D2D1::ImageBrushProperties(samplingBounds,
                                                      D2DExtend(pat->mExtendMode),
                                                      D2DExtend(pat->mExtendMode),
                                                      D2DInterpolationMode(pat->mFilter)),
                           D2D1::BrushProperties(aAlpha, D2DMatrix(mat)),
                           byRef(imageBrush));
 
--- a/gfx/2d/HelpersD2D.h
+++ b/gfx/2d/HelpersD2D.h
@@ -122,16 +122,17 @@ static inline IntSize ToIntSize(const D2
 {
   return IntSize(aSize.width, aSize.height);
 }
 
 static inline SurfaceFormat ToPixelFormat(const D2D1_PIXEL_FORMAT &aFormat)
 {
   switch(aFormat.format) {
   case DXGI_FORMAT_A8_UNORM:
+  case DXGI_FORMAT_R8_UNORM:
     return SurfaceFormat::A8;
   case DXGI_FORMAT_B8G8R8A8_UNORM:
     if (aFormat.alphaMode == D2D1_ALPHA_MODE_IGNORE) {
       return SurfaceFormat::B8G8R8X8;
     } else {
       return SurfaceFormat::B8G8R8A8;
     }
   default:
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -232,17 +232,17 @@ IMFYCbCrImage::GetTextureClient(Composit
 
   if (mTextureClient) {
     return mTextureClient;
   }
 
   RefPtr<ID3D11DeviceContext> ctx;
   device->GetImmediateContext(byRef(ctx));
 
-  CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_A8_UNORM,
+  CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM,
                                 mData.mYSize.width, mData.mYSize.height, 1, 1);
 
   newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
 
   RefPtr<ID3D11Texture2D> textureY;
   HRESULT hr = device->CreateTexture2D(&newDesc, nullptr, byRef(textureY));
   NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
 
--- a/gfx/layers/d3d11/CompositorD3D11.hlsl
+++ b/gfx/layers/d3d11/CompositorD3D11.hlsl
@@ -154,35 +154,35 @@ VS_MASK_3D_OUTPUT LayerQuadMask3DVS(cons
   outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
 
   return outp;
 }
 
 float4 RGBAShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   float2 maskCoords = aVertex.vMaskCoords;
-  float mask = tMask.Sample(sSampler, maskCoords).a;
+  float mask = tMask.Sample(sSampler, maskCoords).r;
   return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
 }
 
 float4 RGBAShaderMask3D(const VS_MASK_3D_OUTPUT aVertex) : SV_Target
 {
   float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
-  float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).a;
+  float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).r;
   return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
 }
 
 float4 RGBShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   float4 result;
   result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
   result.a = fLayerOpacity;
 
   float2 maskCoords = aVertex.vMaskCoords;
-  float mask = tMask.Sample(sSampler, maskCoords).a;
+  float mask = tMask.Sample(sSampler, maskCoords).r;
   return result * mask;
 }
 
 /* From Rec601:
 [R]   [1.1643835616438356,  0.0,                 1.5960267857142858]      [ Y -  16]
 [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708]    x [Cb - 128]
 [B]   [1.1643835616438356,  2.017232142857143,   8.862867620416422e-17]   [Cr - 128]
 
@@ -191,56 +191,56 @@ For [0,1] instead of [0,255], and to 5 p
 [G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196]
 [B]   [1.16438,  2.01723,  0.00000]   [Cr - 0.50196]
 */
 float4 CalculateYCbCrColor(const float2 aTexCoords)
 {
   float4 yuv;
   float4 color;
 
-  yuv.r = tCr.Sample(sSampler, aTexCoords).a - 0.50196;
-  yuv.g = tY.Sample(sSampler, aTexCoords).a  - 0.06275;
-  yuv.b = tCb.Sample(sSampler, aTexCoords).a - 0.50196;
+  yuv.r = tCr.Sample(sSampler, aTexCoords).r - 0.50196;
+  yuv.g = tY.Sample(sSampler, aTexCoords).r  - 0.06275;
+  yuv.b = tCb.Sample(sSampler, aTexCoords).r - 0.50196;
 
   color.r = yuv.g * 1.16438 + yuv.r * 1.59603;
   color.g = yuv.g * 1.16438 - 0.81297 * yuv.r - 0.39176 * yuv.b;
   color.b = yuv.g * 1.16438 + yuv.b * 2.01723;
   color.a = 1.0f;
 
   return color;
 }
 
 float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   float2 maskCoords = aVertex.vMaskCoords;
-  float mask = tMask.Sample(sSampler, maskCoords).a;
+  float mask = tMask.Sample(sSampler, maskCoords).r;
 
   return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * mask;
 }
 
 PS_OUTPUT ComponentAlphaShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   PS_OUTPUT result;
 
   result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords);
   result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc;
   result.vSrc.a = result.vAlpha.g;
 
   float2 maskCoords = aVertex.vMaskCoords;
-  float mask = tMask.Sample(sSampler, maskCoords).a;
+  float mask = tMask.Sample(sSampler, maskCoords).r;
   result.vSrc *= fLayerOpacity * mask;
   result.vAlpha *= fLayerOpacity * mask;
 
   return result;
 }
 
 float4 SolidColorShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   float2 maskCoords = aVertex.vMaskCoords;
-  float mask = tMask.Sample(sSampler, maskCoords).a;
+  float mask = tMask.Sample(sSampler, maskCoords).r;
   return fLayerColor * mask;
 }
 
 /*
  *  Un-masked versions
  *************************************************************
  */
 float4 RGBAShader(const VS_OUTPUT aVertex) : SV_Target
--- a/gfx/layers/d3d11/CompositorD3D11Shaders.h
+++ b/gfx/layers/d3d11/CompositorD3D11Shaders.h
@@ -1,11 +1,15 @@
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tvs_4_0_level_9_3 CompositorD3D11.hlsl -ELayerQuadVS
+//    -VnLayerQuadVS -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
@@ -25,27 +29,27 @@
 // Name                                 Type  Format         Dim Slot Elements
 // ------------------------------ ---------- ------- ----------- ---- --------
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// POSITION                 0   xy          0     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xy          1     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float   xyzw
+// TEXCOORD                 0   xy          1     NONE  float   xy  
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
 // c3         cb0             3         8  ( FLT, FLT, FLT, FLT)
@@ -98,20 +102,20 @@ mad r1.xyzw, cb0[6].xyzw, r0.zzzz, r1.xy
 mad o0.xyzw, cb0[7].xyzw, r0.wwww, r1.xyzw
 mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].xyxx
 ret 
 // Approximately 13 instruction slots used
 #endif
 
 const BYTE LayerQuadVS[] =
 {
-     68,  88,  66,  67, 200, 251, 
-     64, 251, 166, 240, 101, 137, 
-    191, 140,  75, 217,   9, 168, 
-     61, 163,   1,   0,   0,   0, 
+     68,  88,  66,  67,  26, 156, 
+     32, 249,  73, 220,  32,  91, 
+     64, 185, 136, 143, 133, 249, 
+    140, 206,   1,   0,   0,   0, 
     180,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     152,   1,   0,   0, 160,   3, 
       0,   0,  28,   4,   0,   0, 
      40,   6,   0,   0,  92,   6, 
       0,   0,  65, 111, 110,  57, 
      88,   1,   0,   0,  88,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -256,27 +260,27 @@ const BYTE LayerQuadVS[] =
     230, 138,  32,   0,   0,   0, 
       0,   0,   9,   0,   0,   0, 
      70, 128,  32,   0,   0,   0, 
       0,   0,   9,   0,   0,   0, 
      62,   0,   0,   1,  83,  84, 
      65,  84, 116,   0,   0,   0, 
      13,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,  12,   0, 
+      3,   0,   0,   0,   6,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,  82,  68,  69,  70, 
       4,   2,   0,   0,   1,   0, 
@@ -357,20 +361,20 @@ const BYTE LayerQuadVS[] =
       0, 171,   0,   0,   3,   0, 
       1,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      77, 105,  99, 114, 111, 115, 
     111, 102, 116,  32,  40,  82, 
      41,  32,  72,  76,  83,  76, 
      32,  83, 104,  97, 100, 101, 
     114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  54, 
-     46,  51,  46,  57,  54,  48, 
-     48,  46,  49,  54,  51,  56, 
-     52,   0, 171, 171,  73,  83, 
+    105, 108, 101, 114,  32,  57, 
+     46,  50,  57,  46,  57,  53, 
+     50,  46,  51,  49,  49,  49, 
+      0, 171, 171, 171,  73,  83, 
      71,  78,  44,   0,   0,   0, 
       1,   0,   0,   0,   8,   0, 
       0,   0,  32,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   3,   3, 
       0,   0,  80,  79,  83,  73, 
      84,  73,  79,  78,   0, 171, 
@@ -387,17 +391,21 @@ const BYTE LayerQuadVS[] =
       0,   0,   3,  12,   0,   0, 
      83,  86,  95,  80, 111, 115, 
     105, 116, 105, 111, 110,   0, 
      84,  69,  88,  67,  79,  79, 
      82,  68,   0, 171, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ESolidColorShader
+//    -VnSolidColorShader -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16
@@ -417,27 +425,27 @@ const BYTE LayerQuadVS[] =
 // Name                                 Type  Format         Dim Slot Elements
 // ------------------------------ ---------- ------- ----------- ---- --------
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float       
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float       
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             0         1  ( FLT, FLT, FLT, FLT)
 //
@@ -453,20 +461,20 @@ dcl_constantbuffer cb0[1], immediateInde
 dcl_output o0.xyzw
 mov o0.xyzw, cb0[0].xyzw
 ret 
 // Approximately 2 instruction slots used
 #endif
 
 const BYTE SolidColorShader[] =
 {
-     68,  88,  66,  67,  30, 148, 
-    104, 202, 165,  39,  58, 182, 
-    100, 205,  95, 195,  52, 137, 
-    197, 241,   1,   0,   0,   0, 
+     68,  88,  66,  67, 204,   8, 
+      5, 100,  51,  20, 107, 176, 
+    111, 165, 149, 245, 134, 187, 
+     83,  96,   1,   0,   0,   0, 
     224,   3,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     132,   0,   0,   0, 204,   0, 
       0,   0,  72,   1,   0,   0, 
      84,   3,   0,   0, 172,   3, 
       0,   0,  65, 111, 110,  57, 
      68,   0,   0,   0,  68,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -592,19 +600,19 @@ const BYTE SolidColorShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -622,17 +630,21 @@ const BYTE SolidColorShader[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ERGBShader
+//    -VnRGBShader -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -654,27 +666,27 @@ const BYTE SolidColorShader[] =
 // sSampler                          sampler      NA          NA    0        1
 // tRGB                              texture  float4          2d    0        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -708,20 +720,20 @@ sample r0.xyzw, v1.xyxx, t0.xyzw, s0
 mul o0.xyz, r0.xyzx, cb0[1].xxxx
 mov o0.w, cb0[1].x
 ret 
 // Approximately 4 instruction slots used
 #endif
 
 const BYTE RGBShader[] =
 {
-     68,  88,  66,  67, 239, 198, 
-     87, 206,  69,  92, 245,  30, 
-    125, 195, 239,  77,  37, 241, 
-    175, 187,   1,   0,   0,   0, 
+     68,  88,  66,  67,  20, 109, 
+    176, 198,  26, 112, 108, 185, 
+    246, 240, 143,  18,  57, 236, 
+    126,  68,   1,   0,   0,   0, 
     232,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     204,   0,   0,   0, 136,   1, 
       0,   0,   4,   2,   0,   0, 
      92,   4,   0,   0, 180,   4, 
       0,   0,  65, 111, 110,  57, 
     140,   0,   0,   0, 140,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -891,19 +903,19 @@ const BYTE RGBShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -921,17 +933,21 @@ const BYTE RGBShader[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ERGBAShader
+//    -VnRGBAShader -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -953,27 +969,27 @@ const BYTE RGBShader[] =
 // sSampler                          sampler      NA          NA    0        1
 // tRGB                              texture  float4          2d    0        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -1005,20 +1021,20 @@ dcl_temps 1
 sample r0.xyzw, v1.xyxx, t0.xyzw, s0
 mul o0.xyzw, r0.xyzw, cb0[1].xxxx
 ret 
 // Approximately 3 instruction slots used
 #endif
 
 const BYTE RGBAShader[] =
 {
-     68,  88,  66,  67, 230,  59, 
-     90,  23,  60,  77,  18, 113, 
-     14, 129, 183, 152, 233,  55, 
-    111,  42,   1,   0,   0,   0, 
+     68,  88,  66,  67, 214,  26, 
+    168, 112,  65, 151,  75,  99, 
+    196,  63, 136, 104, 158, 202, 
+    217,   7,   1,   0,   0,   0, 
     196,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     192,   0,   0,   0, 100,   1, 
       0,   0, 224,   1,   0,   0, 
      56,   4,   0,   0, 144,   4, 
       0,   0,  65, 111, 110,  57, 
     128,   0,   0,   0, 128,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -1182,19 +1198,19 @@ const BYTE RGBAShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -1212,17 +1228,21 @@ const BYTE RGBAShader[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -EComponentAlphaShader
+//    -VnComponentAlphaShader -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -1245,28 +1265,28 @@ const BYTE RGBAShader[] =
 // tRGB                              texture  float4          2d    0        1
 // tRGBWhite                         texture  float4          2d    1        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
-// SV_Target                1   xyzw        1   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
+// SV_Target                1   xyzw        1   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -1314,20 +1334,20 @@ mov r1.w, r0.y
 mul o1.xyzw, r0.xyzw, cb0[1].xxxx
 mul o0.xyzw, r1.xyzw, cb0[1].xxxx
 ret 
 // Approximately 8 instruction slots used
 #endif
 
 const BYTE ComponentAlphaShader[] =
 {
-     68,  88,  66,  67, 186, 162, 
-     72,  42,  69,  36, 160,  68, 
-    108, 121, 216, 238, 108,  37, 
-      6, 145,   1,   0,   0,   0, 
+     68,  88,  66,  67, 207, 238, 
+    180, 151, 111,  52, 137,   3, 
+     45, 243, 229, 223,  99, 172, 
+     89,   3,   1,   0,   0,   0, 
      68,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      64,   1,   0,   0, 160,   2, 
       0,   0,  28,   3,   0,   0, 
     160,   5,   0,   0, 248,   5, 
       0,   0,  65, 111, 110,  57, 
       0,   1,   0,   0,   0,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -1440,17 +1460,17 @@ const BYTE ComponentAlphaShader[] =
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  82,  68, 
      69,  70, 124,   2,   0,   0, 
       1,   0,   0,   0, 192,   0, 
@@ -1551,19 +1571,19 @@ const BYTE ComponentAlphaShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -1585,17 +1605,21 @@ const BYTE ComponentAlphaShader[] =
       0,   0,   3,   0,   0,   0, 
       1,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -EYCbCrShader
+//    -VnYCbCrShader -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -1619,27 +1643,27 @@ const BYTE ComponentAlphaShader[] =
 // tCb                               texture  float4          2d    1        1
 // tCr                               texture  float4          2d    2        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -1659,64 +1683,64 @@ const BYTE ComponentAlphaShader[] =
     def c1, -0.50195998, -0.0627499968, 1.59603, 0.812969983
     def c2, 1.16437995, 2.01723003, 0.391759992, 1
     dcl t0.xy
     dcl_2d s0
     dcl_2d s1
     dcl_2d s2
     texld r0, t0, s0
     texld r1, t0, s2
-    add r0.x, r1.w, c1.x
-    mul r0.xy, r0.x, c1.zwzw
-    add r0.z, r0.w, c1.y
-    mad r0.y, r0.z, c2.x, -r0.y
-    mad r1.x, r0.z, c2.x, r0.x
+    add r0.y, r1.x, c1.x
+    mul r0.yz, r0.y, c1.xzww
+    add r0.x, r0.x, c1.y
+    mad r0.z, r0.x, c2.x, -r0.z
+    mad r1.x, r0.x, c2.x, r0.y
     texld r2, t0, s1
-    add r0.x, r2.w, c1.x
-    mad r1.y, r0.x, -c2.z, r0.y
-    mul r0.x, r0.x, c2.y
-    mad r1.z, r0.z, c2.x, r0.x
+    add r0.y, r2.x, c1.x
+    mad r1.y, r0.y, -c2.z, r0.z
+    mul r0.y, r0.y, c2.y
+    mad r1.z, r0.x, c2.x, r0.y
     mov r1.w, c2.w
     mul r0, r1, c0.x
     mov oC0, r0
 
 // approximately 15 instruction slots used (3 texture, 12 arithmetic)
 ps_4_0
 dcl_constantbuffer cb0[2], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t0
 dcl_resource_texture2d (float,float,float,float) t1
 dcl_resource_texture2d (float,float,float,float) t2
 dcl_input_ps linear v1.xy
 dcl_output o0.xyzw
 dcl_temps 3
 sample r0.xyzw, v1.xyxx, t2.xyzw, s0
-add r0.x, r0.w, l(-0.501960)
+add r0.x, r0.x, l(-0.501960)
 mul r0.xy, r0.xxxx, l(1.596030, 0.812970, 0.000000, 0.000000)
 sample r1.xyzw, v1.xyxx, t0.xyzw, s0
-add r0.z, r1.w, l(-0.062750)
+add r0.z, r1.x, l(-0.062750)
 mad r0.y, r0.z, l(1.164380), -r0.y
 mad r1.x, r0.z, l(1.164380), r0.x
 sample r2.xyzw, v1.xyxx, t1.xyzw, s0
-add r0.x, r2.w, l(-0.501960)
+add r0.x, r2.x, l(-0.501960)
 mad r1.y, -r0.x, l(0.391760), r0.y
 mul r0.x, r0.x, l(2.017230)
 mad r1.z, r0.z, l(1.164380), r0.x
 mov r1.w, l(1.000000)
 mul o0.xyzw, r1.xyzw, cb0[1].xxxx
 ret 
 // Approximately 15 instruction slots used
 #endif
 
 const BYTE YCbCrShader[] =
 {
-     68,  88,  66,  67, 181, 118, 
-    100,  53, 248, 120, 136,  92, 
-     59, 190,  18, 201, 139, 224, 
-     32, 141,   1,   0,   0,   0, 
+     68,  88,  66,  67,  54,  63, 
+    153,   7,  84, 231,  22,  28, 
+    117, 160,  57,  24, 123, 163, 
+     52, 109,   1,   0,   0,   0, 
     212,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     220,   1,   0,   0,  44,   4, 
       0,   0, 168,   4,   0,   0, 
      72,   7,   0,   0, 160,   7, 
       0,   0,  65, 111, 110,  57, 
     156,   1,   0,   0, 156,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -1746,45 +1770,45 @@ const BYTE YCbCrShader[] =
      15, 160,  31,   0,   0,   2, 
       0,   0,   0, 144,   2,   8, 
      15, 160,  66,   0,   0,   3, 
       0,   0,  15, 128,   0,   0, 
     228, 176,   0,   8, 228, 160, 
      66,   0,   0,   3,   1,   0, 
      15, 128,   0,   0, 228, 176, 
       2,   8, 228, 160,   2,   0, 
-      0,   3,   0,   0,   1, 128, 
-      1,   0, 255, 128,   1,   0, 
+      0,   3,   0,   0,   2, 128, 
+      1,   0,   0, 128,   1,   0, 
       0, 160,   5,   0,   0,   3, 
-      0,   0,   3, 128,   0,   0, 
-      0, 128,   1,   0, 238, 160, 
+      0,   0,   6, 128,   0,   0, 
+     85, 128,   1,   0, 248, 160, 
       2,   0,   0,   3,   0,   0, 
-      4, 128,   0,   0, 255, 128, 
+      1, 128,   0,   0,   0, 128, 
       1,   0,  85, 160,   4,   0, 
-      0,   4,   0,   0,   2, 128, 
-      0,   0, 170, 128,   2,   0, 
-      0, 160,   0,   0,  85, 129, 
+      0,   4,   0,   0,   4, 128, 
+      0,   0,   0, 128,   2,   0, 
+      0, 160,   0,   0, 170, 129, 
       4,   0,   0,   4,   1,   0, 
-      1, 128,   0,   0, 170, 128, 
+      1, 128,   0,   0,   0, 128, 
       2,   0,   0, 160,   0,   0, 
-      0, 128,  66,   0,   0,   3, 
+     85, 128,  66,   0,   0,   3, 
       2,   0,  15, 128,   0,   0, 
     228, 176,   1,   8, 228, 160, 
       2,   0,   0,   3,   0,   0, 
-      1, 128,   2,   0, 255, 128, 
+      2, 128,   2,   0,   0, 128, 
       1,   0,   0, 160,   4,   0, 
       0,   4,   1,   0,   2, 128, 
-      0,   0,   0, 128,   2,   0, 
-    170, 161,   0,   0,  85, 128, 
+      0,   0,  85, 128,   2,   0, 
+    170, 161,   0,   0, 170, 128, 
       5,   0,   0,   3,   0,   0, 
-      1, 128,   0,   0,   0, 128, 
+      2, 128,   0,   0,  85, 128, 
       2,   0,  85, 160,   4,   0, 
       0,   4,   1,   0,   4, 128, 
-      0,   0, 170, 128,   2,   0, 
-      0, 160,   0,   0,   0, 128, 
+      0,   0,   0, 128,   2,   0, 
+      0, 160,   0,   0,  85, 128, 
       1,   0,   0,   2,   1,   0, 
       8, 128,   2,   0, 255, 160, 
       5,   0,   0,   3,   0,   0, 
      15, 128,   1,   0, 228, 128, 
       0,   0,   0, 160,   1,   0, 
       0,   2,   0,   8,  15, 128, 
       0,   0, 228, 128, 255, 255, 
       0,   0,  83,  72,  68,  82, 
@@ -1811,34 +1835,34 @@ const BYTE YCbCrShader[] =
      69,   0,   0,   9, 242,   0, 
      16,   0,   0,   0,   0,   0, 
      70,  16,  16,   0,   1,   0, 
       0,   0,  70, 126,  16,   0, 
       2,   0,   0,   0,   0,  96, 
      16,   0,   0,   0,   0,   0, 
       0,   0,   0,   7,  18,   0, 
      16,   0,   0,   0,   0,   0, 
-     58,   0,  16,   0,   0,   0, 
+     10,   0,  16,   0,   0,   0, 
       0,   0,   1,  64,   0,   0, 
     115, 128,   0, 191,  56,   0, 
       0,  10,  50,   0,  16,   0, 
       0,   0,   0,   0,   6,   0, 
      16,   0,   0,   0,   0,   0, 
       2,  64,   0,   0, 182,  74, 
     204,  63, 205,  30,  80,  63, 
       0,   0,   0,   0,   0,   0, 
       0,   0,  69,   0,   0,   9, 
     242,   0,  16,   0,   1,   0, 
       0,   0,  70,  16,  16,   0, 
       1,   0,   0,   0,  70, 126, 
      16,   0,   0,   0,   0,   0, 
       0,  96,  16,   0,   0,   0, 
       0,   0,   0,   0,   0,   7, 
      66,   0,  16,   0,   0,   0, 
-      0,   0,  58,   0,  16,   0, 
+      0,   0,  10,   0,  16,   0, 
       1,   0,   0,   0,   1,  64, 
       0,   0,  18, 131, 128, 189, 
      50,   0,   0,  10,  34,   0, 
      16,   0,   0,   0,   0,   0, 
      42,   0,  16,   0,   0,   0, 
       0,   0,   1,  64,   0,   0, 
     103,  10, 149,  63,  26,   0, 
      16, 128,  65,   0,   0,   0, 
@@ -1851,17 +1875,17 @@ const BYTE YCbCrShader[] =
       0,   0,   0,   0,  69,   0, 
       0,   9, 242,   0,  16,   0, 
       2,   0,   0,   0,  70,  16, 
      16,   0,   1,   0,   0,   0, 
      70, 126,  16,   0,   1,   0, 
       0,   0,   0,  96,  16,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   7,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58,   0, 
+      0,   0,   0,   0,  10,   0, 
      16,   0,   2,   0,   0,   0, 
       1,  64,   0,   0, 115, 128, 
       0, 191,  50,   0,   0,  10, 
      34,   0,  16,   0,   1,   0, 
       0,   0,  10,   0,  16, 128, 
      65,   0,   0,   0,   0,   0, 
       0,   0,   1,  64,   0,   0, 
     196, 148, 200,  62,  26,   0, 
@@ -1885,17 +1909,17 @@ const BYTE YCbCrShader[] =
      70,  14,  16,   0,   1,   0, 
       0,   0,   6, 128,  32,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,  62,   0,   0,   1, 
      83,  84,  65,  84, 116,   0, 
       0,   0,  15,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,   2,   0,   0,   0, 
-     10,   0,   0,   0,   0,   0, 
+      6,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2011,19 +2035,19 @@ const BYTE YCbCrShader[] =
      97, 100,   0, 118,  77,  97, 
     115, 107,  81, 117,  97, 100, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0, 171, 171,  73,  83, 
      71,  78,  80,   0,   0,   0, 
       2,   0,   0,   0,   8,   0, 
       0,   0,  56,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  68,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2040,17 +2064,21 @@ const BYTE YCbCrShader[] =
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tvs_4_0_level_9_3 CompositorD3D11.hlsl -ELayerQuadMaskVS
+//    -VnLayerQuadMaskVS -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
@@ -2070,28 +2098,28 @@ const BYTE YCbCrShader[] =
 // Name                                 Type  Format         Dim Slot Elements
 // ------------------------------ ---------- ------- ----------- ---- --------
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// POSITION                 0   xy          0     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float   xyzw
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1     zw        1     NONE  float     zw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
 // c3         cb0             3         9  ( FLT, FLT, FLT, FLT)
@@ -2153,20 +2181,20 @@ mad r1.xyzw, cb0[6].xyzw, r0.zzzz, r1.xy
 mad o0.xyzw, cb0[7].xyzw, r0.wwww, r1.xyzw
 mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].xyxx
 ret 
 // Approximately 16 instruction slots used
 #endif
 
 const BYTE LayerQuadMaskVS[] =
 {
-     68,  88,  66,  67, 223, 251, 
-     10,  17,  13,  90,  47,  25, 
-    119, 198,  20, 157, 124, 193, 
-    251, 234,   1,   0,   0,   0, 
+     68,  88,  66,  67,  15, 196, 
+    252, 199, 211, 188,  92,  26, 
+     46, 113, 249,  29, 135, 110, 
+     83, 119,   1,   0,   0,   0, 
     120,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     224,   1,   0,   0,  76,   4, 
       0,   0, 200,   4,   0,   0, 
     212,   6,   0,   0,   8,   7, 
       0,   0,  65, 111, 110,  57, 
     160,   1,   0,   0, 160,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -2340,17 +2368,17 @@ const BYTE LayerQuadMaskVS[] =
      32,   0,   0,   0,   0,   0, 
       9,   0,   0,   0,  70, 128, 
      32,   0,   0,   0,   0,   0, 
       9,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  16,   0, 
       0,   0,   2,   0,   0,   0, 
       0,   0,   0,   0,   4,   0, 
-      0,   0,  14,   0,   0,   0, 
+      0,   0,   8,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2441,19 +2469,19 @@ const BYTE LayerQuadMaskVS[] =
       0,   0,   3,   0,   1,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  77, 105, 
      99, 114, 111, 115, 111, 102, 
     116,  32,  40,  82,  41,  32, 
      72,  76,  83,  76,  32,  83, 
     104,  97, 100, 101, 114,  32, 
      67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
+    101, 114,  32,  57,  46,  50, 
+     57,  46,  57,  53,  50,  46, 
+     51,  49,  49,  49,   0, 171, 
     171, 171,  73,  83,  71,  78, 
      44,   0,   0,   0,   1,   0, 
       0,   0,   8,   0,   0,   0, 
      32,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,   3,   3,   0,   0, 
      80,  79,  83,  73,  84,  73, 
@@ -2475,17 +2503,21 @@ const BYTE LayerQuadMaskVS[] =
      12,   3,   0,   0,  83,  86, 
      95,  80, 111, 115, 105, 116, 
     105, 111, 110,   0,  84,  69, 
      88,  67,  79,  79,  82,  68, 
       0, 171, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tvs_4_0_level_9_3 CompositorD3D11.hlsl -ELayerQuadMask3DVS
+//    -VnLayerQuadMask3DVS -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
@@ -2505,28 +2537,28 @@ const BYTE LayerQuadMaskVS[] =
 // Name                                 Type  Format         Dim Slot Elements
 // ------------------------------ ---------- ------- ----------- ---- --------
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// POSITION                 0   xy          0     NONE  float   xy  
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1   xyz         2     NONE   float   xyz 
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float   xyzw
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1   xyz         2     NONE  float   xyz 
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
 // c3         cb0             3         9  ( FLT, FLT, FLT, FLT)
@@ -2592,20 +2624,20 @@ mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].
 mov r0.z, l(1.000000)
 mul o2.xyz, r0.wwww, r0.xyzx
 ret 
 // Approximately 17 instruction slots used
 #endif
 
 const BYTE LayerQuadMask3DVS[] =
 {
-     68,  88,  66,  67, 151, 141, 
-     11,  11, 111, 244,  17, 242, 
-    119, 116, 248,  53, 235, 192, 
-     38, 193,   1,   0,   0,   0, 
+     68,  88,  66,  67, 100,  40, 
+     55,  29, 238,  71, 107,  78, 
+    214, 182,  73, 149, 138,  22, 
+    163, 187,   1,   0,   0,   0, 
     204,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      24,   2,   0,   0, 160,   4, 
       0,   0,  28,   5,   0,   0, 
      40,   7,   0,   0,  92,   7, 
       0,   0,  65, 111, 110,  57, 
     216,   1,   0,   0, 216,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -2793,27 +2825,27 @@ const BYTE LayerQuadMask3DVS[] =
      16,   0,   2,   0,   0,   0, 
     246,  15,  16,   0,   0,   0, 
       0,   0,  70,   2,  16,   0, 
       0,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  17,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   4,   0, 
-      0,   0,  15,   0,   0,   0, 
+      0,   0,   9,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      82,  68,  69,  70,   4,   2, 
       0,   0,   1,   0,   0,   0, 
@@ -2894,19 +2926,19 @@ const BYTE LayerQuadMask3DVS[] =
       0,   0,   3,   0,   1,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  77, 105, 
      99, 114, 111, 115, 111, 102, 
     116,  32,  40,  82,  41,  32, 
      72,  76,  83,  76,  32,  83, 
     104,  97, 100, 101, 114,  32, 
      67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
+    101, 114,  32,  57,  46,  50, 
+     57,  46,  57,  53,  50,  46, 
+     51,  49,  49,  49,   0, 171, 
     171, 171,  73,  83,  71,  78, 
      44,   0,   0,   0,   1,   0, 
       0,   0,   8,   0,   0,   0, 
      32,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,   3,   3,   0,   0, 
      80,  79,  83,  73,  84,  73, 
@@ -2928,17 +2960,21 @@ const BYTE LayerQuadMask3DVS[] =
       7,   8,   0,   0,  83,  86, 
      95,  80, 111, 115, 105, 116, 
     105, 111, 110,   0,  84,  69, 
      88,  67,  79,  79,  82,  68, 
       0, 171, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ESolidColorShaderMask
+//    -VnSolidColorShaderMask -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16
@@ -2960,28 +2996,28 @@ const BYTE LayerQuadMask3DVS[] =
 // sSampler                          sampler      NA          NA    0        1
 // tMask                             texture  float4          2d    3        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float       
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float       
+// TEXCOORD                 1     zw        1     NONE  float     zw
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             0         1  ( FLT, FLT, FLT, FLT)
 //
@@ -2995,39 +3031,39 @@ const BYTE LayerQuadMask3DVS[] =
 //
 // Level9 shader bytecode:
 //
     ps_2_x
     dcl t0
     dcl_2d s0
     mov r0.xy, t0.wzzw
     texld r0, r0, s0
-    mul r0, r0.w, c0
+    mul r0, r0.x, c0
     mov oC0, r0
 
 // approximately 4 instruction slots used (1 texture, 3 arithmetic)
 ps_4_0
 dcl_constantbuffer cb0[1], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t3
 dcl_input_ps linear v1.zw
 dcl_output o0.xyzw
 dcl_temps 1
 sample r0.xyzw, v1.zwzz, t3.xyzw, s0
-mul o0.xyzw, r0.wwww, cb0[0].xyzw
+mul o0.xyzw, r0.xxxx, cb0[0].xyzw
 ret 
 // Approximately 3 instruction slots used
 #endif
 
 const BYTE SolidColorShaderMask[] =
 {
-     68,  88,  66,  67, 236, 109, 
-     19, 151,  23, 187, 157, 205, 
-    112, 188,  91, 187, 108, 106, 
-    138,  14,   1,   0,   0,   0, 
+     68,  88,  66,  67, 218,  73, 
+     87,  32, 206,  67,  79,  54, 
+     31, 104, 228, 152, 133, 115, 
+    245,   3,   1,   0,   0,   0, 
     232,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     204,   0,   0,   0, 112,   1, 
       0,   0, 236,   1,   0,   0, 
      68,   4,   0,   0, 180,   4, 
       0,   0,  65, 111, 110,  57, 
     140,   0,   0,   0, 140,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -3044,17 +3080,17 @@ const BYTE SolidColorShaderMask[] =
      31,   0,   0,   2,   0,   0, 
       0, 144,   0,   8,  15, 160, 
       1,   0,   0,   2,   0,   0, 
       3, 128,   0,   0, 235, 176, 
      66,   0,   0,   3,   0,   0, 
      15, 128,   0,   0, 228, 128, 
       0,   8, 228, 160,   5,   0, 
       0,   3,   0,   0,  15, 128, 
-      0,   0, 255, 128,   0,   0, 
+      0,   0,   0, 128,   0,   0, 
     228, 160,   1,   0,   0,   2, 
       0,   8,  15, 128,   0,   0, 
     228, 128, 255, 255,   0,   0, 
      83,  72,  68,  82, 156,   0, 
       0,   0,  64,   0,   0,   0, 
      39,   0,   0,   0,  89,   0, 
       0,   4,  70, 142,  32,   0, 
       0,   0,   0,   0,   1,   0, 
@@ -3071,17 +3107,17 @@ const BYTE SolidColorShaderMask[] =
       0,   0,  69,   0,   0,   9, 
     242,   0,  16,   0,   0,   0, 
       0,   0, 230,  26,  16,   0, 
       1,   0,   0,   0,  70, 126, 
      16,   0,   3,   0,   0,   0, 
       0,  96,  16,   0,   0,   0, 
       0,   0,  56,   0,   0,   8, 
     242,  32,  16,   0,   0,   0, 
-      0,   0, 246,  15,  16,   0, 
+      0,   0,   6,   0,  16,   0, 
       0,   0,   0,   0,  70, 142, 
      32,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,   3,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   2,   0, 
       0,   0,   1,   0,   0,   0, 
@@ -3193,19 +3229,19 @@ const BYTE SolidColorShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3227,17 +3263,21 @@ const BYTE SolidColorShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ERGBShaderMask
+//    -VnRGBShaderMask -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -3260,28 +3300,28 @@ const BYTE SolidColorShaderMask[] =
 // tRGB                              texture  float4          2d    0        1
 // tMask                             texture  float4          2d    3        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1     zw        1     NONE  float     zw
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -3300,44 +3340,44 @@ const BYTE SolidColorShaderMask[] =
     dcl t0
     dcl_2d s0
     dcl_2d s1
     mov r0.xy, t0.wzzw
     texld r1, t0, s1
     texld r0, r0, s0
     mul r1.xyz, r1, c0.x
     mov r1.w, c0.x
-    mul r0, r0.w, r1
+    mul r0, r0.x, r1
     mov oC0, r0
 
 // approximately 7 instruction slots used (2 texture, 5 arithmetic)
 ps_4_0
 dcl_constantbuffer cb0[2], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t0
 dcl_resource_texture2d (float,float,float,float) t3
 dcl_input_ps linear v1.xy
 dcl_input_ps linear v1.zw
 dcl_output o0.xyzw
 dcl_temps 2
 sample r0.xyzw, v1.xyxx, t0.xyzw, s0
 mul r0.xyz, r0.xyzx, cb0[1].xxxx
 sample r1.xyzw, v1.zwzz, t3.xyzw, s0
 mov r0.w, cb0[1].x
-mul o0.xyzw, r0.xyzw, r1.wwww
+mul o0.xyzw, r0.xyzw, r1.xxxx
 ret 
 // Approximately 6 instruction slots used
 #endif
 
 const BYTE RGBShaderMask[] =
 {
-     68,  88,  66,  67,  30,  30, 
-     87,  58, 114, 156, 251, 151, 
-     29,  94,  34, 100, 228, 250, 
-     37, 251,   1,   0,   0,   0, 
+     68,  88,  66,  67,  77,  94, 
+    252, 215, 133,  78, 101, 216, 
+    220,   8,  70, 254,  89, 142, 
+    130, 135,   1,   0,   0,   0, 
     192,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
       8,   1,   0,   0,  32,   2, 
       0,   0, 156,   2,   0,   0, 
      28,   5,   0,   0, 140,   5, 
       0,   0,  65, 111, 110,  57, 
     200,   0,   0,   0, 200,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -3364,17 +3404,17 @@ const BYTE RGBShaderMask[] =
       0,   0,  15, 128,   0,   0, 
     228, 128,   0,   8, 228, 160, 
       5,   0,   0,   3,   1,   0, 
       7, 128,   1,   0, 228, 128, 
       0,   0,   0, 160,   1,   0, 
       0,   2,   1,   0,   8, 128, 
       0,   0,   0, 160,   5,   0, 
       0,   3,   0,   0,  15, 128, 
-      0,   0, 255, 128,   1,   0, 
+      0,   0,   0, 128,   1,   0, 
     228, 128,   1,   0,   0,   2, 
       0,   8,  15, 128,   0,   0, 
     228, 128, 255, 255,   0,   0, 
      83,  72,  68,  82,  16,   1, 
       0,   0,  64,   0,   0,   0, 
      68,   0,   0,   0,  89,   0, 
       0,   4,  70, 142,  32,   0, 
       0,   0,   0,   0,   2,   0, 
@@ -3412,17 +3452,17 @@ const BYTE RGBShaderMask[] =
       0,  96,  16,   0,   0,   0, 
       0,   0,  54,   0,   0,   6, 
     130,   0,  16,   0,   0,   0, 
       0,   0,  10, 128,  32,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,  56,   0,   0,   7, 
     242,  32,  16,   0,   0,   0, 
       0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0, 246,  15, 
+      0,   0,   0,   0,   6,   0, 
      16,   0,   1,   0,   0,   0, 
      62,   0,   0,   1,  83,  84, 
      65,  84, 116,   0,   0,   0, 
       6,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
@@ -3539,19 +3579,19 @@ const BYTE RGBShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3573,17 +3613,21 @@ const BYTE RGBShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ERGBAShaderMask
+//    -VnRGBAShaderMask -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -3606,28 +3650,28 @@ const BYTE RGBShaderMask[] =
 // tRGB                              texture  float4          2d    0        1
 // tMask                             texture  float4          2d    3        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1     zw        1     NONE  float     zw
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -3645,43 +3689,43 @@ const BYTE RGBShaderMask[] =
     ps_2_x
     dcl t0
     dcl_2d s0
     dcl_2d s1
     mov r0.xy, t0.wzzw
     texld r1, t0, s1
     texld r0, r0, s0
     mul r1, r1, c0.x
-    mul r0, r0.w, r1
+    mul r0, r0.x, r1
     mov oC0, r0
 
 // approximately 6 instruction slots used (2 texture, 4 arithmetic)
 ps_4_0
 dcl_constantbuffer cb0[2], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t0
 dcl_resource_texture2d (float,float,float,float) t3
 dcl_input_ps linear v1.xy
 dcl_input_ps linear v1.zw
 dcl_output o0.xyzw
 dcl_temps 2
 sample r0.xyzw, v1.xyxx, t0.xyzw, s0
 mul r0.xyzw, r0.xyzw, cb0[1].xxxx
 sample r1.xyzw, v1.zwzz, t3.xyzw, s0
-mul o0.xyzw, r0.xyzw, r1.wwww
+mul o0.xyzw, r0.xyzw, r1.xxxx
 ret 
 // Approximately 5 instruction slots used
 #endif
 
 const BYTE RGBAShaderMask[] =
 {
-     68,  88,  66,  67, 188,  13, 
-    191, 168, 231, 201,  42, 209, 
-     88, 243,  29,  35, 226,  31, 
-    145,  20,   1,   0,   0,   0, 
+     68,  88,  66,  67, 138,  69, 
+     81, 181, 217,  15, 199,  10, 
+    146, 208, 232, 248,  24,  27, 
+    141,  26,   1,   0,   0,   0, 
     156,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     252,   0,   0,   0, 252,   1, 
       0,   0, 120,   2,   0,   0, 
     248,   4,   0,   0, 104,   5, 
       0,   0,  65, 111, 110,  57, 
     188,   0,   0,   0, 188,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -3706,17 +3750,17 @@ const BYTE RGBAShaderMask[] =
       0,   0, 228, 176,   1,   8, 
     228, 160,  66,   0,   0,   3, 
       0,   0,  15, 128,   0,   0, 
     228, 128,   0,   8, 228, 160, 
       5,   0,   0,   3,   1,   0, 
      15, 128,   1,   0, 228, 128, 
       0,   0,   0, 160,   5,   0, 
       0,   3,   0,   0,  15, 128, 
-      0,   0, 255, 128,   1,   0, 
+      0,   0,   0, 128,   1,   0, 
     228, 128,   1,   0,   0,   2, 
       0,   8,  15, 128,   0,   0, 
     228, 128, 255, 255,   0,   0, 
      83,  72,  68,  82, 248,   0, 
       0,   0,  64,   0,   0,   0, 
      62,   0,   0,   0,  89,   0, 
       0,   4,  70, 142,  32,   0, 
       0,   0,   0,   0,   2,   0, 
@@ -3750,17 +3794,17 @@ const BYTE RGBAShaderMask[] =
     242,   0,  16,   0,   1,   0, 
       0,   0, 230,  26,  16,   0, 
       1,   0,   0,   0,  70, 126, 
      16,   0,   3,   0,   0,   0, 
       0,  96,  16,   0,   0,   0, 
       0,   0,  56,   0,   0,   7, 
     242,  32,  16,   0,   0,   0, 
       0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0, 246,  15, 
+      0,   0,   0,   0,   6,   0, 
      16,   0,   1,   0,   0,   0, 
      62,   0,   0,   1,  83,  84, 
      65,  84, 116,   0,   0,   0, 
       5,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
@@ -3877,19 +3921,19 @@ const BYTE RGBAShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3911,17 +3955,21 @@ const BYTE RGBAShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -ERGBAShaderMask3D
+//    -VnRGBAShaderMask3D -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -3945,28 +3993,28 @@ const BYTE RGBAShaderMask[] =
 // tRGB                              texture  float4          2d    0        1
 // tMask                             texture  float4          2d    3        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1   xyz         2     NONE   float   xyz 
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1   xyz         2     NONE  float   xyz 
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -3986,17 +4034,17 @@ const BYTE RGBAShaderMask[] =
     dcl t1.xyz
     dcl_2d s0
     dcl_2d s1
     rcp r0.w, t1.z
     mul r0.xy, r0.w, t1
     texld r1, t0, s0
     texld r0, r0, s1
     mul r1, r1, c0.x
-    mul r0, r0.w, r1
+    mul r0, r0.x, r1
     mov oC0, r0
 
 // approximately 7 instruction slots used (2 texture, 5 arithmetic)
 ps_4_0
 dcl_constantbuffer cb0[2], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_sampler s1, mode_default
 dcl_resource_texture2d (float,float,float,float) t0
@@ -4004,27 +4052,27 @@ dcl_resource_texture2d (float,float,floa
 dcl_input_ps linear v1.xy
 dcl_input_ps linear v2.xyz
 dcl_output o0.xyzw
 dcl_temps 2
 div r0.xy, v2.xyxx, v2.zzzz
 sample r0.xyzw, r0.xyxx, t3.xyzw, s1
 sample r1.xyzw, v1.xyxx, t0.xyzw, s0
 mul r1.xyzw, r1.xyzw, cb0[1].xxxx
-mul o0.xyzw, r0.wwww, r1.xyzw
+mul o0.xyzw, r0.xxxx, r1.xyzw
 ret 
 // Approximately 6 instruction slots used
 #endif
 
 const BYTE RGBAShaderMask3D[] =
 {
-     68,  88,  66,  67, 113, 141, 
-     78,  23, 128, 223, 235,  10, 
-      0,  97,  49, 111,  47,  53, 
-    229,  55,   1,   0,   0,   0, 
+     68,  88,  66,  67,   4, 135, 
+     55,   9, 144, 137,  25,  77, 
+     92, 150, 209,   2,  32, 225, 
+     75, 182,   1,   0,   0,   0, 
      24,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      24,   1,   0,   0,  64,   2, 
       0,   0, 188,   2,   0,   0, 
     116,   5,   0,   0, 228,   5, 
       0,   0,  65, 111, 110,  57, 
     216,   0,   0,   0, 216,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -4054,17 +4102,17 @@ const BYTE RGBAShaderMask3D[] =
     228, 176,   0,   8, 228, 160, 
      66,   0,   0,   3,   0,   0, 
      15, 128,   0,   0, 228, 128, 
       1,   8, 228, 160,   5,   0, 
       0,   3,   1,   0,  15, 128, 
       1,   0, 228, 128,   0,   0, 
       0, 160,   5,   0,   0,   3, 
       0,   0,  15, 128,   0,   0, 
-    255, 128,   1,   0, 228, 128, 
+      0, 128,   1,   0, 228, 128, 
       1,   0,   0,   2,   0,   8, 
      15, 128,   0,   0, 228, 128, 
     255, 255,   0,   0,  83,  72, 
      68,  82,  32,   1,   0,   0, 
      64,   0,   0,   0,  72,   0, 
       0,   0,  89,   0,   0,   4, 
      70, 142,  32,   0,   0,   0, 
       0,   0,   2,   0,   0,   0, 
@@ -4103,17 +4151,17 @@ const BYTE RGBAShaderMask3D[] =
       0,  96,  16,   0,   0,   0, 
       0,   0,  56,   0,   0,   8, 
     242,   0,  16,   0,   1,   0, 
       0,   0,  70,  14,  16,   0, 
       1,   0,   0,   0,   6, 128, 
      32,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,  56,   0, 
       0,   7, 242,  32,  16,   0, 
-      0,   0,   0,   0, 246,  15, 
+      0,   0,   0,   0,   6,   0, 
      16,   0,   0,   0,   0,   0, 
      70,  14,  16,   0,   1,   0, 
       0,   0,  62,   0,   0,   1, 
      83,  84,  65,  84, 116,   0, 
       0,   0,   6,   0,   0,   0, 
       2,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
@@ -4241,19 +4289,19 @@ const BYTE RGBAShaderMask3D[] =
      97, 100,   0, 118,  77,  97, 
     115, 107,  81, 117,  97, 100, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0, 171, 171,  73,  83, 
      71,  78, 104,   0,   0,   0, 
       3,   0,   0,   0,   8,   0, 
       0,   0,  80,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  92,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4274,17 +4322,21 @@ const BYTE RGBAShaderMask3D[] =
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl -EYCbCrShaderMask
+//    -VnYCbCrShaderMask -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -4309,28 +4361,28 @@ const BYTE RGBAShaderMask3D[] =
 // tCr                               texture  float4          2d    2        1
 // tMask                             texture  float4          2d    3        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1     zw        1     NONE  float     zw
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -4352,71 +4404,71 @@ const BYTE RGBAShaderMask3D[] =
     def c2, 1.16437995, 2.01723003, 0.391759992, 1
     dcl t0
     dcl_2d s0
     dcl_2d s1
     dcl_2d s2
     dcl_2d s3
     texld r0, t0, s1
     texld r1, t0, s3
-    add r0.x, r1.w, c1.x
-    mul r0.xy, r0.x, c1.zwzw
-    add r0.z, r0.w, c1.y
-    mad r0.y, r0.z, c2.x, -r0.y
-    mad r1.x, r0.z, c2.x, r0.x
+    add r0.y, r1.x, c1.x
+    mul r0.yz, r0.y, c1.xzww
+    add r0.x, r0.x, c1.y
+    mad r0.z, r0.x, c2.x, -r0.z
+    mad r1.x, r0.x, c2.x, r0.y
     mov r2.xy, t0.wzzw
     texld r3, t0, s2
     texld r2, r2, s0
-    add r0.x, r3.w, c1.x
-    mad r1.y, r0.x, -c2.z, r0.y
-    mul r0.x, r0.x, c2.y
-    mad r1.z, r0.z, c2.x, r0.x
+    add r0.y, r3.x, c1.x
+    mad r1.y, r0.y, -c2.z, r0.z
+    mul r0.y, r0.y, c2.y
+    mad r1.z, r0.x, c2.x, r0.y
     mov r1.w, c2.w
     mul r0, r1, c0.x
-    mul r0, r2.w, r0
+    mul r0, r2.x, r0
     mov oC0, r0
 
 // approximately 18 instruction slots used (4 texture, 14 arithmetic)
 ps_4_0
 dcl_constantbuffer cb0[2], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t0
 dcl_resource_texture2d (float,float,float,float) t1
 dcl_resource_texture2d (float,float,float,float) t2
 dcl_resource_texture2d (float,float,float,float) t3
 dcl_input_ps linear v1.xy
 dcl_input_ps linear v1.zw
 dcl_output o0.xyzw
 dcl_temps 3
 sample r0.xyzw, v1.xyxx, t2.xyzw, s0
-add r0.x, r0.w, l(-0.501960)
+add r0.x, r0.x, l(-0.501960)
 mul r0.xy, r0.xxxx, l(1.596030, 0.812970, 0.000000, 0.000000)
 sample r1.xyzw, v1.xyxx, t0.xyzw, s0
-add r0.z, r1.w, l(-0.062750)
+add r0.z, r1.x, l(-0.062750)
 mad r0.y, r0.z, l(1.164380), -r0.y
 mad r1.x, r0.z, l(1.164380), r0.x
 sample r2.xyzw, v1.xyxx, t1.xyzw, s0
-add r0.x, r2.w, l(-0.501960)
+add r0.x, r2.x, l(-0.501960)
 mad r1.y, -r0.x, l(0.391760), r0.y
 mul r0.x, r0.x, l(2.017230)
 mad r1.z, r0.z, l(1.164380), r0.x
 mov r1.w, l(1.000000)
 mul r0.xyzw, r1.xyzw, cb0[1].xxxx
 sample r1.xyzw, v1.zwzz, t3.xyzw, s0
-mul o0.xyzw, r0.xyzw, r1.wwww
+mul o0.xyzw, r0.xyzw, r1.xxxx
 ret 
 // Approximately 17 instruction slots used
 #endif
 
 const BYTE YCbCrShaderMask[] =
 {
-     68,  88,  66,  67, 103, 162, 
-    223, 236, 236, 142, 143, 151, 
-     73, 154, 187, 112,  81, 114, 
-    229, 251,   1,   0,   0,   0, 
+     68,  88,  66,  67,  74,  33, 
+    155, 235,  22, 178,  84, 169, 
+    113,  91, 240,  98, 157, 143, 
+    221,  19,   1,   0,   0,   0, 
     168,   8,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      24,   2,   0,   0, 196,   4, 
       0,   0,  64,   5,   0,   0, 
       4,   8,   0,   0, 116,   8, 
       0,   0,  65, 111, 110,  57, 
     216,   1,   0,   0, 216,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -4449,56 +4501,56 @@ const BYTE YCbCrShaderMask[] =
      31,   0,   0,   2,   0,   0, 
       0, 144,   3,   8,  15, 160, 
      66,   0,   0,   3,   0,   0, 
      15, 128,   0,   0, 228, 176, 
       1,   8, 228, 160,  66,   0, 
       0,   3,   1,   0,  15, 128, 
       0,   0, 228, 176,   3,   8, 
     228, 160,   2,   0,   0,   3, 
-      0,   0,   1, 128,   1,   0, 
-    255, 128,   1,   0,   0, 160, 
+      0,   0,   2, 128,   1,   0, 
+      0, 128,   1,   0,   0, 160, 
       5,   0,   0,   3,   0,   0, 
-      3, 128,   0,   0,   0, 128, 
-      1,   0, 238, 160,   2,   0, 
-      0,   3,   0,   0,   4, 128, 
-      0,   0, 255, 128,   1,   0, 
+      6, 128,   0,   0,  85, 128, 
+      1,   0, 248, 160,   2,   0, 
+      0,   3,   0,   0,   1, 128, 
+      0,   0,   0, 128,   1,   0, 
      85, 160,   4,   0,   0,   4, 
-      0,   0,   2, 128,   0,   0, 
-    170, 128,   2,   0,   0, 160, 
-      0,   0,  85, 129,   4,   0, 
+      0,   0,   4, 128,   0,   0, 
+      0, 128,   2,   0,   0, 160, 
+      0,   0, 170, 129,   4,   0, 
       0,   4,   1,   0,   1, 128, 
-      0,   0, 170, 128,   2,   0, 
-      0, 160,   0,   0,   0, 128, 
+      0,   0,   0, 128,   2,   0, 
+      0, 160,   0,   0,  85, 128, 
       1,   0,   0,   2,   2,   0, 
       3, 128,   0,   0, 235, 176, 
      66,   0,   0,   3,   3,   0, 
      15, 128,   0,   0, 228, 176, 
       2,   8, 228, 160,  66,   0, 
       0,   3,   2,   0,  15, 128, 
       2,   0, 228, 128,   0,   8, 
     228, 160,   2,   0,   0,   3, 
-      0,   0,   1, 128,   3,   0, 
-    255, 128,   1,   0,   0, 160, 
+      0,   0,   2, 128,   3,   0, 
+      0, 128,   1,   0,   0, 160, 
       4,   0,   0,   4,   1,   0, 
-      2, 128,   0,   0,   0, 128, 
+      2, 128,   0,   0,  85, 128, 
       2,   0, 170, 161,   0,   0, 
-     85, 128,   5,   0,   0,   3, 
-      0,   0,   1, 128,   0,   0, 
-      0, 128,   2,   0,  85, 160, 
+    170, 128,   5,   0,   0,   3, 
+      0,   0,   2, 128,   0,   0, 
+     85, 128,   2,   0,  85, 160, 
       4,   0,   0,   4,   1,   0, 
-      4, 128,   0,   0, 170, 128, 
+      4, 128,   0,   0,   0, 128, 
       2,   0,   0, 160,   0,   0, 
-      0, 128,   1,   0,   0,   2, 
+     85, 128,   1,   0,   0,   2, 
       1,   0,   8, 128,   2,   0, 
     255, 160,   5,   0,   0,   3, 
       0,   0,  15, 128,   1,   0, 
     228, 128,   0,   0,   0, 160, 
       5,   0,   0,   3,   0,   0, 
-     15, 128,   2,   0, 255, 128, 
+     15, 128,   2,   0,   0, 128, 
       0,   0, 228, 128,   1,   0, 
       0,   2,   0,   8,  15, 128, 
       0,   0, 228, 128, 255, 255, 
       0,   0,  83,  72,  68,  82, 
     164,   2,   0,   0,  64,   0, 
       0,   0, 169,   0,   0,   0, 
      89,   0,   0,   4,  70, 142, 
      32,   0,   0,   0,   0,   0, 
@@ -4525,17 +4577,17 @@ const BYTE YCbCrShaderMask[] =
       3,   0,   0,   0,  69,   0, 
       0,   9, 242,   0,  16,   0, 
       0,   0,   0,   0,  70,  16, 
      16,   0,   1,   0,   0,   0, 
      70, 126,  16,   0,   2,   0, 
       0,   0,   0,  96,  16,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   7,  18,   0,  16,   0, 
-      0,   0,   0,   0,  58,   0, 
+      0,   0,   0,   0,  10,   0, 
      16,   0,   0,   0,   0,   0, 
       1,  64,   0,   0, 115, 128, 
       0, 191,  56,   0,   0,  10, 
      50,   0,  16,   0,   0,   0, 
       0,   0,   6,   0,  16,   0, 
       0,   0,   0,   0,   2,  64, 
       0,   0, 182,  74, 204,  63, 
     205,  30,  80,  63,   0,   0, 
@@ -4543,17 +4595,17 @@ const BYTE YCbCrShaderMask[] =
      69,   0,   0,   9, 242,   0, 
      16,   0,   1,   0,   0,   0, 
      70,  16,  16,   0,   1,   0, 
       0,   0,  70, 126,  16,   0, 
       0,   0,   0,   0,   0,  96, 
      16,   0,   0,   0,   0,   0, 
       0,   0,   0,   7,  66,   0, 
      16,   0,   0,   0,   0,   0, 
-     58,   0,  16,   0,   1,   0, 
+     10,   0,  16,   0,   1,   0, 
       0,   0,   1,  64,   0,   0, 
      18, 131, 128, 189,  50,   0, 
       0,  10,  34,   0,  16,   0, 
       0,   0,   0,   0,  42,   0, 
      16,   0,   0,   0,   0,   0, 
       1,  64,   0,   0, 103,  10, 
     149,  63,  26,   0,  16, 128, 
      65,   0,   0,   0,   0,   0, 
@@ -4566,17 +4618,17 @@ const BYTE YCbCrShaderMask[] =
       0,   0,  69,   0,   0,   9, 
     242,   0,  16,   0,   2,   0, 
       0,   0,  70,  16,  16,   0, 
       1,   0,   0,   0,  70, 126, 
      16,   0,   1,   0,   0,   0, 
       0,  96,  16,   0,   0,   0, 
       0,   0,   0,   0,   0,   7, 
      18,   0,  16,   0,   0,   0, 
-      0,   0,  58,   0,  16,   0, 
+      0,   0,  10,   0,  16,   0, 
       2,   0,   0,   0,   1,  64, 
       0,   0, 115, 128,   0, 191, 
      50,   0,   0,  10,  34,   0, 
      16,   0,   1,   0,   0,   0, 
      10,   0,  16, 128,  65,   0, 
       0,   0,   0,   0,   0,   0, 
       1,  64,   0,   0, 196, 148, 
     200,  62,  26,   0,  16,   0, 
@@ -4604,23 +4656,23 @@ const BYTE YCbCrShaderMask[] =
      16,   0,   1,   0,   0,   0, 
     230,  26,  16,   0,   1,   0, 
       0,   0,  70, 126,  16,   0, 
       3,   0,   0,   0,   0,  96, 
      16,   0,   0,   0,   0,   0, 
      56,   0,   0,   7, 242,  32, 
      16,   0,   0,   0,   0,   0, 
      70,  14,  16,   0,   0,   0, 
-      0,   0, 246,  15,  16,   0, 
+      0,   0,   6,   0,  16,   0, 
       1,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  17,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   3,   0, 
-      0,   0,  11,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       4,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4742,19 +4794,19 @@ const BYTE YCbCrShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  54,  46,  51,  46, 
-     57,  54,  48,  48,  46,  49, 
-     54,  51,  56,  52,   0, 171, 
+    114,  32,  57,  46,  50,  57, 
+     46,  57,  53,  50,  46,  51, 
+     49,  49,  49,   0, 171, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4776,17 +4828,22 @@ const BYTE YCbCrShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11.hlsl
+//    -EComponentAlphaShaderMask -VnComponentAlphaShaderMask
+//    -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -4810,29 +4867,29 @@ const BYTE YCbCrShaderMask[] =
 // tRGBWhite                         texture  float4          2d    1        1
 // tMask                             texture  float4          2d    3        1
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1     zw        1     NONE  float     zw
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
-// SV_Target                1   xyzw        1   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
+// SV_Target                1   xyzw        1   TARGET  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
 //
@@ -4851,17 +4908,17 @@ const BYTE YCbCrShaderMask[] =
     ps_2_x
     def c1, 1, 0, 0, 0
     dcl t0
     dcl_2d s0
     dcl_2d s1
     dcl_2d s2
     mov r0.xy, t0.wzzw
     texld r0, r0, s0
-    mul r0.x, r0.w, c0.x
+    mul r0.x, r0.x, c0.x
     texld r1, t0, s1
     texld r2, t0, s2
     add r2, r1, -r2
     add r2, r2, c1.x
     mov r1.w, r2.y
     mul r2, r0.x, r2
     mul r0, r0.x, r1
     mov oC0, r0
@@ -4880,29 +4937,29 @@ dcl_output o0.xyzw
 dcl_output o1.xyzw
 dcl_temps 3
 sample r0.xyzw, v1.xyxx, t1.xyzw, s0
 sample r1.xyzw, v1.xyxx, t0.xyzw, s0
 add r0.xyzw, -r0.xyzw, r1.xyzw
 add r0.xyzw, r0.xyzw, l(1.000000, 1.000000, 1.000000, 1.000000)
 mov r1.w, r0.y
 sample r2.xyzw, v1.zwzz, t3.xyzw, s0
-mul r2.x, r2.w, cb0[1].x
+mul r2.x, r2.x, cb0[1].x
 mul o0.xyzw, r1.xyzw, r2.xxxx
 mul o1.xyzw, r0.xyzw, r2.xxxx
 ret 
 // Approximately 10 instruction slots used
 #endif
 
 const BYTE ComponentAlphaShaderMask[] =
 {
-     68,  88,  66,  67, 245,  71, 
-    211, 223, 156, 101, 223, 204, 
-    145, 138,  53,  12,  16, 220, 
-    106,  83,   1,   0,   0,   0, 
+     68,  88,  66,  67, 214,  67, 
+    206,  69,  12, 117, 144,  46, 
+    127, 133, 145, 240,  56, 186, 
+    119, 195,   1,   0,   0,   0, 
      20,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     124,   1,   0,   0,  52,   3, 
       0,   0, 176,   3,   0,   0, 
      88,   6,   0,   0, 200,   6, 
       0,   0,  65, 111, 110,  57, 
      60,   1,   0,   0,  60,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -4928,17 +4985,17 @@ const BYTE ComponentAlphaShaderMask[] =
      15, 160,  31,   0,   0,   2, 
       0,   0,   0, 144,   2,   8, 
      15, 160,   1,   0,   0,   2, 
       0,   0,   3, 128,   0,   0, 
     235, 176,  66,   0,   0,   3, 
       0,   0,  15, 128,   0,   0, 
     228, 128,   0,   8, 228, 160, 
       5,   0,   0,   3,   0,   0, 
-      1, 128,   0,   0, 255, 128, 
+      1, 128,   0,   0,   0, 128, 
       0,   0,   0, 160,  66,   0, 
       0,   3,   1,   0,  15, 128, 
       0,   0, 228, 176,   1,   8, 
     228, 160,  66,   0,   0,   3, 
       2,   0,  15, 128,   0,   0, 
     228, 176,   2,   8, 228, 160, 
       2,   0,   0,   3,   2,   0, 
      15, 128,   1,   0, 228, 128, 
@@ -5012,17 +5069,17 @@ const BYTE ComponentAlphaShaderMask[] =
       0,   0,  69,   0,   0,   9, 
     242,   0,  16,   0,   2,   0, 
       0,   0, 230,  26,  16,   0, 
       1,   0,   0,   0,  70, 126, 
      16,   0,   3,   0,   0,   0, 
       0,  96,  16,   0,   0,   0, 
       0,   0,  56,   0,   0,   8, 
      18,   0,  16,   0,   2,   0, 
-      0,   0,  58,   0,  16,   0, 
+      0,   0,  10,   0,  16,   0, 
       2,   0,   0,   0,  10, 128, 
      32,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,  56,   0, 
       0,   7, 242,  32,  16,   0, 
       0,   0,   0,   0,  70,  14, 
      16,   0,   1,   0,   0,   0, 
       6,   0,  16,   0,   2,   0, 
       0,   0,  56,   0,   0,   7, 
@@ -5039,17 +5096,17 @@ const BYTE ComponentAlphaShaderMask[] =
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,  82,  68,  69,  70, 
     160,   2,   0,   0,   1,   0, 
@@ -5157,19 +5214,19 @@ const BYTE ComponentAlphaShaderMask[] =
      97, 100,   0, 118,  77,  97, 
     115, 107,  81, 117,  97, 100, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171,  73,  83, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0, 171, 171,  73,  83, 
      71,  78, 104,   0,   0,   0, 
       3,   0,   0,   0,   8,   0, 
       0,   0,  80,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  92,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
--- a/gfx/layers/d3d11/CompositorD3D11ShadersVR.h
+++ b/gfx/layers/d3d11/CompositorD3D11ShadersVR.h
@@ -1,11 +1,15 @@
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tvs_4_0_level_9_3 CompositorD3D11VR.hlsl
+//    -EOculusVRDistortionVS -VnOculusVRDistortionVS -FhtmpShaderHeader
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 VREyeToSource;              // Offset:    0 Size:    16
@@ -19,34 +23,34 @@
 // Name                                 Type  Format         Dim Slot Elements
 // ------------------------------ ---------- ------- ----------- ---- --------
 // $Globals                          cbuffer      NA          NA    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1   xy          2     NONE   float   xy  
-// TEXCOORD                 2   xy          3     NONE   float   xy  
-// COLOR                    0   xyzw        4     NONE   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// POSITION                 0   xy          0     NONE  float   xy  
+// TEXCOORD                 0   xy          1     NONE  float   xy  
+// TEXCOORD                 1   xy          2     NONE  float   xy  
+// TEXCOORD                 2   xy          3     NONE  float   xy  
+// COLOR                    0   xyzw        4     NONE  float   xyzw
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xyz         1     NONE   float   xyz 
-// TEXCOORD                 1   xyz         2     NONE   float   xyz 
-// TEXCOORD                 2   xyz         3     NONE   float   xyz 
-// COLOR                    0   xyzw        4     NONE   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float   xyzw
+// TEXCOORD                 0   xyz         1     NONE  float   xyz 
+// TEXCOORD                 1   xyz         2     NONE  float   xyz 
+// TEXCOORD                 2   xyz         3     NONE  float   xyz 
+// COLOR                    0   xyzw        4     NONE  float   xyzw
 //
 //
 // Constant buffer to DX9 shader constant mappings:
 //
 // Target Reg Buffer  Start Reg # of Regs        Data Conversion
 // ---------- ------- --------- --------- ----------------------
 // c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
 //
@@ -101,20 +105,20 @@ mad o3.xy, v3.xyxx, cb0[0].zwzz, cb0[0].
 mov o3.z, l(1.000000)
 mov o4.xyzw, v4.xyzw
 ret 
 // Approximately 10 instruction slots used
 #endif
 
 const BYTE OculusVRDistortionVS[] =
 {
-     68,  88,  66,  67,   3,  61, 
-    196, 122,  10,  53,  44, 234, 
-     18, 242, 195, 238,  42,  90, 
-     72, 193,   1,   0,   0,   0, 
+     68,  88,  66,  67, 206, 154, 
+    203,  64, 121,  47, 121, 169, 
+    222, 206, 108, 175, 167, 227, 
+    154,  37,   1,   0,   0,   0, 
     244,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     108,   1,   0,   0,  44,   3, 
       0,   0, 168,   3,   0,   0, 
     176,   4,   0,   0,  80,   5, 
       0,   0,  65, 111, 110,  57, 
      44,   1,   0,   0,  44,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -240,17 +244,17 @@ const BYTE OculusVRDistortionVS[] =
     128,  63,  54,   0,   0,   5, 
     242,  32,  16,   0,   4,   0, 
       0,   0,  70,  30,  16,   0, 
       4,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  10,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  10,   0, 
-      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -298,19 +302,19 @@ const BYTE OculusVRDistortionVS[] =
      99,  97, 108, 101,  65, 110, 
     100,  79, 102, 102, 115, 101, 
     116,   0,  77, 105,  99, 114, 
     111, 115, 111, 102, 116,  32, 
      40,  82,  41,  32,  72,  76, 
      83,  76,  32,  83, 104,  97, 
     100, 101, 114,  32,  67, 111, 
     109, 112, 105, 108, 101, 114, 
-     32,  54,  46,  51,  46,  57, 
-     54,  48,  48,  46,  49,  54, 
-     51,  56,  52,   0, 171, 171, 
+     32,  57,  46,  50,  57,  46, 
+     57,  53,  50,  46,  51,  49, 
+     49,  49,   0, 171, 171, 171, 
      73,  83,  71,  78, 152,   0, 
       0,   0,   5,   0,   0,   0, 
       8,   0,   0,   0, 128,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   3,   0,   0, 137,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -358,44 +362,48 @@ const BYTE OculusVRDistortionVS[] =
       0,   0,  83,  86,  95,  80, 
     111, 115, 105, 116, 105, 111, 
     110,   0,  84,  69,  88,  67, 
      79,  79,  82,  68,   0,  67, 
      79,  76,  79,  82,   0, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111
+//
+//
+//   fxc -nologo -Tps_4_0_level_9_3 CompositorD3D11VR.hlsl
+//    -EOculusVRDistortionPS -VnOculusVRDistortionPS -FhtmpShaderHeader
 //
 //
 // Resource Bindings:
 //
 // Name                                 Type  Format         Dim Slot Elements
 // ------------------------------ ---------- ------- ----------- ---- --------
 // Linear                            sampler      NA          NA    0        1
 // Texture                           texture  float4          2d    0        1
 //
 //
 //
 // Input signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xyz         1     NONE   float   xy  
-// TEXCOORD                 1   xyz         2     NONE   float   xy  
-// TEXCOORD                 2   xyz         3     NONE   float   xy  
-// COLOR                    0   xyzw        4     NONE   float   x   
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Position              0   xyzw        0      POS  float       
+// TEXCOORD                 0   xyz         1     NONE  float   xy  
+// TEXCOORD                 1   xyz         2     NONE  float   xy  
+// TEXCOORD                 2   xyz         3     NONE  float   xy  
+// COLOR                    0   xyzw        4     NONE  float   x   
 //
 //
 // Output signature:
 //
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
+// Name                 Index   Mask Register SysValue Format   Used
+// -------------------- ----- ------ -------- -------- ------ ------
+// SV_Target                0   xyzw        0   TARGET  float   xyzw
 //
 //
 // Sampler/Resource to DX9 shader sampler mappings:
 //
 // Target Sampler Source Sampler  Source Resource
 // -------------- --------------- ----------------
 // s0             s0              t0               
 //
@@ -436,25 +444,25 @@ sample r0.xyzw, v3.xyxx, t0.xyzw, s0
 mul o0.z, r0.z, v4.x
 mov o0.w, l(1.000000)
 ret 
 // Approximately 8 instruction slots used
 #endif
 
 const BYTE OculusVRDistortionPS[] =
 {
-     68,  88,  66,  67, 108, 219, 
-     61, 216,  27,   0,  27, 222, 
-    242, 132, 183,  21, 166, 141, 
-    130,  39,   1,   0,   0,   0, 
-    128,   4,   0,   0,   6,   0, 
+     68,  88,  66,  67,  48, 161, 
+    127, 216, 149, 107,  53,  57, 
+    164,  84,  84, 154,  58, 227, 
+    125,  61,   1,   0,   0,   0, 
+    124,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      60,   1,   0,   0, 132,   2, 
       0,   0,   0,   3,   0,   0, 
-    168,   3,   0,   0,  76,   4, 
+    164,   3,   0,   0,  72,   4, 
       0,   0,  65, 111, 110,  57, 
     252,   0,   0,   0, 252,   0, 
       0,   0,   0,   2, 255, 255, 
     212,   0,   0,   0,  40,   0, 
       0,   0,   0,   0,  40,   0, 
       0,   0,  40,   0,   0,   0, 
      40,   0,   1,   0,  36,   0, 
       0,   0,  40,   0,   0,   0, 
@@ -564,17 +572,17 @@ const BYTE OculusVRDistortionPS[] =
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70, 160,   0, 
+     82,  68,  69,  70, 156,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   2,   0, 
       0,   0,  28,   0,   0,   0, 
       0,   4, 255, 255,   0,   1, 
       0,   0, 107,   0,   0,   0, 
      92,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -589,48 +597,48 @@ const BYTE OculusVRDistortionPS[] =
     110, 101,  97, 114,   0,  84, 
     101, 120, 116, 117, 114, 101, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     54,  46,  51,  46,  57,  54, 
-     48,  48,  46,  49,  54,  51, 
-     56,  52,   0, 171, 171, 171, 
-     73,  83,  71,  78, 156,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 128,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0, 140,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      7,   3,   0,   0, 140,   0, 
+     57,  46,  50,  57,  46,  57, 
+     53,  50,  46,  51,  49,  49, 
+     49,   0,  73,  83,  71,  78, 
+    156,   0,   0,   0,   5,   0, 
+      0,   0,   8,   0,   0,   0, 
+    128,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   3,   0,   0, 140,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   3,   0,   0,   0, 
-      7,   3,   0,   0, 149,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   4,   0,   0,   0, 
-     15,   1,   0,   0,  83,  86, 
-     95,  80, 111, 115, 105, 116, 
-    105, 111, 110,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0,  67,  79,  76,  79,  82, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  97, 114, 
-    103, 101, 116,   0, 171, 171
+    140,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   7,   3,   0,   0, 
+    140,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   7,   3,   0,   0, 
+    140,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   3,   0, 
+      0,   0,   7,   3,   0,   0, 
+    149,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0,  15,   1,   0,   0, 
+     83,  86,  95,  80, 111, 115, 
+    105, 116, 105, 111, 110,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0,  67,  79,  76, 
+     79,  82,   0, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171
 };
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -29,17 +29,17 @@ SurfaceFormatToDXGIFormat(gfx::SurfaceFo
       return DXGI_FORMAT_B8G8R8A8_UNORM;
     case SurfaceFormat::B8G8R8X8:
       return DXGI_FORMAT_B8G8R8A8_UNORM;
     case SurfaceFormat::R8G8B8A8:
       return DXGI_FORMAT_R8G8B8A8_UNORM;
     case SurfaceFormat::R8G8B8X8:
       return DXGI_FORMAT_R8G8B8A8_UNORM;
     case SurfaceFormat::A8:
-      return DXGI_FORMAT_A8_UNORM;
+      return DXGI_FORMAT_R8_UNORM;
     default:
       MOZ_ASSERT(false, "unsupported format");
       return DXGI_FORMAT_UNKNOWN;
   }
 }
 
 static uint32_t
 GetRequiredTilesD3D11(uint32_t aSize, uint32_t aMaxSize)
@@ -446,17 +446,17 @@ TextureClientD3D11::AllocateForSurface(g
     // Currently TextureClientD3D11 does not support A8 surfaces. Fallback.
     return false;
   }
 
   ID3D11Device* d3d11device = gfxWindowsPlatform::GetPlatform()->GetD3D11ContentDevice();
 
   if (gfxPrefs::Direct2DUse1_1() && d3d11device) {
 
-    CD3D11_TEXTURE2D_DESC newDesc(mFormat == SurfaceFormat::A8 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM,
+    CD3D11_TEXTURE2D_DESC newDesc(mFormat == SurfaceFormat::A8 ? DXGI_FORMAT_R8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM,
                                   aSize.width, aSize.height, 1, 1,
                                   D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
 
     newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
 
     hr = d3d11device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture));
     if (FAILED(hr)) {
       gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr);
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1825,33 +1825,17 @@ bool DoesD3D11TextureSharingWork(ID3D11D
   checked = true;
 
   result = DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_B8G8R8A8_UNORM, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE);
   return result;
 }
 
 bool DoesD3D11AlphaTextureSharingWork(ID3D11Device *device)
 {
-  nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
-  if (gfxInfo) {
-    // A8 texture sharing crashes on this intel driver version (and no others)
-    // so just avoid using it in that case.
-    nsString adapterVendor;
-    nsString driverVersion;
-    gfxInfo->GetAdapterVendorID(adapterVendor);
-    gfxInfo->GetAdapterDriverVersion(driverVersion);
-
-    nsAString &intelVendorID = (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorIntel);
-    if (adapterVendor.Equals(intelVendorID, nsCaseInsensitiveStringComparator()) &&
-        driverVersion.Equals(NS_LITERAL_STRING("8.15.10.2086"))) {
-      return false;
-    }
-  }
-
-  return DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_A8_UNORM, D3D11_BIND_SHADER_RESOURCE);
+  return DoesD3D11TextureSharingWorkInternal(device, DXGI_FORMAT_R8_UNORM, D3D11_BIND_SHADER_RESOURCE);
 }
 
 void
 gfxWindowsPlatform::InitD3D11Devices()
 {
   // This function attempts to initialize our D3D11 devices. If the hardware
   // is not blacklisted for D3D11 layers. This will first attempt to create a
   // hardware accelerated device. If this creation fails or the hardware is
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -4,17 +4,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_HeapAPI_h
 #define js_HeapAPI_h
 
 #include <limits.h>
 
-#include "js/TracingAPI.h"
+#include "jspubtd.h"
+
+#include "js/TraceKind.h"
 #include "js/Utility.h"
 
 /* These values are private to the JS engine. */
 namespace js {
 
 // Whether the current thread is permitted access to any part of the specified
 // runtime or zone.
 JS_FRIEND_API(bool)
@@ -160,16 +162,17 @@ class JS_FRIEND_API(GCCellPtr)
     // Automatically construct a null GCCellPtr from nullptr.
     MOZ_IMPLICIT GCCellPtr(decltype(nullptr)) : ptr(checkedCast(nullptr, JS::TraceKind::Null)) {}
 
     // Construction from an explicit type.
     explicit GCCellPtr(JSObject* obj) : ptr(checkedCast(obj, JS::TraceKind::Object)) { }
     explicit GCCellPtr(JSFunction* fun) : ptr(checkedCast(fun, JS::TraceKind::Object)) { }
     explicit GCCellPtr(JSString* str) : ptr(checkedCast(str, JS::TraceKind::String)) { }
     explicit GCCellPtr(JSFlatString* str) : ptr(checkedCast(str, JS::TraceKind::String)) { }
+    explicit GCCellPtr(JS::Symbol* sym) : ptr(checkedCast(sym, JS::TraceKind::Symbol)) { }
     explicit GCCellPtr(JSScript* script) : ptr(checkedCast(script, JS::TraceKind::Script)) { }
     explicit GCCellPtr(const Value& v);
 
     JS::TraceKind kind() const {
         JS::TraceKind traceKind = JS::TraceKind(ptr & OutOfLineTraceKindMask);
         if (uintptr_t(traceKind) != OutOfLineTraceKindMask)
             return traceKind;
         return outOfLineKind();
new file mode 100644
--- /dev/null
+++ b/js/public/TraceKind.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef js_TraceKind_h
+#define js_TraceKind_h
+
+namespace JS {
+
+// When tracing a thing, the GC needs to know about the layout of the object it
+// is looking at. There are a fixed number of different layouts that the GC
+// knows about. The "trace kind" is a static map which tells which layout a GC
+// thing has.
+//
+// Although this map is public, the details are completely hidden. Not all of
+// the matching C++ types are exposed, and those that are, are opaque.
+//
+// See Value::gcKind() and JSTraceCallback in Tracer.h for more details.
+enum class TraceKind
+{
+    // These trace kinds have a publicly exposed, although opaque, C++ type.
+    // Note: The order here is determined by our Value packing. Other users
+    //       should sort alphabetically, for consistency.
+    Object = 0x00,
+    String = 0x01,
+    Symbol = 0x02,
+    Script = 0x03,
+
+    // Shape details are exposed through JS_TraceShapeCycleCollectorChildren.
+    Shape = 0x04,
+
+    // ObjectGroup details are exposed through JS_TraceObjectGroupCycleCollectorChildren.
+    ObjectGroup = 0x05,
+
+    // The kind associated with a nullptr.
+    Null = 0x06,
+
+    // The following kinds do not have an exposed C++ idiom.
+    BaseShape = 0x0F,
+    JitCode = 0x1F,
+    LazyScript = 0x2F
+};
+const static uintptr_t OutOfLineTraceKindMask = 0x07;
+static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set");
+static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set");
+static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set");
+
+} // namespace JS
+
+#endif // js_TraceKind_h
--- a/js/public/TracingAPI.h
+++ b/js/public/TracingAPI.h
@@ -3,87 +3,42 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_TracingAPI_h
 #define js_TracingAPI_h
 
 #include "jsalloc.h"
-#include "jspubtd.h"
 
 #include "js/HashTable.h"
+#include "js/HeapAPI.h"
+#include "js/TraceKind.h"
 
 class JS_PUBLIC_API(JSTracer);
 
 namespace JS {
 class JS_PUBLIC_API(CallbackTracer);
 template <typename T> class Heap;
 template <typename T> class TenuredHeap;
 
-// When tracing a thing, the GC needs to know about the layout of the object it
-// is looking at. There are a fixed number of different layouts that the GC
-// knows about. The "trace kind" is a static map which tells which layout a GC
-// thing has.
-//
-// Although this map is public, the details are completely hidden. Not all of
-// the matching C++ types are exposed, and those that are, are opaque.
-//
-// See Value::gcKind() and JSTraceCallback in Tracer.h for more details.
-enum class TraceKind
-{
-    // These trace kinds have a publicly exposed, although opaque, C++ type.
-    // Note: The order here is determined by our Value packing. Other users
-    //       should sort alphabetically, for consistency.
-    Object = 0x00,
-    String = 0x01,
-    Symbol = 0x02,
-    Script = 0x03,
-
-    // Shape details are exposed through JS_TraceShapeCycleCollectorChildren.
-    Shape = 0x04,
-
-    // ObjectGroup details are exposed through JS_TraceObjectGroupCycleCollectorChildren.
-    ObjectGroup = 0x05,
-
-    // The kind associated with a nullptr.
-    Null = 0x06,
-
-    // The following kinds do not have an exposed C++ idiom.
-    BaseShape = 0x0F,
-    JitCode = 0x1F,
-    LazyScript = 0x2F
-};
-const static uintptr_t OutOfLineTraceKindMask = 0x07;
-static_assert(uintptr_t(JS::TraceKind::BaseShape) & OutOfLineTraceKindMask, "mask bits are set");
-static_assert(uintptr_t(JS::TraceKind::JitCode) & OutOfLineTraceKindMask, "mask bits are set");
-static_assert(uintptr_t(JS::TraceKind::LazyScript) & OutOfLineTraceKindMask, "mask bits are set");
-
 // Returns a static string equivalent of |kind|.
 JS_FRIEND_API(const char*)
 GCTraceKindToAscii(JS::TraceKind kind);
 
 } // namespace JS
 
-// Tracer callback, called for each traceable thing directly referenced by a
-// particular object or runtime structure. It is the callback responsibility
-// to ensure the traversal of the full object graph via calling eventually
-// JS_TraceChildren on the passed thing. In this case the callback must be
-// prepared to deal with cycles in the traversal graph.
-//
-// kind argument is one of JS::TraceKind::Object, JS::TraceKind::String or a
-// tag denoting internal implementation-specific traversal kind. In the latter
-// case the only operations on thing that the callback can do is to call
-// JS_TraceChildren or JS_GetTraceThingInfo.
-//
-// If eagerlyTraceWeakMaps is true, when we trace a WeakMap visit all
-// of its mappings. This should be used in cases where the tracer
-// wants to use the existing liveness of entries.
-typedef void
-(* JSTraceCallback)(JS::CallbackTracer* trc, void** thingp, JS::TraceKind kind);
+namespace js {
+class BaseShape;
+class LazyScript;
+class ObjectGroup;
+namespace jit {
+class JitCode;
+} // namespace jit
+} // namespace js
 
 enum WeakMapTraceKind {
     DoNotTraceWeakMaps = 0,
     TraceWeakMapValues = 1,
     TraceWeakMapKeysValues = 2
 };
 
 class JS_PUBLIC_API(JSTracer)
@@ -127,18 +82,44 @@ class AutoTracingCallback;
 class JS_PUBLIC_API(CallbackTracer) : public JSTracer
 {
   public:
     CallbackTracer(JSRuntime* rt, WeakMapTraceKind weakTraceKind = TraceWeakMapValues)
       : JSTracer(rt, JSTracer::TracerKindTag::Callback, weakTraceKind),
         contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr)
     {}
 
-    // Override this method to receive notification when an edge is visited.
-    virtual void trace(void** thing, JS::TraceKind kind) = 0;
+    // Override these methods to receive notification when an edge is visited
+    // with the type contained in the callback. The default implementation
+    // dispatches to the fully-generic onChild implementation, so for cases that
+    // do not care about boxing overhead and do not need the actual edges,
+    // just override the generic onChild.
+    virtual void onObjectEdge(JSObject** objp) { onChild(JS::GCCellPtr(*objp)); }
+    virtual void onStringEdge(JSString** strp) { onChild(JS::GCCellPtr(*strp)); }
+    virtual void onSymbolEdge(JS::Symbol** symp) { onChild(JS::GCCellPtr(*symp)); }
+    virtual void onScriptEdge(JSScript** scriptp) { onChild(JS::GCCellPtr(*scriptp)); }
+    virtual void onShapeEdge(js::Shape** shapep) {
+        onChild(JS::GCCellPtr(*shapep, JS::TraceKind::Shape));
+    }
+    virtual void onObjectGroupEdge(js::ObjectGroup** groupp) {
+        onChild(JS::GCCellPtr(*groupp, JS::TraceKind::ObjectGroup));
+    }
+    virtual void onBaseShapeEdge(js::BaseShape** basep) {
+        onChild(JS::GCCellPtr(*basep, JS::TraceKind::BaseShape));
+    }
+    virtual void onJitCodeEdge(js::jit::JitCode** codep) {
+        onChild(JS::GCCellPtr(*codep, JS::TraceKind::JitCode));
+    }
+    virtual void onLazyScriptEdge(js::LazyScript** lazyp) {
+        onChild(JS::GCCellPtr(*lazyp, JS::TraceKind::LazyScript));
+    }
+
+    // Override this method to receive notification when a node in the GC
+    // heap graph is visited.
+    virtual void onChild(const JS::GCCellPtr& thing) = 0;
 
     // Access to the tracing context:
     // When tracing with a JS::CallbackTracer, we invoke the callback with the
     // edge location and the type of target. This is useful for operating on
     // the edge in the abstract or on the target thing, satisfying most common
     // use cases.  However, some tracers need additional detail about the
     // specific edge that is being traced in order to be useful. Unfortunately,
     // the raw pointer to the edge that we provide is not enough information to
@@ -180,16 +161,31 @@ class JS_PUBLIC_API(CallbackTracer) : pu
         virtual void operator()(CallbackTracer* trc, char* buf, size_t bufsize) = 0;
     };
 
 #ifdef DEBUG
     enum class TracerKind { DoNotCare, Moving, GrayBuffering, VerifyTraceProtoAndIface };
     virtual TracerKind getTracerKind() const { return TracerKind::DoNotCare; }
 #endif
 
+    // In C++, overriding a method hides all methods in the base class with
+    // that name, not just methods with that signature. Thus, the typed edge
+    // methods have to have distinct names to allow us to override them
+    // individually, which is freqently useful if, for example, we only want to
+    // process only one type of edge.
+    void dispatchToOnEdge(JSObject** objp) { onObjectEdge(objp); }
+    void dispatchToOnEdge(JSString** strp) { onStringEdge(strp); }
+    void dispatchToOnEdge(JS::Symbol** symp) { onSymbolEdge(symp); }
+    void dispatchToOnEdge(JSScript** scriptp) { onScriptEdge(scriptp); }
+    void dispatchToOnEdge(js::Shape** shapep) { onShapeEdge(shapep); }
+    void dispatchToOnEdge(js::ObjectGroup** groupp) { onObjectGroupEdge(groupp); }
+    void dispatchToOnEdge(js::BaseShape** basep) { onBaseShapeEdge(basep); }
+    void dispatchToOnEdge(js::jit::JitCode** codep) { onJitCodeEdge(codep); }
+    void dispatchToOnEdge(js::LazyScript** lazyp) { onLazyScriptEdge(lazyp); }
+
   private:
     friend class AutoTracingName;
     const char* contextName_;
 
     friend class AutoTracingIndex;
     size_t contextIndex_;
 
     friend class AutoTracingDetails;
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -326,17 +326,17 @@ class Node {
         return *this;
     }
 
     // Constructors accepting SpiderMonkey's other generic-pointer-ish types.
     // Note that we *do* want an implicit constructor here: JS::Value and
     // JS::ubi::Node are both essentially tagged references to other sorts of
     // objects, so letting conversions happen automatically is appropriate.
     MOZ_IMPLICIT Node(JS::HandleValue value);
-    Node(JS::TraceKind kind, void* ptr);
+    explicit Node(const JS::GCCellPtr& thing);
 
     // copy construction and copy assignment just use memcpy, since we know
     // instances contain nothing but a vtable pointer and a data pointer.
     //
     // To be completely correct, concrete classes could provide a virtual
     // 'construct' member function, which we could invoke on rhs to construct an
     // instance in our storage. But this is good enough; there's no need to jump
     // through vtables for copying and assignment that are just going to move
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -803,18 +803,18 @@ NondeterministicGetWeakMapKeys(JSContext
     return true;
 }
 
 class HasChildTracer : public JS::CallbackTracer
 {
     RootedValue child_;
     bool found_;
 
-    void trace(void** thingp, JS::TraceKind kind) {
-        if (*thingp == child_.toGCThing())
+    void onChild(const JS::GCCellPtr& thing) override {
+        if (thing.asCell() == child_.toGCThing())
             found_ = true;
     }
 
   public:
     HasChildTracer(JSRuntime* rt, HandleValue child)
       : JS::CallbackTracer(rt, TraceWeakMapKeysValues), child_(rt, child), found_(false)
     {}
 
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.h
@@ -133,19 +133,25 @@ struct AutoStopVerifyingBarriers
 };
 #endif /* JS_GC_ZEAL */
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 void
 CheckHashTablesAfterMovingGC(JSRuntime* rt);
 #endif
 
-struct MovingTracer : JS::CallbackTracer {
+struct MovingTracer : JS::CallbackTracer
+{
     explicit MovingTracer(JSRuntime* rt) : CallbackTracer(rt, TraceWeakMapKeysValues) {}
-    void trace(void** thingp, JS::TraceKind kind) override;
+
+    void onObjectEdge(JSObject** objp) override;
+    void onChild(const JS::GCCellPtr& thing) override {
+        MOZ_ASSERT(!RelocationOverlay::isCellForwarded(thing.asCell()));
+    }
+
 #ifdef DEBUG
     TracerKind getTracerKind() const override { return TracerKind::Moving; }
 #endif
 };
 
 class AutoMaybeStartBackgroundAllocation
 {
   private:
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1225,18 +1225,18 @@ GCMarker::processMarkStackTop(SliceBudge
 
       case JitCodeTag: {
         return reinterpret_cast<jit::JitCode*>(addr)->traceChildren(this);
       }
 
       case SavedValueArrayTag: {
         MOZ_ASSERT(!(addr & CellMask));
         JSObject* obj = reinterpret_cast<JSObject*>(addr);
-        HeapValue* vp;
-        HeapValue* end;
+        HeapSlot* vp;
+        HeapSlot* end;
         if (restoreValueArray(obj, (void**)&vp, (void**)&end))
             pushValueArray(&obj->as<NativeObject>(), vp, end);
         else
             repush(obj);
         return;
       }
 
       default: MOZ_CRASH("Invalid tag in mark stack");
@@ -2273,19 +2273,19 @@ TypeSet::MarkTypeUnbarriered(JSTracer* t
 }
 
 
 /*** Cycle Collector Barrier Implementation *******************************************************/
 
 #ifdef DEBUG
 struct AssertNonGrayTracer : public JS::CallbackTracer {
     explicit AssertNonGrayTracer(JSRuntime* rt) : JS::CallbackTracer(rt) {}
-    void trace(void** thingp, JS::TraceKind kind) override {
-        DebugOnly<Cell*> thing(static_cast<Cell*>(*thingp));
-        MOZ_ASSERT_IF(thing->isTenured(), !thing->asTenured().isMarked(js::gc::GRAY));
+    void onChild(const JS::GCCellPtr& thing) override {
+        MOZ_ASSERT_IF(thing.asCell()->isTenured(),
+                      !thing.asCell()->asTenured().isMarked(js::gc::GRAY));
     }
 };
 #endif
 
 struct UnmarkGrayTracer : public JS::CallbackTracer
 {
     /*
      * We set eagerlyTraceWeakMaps to false because the cycle collector will fix
@@ -2300,17 +2300,17 @@ struct UnmarkGrayTracer : public JS::Cal
 
     UnmarkGrayTracer(JSTracer* trc, bool tracingShape)
       : JS::CallbackTracer(trc->runtime(), DoNotTraceWeakMaps),
         tracingShape(tracingShape),
         previousShape(nullptr),
         unmarkedAny(false)
     {}
 
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 
     /* True iff we are tracing the immediate children of a shape. */
     bool tracingShape;
 
     /* If tracingShape, shape child or nullptr. Otherwise, nullptr. */
     Shape* previousShape;
 
     /* Whether we unmarked anything. */
@@ -2343,64 +2343,64 @@ struct UnmarkGrayTracer : public JS::Cal
  * - A special pass enumerating all of the containers that know about the
  *   implicit edges to fix any black-gray edges that have been created. This
  *   is implemented in nsXPConnect::FixWeakMappingGrayBits.
  * - To prevent any incorrectly gray objects from escaping to live JS outside
  *   of the containers, we must add unmark-graying read barriers to these
  *   containers.
  */
 void
-UnmarkGrayTracer::trace(void** thingp, JS::TraceKind kind)
+UnmarkGrayTracer::onChild(const JS::GCCellPtr& thing)
 {
     int stackDummy;
     if (!JS_CHECK_STACK_SIZE(runtime()->mainThread.nativeStackLimit[StackForSystemCode],
                              &stackDummy))
     {
         /*
          * If we run out of stack, we take a more drastic measure: require that
          * we GC again before the next CC.
          */
         runtime()->gc.setGrayBitsInvalid();
         return;
     }
 
-    Cell* cell = static_cast<Cell*>(*thingp);
+    Cell* cell = thing.asCell();
 
     // Cells in the nursery cannot be gray, and therefore must necessarily point
     // to only black edges.
     if (!cell->isTenured()) {
 #ifdef DEBUG
         AssertNonGrayTracer nongray(runtime());
-        TraceChildren(&nongray, cell, kind);
+        TraceChildren(&nongray, cell, thing.kind());
 #endif
         return;
     }
 
     TenuredCell& tenured = cell->asTenured();
     if (!tenured.isMarked(js::gc::GRAY))
         return;
     tenured.unmark(js::gc::GRAY);
 
     unmarkedAny = true;
 
     // Trace children of |tenured|. If |tenured| and its parent are both
     // shapes, |tenured| will get saved to mPreviousShape without being traced.
     // The parent will later trace |tenured|. This is done to avoid increasing
     // the stack depth during shape tracing. It is safe to do because a shape
     // can only have one child that is a shape.
-    UnmarkGrayTracer childTracer(this, kind == JS::TraceKind::Shape);
+    UnmarkGrayTracer childTracer(this, thing.kind() == JS::TraceKind::Shape);
 
-    if (kind != JS::TraceKind::Shape) {
-        TraceChildren(&childTracer, &tenured, kind);
+    if (thing.kind() != JS::TraceKind::Shape) {
+        TraceChildren(&childTracer, &tenured, thing.kind());
         MOZ_ASSERT(!childTracer.previousShape);
         unmarkedAny |= childTracer.unmarkedAny;
         return;
     }
 
-    MOZ_ASSERT(kind == JS::TraceKind::Shape);
+    MOZ_ASSERT(thing.kind() == JS::TraceKind::Shape);
     Shape* shape = static_cast<Shape*>(&tenured);
     if (tracingShape) {
         MOZ_ASSERT(!previousShape);
         previousShape = shape;
         return;
     }
 
     do {
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -190,19 +190,16 @@ class GCMarker : public JSTracer
     void setGCMode(JSGCMode mode) { stack.setGCMode(mode); }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
 #ifdef DEBUG
     bool shouldCheckCompartments() { return strictCompartmentChecking; }
 #endif
 
-    /* This is public exclusively for ScanRope. */
-    MarkStack stack;
-
   private:
 #ifdef DEBUG
     void checkZone(void* p);
 #else
     void checkZone(void* p) {}
 #endif
 
     /*
@@ -252,17 +249,17 @@ class GCMarker : public JSTracer
     void pushTaggedPtr(StackTag tag, void* ptr) {
         checkZone(ptr);
         uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
         MOZ_ASSERT(!(addr & StackTagMask));
         if (!stack.push(addr | uintptr_t(tag)))
             delayMarkingChildren(ptr);
     }
 
-    void pushValueArray(JSObject* obj, void* start, void* end) {
+    void pushValueArray(JSObject* obj, HeapSlot* start, HeapSlot* end) {
         checkZone(obj);
 
         MOZ_ASSERT(start <= end);
         uintptr_t tagged = reinterpret_cast<uintptr_t>(obj) | GCMarker::ValueArrayTag;
         uintptr_t startAddr = reinterpret_cast<uintptr_t>(start);
         uintptr_t endAddr = reinterpret_cast<uintptr_t>(end);
 
         /*
@@ -276,16 +273,19 @@ class GCMarker : public JSTracer
     bool isMarkStackEmpty() {
         return stack.isEmpty();
     }
 
     bool restoreValueArray(JSObject* obj, void** vpp, void** endp);
     void saveValueRanges();
     inline void processMarkStackTop(SliceBudget& budget);
 
+    /* The mark stack. Pointers in this stack are "gray" in the GC sense. */
+    MarkStack stack;
+
     /* The color is only applied to objects and functions. */
     uint32_t color;
 
     /* Pointer to the top of the stack of arenas we are delaying marking on. */
     js::gc::ArenaHeader* unmarkedArenaStackTop;
 
     /* Count of arenas that are currently in the stack. */
     mozilla::DebugOnly<size_t> markLaterArenas;
--- a/js/src/gc/RootMarking.cpp
+++ b/js/src/gc/RootMarking.cpp
@@ -547,17 +547,17 @@ js::gc::GCRuntime::markRuntime(JSTracer*
 
 // Append traced things to a buffer on the zone for use later in the GC.
 // See the comment in GCRuntime.h above grayBufferState for details.
 class BufferGrayRootsTracer : public JS::CallbackTracer
 {
     // Set to false if we OOM while buffering gray roots.
     bool bufferingGrayRootsFailed;
 
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 
   public:
     explicit BufferGrayRootsTracer(JSRuntime* rt)
       : JS::CallbackTracer(rt), bufferingGrayRootsFailed(false)
     {}
 
     bool failed() const { return bufferingGrayRootsFailed; }
 
@@ -600,34 +600,34 @@ js::gc::GCRuntime::bufferGrayRoots()
     }
 }
 
 struct SetMaybeAliveFunctor {
     template <typename T> void operator()(T* t) { SetMaybeAliveFlag(t); }
 };
 
 void
-BufferGrayRootsTracer::trace(void** thingp, JS::TraceKind kind)
+BufferGrayRootsTracer::onChild(const JS::GCCellPtr& thing)
 {
     MOZ_ASSERT(runtime()->isHeapBusy());
 
     if (bufferingGrayRootsFailed)
         return;
 
-    gc::TenuredCell* thing = gc::TenuredCell::fromPointer(*thingp);
+    gc::TenuredCell* tenured = gc::TenuredCell::fromPointer(thing.asCell());
 
-    Zone* zone = thing->zone();
+    Zone* zone = tenured->zone();
     if (zone->isCollecting()) {
         // See the comment on SetMaybeAliveFlag to see why we only do this for
         // objects and scripts. We rely on gray root buffering for this to work,
         // but we only need to worry about uncollected dead compartments during
         // incremental GCs (when we do gray root buffering).
-        CallTyped(SetMaybeAliveFunctor(), thing, kind);
+        CallTyped(SetMaybeAliveFunctor(), tenured, thing.kind());
 
-        if (!zone->gcGrayRoots.append(thing))
+        if (!zone->gcGrayRoots.append(tenured))
             bufferingGrayRootsFailed = true;
     }
 }
 
 void
 GCRuntime::markBufferedGrayRoots(JS::Zone* zone)
 {
     MOZ_ASSERT(grayBufferState == GrayBufferState::Okay);
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -41,19 +41,18 @@ CheckTracedThing(JSTracer* trc, T thing)
 
 /*** Callback Tracer Dispatch ********************************************************************/
 
 template <typename T>
 T
 DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name)
 {
     CheckTracedThing(trc, *thingp);
-    JS::TraceKind kind = MapTypeToTraceKind<typename mozilla::RemovePointer<T>::Type>::kind;
     JS::AutoTracingName ctx(trc, name);
-    trc->trace(reinterpret_cast<void**>(thingp), kind);
+    trc->dispatchToOnEdge(thingp);
     return *thingp;
 }
 #define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(name, type, _) \
     template type* DoCallback<type*>(JS::CallbackTracer*, type**, const char*);
 FOR_EACH_GC_LAYOUT(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS);
 #undef INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS
 
 template <typename S>
@@ -317,31 +316,29 @@ TraceObjectGroupCycleCollectorChildrenCa
 // avoid blowing the stack when running the cycle collector's callback tracer.
 struct ObjectGroupCycleCollectorTracer : public JS::CallbackTracer
 {
     explicit ObjectGroupCycleCollectorTracer(JS::CallbackTracer* innerTracer)
         : JS::CallbackTracer(innerTracer->runtime(), DoNotTraceWeakMaps),
           innerTracer(innerTracer)
     {}
 
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 
     JS::CallbackTracer* innerTracer;
     Vector<ObjectGroup*, 4, SystemAllocPolicy> seen, worklist;
 };
 
 void
-ObjectGroupCycleCollectorTracer::trace(void** thingp, JS::TraceKind kind)
+ObjectGroupCycleCollectorTracer::onChild(const JS::GCCellPtr& thing)
 {
-    JS::GCCellPtr thing(*thingp, kind);
-
     if (thing.isObject() || thing.isScript()) {
         // Invoke the inner cycle collector callback on this child. It will not
         // recurse back into TraceChildren.
-        innerTracer->trace(thingp, kind);
+        innerTracer->onChild(thing);
         return;
     }
 
     if (thing.isObjectGroup()) {
         // If this group is required to be in an ObjectGroup chain, trace it
         // via the provided worklist rather than continuing to recurse.
         ObjectGroup* group = static_cast<ObjectGroup*>(thing.asCell());
         if (group->maybeUnboxedLayout()) {
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -76,17 +76,17 @@ typedef HashMap<void*, VerifyNode*, Defa
  *
  * The nodemap field is a hashtable that maps from the address of the GC thing
  * to the VerifyNode that represents it.
  */
 class js::VerifyPreTracer : public JS::CallbackTracer
 {
     JS::AutoDisableGenerationalGC noggc;
 
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 
   public:
     /* The gcNumber when the verification began. */
     uint64_t number;
 
     /* This counts up to gcZealFrequency to decide whether to verify. */
     int count;
 
@@ -107,31 +107,31 @@ class js::VerifyPreTracer : public JS::C
     }
 };
 
 /*
  * This function builds up the heap snapshot by adding edges to the current
  * node.
  */
 void
-VerifyPreTracer::trace(void** thingp, JS::TraceKind kind)
+VerifyPreTracer::onChild(const JS::GCCellPtr& thing)
 {
-    MOZ_ASSERT(!IsInsideNursery(*reinterpret_cast<Cell**>(thingp)));
+    MOZ_ASSERT(!IsInsideNursery(thing.asCell()));
 
     edgeptr += sizeof(EdgeValue);
     if (edgeptr >= term) {
         edgeptr = term;
         return;
     }
 
     VerifyNode* node = curnode;
     uint32_t i = node->count;
 
-    node->edges[i].thing = *thingp;
-    node->edges[i].kind = kind;
+    node->edges[i].thing = thing.asCell();
+    node->edges[i].kind = thing.kind();
     node->edges[i].label = contextName();
     node->count++;
 }
 
 static VerifyNode*
 MakeNode(VerifyPreTracer* trc, void* thing, JS::TraceKind kind)
 {
     NodeMap::AddPtr p = trc->nodemap.lookupForAdd(thing);
@@ -247,38 +247,38 @@ static bool
 IsMarkedOrAllocated(TenuredCell* cell)
 {
     return cell->isMarked() || cell->arenaHeader()->allocatedDuringIncremental;
 }
 
 struct CheckEdgeTracer : public JS::CallbackTracer {
     VerifyNode* node;
     explicit CheckEdgeTracer(JSRuntime* rt) : JS::CallbackTracer(rt), node(nullptr) {}
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 };
 
 static const uint32_t MAX_VERIFIER_EDGES = 1000;
 
 /*
  * This function is called by EndVerifyBarriers for every heap edge. If the edge
  * already existed in the original snapshot, we "cancel it out" by overwriting
  * it with nullptr. EndVerifyBarriers later asserts that the remaining
  * non-nullptr edges (i.e., the ones from the original snapshot that must have
  * been modified) must point to marked objects.
  */
 void
-CheckEdgeTracer::trace(void** thingp, JS::TraceKind kind)
+CheckEdgeTracer::onChild(const JS::GCCellPtr& thing)
 {
     /* Avoid n^2 behavior. */
     if (node->count > MAX_VERIFIER_EDGES)
         return;
 
     for (uint32_t i = 0; i < node->count; i++) {
-        if (node->edges[i].thing == *thingp) {
-            MOZ_ASSERT(node->edges[i].kind == kind);
+        if (node->edges[i].thing == thing.asCell()) {
+            MOZ_ASSERT(node->edges[i].kind == thing.kind());
             node->edges[i].thing = nullptr;
             return;
         }
     }
 }
 
 static void
 AssertMarkedOrAllocated(const EdgeValue& edge)
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/bug1174372.js
@@ -0,0 +1,6 @@
+// |jit-test| --no-baseline; --non-writable-jitcode
+(function(stdlib, foreign, heap) {
+    "use asm";
+    function f() {}
+    return f;
+})();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/tracelogger/bug1174542.js
@@ -0,0 +1,6 @@
+var du = new Debugger();
+if (typeof du.setupTraceLogger === "function")
+    du.setupTraceLogger({Scripts: true});
+(function() {
+    for (var i = 0; i < 15; ++i) {}
+})();
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -907,17 +907,16 @@ BaselineScript::initTraceLogger(JSRuntim
 
     TraceLoggerThread* logger = TraceLoggerForMainThread(runtime);
     if (TraceLogTextIdEnabled(TraceLogger_Scripts))
         traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts, script);
     else
         traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts);
 
     if (TraceLogTextIdEnabled(TraceLogger_Engine) || TraceLogTextIdEnabled(TraceLogger_Scripts)) {
-        AutoWritableJitCode awjc(method_);
         CodeLocationLabel enter(method_, CodeOffsetLabel(traceLoggerEnterToggleOffset_));
         CodeLocationLabel exit(method_, CodeOffsetLabel(traceLoggerExitToggleOffset_));
         Assembler::ToggleToCmp(enter);
         Assembler::ToggleToCmp(exit);
     }
 }
 
 void
--- a/js/src/jit/ExecutableAllocator.cpp
+++ b/js/src/jit/ExecutableAllocator.cpp
@@ -24,31 +24,57 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "jit/ExecutableAllocator.h"
 
 #include "js/MemoryMetrics.h"
 
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
+
 using namespace js::jit;
 
 size_t ExecutableAllocator::pageSize = 0;
 size_t ExecutableAllocator::largeAllocSize = 0;
 
 ExecutablePool::~ExecutablePool()
 {
     MOZ_ASSERT(m_ionCodeBytes == 0);
     MOZ_ASSERT(m_baselineCodeBytes == 0);
     MOZ_ASSERT(m_regexpCodeBytes == 0);
     MOZ_ASSERT(m_otherCodeBytes == 0);
 
     m_allocator->releasePoolPages(this);
 }
 
+/* static */ void
+ExecutableAllocator::initStatic()
+{
+    if (!pageSize) {
+        pageSize = determinePageSize();
+        // On Windows, VirtualAlloc effectively allocates in 64K chunks.
+        // (Technically, it allocates in page chunks, but the starting
+        // address is always a multiple of 64K, so each allocation uses up
+        // 64K of address space.)  So a size less than that would be
+        // pointless.  But it turns out that 64KB is a reasonable size for
+        // all platforms.  (This assumes 4KB pages.) On 64-bit windows,
+        // AllocateExecutableMemory prepends an extra page for structured
+        // exception handling data (see comments in function) onto whatever
+        // is passed in, so subtract one page here.
+#if defined(JS_CPU_X64) && defined(XP_WIN)
+        largeAllocSize = pageSize * 15;
+#else
+        largeAllocSize = pageSize * 16;
+#endif
+    }
+}
+
 void
 ExecutableAllocator::addSizeOfCode(JS::CodeSizes* sizes) const
 {
     if (m_pools.initialized()) {
         for (ExecPoolHashSet::Range r = m_pools.all(); !r.empty(); r.popFront()) {
             ExecutablePool* pool = r.front();
             sizes->ion      += pool->m_ionCodeBytes;
             sizes->baseline += pool->m_baselineCodeBytes;
@@ -57,13 +83,13 @@ ExecutableAllocator::addSizeOfCode(JS::C
             sizes->unused   += pool->m_allocation.size - pool->m_ionCodeBytes
                                                        - pool->m_baselineCodeBytes
                                                        - pool->m_regexpCodeBytes
                                                        - pool->m_otherCodeBytes;
         }
     }
 }
 
-#ifdef TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE
 bool ExecutableAllocator::nonWritableJitCode = true;
 #else
 bool ExecutableAllocator::nonWritableJitCode = false;
 #endif
--- a/js/src/jit/ExecutableAllocator.h
+++ b/js/src/jit/ExecutableAllocator.h
@@ -177,34 +177,16 @@ class ExecutableAllocator
     DestroyCallback destroyCallback;
 
   public:
     enum ProtectionSetting { Writable, Executable };
 
     ExecutableAllocator()
       : destroyCallback(nullptr)
     {
-        if (!pageSize) {
-            pageSize = determinePageSize();
-            // On Windows, VirtualAlloc effectively allocates in 64K chunks.
-            // (Technically, it allocates in page chunks, but the starting
-            // address is always a multiple of 64K, so each allocation uses up
-            // 64K of address space.)  So a size less than that would be
-            // pointless.  But it turns out that 64KB is a reasonable size for
-            // all platforms.  (This assumes 4KB pages.) On 64-bit windows,
-            // AllocateExecutableMemory prepends an extra page for structured
-            // exception handling data (see comments in function) onto whatever
-            // is passed in, so subtract one page here.
-#if defined(JS_CPU_X64) && defined(XP_WIN)
-            largeAllocSize = pageSize * 15;
-#else
-            largeAllocSize = pageSize * 16;
-#endif
-        }
-
         MOZ_ASSERT(m_smallPools.empty());
     }
 
     ~ExecutableAllocator()
     {
         for (size_t i = 0; i < m_smallPools.length(); i++)
             m_smallPools[i]->release(/* willDestroy = */true);
 
@@ -258,16 +240,18 @@ class ExecutableAllocator
     }
 
     void addSizeOfCode(JS::CodeSizes* sizes) const;
 
     void setDestroyCallback(DestroyCallback destroyCallback) {
         this->destroyCallback = destroyCallback;
     }
 
+    static void initStatic();
+
     static bool nonWritableJitCode;
 
   private:
     static size_t pageSize;
     static size_t largeAllocSize;
 #ifdef XP_WIN
     static uint64_t rngSeed;
 #endif
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -1211,17 +1211,17 @@ IonScript::purgeCaches()
     // no longer run, however, the IC slow paths may be active on the stack.
     // ICs therefore are required to check for invalidation before patching,
     // to ensure the same invariant.
     if (invalidated())
         return;
 
     AutoWritableJitCode awjc(method());
     for (size_t i = 0; i < numCaches(); i++)
-        getCacheFromIndex(i).reset();
+        getCacheFromIndex(i).reset(DontReprotect);
 }
 
 void
 IonScript::unlinkFromRuntime(FreeOp* fop)
 {
     // The writes to the executable buffer below may clobber backedge jumps, so
     // make sure that those backedges are unlinked from the runtime and not
     // reclobbered with garbage if an interrupt is requested.
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1662,17 +1662,17 @@ GetPropertyIC::tryAttachDOMProxyUnshadow
 
     if (resetNeeded) {
         // If we know that we have a DoesntShadowUnique object, then
         // we reset the cache to clear out an existing IC for the object
         // (if there is one). The generation is a constant in the generated
         // code and we will not have the same generation again for this
         // object, so the generation check in the existing IC would always
         // fail anyway.
-        reset();
+        reset(Reprotect);
     }
 
     Label failures;
     MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
     StubAttacher attacher(*this);
 
     // Guard on the shape of the object.
     attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
@@ -1987,39 +1987,38 @@ GetPropertyIC::update(JSContext* cx, Han
         if (!cache.monitoredResult())
             TypeScript::Monitor(cx, script, pc, vp);
     }
 
     return true;
 }
 
 void
-GetPropertyIC::reset()
+GetPropertyIC::reset(ReprotectCode reprotect)
 {
-    IonCache::reset();
+    IonCache::reset(reprotect);
     hasTypedArrayLengthStub_ = false;
     hasSharedTypedArrayLengthStub_ = false;
     hasStrictArgumentsLengthStub_ = false;
     hasNormalArgumentsLengthStub_ = false;
     hasGenericProxyStub_ = false;
 }
 
 void
-IonCache::disable(IonScript* ion)
+IonCache::disable()
 {
-    AutoWritableJitCode awjc(ion->method());
-    reset();
+    reset(Reprotect);
     this->disabled_ = 1;
 }
 
 void
-IonCache::reset()
+IonCache::reset(ReprotectCode reprotect)
 {
     this->stubCount_ = 0;
-    PatchJump(initialJump_, fallbackLabel_);
+    PatchJump(initialJump_, fallbackLabel_, reprotect);
     lastJump_ = initialJump_;
 }
 
 // Jump to failure if a value being written is not a property for obj/id.
 // This might clobber |object|.
 static void
 CheckTypeSetForWrite(MacroAssembler& masm, JSObject* obj, jsid id,
                      Register object, ConstantOrRegister value, Label* failure)
@@ -3214,17 +3213,17 @@ SetPropertyIC::update(JSContext* cx, Han
                     return false;
                 if (DOMProxyIsShadowing(shadows)) {
                     if (!cache.attachDOMProxyShadowed(cx, outerScript, ion, obj, returnAddr))
                         return false;
                     addedSetterStub = true;
                 } else {
                     MOZ_ASSERT(shadows == DoesntShadow || shadows == DoesntShadowUnique);
                     if (shadows == DoesntShadowUnique)
-                        cache.reset();
+                        cache.reset(Reprotect);
                     if (!cache.attachDOMProxyUnshadowed(cx, outerScript, ion, obj, returnAddr))
                         return false;
                     addedSetterStub = true;
                 }
             }
 
             if (!addedSetterStub && !cache.hasGenericProxyStub()) {
                 if (!cache.attachGenericProxy(cx, outerScript, ion, returnAddr))
@@ -3318,19 +3317,19 @@ SetPropertyIC::update(JSContext* cx, Han
 
     if (!addedSetterStub)
         JitSpew(JitSpew_IonIC, "Failed to attach SETPROP cache");
 
     return true;
 }
 
 void
-SetPropertyIC::reset()
+SetPropertyIC::reset(ReprotectCode reprotect)
 {
-    IonCache::reset();
+    IonCache::reset(reprotect);
     hasGenericProxyStub_ = false;
 }
 
 const size_t GetElementIC::MAX_FAILED_UPDATES = 16;
 
 /* static */ bool
 GetElementIC::canAttachGetProp(JSObject* obj, const Value& idval, jsid id)
 {
@@ -4032,31 +4031,31 @@ GetElementIC::update(JSContext* cx, Hand
     if (!GetObjectElementOperation(cx, JSOp(*pc), obj, obj, idval, res))
         return false;
 
     // Disable cache when we reach max stubs or update failed too much.
     if (!attachedStub) {
         cache.incFailedUpdates();
         if (cache.shouldDisable()) {
             JitSpew(JitSpew_IonIC, "Disable inline cache");
-            cache.disable(ion);
+            cache.disable();
         }
     } else {
         cache.resetFailedUpdates();
     }
 
     if (!cache.monitoredResult())
         TypeScript::Monitor(cx, script, pc, res);
     return true;
 }
 
 void
-GetElementIC::reset()
+GetElementIC::reset(ReprotectCode reprotect)
 {
-    IonCache::reset();
+    IonCache::reset(reprotect);
     hasDenseStub_ = false;
     hasStrictArgumentsStub_ = false;
     hasNormalArgumentsStub_ = false;
 }
 
 static bool
 IsDenseElementSetInlineable(JSObject* obj, const Value& idval)
 {
@@ -4383,19 +4382,19 @@ SetElementIC::update(JSContext* cx, Hand
     }
 
     if (!SetObjectElement(cx, obj, idval, value, cache.strict()))
         return false;
     return true;
 }
 
 void
-SetElementIC::reset()
+SetElementIC::reset(ReprotectCode reprotect)
 {
-    IonCache::reset();
+    IonCache::reset(reprotect);
     hasDenseStub_ = false;
 }
 
 bool
 BindNameIC::attachGlobal(JSContext* cx, HandleScript outerScript, IonScript* ion,
                          HandleObject scopeChain)
 {
     MOZ_ASSERT(scopeChain->is<GlobalObject>());
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -238,17 +238,17 @@ class IonCache
         pc_(nullptr),
         profilerLeavePc_(nullptr),
         initialJump_(),
         lastJump_(),
         rejoinLabel_()
     {
     }
 
-    void disable(IonScript* ion);
+    void disable();
     inline bool isDisabled() const {
         return disabled_;
     }
 
     // Set the initial 'out-of-line' jump state of the cache. The fallbackLabel is
     // the location of the out-of-line update (slow) path.  This location will
     // be set to the exitJump of the last generated stub.
     void setFallbackLabel(CodeOffsetLabel fallbackLabel) {
@@ -264,17 +264,17 @@ class IonCache
     void* rejoinAddress() const {
         return rejoinLabel_.raw();
     }
 
     void emitInitialJump(MacroAssembler& masm, RepatchLabel& entry);
     void updateBaseAddress(JitCode* code, MacroAssembler& masm);
 
     // Reset the cache around garbage collection.
-    virtual void reset();
+    virtual void reset(ReprotectCode reprotect);
 
     bool canAttachStub() const {
         return stubCount_ < MAX_STUBS;
     }
     bool empty() const {
         return stubCount_ == 0;
     }
 
@@ -407,17 +407,17 @@ class GetPropertyIC : public IonCache
         hasStrictArgumentsLengthStub_(false),
         hasNormalArgumentsLengthStub_(false),
         hasGenericProxyStub_(false)
     {
     }
 
     CACHE_HEADER(GetProperty)
 
-    void reset();
+    void reset(ReprotectCode reprotect);
 
     Register object() const {
         return object_;
     }
     PropertyName* name() const {
         return name_;
     }
     TypedOrValueRegister output() const {
@@ -542,17 +542,17 @@ class SetPropertyIC : public IonCache
         strict_(strict),
         needsTypeBarrier_(needsTypeBarrier),
         hasGenericProxyStub_(false)
     {
     }
 
     CACHE_HEADER(SetProperty)
 
-    void reset();
+    void reset(ReprotectCode reprotect);
 
     Register object() const {
         return object_;
     }
     PropertyName* name() const {
         return name_;
     }
     ConstantOrRegister value() const {
@@ -636,17 +636,17 @@ class GetElementIC : public IonCache
         hasStrictArgumentsStub_(false),
         hasNormalArgumentsStub_(false),
         failedUpdates_(0)
     {
     }
 
     CACHE_HEADER(GetElement)
 
-    void reset();
+    void reset(ReprotectCode reprotect);
 
     Register object() const {
         return object_;
     }
     ConstantOrRegister index() const {
         return index_;
     }
     TypedOrValueRegister output() const {
@@ -745,17 +745,17 @@ class SetElementIC : public IonCache
         strict_(strict),
         guardHoles_(guardHoles),
         hasDenseStub_(false)
     {
     }
 
     CACHE_HEADER(SetElement)
 
-    void reset();
+    void reset(ReprotectCode reprotect);
 
     Register object() const {
         return object_;
     }
     Register tempToUnboxIndex() const {
         return tempToUnboxIndex_;
     }
     Register temp() const {
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -2178,16 +2178,18 @@ SnapshotIterator::initInstructionResults
     // If there is only one resume point in the list of instructions, then there
     // is no instruction to recover, and thus no need to register any results.
     if (recover_.numInstructions() == 1)
         return true;
 
     JitFrameLayout* fp = fallback.frame->jsFrame();
     RInstructionResults* results = fallback.activation->maybeIonFrameRecovery(fp);
     if (!results) {
+        AutoCompartment ac(cx, fallback.frame->script()->compartment());
+
         // We do not have the result yet, which means that an observable stack
         // slot is requested.  As we do not want to bailout every time for the
         // same reason, we need to recompile without optimizing away the
         // observable stack slots.  The script would later be recompiled to have
         // support for Argument objects.
         if (fallback.consequence == MaybeReadFallback::Fallback_Invalidate &&
             !ionScript_->invalidate(cx, /* resetUses = */ false, "Observe recovered instruction."))
         {
--- a/js/src/jsapi-tests/testGCMarking.cpp
+++ b/js/src/jsapi-tests/testGCMarking.cpp
@@ -3,26 +3,26 @@
 */
 /* 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 "jsapi-tests/tests.h"
 
 class CCWTestTracer : public JS::CallbackTracer {
-    void trace(void** thingp, JS::TraceKind kind) {
+    void onChild(const JS::GCCellPtr& thing) override {
         numberOfThingsTraced++;
 
-        printf("*thingp         = %p\n", *thingp);
+        printf("*thingp         = %p\n", thing.asCell());
         printf("*expectedThingp = %p\n", *expectedThingp);
 
-        printf("kind         = %d\n", static_cast<int>(kind));
+        printf("kind         = %d\n", static_cast<int>(thing.kind()));
         printf("expectedKind = %d\n", static_cast<int>(expectedKind));
 
-        if (*thingp != *expectedThingp || kind != expectedKind)
+        if (thing.asCell() != *expectedThingp || thing.kind() != expectedKind)
             okay = false;
     }
 
   public:
     bool          okay;
     size_t        numberOfThingsTraced;
     void**        expectedThingp;
     JS::TraceKind expectedKind;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -547,16 +547,18 @@ JS_Init(void)
 #ifdef DEBUG
     CheckMessageParameterCounts();
 #endif
 
     using js::TlsPerThreadData;
     if (!TlsPerThreadData.initialized() && !TlsPerThreadData.init())
         return false;
 
+    jit::ExecutableAllocator::initStatic();
+
     if (!jit::InitializeIon())
         return false;
 
 #if EXPOSE_INTL_API
     UErrorCode err = U_ZERO_ERROR;
     u_init(&err);
     if (U_FAILURE(err))
         return false;
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -899,17 +899,17 @@ struct DumpHeapTracer : public JS::Callb
         JSObject* kdelegate = nullptr;
         if (key.isObject())
             kdelegate = js::GetWeakmapKeyDelegate(key.toObject());
 
         fprintf(output, "WeakMapEntry map=%p key=%p keyDelegate=%p value=%p\n",
                 map, key.asCell(), kdelegate, value.asCell());
     }
 
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 };
 
 static char
 MarkDescriptor(void* thing)
 {
     gc::TenuredCell* cell = gc::TenuredCell::fromPointer(thing);
     if (cell->isMarked(gc::BLACK))
         return cell->isMarked(gc::GRAY) ? 'G' : 'B';
@@ -953,24 +953,24 @@ DumpHeapVisitCell(JSRuntime* rt, void* d
     DumpHeapTracer* dtrc = static_cast<DumpHeapTracer*>(data);
     char cellDesc[1024 * 32];
     JS_GetTraceThingInfo(cellDesc, sizeof(cellDesc), dtrc, thing, traceKind, true);
     fprintf(dtrc->output, "%p %c %s\n", thing, MarkDescriptor(thing), cellDesc);
     JS_TraceChildren(dtrc, thing, traceKind);
 }
 
 void
-DumpHeapTracer::trace(void** thingp, JS::TraceKind kind)
+DumpHeapTracer::onChild(const JS::GCCellPtr& thing)
 {
-    if (gc::IsInsideNursery((js::gc::Cell*)*thingp))
+    if (gc::IsInsideNursery(thing.asCell()))
         return;
 
     char buffer[1024];
     getTracingEdgeName(buffer, sizeof(buffer));
-    fprintf(output, "%s%p %c %s\n", prefix, *thingp, MarkDescriptor(*thingp), buffer);
+    fprintf(output, "%s%p %c %s\n", prefix, thing.asCell(), MarkDescriptor(thing.asCell()), buffer);
 }
 
 void
 js::DumpHeap(JSRuntime* rt, FILE* fp, js::DumpHeapNurseryBehaviour nurseryBehaviour)
 {
     if (nurseryBehaviour == js::CollectNurseryBeforeDump)
         rt->gc.evictNursery(JS::gcreason::API);
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1690,16 +1690,22 @@ JS_NewSharedUint32ArrayWithBuffer(JSCont
 extern JS_FRIEND_API(JSObject*)
 JS_NewSharedFloat32ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
                                    uint32_t byteOffset, uint32_t length);
 extern JS_FRIEND_API(JSObject*)
 JS_NewSharedFloat64ArrayWithBuffer(JSContext* cx, JS::HandleObject arrayBuffer,
                                    uint32_t byteOffset, uint32_t length);
 
 /*
+ * Create a new SharedArrayBuffer with the given byte length.
+ */
+extern JS_FRIEND_API(JSObject*)
+JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes);
+
+/*
  * Create a new ArrayBuffer with the given byte length.
  */
 extern JS_FRIEND_API(JSObject*)
 JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes);
 
 /*
  * Check whether obj supports JS_GetTypedArray* APIs. Note that this may return
  * false if a security wrapper is encountered that denies the unwrapping. If
@@ -1813,16 +1819,23 @@ extern JS_FRIEND_API(JSObject*)
 UnwrapSharedInt32Array(JSObject* obj);
 extern JS_FRIEND_API(JSObject*)
 UnwrapSharedUint32Array(JSObject* obj);
 extern JS_FRIEND_API(JSObject*)
 UnwrapSharedFloat32Array(JSObject* obj);
 extern JS_FRIEND_API(JSObject*)
 UnwrapSharedFloat64Array(JSObject* obj);
 
+extern JS_FRIEND_API(JSObject*)
+UnwrapSharedArrayBuffer(JSObject* obj);
+
+extern JS_FRIEND_API(JSObject*)
+UnwrapSharedArrayBufferView(JSObject* obj);
+
+
 namespace detail {
 
 extern JS_FRIEND_DATA(const Class* const) Int8ArrayClassPtr;
 extern JS_FRIEND_DATA(const Class* const) Uint8ArrayClassPtr;
 extern JS_FRIEND_DATA(const Class* const) Uint8ClampedArrayClassPtr;
 extern JS_FRIEND_DATA(const Class* const) Int16ArrayClassPtr;
 extern JS_FRIEND_DATA(const Class* const) Uint16ArrayClassPtr;
 extern JS_FRIEND_DATA(const Class* const) Int32ArrayClassPtr;
@@ -1864,28 +1877,44 @@ JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint8Clamped, uint8_t)
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int16, int16_t)
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint16, uint16_t)
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Int32, int32_t)
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Uint32, uint32_t)
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float32, float)
 JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(Float64, double)
 
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedInt8, int8_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint8, uint8_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint8Clamped, uint8_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedInt16, int16_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint16, uint16_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedInt32, int32_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedUint32, uint32_t)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedFloat32, float)
+JS_DEFINE_DATA_AND_LENGTH_ACCESSOR(SharedFloat64, double)
+
 #undef JS_DEFINE_DATA_AND_LENGTH_ACCESSOR
 
 // This one isn't inlined because it's rather tricky (by dint of having to deal
 // with a dozen-plus classes and varying slot layouts.
 extern JS_FRIEND_API(void)
 GetArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
 
+extern JS_FRIEND_API(void)
+GetSharedArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
+
 // This one isn't inlined because there are a bunch of different ArrayBuffer
 // classes that would have to be individually handled here.
 extern JS_FRIEND_API(void)
 GetArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
 
+extern JS_FRIEND_API(void)
+GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data);
+
 } // namespace js
 
 /*
  * Unwrap Typed arrays all at once. Return nullptr without throwing if the
  * object cannot be viewed as the correct typed array, or the typed array
  * object on success, filling both outparameters.
  */
 extern JS_FRIEND_API(JSObject*)
@@ -1916,16 +1945,19 @@ JS_GetObjectAsArrayBuffer(JSObject* obj,
  *
  * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow
  * be known that it would pass such a test: it is an ArrayBufferView or a
  * wrapper of an ArrayBufferView, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(js::Scalar::Type)
 JS_GetArrayBufferViewType(JSObject* obj);
 
+extern JS_FRIEND_API(js::Scalar::Type)
+JS_GetSharedArrayBufferViewType(JSObject* obj);
+
 /*
  * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
  * return false if a security wrapper is encountered that denies the
  * unwrapping. If this test succeeds, then it is safe to call the various
  * accessor JSAPI calls defined below.
  */
 extern JS_FRIEND_API(bool)
 JS_IsArrayBufferObject(JSObject* obj);
@@ -2035,16 +2067,37 @@ extern JS_FRIEND_API(int32_t*)
 JS_GetInt32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
 extern JS_FRIEND_API(uint32_t*)
 JS_GetUint32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
 extern JS_FRIEND_API(float*)
 JS_GetFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
 extern JS_FRIEND_API(double*)
 JS_GetFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
 
+extern JS_FRIEND_API(uint8_t*)
+JS_GetSharedArrayBufferData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(int8_t*)
+JS_GetSharedInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(uint8_t*)
+JS_GetSharedUint8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(uint8_t*)
+JS_GetSharedUint8ClampedArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(int16_t*)
+JS_GetSharedInt16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(uint16_t*)
+JS_GetSharedUint16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(int32_t*)
+JS_GetSharedInt32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(uint32_t*)
+JS_GetSharedUint32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(float*)
+JS_GetSharedFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+extern JS_FRIEND_API(double*)
+JS_GetSharedFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&);
+
 /*
  * Same as above, but for any kind of ArrayBufferView. Prefer the type-specific
  * versions when possible.
  */
 extern JS_FRIEND_API(void*)
 JS_GetArrayBufferViewData(JSObject* obj, const JS::AutoCheckCannotGC&);
 
 /*
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2202,29 +2202,20 @@ GCRuntime::relocateArenas(Zone* zone, JS
         }
     }
 #endif
 
     return true;
 }
 
 void
-MovingTracer::trace(void** thingp, JS::TraceKind kind)
-{
-    TenuredCell* thing = TenuredCell::fromPointer(*thingp);
-
-    // Currently we only relocate objects.
-    if (kind != JS::TraceKind::Object) {
-        MOZ_ASSERT(!RelocationOverlay::isCellForwarded(thing));
-        return;
-    }
-
-    JSObject* obj = reinterpret_cast<JSObject*>(thing);
-    if (IsForwarded(obj))
-        *thingp = Forwarded(obj);
+MovingTracer::onObjectEdge(JSObject** objp)
+{
+    if (IsForwarded(*objp))
+        *objp = Forwarded(*objp);
 }
 
 void
 GCRuntime::sweepTypesAfterCompacting(Zone* zone)
 {
     FreeOp* fop = rt->defaultFreeOp();
     zone->beginSweepTypes(fop, rt->gc.releaseObservedTypes && !zone->isPreservingCode());
 
@@ -3672,17 +3663,17 @@ GCRuntime::shouldPreserveJITCode(JSCompa
         return true;
 
     return false;
 }
 
 #ifdef DEBUG
 class CompartmentCheckTracer : public JS::CallbackTracer
 {
-    void trace(void** thingp, JS::TraceKind kind) override;
+    void onChild(const JS::GCCellPtr& thing) override;
 
   public:
     explicit CompartmentCheckTracer(JSRuntime* rt)
       : JS::CallbackTracer(rt), src(nullptr), zone(nullptr), compartment(nullptr)
     {}
 
     Cell* src;
     JS::TraceKind srcKind;
@@ -3715,27 +3706,27 @@ InCrossCompartmentMap(JSObject* src, Cel
     return false;
 }
 
 struct MaybeCompartmentFunctor {
     template <typename T> JSCompartment* operator()(T* t) { return t->maybeCompartment(); }
 };
 
 void
-CompartmentCheckTracer::trace(void** thingp, JS::TraceKind kind)
-{
-    TenuredCell* thing = TenuredCell::fromPointer(*thingp);
-
-    JSCompartment* comp = CallTyped(MaybeCompartmentFunctor(), thing, kind);
+CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing)
+{
+    TenuredCell* tenured = TenuredCell::fromPointer(thing.asCell());
+
+    JSCompartment* comp = CallTyped(MaybeCompartmentFunctor(), tenured, thing.kind());
     if (comp && compartment) {
         MOZ_ASSERT(comp == compartment || runtime()->isAtomsCompartment(comp) ||
                    (srcKind == JS::TraceKind::Object &&
-                    InCrossCompartmentMap(static_cast<JSObject*>(src), thing, kind)));
+                    InCrossCompartmentMap(static_cast<JSObject*>(src), tenured, thing.kind())));
     } else {
-        MOZ_ASSERT(thing->zone() == zone || thing->zone()->isAtomsZone());
+        MOZ_ASSERT(tenured->zone() == zone || tenured->zone()->isAtomsZone());
     }
 }
 
 void
 GCRuntime::checkForCompartmentMismatches()
 {
     if (disableStrictProxyCheckingCount)
         return;
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -26,17 +26,17 @@ with Files('gc/**'):
     BUG_COMPONENT = component_gc
 with Files('jit/**'):
     BUG_COMPONENT = component_jit
 
 # File-specific metadata
 for gcfile in ['jsgc*', 'devtools/rootAnalysis', 'devtools/gc-ubench', 'devtools/gctrace']:
     with Files(gcfile):
         BUG_COMPONENT = component_gc
-for header in ('GCAPI.h', 'HeapAPI.h', 'RootingAPI.h', 'SliceBudget.h', 'TracingAPI.h', 'WeakMapPtr.h'):
+for header in ('GCAPI.h', 'HeapAPI.h', 'RootingAPI.h', 'SliceBudget.h', 'TraceKind.h', 'TracingAPI.h', 'WeakMapPtr.h'):
     with Files('../public/' + header):
         BUG_COMPONENT = component_gc
 
 for stlfile in ['jsarray.*', 'jsbool*', 'jsdate.*', 'jsnum.*', 'json.*', 'jsreflect.*', 'jsstr.*']:
     with Files(stlfile):
         BUG_COMPONENT = component_stl
 
 with Files('builtin/Intl*'):
@@ -117,16 +117,17 @@ EXPORTS.js += [
     '../public/Principals.h',
     '../public/ProfilingFrameIterator.h',
     '../public/ProfilingStack.h',
     '../public/Proxy.h',
     '../public/RequiredDefines.h',
     '../public/RootingAPI.h',
     '../public/SliceBudget.h',
     '../public/StructuredClone.h',
+    '../public/TraceKind.h',
     '../public/TracingAPI.h',
     '../public/TrackedOptimizationInfo.h',
     '../public/TypeDecls.h',
     '../public/UbiNode.h',
     '../public/UbiNodeTraverse.h',
     '../public/Utility.h',
     '../public/Value.h',
     '../public/Vector.h',
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -37,16 +37,17 @@
 #include "asmjs/AsmJSValidate.h"
 #include "gc/Barrier.h"
 #include "gc/Marking.h"
 #include "gc/Memory.h"
 #include "js/Conversions.h"
 #include "js/MemoryMetrics.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
+#include "vm/SharedArrayObject.h"
 #include "vm/WrapperObject.h"
 
 #include "jsatominlines.h"
 
 #include "vm/NativeObject-inl.h"
 #include "vm/Shape-inl.h"
 
 using JS::ToInt32;
@@ -1280,16 +1281,24 @@ JS_IsArrayBufferViewObject(JSObject* obj
 JS_FRIEND_API(JSObject*)
 js::UnwrapArrayBufferView(JSObject* obj)
 {
     if (JSObject* unwrapped = CheckedUnwrap(obj))
         return unwrapped->is<ArrayBufferViewObject>() ? unwrapped : nullptr;
     return nullptr;
 }
 
+JS_FRIEND_API(JSObject*)
+js::UnwrapSharedArrayBufferView(JSObject* obj)
+{
+    if (JSObject* unwrapped = CheckedUnwrap(obj))
+        return unwrapped->is<SharedTypedArrayObject>() ? unwrapped : nullptr;
+    return nullptr;
+}
+
 JS_FRIEND_API(uint32_t)
 JS_GetArrayBufferByteLength(JSObject* obj)
 {
     obj = CheckedUnwrap(obj);
     return obj ? AsArrayBuffer(obj).byteLength() : 0;
 }
 
 JS_FRIEND_API(uint8_t*)
@@ -1341,16 +1350,23 @@ JS_IsNeuteredArrayBufferObject(JSObject*
 
 JS_FRIEND_API(JSObject*)
 JS_NewArrayBuffer(JSContext* cx, uint32_t nbytes)
 {
     MOZ_ASSERT(nbytes <= INT32_MAX);
     return ArrayBufferObject::create(cx, nbytes);
 }
 
+JS_FRIEND_API(JSObject*)
+JS_NewSharedArrayBuffer(JSContext* cx, uint32_t nbytes)
+{
+    MOZ_ASSERT(nbytes <= INT32_MAX);
+    return SharedArrayBufferObject::New(cx, nbytes);
+}
+
 JS_PUBLIC_API(JSObject*)
 JS_NewArrayBufferWithContents(JSContext* cx, size_t nbytes, void* data)
 {
     MOZ_ASSERT_IF(!data, nbytes == 0);
     ArrayBufferObject::BufferContents contents =
         ArrayBufferObject::BufferContents::create<ArrayBufferObject::PLAIN>(data);
     return ArrayBufferObject::create(cx, nbytes, contents, ArrayBufferObject::OwnsData, TenuredObject);
 }
@@ -1371,16 +1387,24 @@ JS_ArrayBufferHasData(JSObject* obj)
 JS_FRIEND_API(JSObject*)
 js::UnwrapArrayBuffer(JSObject* obj)
 {
     if (JSObject* unwrapped = CheckedUnwrap(obj))
         return unwrapped->is<ArrayBufferObject>() ? unwrapped : nullptr;
     return nullptr;
 }
 
+JS_FRIEND_API(JSObject*)
+js::UnwrapSharedArrayBuffer(JSObject* obj)
+{
+    if (JSObject* unwrapped = CheckedUnwrap(obj))
+        return unwrapped->is<SharedArrayBufferObject>() ? unwrapped : nullptr;
+    return nullptr;
+}
+
 JS_PUBLIC_API(void*)
 JS_StealArrayBufferContents(JSContext* cx, HandleObject objArg)
 {
     JSObject* obj = CheckedUnwrap(objArg);
     if (!obj)
         return nullptr;
 
     if (!obj->is<ArrayBufferObject>()) {
--- a/js/src/vm/SharedArrayObject.cpp
+++ b/js/src/vm/SharedArrayObject.cpp
@@ -377,14 +377,41 @@ js::IsSharedArrayBuffer(HandleObject o)
 
 SharedArrayBufferObject&
 js::AsSharedArrayBuffer(HandleObject obj)
 {
     MOZ_ASSERT(IsSharedArrayBuffer(obj));
     return obj->as<SharedArrayBufferObject>();
 }
 
+JS_FRIEND_API(void)
+js::GetSharedArrayBufferViewLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data)
+{
+    MOZ_ASSERT(obj->is<SharedTypedArrayObject>());
+
+    *length = obj->as<SharedTypedArrayObject>().byteLength();
+
+    *data = static_cast<uint8_t*>(obj->as<SharedTypedArrayObject>().viewData());
+}
+
+JS_FRIEND_API(void)
+js::GetSharedArrayBufferLengthAndData(JSObject* obj, uint32_t* length, uint8_t** data)
+{
+    MOZ_ASSERT(obj->is<SharedArrayBufferObject>());
+    *length = obj->as<SharedArrayBufferObject>().byteLength();
+    *data = obj->as<SharedArrayBufferObject>().dataPointer();
+}
+
 JS_FRIEND_API(bool)
 JS_IsSharedArrayBufferObject(JSObject* obj)
 {
     obj = CheckedUnwrap(obj);
-    return obj ? obj->is<ArrayBufferObject>() : false;
+    return obj ? obj->is<SharedArrayBufferObject>() : false;
 }
+
+JS_FRIEND_API(uint8_t*)
+JS_GetSharedArrayBufferData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    return obj->as<SharedArrayBufferObject>().dataPointer();
+}
--- a/js/src/vm/SharedTypedArrayObject.cpp
+++ b/js/src/vm/SharedTypedArrayObject.cpp
@@ -994,14 +994,113 @@ SharedTypedArrayObject::setElement(Share
       case Scalar::Float64:
         SharedTypedArrayObjectTemplate<double>::setIndexValue(obj, index, d);
         break;
       default:
         MOZ_CRASH("Unknown SharedTypedArray type");
     }
 }
 
+JS_FRIEND_API(int8_t*)
+JS_GetSharedInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int8);
+    return static_cast<int8_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(uint8_t*)
+JS_GetSharedUint8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8);
+    return static_cast<uint8_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(uint8_t*)
+JS_GetSharedUint8ClampedArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint8Clamped);
+    return static_cast<uint8_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(int16_t*)
+JS_GetSharedInt16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int16);
+    return static_cast<int16_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(uint16_t*)
+JS_GetSharedUint16ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint16);
+    return static_cast<uint16_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(int32_t*)
+JS_GetSharedInt32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int32);
+    return static_cast<int32_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(uint32_t*)
+JS_GetSharedUint32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Uint32);
+    return static_cast<uint32_t*>(tarr->viewData());
+}
+
+JS_FRIEND_API(float*)
+JS_GetSharedFloat32ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float32);
+    return static_cast<float*>(tarr->viewData());
+}
+
+JS_FRIEND_API(double*)
+JS_GetSharedFloat64ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return nullptr;
+    SharedTypedArrayObject* tarr = &obj->as<SharedTypedArrayObject>();
+    MOZ_ASSERT((int32_t) tarr->type() == Scalar::Float64);
+    return static_cast<double*>(tarr->viewData());
+}
+
 #undef IMPL_SHARED_TYPED_ARRAY_STATICS
 #undef IMPL_SHARED_TYPED_ARRAY_JSAPI_CONSTRUCTORS
 #undef IMPL_SHARED_TYPED_ARRAY_COMBINED_UNWRAPPERS
 #undef SHARED_TYPED_ARRAY_CLASS_SPEC
 #undef IMPL_SHARED_TYPED_ARRAY_PROTO_CLASS
 #undef IMPL_SHARED_TYPED_ARRAY_FAST_CLASS
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -2206,16 +2206,28 @@ JS_GetArrayBufferViewType(JSObject* obj)
 
     if (obj->is<TypedArrayObject>())
         return obj->as<TypedArrayObject>().type();
     else if (obj->is<DataViewObject>())
         return Scalar::MaxTypedArrayViewType;
     MOZ_CRASH("invalid ArrayBufferView type");
 }
 
+JS_FRIEND_API(js::Scalar::Type)
+JS_GetSharedArrayBufferViewType(JSObject* obj)
+{
+    obj = CheckedUnwrap(obj);
+    if (!obj)
+        return Scalar::MaxTypedArrayViewType;
+
+    if (obj->is<SharedTypedArrayObject>())
+        return obj->as<SharedTypedArrayObject>().type();
+    MOZ_CRASH("invalid SharedArrayBufferView type");
+}
+
 JS_FRIEND_API(int8_t*)
 JS_GetInt8ArrayData(JSObject* obj, const JS::AutoCheckCannotGC&)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     TypedArrayObject* tarr = &obj->as<TypedArrayObject>();
     MOZ_ASSERT((int32_t) tarr->type() == Scalar::Int8);
--- a/js/src/vm/UbiNode.cpp
+++ b/js/src/vm/UbiNode.cpp
@@ -60,19 +60,19 @@ Concrete<void>::size(mozilla::MallocSize
 {
     MOZ_CRASH("null ubi::Node");
 }
 
 struct Node::ConstructFunctor : public js::BoolDefaultAdaptor<Value, false> {
     template <typename T> bool operator()(T* t, Node* node) { node->construct(t); return true; }
 };
 
-Node::Node(JS::TraceKind kind, void* ptr)
+Node::Node(const JS::GCCellPtr &thing)
 {
-    js::gc::CallTyped(ConstructFunctor(), ptr, kind, this);
+    js::gc::CallTyped(ConstructFunctor(), thing.asCell(), thing.kind(), this);
 }
 
 Node::Node(HandleValue value)
 {
     if (!DispatchValueTyped(ConstructFunctor(), value, this))
         construct<void>(nullptr);
 }
 
@@ -106,17 +106,17 @@ Node::exposeToJS() const
 // edge on which it is invoked.
 class SimpleEdgeVectorTracer : public JS::CallbackTracer {
     // The vector to which we add SimpleEdges.
     SimpleEdgeVector* vec;
 
     // True if we should populate the edge's names.
     bool wantNames;
 
-    void trace(void** thingp, JS::TraceKind kind) {
+    void onChild(const JS::GCCellPtr& thing) override {
         if (!okay)
             return;
 
         char16_t* name16 = nullptr;
         if (wantNames) {
             // Ask the tracer to compute an edge name for us.
             char buffer[1024];
             getTracingEdgeName(buffer, sizeof(buffer));
@@ -134,17 +134,17 @@ class SimpleEdgeVectorTracer : public JS
                 name16[i] = name[i];
             name16[i] = '\0';
         }
 
         // The simplest code is correct! The temporary SimpleEdge takes
         // ownership of name; if the append succeeds, the vector element
         // then takes ownership; if the append fails, then the temporary
         // retains it, and its destructor will free it.
-        if (!vec->append(mozilla::Move(SimpleEdge(name16, Node(kind, *thingp))))) {
+        if (!vec->append(mozilla::Move(SimpleEdge(name16, Node(thing))))) {
             okay = false;
             return;
         }
     }
 
   public:
     // True if no errors (OOM, say) have yet occurred.
     bool okay;
deleted file mode 100644
--- a/layout/mathml/MathJaxFonts.html
+++ /dev/null
@@ -1,178 +0,0 @@
-<!-- -*- mode: HTML; tab-width: 2; indent-tabs-mode: nil; -*- -->
-<!-- vim: set tabstop=2 expandtab shiftwidth=2 textwidth=80:  -->
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
-   - License, v. 2.0. If a copy of the MPL was not distributed with this
-   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>MathJax fonts</title>
-    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-    <script type="text/x-mathjax-config">
-      MathJax.Hub.Config({
-        jax: ["output/HTML-CSS"],
-        "HTML-CSS": { availableFonts: ["TeX"] }
-      });
-    </script>
-    <script type="text/javascript"
-            src="http://cdn.mathjax.org/mathjax/latest/unpacked/MathJax.js">
-    </script>
-    <script type="text/javascript">
-      var fontList = [
-        "MathJax_Main",
-        "MathJax_Size1",
-        "MathJax_Size2",
-        "MathJax_Size3",
-        "MathJax_Size4",
-        "MathJax_AMS",
-        "MathJax_Main-bold"
-      ];
-
-      var noChar = codePoint();
-
-      function codePoint(aValue, aFont)
-      {
-        var v = 0xFFFD;
-        if (aValue) {
-          v = aValue;
-        }
-        var f = "";
-        if (aFont) {
-          var i = fontList.indexOf(aFont);
-          if (i > 0) {
-            f = "@" + i;
-          }
-        }
-        var hexacode = Number(v).toString(16).toUpperCase();
-        while (hexacode.length < 4) {
-          hexacode = "0" + hexacode;
-        }
-        return "\\u" + hexacode + f;
-      }
-
-      function codePoint2(aList)
-      {
-        if (aList) {
-          return codePoint(aList[0], aList[1]);
-        } else {
-          return noChar;
-        }
-      }
-
-      function isSupported(aStretch)
-      {
-        for (var x in aStretch) {
-          var part = aStretch[x];
-          if (part[0] instanceof Array) {
-            // Composite char
-            return false;
-          } else if (part.length > 2) {
-            // Part has scale factor
-            return false;
-          }
-        }
-        return true;
-      }
-
-      MathJax.Hub.Queue(
-      ["Require", MathJax.Ajax, "[MathJax]/jax/element/mml/jax.js"],
-      ["Require", MathJax.Ajax, "[MathJax]/jax/output/HTML-CSS/jax.js"],
-      ["Require", MathJax.Ajax, "[MathJax]/jax/output/HTML-CSS/fonts/TeX/fontdata-extra.js"],
-      function () {
-
-      var t = document.getElementById("output");
-      t.value = "";
-
-      var fontData = MathJax.OutputJax["HTML-CSS"].FONTDATA;
-
-      t.value += "# Content below is generated from MathJaxFonts.html. Do not edit.\n";
-      t.value += "\n";
-
-      // Generate the list of external fonts
-      for (var i = 1; i < fontList.length; i++) {
-        t.value += "external." + i + " = " + fontList[i] + "\n";
-      }
-      t.value += "\n";
-
-      // Generate stretchy table for delimiters
-      var delimiters = fontData.DELIMITERS;
-      for (var u in delimiters) {
-
-        var v = delimiters[u];
-
-        if (v.load) {
-          // These characters are already handled when we load fontdata-extra.js
-          continue;
-        }
-
-        if (v.alias) {
-          if (delimiters.hasOwnProperty(v.alias)) {
-            // use data from the char pointed by this alias
-            v = delimiters[v.alias];
-          } else {
-            // It is an alias to a non-stretchy char. Ignore it.
-            continue;
-          }
-        }
-
-        if (v.stretch && !isSupported(v.stretch)) {
-          // This construction is not supported.
-          t.value += "# " + codePoint(u) + " = [not supported]\n";
-          continue;
-        }
-
-        t.value += codePoint(u);
-        t.value += " = ";
-        if (v.stretch) {
-          if (v.dir == "V") {
-            t.value += codePoint2(v.stretch.top);
-            t.value += codePoint2(v.stretch.mid);
-            t.value += codePoint2(v.stretch.bot);
-            t.value += codePoint2(v.stretch.ext);
-          } else {
-            t.value += codePoint2(v.stretch.left);
-            t.value += codePoint2(v.stretch.mid);
-            t.value += codePoint2(v.stretch.right);
-            t.value += codePoint2(v.stretch.rep);
-          }
-        } else {
-          t.value += noChar + noChar + noChar + noChar;
-        }
-
-        for (var i in v.HW) {
-            t.value += codePoint(u, v.HW[i][1]);
-        }
-
-        t.value += "\n";
-      }
-
-      // Generate table for large operators
-      var fonts1 = fontData.FONTS[fontList[1]];
-      var fonts2 = fontData.FONTS[fontList[2]];
-      for (var u in fonts1) {
-        if (delimiters.hasOwnProperty(u) || // already listed above
-            u == "version" || u == "available" ||
-            u == "directory" ||  u == "family" || u == "testString") {
-          // Ignore these properties
-          continue;
-        }
-        t.value += codePoint(u);
-        t.value += " = ";
-        t.value += noChar + noChar + noChar + noChar;
-        t.value += codePoint(u, fontList[1]);
-        if (fonts2.hasOwnProperty(u)) {
-          t.value += codePoint(u, fontList[2]);
-        }
-        t.value += "\n";
-       }
- 
-     });
-    </script>
-  </head>
-
-  <body>
-
-    <textarea id="output" cols="80" rows="20"></textarea>
-
-  </body>
-</html>
deleted file mode 100644
--- a/layout/mathml/mathfontMathJax_Main.properties
+++ /dev/null
@@ -1,144 +0,0 @@
-# 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/.
-
-# Content below is generated from MathJaxFonts.html. Do not edit.
-
-external.1 = MathJax_Size1
-external.2 = MathJax_Size2
-external.3 = MathJax_Size3
-external.4 = MathJax_Size4
-external.5 = MathJax_AMS
-# external.6 = MathJax_Main-bold
-
-\u0028 = \u239B@4\uFFFD\u239D@4\u239C@4\u0028\u0028@1\u0028@2\u0028@3\u0028@4
-\u0029 = \u239E@4\uFFFD\u23A0@4\u239F@4\u0029\u0029@1\u0029@2\u0029@3\u0029@4
-\u002F = \uFFFD\uFFFD\uFFFD\uFFFD\u002F\u002F@1\u002F@2\u002F@3\u002F@4
-\u005B = \u23A1@4\uFFFD\u23A3@4\u23A2@4\u005B\u005B@1\u005B@2\u005B@3\u005B@4
-\u005C = \uFFFD\uFFFD\uFFFD\uFFFD\u005C\u005C@1\u005C@2\u005C@3\u005C@4
-\u005D = \u23A4@4\uFFFD\u23A6@4\u23A5@4\u005D\u005D@1\u005D@2\u005D@3\u005D@4
-\u007B = \u23A7@4\u23A8@4\u23A9@4\u23AA@4\u007B\u007B@1\u007B@2\u007B@3\u007B@4
-\u007C = \uFFFD\uFFFD\uFFFD\u2223\u007C
-\u007D = \u23AB@4\u23AC@4\u23AD@4\u23AA@4\u007D\u007D@1\u007D@2\u007D@3\u007D@4
-\u00AF = \uFFFD\uFFFD\uFFFD\u00AF\u00AF
-\u02C6 = \uFFFD\uFFFD\uFFFD\uFFFD\u02C6\u02C6@1\u02C6@2\u02C6@3\u02C6@4
-\u02DC = \uFFFD\uFFFD\uFFFD\uFFFD\u02DC\u02DC@1\u02DC@2\u02DC@3\u02DC@4
-\u2016 = \uFFFD\uFFFD\uFFFD\u2225\u2016@1\u2016
-\u2190 = \u2190\uFFFD\uFFFD\u2212\u2190
-\u2191 = \u2191@1\uFFFD\uFFFD\u23D0@1\u2191
-\u2192 = \uFFFD\uFFFD\u2192\u2212\u2192
-\u2193 = \uFFFD\uFFFD\u2193@1\u23D0@1\u2193
-\u2194 = \u2190\uFFFD\u2192\u2212\u2194
-\u2195 = \u2191@1\uFFFD\u2193@1\u23D0@1\u2195
-\u21D0 = \u21D0\uFFFD\uFFFD\u003D\u21D0
-\u21D1 = \u21D1@1\uFFFD\uFFFD\u2016@1\u21D1
-\u21D2 = \uFFFD\uFFFD\u21D2\u003D\u21D2
-\u21D3 = \uFFFD\uFFFD\u21D3@1\u2016@1\u21D3
-\u21D4 = \u21D0\uFFFD\u21D2\u003D\u21D4
-\u21D5 = \u21D1@1\uFFFD\u21D3@1\u2016@1\u21D5
-\u2212 = \uFFFD\uFFFD\uFFFD\u2212\u2212
-\u221A = \uE001@4\uFFFD\u23B7@4\uE000@4\u221A\u221A@1\u221A@2\u221A@3\u221A@4
-\u2223 = \uFFFD\uFFFD\uFFFD\u2223\u2223
-\u2225 = \uFFFD\uFFFD\uFFFD\u2225\u2225
-\u2308 = \u23A1@4\uFFFD\uFFFD\u23A2@4\u2308\u2308@1\u2308@2\u2308@3\u2308@4
-\u2309 = \u23A4@4\uFFFD\uFFFD\u23A5@4\u2309\u2309@1\u2309@2\u2309@3\u2309@4
-\u230A = \uFFFD\uFFFD\u23A3@4\u23A2@4\u230A\u230A@1\u230A@2\u230A@3\u230A@4
-\u230B = \uFFFD\uFFFD\u23A6@4\u23A5@4\u230B\u230B@1\u230B@2\u230B@3\u230B@4
-\u23AA = \u23AA@4\uFFFD\u23AA@4\u23AA@4\u23AA@4
-\u23B0 = \u23A7@4\uFFFD\u23AD@4\u23AA@4\u23B0
-\u23B1 = \u23AB@4\uFFFD\u23A9@4\u23AA@4\u23B1
-\u23D0 = \uFFFD\uFFFD\uFFFD\u2223\u23D0@1\u23D0
-# \u23DE = [not supported]
-# \u23DF = [not supported]
-\u27E8 = \uFFFD\uFFFD\uFFFD\uFFFD\u27E8\u27E8@1\u27E8@2\u27E8@3\u27E8@4
-\u27E9 = \uFFFD\uFFFD\uFFFD\uFFFD\u27E9\u27E9@1\u27E9@2\u27E9@3\u27E9@4
-\u27EE = \u23A7@4\uFFFD\u23A9@4\u23AA@4\u27EE
-\u27EF = \u23AB@4\uFFFD\u23AD@4\u23AA@4\u27EF
-\u002D = \uFFFD\uFFFD\uFFFD\u2212\u002D
-\u005E = \uFFFD\uFFFD\uFFFD\uFFFD\u005E\u005E@1\u005E@2\u005E@3\u005E@4
-\u005F = \uFFFD\uFFFD\uFFFD\u2212\u005F
-\u007E = \uFFFD\uFFFD\uFFFD\uFFFD\u007E\u007E@1\u007E@2\u007E@3\u007E@4
-\u02C9 = \uFFFD\uFFFD\uFFFD\u00AF\u02C9
-\u0302 = \uFFFD\uFFFD\uFFFD\uFFFD\u0302\u0302@1\u0302@2\u0302@3\u0302@4
-\u0303 = \uFFFD\uFFFD\uFFFD\uFFFD\u0303\u0303@1\u0303@2\u0303@3\u0303@4
-\u0332 = \uFFFD\uFFFD\uFFFD\u2212\u0332
-\u2015 = \uFFFD\uFFFD\uFFFD\u2212\u2015
-\u2017 = \uFFFD\uFFFD\uFFFD\u2212\u2017
-\u203E = \uFFFD\uFFFD\uFFFD\u00AF\u203E
-\u2215 = \uFFFD\uFFFD\uFFFD\uFFFD\u2215\u2215@1\u2215@2\u2215@3\u2215@4
-\u2329 = \uFFFD\uFFFD\uFFFD\uFFFD\u2329\u2329@1\u2329@2\u2329@3\u2329@4
-\u232A = \uFFFD\uFFFD\uFFFD\uFFFD\u232A\u232A@1\u232A@2\u232A@3\u232A@4
-\u23AF = \uFFFD\uFFFD\uFFFD\u2212\u23AF
-\u2500 = \uFFFD\uFFFD\uFFFD\u2212\u2500
-\u2758 = \uFFFD\uFFFD\uFFFD\u2223\u2758
-\u3008 = \uFFFD\uFFFD\uFFFD\uFFFD\u3008\u3008@1\u3008@2\u3008@3\u3008@4
-\u3009 = \uFFFD\uFFFD\uFFFD\uFFFD\u3009\u3009@1\u3009@2\u3009@3\u3009@4
-# \uFE37 = [not supported]
-# \uFE38 = [not supported]
-\u003D = \uFFFD\uFFFD\uFFFD\u003D\u003D
-\u219E = \u219E@5\uFFFD\uFFFD\u2212\u219E@5
-\u21A0 = \uFFFD\uFFFD\u21A0@5\u2212\u21A0@5
-# \u21A4 = [not supported]
-# \u21A5 = [not supported]
-# \u21A6 = [not supported]
-# \u21A7 = [not supported]
-# \u21B0 = [not supported]
-# \u21B1 = [not supported]
-\u21BC = \u21BC\uFFFD\uFFFD\u2212\u21BC
-\u21BD = \u21BD\uFFFD\uFFFD\u2212\u21BD
-# \u21BE = [not supported]
-# \u21BF = [not supported]
-\u21C0 = \uFFFD\uFFFD\u21C0\u2212\u21C0
-\u21C1 = \uFFFD\uFFFD\u21C1\u2212\u21C1
-# \u21C2 = [not supported]
-# \u21C3 = [not supported]
-\u21DA = \u21DA@5\uFFFD\uFFFD\u2261\u21DA@5
-\u21DB = \uFFFD\uFFFD\u21DB@5\u2261\u21DB@5
-# \u23B4 = [not supported]
-# \u23B5 = [not supported]
-\u23DC = \uE150@4\uFFFD\uE151@4\uE154@4\u23DC@5\u23DC
-\u23DD = \uE152@4\uFFFD\uE153@4\uE154@4\u23DD@5\u23DD
-# \u23E0 = [not supported]
-# \u23E1 = [not supported]
-# \u2906 = [not supported]
-# \u2907 = [not supported]
-\u294E = \u21BC\uFFFD\u21C0\u2212
-# \u294F = [not supported]
-\u2950 = \u21BD\uFFFD\u21C1\u2212
-# \u2951 = [not supported]
-# \u295A = [not supported]
-# \u295B = [not supported]
-# \u295C = [not supported]
-# \u295D = [not supported]
-# \u295E = [not supported]
-# \u295F = [not supported]
-# \u2960 = [not supported]
-# \u2961 = [not supported]
-\u27F5 = \u2190\uFFFD\uFFFD\u2212\u27F5
-\u27F6 = \uFFFD\uFFFD\u2192\u2212\u27F6
-\u27F7 = \u2190\uFFFD\u2192\u2212\u27F7
-\u27F8 = \u21D0\uFFFD\uFFFD\u003D\u27F8
-\u27F9 = \uFFFD\uFFFD\u21D2\u003D\u27F9
-\u27FA = \u21D0\uFFFD\u21D2\u003D\u27FA
-# \u27FB = [not supported]
-# \u27FC = [not supported]
-# \u27FD = [not supported]
-# \u27FE = [not supported]
-\u0020 = \uFFFD\uFFFD\uFFFD\uFFFD\u0020@1\u0020@2
-\u00A0 = \uFFFD\uFFFD\uFFFD\uFFFD\u00A0@1\u00A0@2
-\u220F = \uFFFD\uFFFD\uFFFD\uFFFD\u220F@1\u220F@2
-\u2210 = \uFFFD\uFFFD\uFFFD\uFFFD\u2210@1\u2210@2
-\u2211 = \uFFFD\uFFFD\uFFFD\uFFFD\u2211@1\u2211@2
-\u222B = \uFFFD\uFFFD\uFFFD\uFFFD\u222B@1\u222B@2
-\u222C = \uFFFD\uFFFD\uFFFD\uFFFD\u222C@1\u222C@2
-\u222D = \uFFFD\uFFFD\uFFFD\uFFFD\u222D@1\u222D@2
-\u222E = \uFFFD\uFFFD\uFFFD\uFFFD\u222E@1\u222E@2
-\u22C0 = \uFFFD\uFFFD\uFFFD\uFFFD\u22C0@1\u22C0@2
-\u22C1 = \uFFFD\uFFFD\uFFFD\uFFFD\u22C1@1\u22C1@2
-\u22C2 = \uFFFD\uFFFD\uFFFD\uFFFD\u22C2@1\u22C2@2
-\u22C3 = \uFFFD\uFFFD\uFFFD\uFFFD\u22C3@1\u22C3@2
-\u2A00 = \uFFFD\uFFFD\uFFFD\uFFFD\u2A00@1\u2A00@2
-\u2A01 = \uFFFD\uFFFD\uFFFD\uFFFD\u2A01@1\u2A01@2
-\u2A02 = \uFFFD\uFFFD\uFFFD\uFFFD\u2A02@1\u2A02@2
-\u2A04 = \uFFFD\uFFFD\uFFFD\uFFFD\u2A04@1\u2A04@2
-\u2A06 = \uFFFD\uFFFD\uFFFD\uFFFD\u2A06@1\u2A06@2
deleted file mode 100644
--- a/layout/mathml/mathfontStandardSymbolsL.properties
+++ /dev/null
@@ -1,43 +0,0 @@
-# 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/.
-
-#  LOCALIZATION NOTE: FILE
-#  Do not translate anything in this file
-
-# This file contains the list of all stretchy MathML chars that
-# can be rendered with Standard Symbols L.
-
-#        [ T/L |  M  | B/R |  G  | size0 ... size{N-1} ]
-\u0028 = \uF8EB\uFFFD\uF8ED\uF8EC\u0028 # (
-\u0029 = \uF8F6\uFFFD\uF8F8\uF8F7\u0029 # )
-\u005B = \uF8EE\uFFFD\uF8F0\uF8EF\u005B # [
-\u005D = \uF8F9\uFFFD\uF8FB\uF8FA\u005D # ]
-\u007B = \uF8F1\uF8F2\uF8F3\uF8F4\u007B # {
-\u007C = \uFFFD\uFFFD\uFFFD\u007C\u007C # |
-\u007D = \uF8FC\uF8FD\uF8FE\uF8F4\u007D # }
-
-\u00AF = \uFFFD\uFFFD\uFFFD\uF8E5\u00AF # ad-hoc: overbar is stretched with the radical extender 
-\u0332 = \uFFFD\uFFFD\uFFFD\u005F\u0332 # ad-hock: UnderBar (0x0332) is stretched with underscore
-
-\u2190 = \u2190\uFFFD\uFFFD\uF8E7\u2190 # LeftArrow, larr, leftarrow
-\u2191 = \u2191\uFFFD\uFFFD\uF8E6\u2191 # UpArrow, uarr, uparrow
-\u2192 = \uFFFD\uFFFD\u2192\uF8E7\u2192 # RightArrow, rarr, rightarrow
-\u2193 = \uFFFD\uFFFD\u2193\uF8E6\u2193 # DownArrow, darr, downarrow
-\u2194 = \u2190\uFFFD\u2192\uF8E7\u2194 # LeftRightArrow, harr, leftrightarrow
-\u2195 = \u2191\uFFFD\u2193\uF8E6\u2195 # UpDownArrow, updownarrow, varr
-
-\u222B = \u2320\uFFFD\u2321\uF8F5\u222B # Integral, int
-# If there are problems with the font-supplied glue use a rule:
-# \u222B = \u2320\uFFFD\u2321\uFFFD\u222B # Integral, int
-
-# Using parts of [ and ]
-\u2308 = \uF8EE\uFFFD\uFFFD\uF8EF\u2308 # LeftCeiling, lceil
-\u2309 = \uF8F9\uFFFD\uFFFD\uF8FA\u2309 # RightCeiling, rceil
-\u230A = \uFFFD\uFFFD\uF8F0\uF8EF\u230A # LeftFloor, lfloor
-\u230B = \uFFFD\uFFFD\uF8FB\uF8FA\u230B # RightFloor, rfloor
-
-# same as normal arrows
-\u27F5 = \u2190\uFFFD\uFFFD\uF8E7\u27F5 # LongLeftArrow
-\u27F6 = \uFFFD\uFFFD\u2192\uF8E7\u27F6 # LongRightArrow
-\u27F7 = \u2190\uFFFD\u2192\uF8E7\u27F7 # LongLeftRightArrow
--- a/layout/mathml/moz.build
+++ b/layout/mathml/moz.build
@@ -50,18 +50,16 @@ LOCAL_INCLUDES += [
     '/dom/base',
     '/dom/mathml',
 ]
 
 JAR_MANIFESTS += ['jar.mn']
 
 RESOURCE_FILES.fonts += [
     'mathfont.properties',
-    'mathfontMathJax_Main.properties',
-    'mathfontStandardSymbolsL.properties',
     'mathfontSTIXGeneral.properties',
     'mathfontUnicode.properties',
 ]
 
 RESOURCE_FILES.fonts['mathfont.properties'].preprocess = True
 
 if CONFIG['TARGET_MD_ARCH'] == 'win32':
     RESOURCE_FILES.fonts += [
--- a/layout/mathml/nsMathMLChar.cpp
+++ b/layout/mathml/nsMathMLChar.cpp
@@ -729,19 +729,17 @@ InitGlobals(nsPresContext* aPresContext)
   }
   if (NS_FAILED(rv)) {
     return rv;
   }
   // The gGlyphTableList has been successfully registered as a shutdown
   // observer and will be deleted at shutdown. We now add some private
   // per font-family tables for stretchy operators, in order of preference.
   // Do not include the Unicode table in this list.
-  if (!glyphTableList->AddGlyphTable(NS_LITERAL_STRING("MathJax_Main")) ||
-      !glyphTableList->AddGlyphTable(NS_LITERAL_STRING("STIXGeneral")) ||
-      !glyphTableList->AddGlyphTable(NS_LITERAL_STRING("Standard Symbols L"))
+  if (!glyphTableList->AddGlyphTable(NS_LITERAL_STRING("STIXGeneral"))
 #ifdef XP_WIN
       || !glyphTableList->AddGlyphTable(NS_LITERAL_STRING("Symbol"))
 #endif
       ) {
     rv = NS_ERROR_OUT_OF_MEMORY;
   }
 
   glyphTableList.forget(&gGlyphTableList);
--- a/media/libstagefright/binding/BufferStream.cpp
+++ b/media/libstagefright/binding/BufferStream.cpp
@@ -8,21 +8,21 @@
 #include <algorithm>
 
 using namespace mozilla;
 
 namespace mp4_demuxer {
 
 BufferStream::BufferStream()
   : mStartOffset(0)
-  , mData(new mozilla::MediaLargeByteBuffer)
+  , mData(new mozilla::MediaByteBuffer)
 {
 }
 
-BufferStream::BufferStream(mozilla::MediaLargeByteBuffer* aBuffer)
+BufferStream::BufferStream(mozilla::MediaByteBuffer* aBuffer)
   : mStartOffset(0)
   , mData(aBuffer)
 {
 }
 
 BufferStream::~BufferStream()
 {
 }
--- a/media/libstagefright/binding/include/mp4_demuxer/BufferStream.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/BufferStream.h
@@ -5,42 +5,42 @@
 #ifndef BUFFER_STREAM_H_
 #define BUFFER_STREAM_H_
 
 #include "mp4_demuxer/Stream.h"
 #include "nsTArray.h"
 #include "MediaResource.h"
 
 namespace mozilla {
-class MediaLargeByteBuffer;
+class MediaByteBuffer;
 }
 
 namespace mp4_demuxer {
 
 class BufferStream : public Stream
 {
 public:
   /* BufferStream does not take ownership of aData nor does it make a copy.
    * Therefore BufferStream shouldn't get used after aData is destroyed.
    */
   BufferStream();
-  explicit BufferStream(mozilla::MediaLargeByteBuffer* aBuffer);
+  explicit BufferStream(mozilla::MediaByteBuffer* aBuffer);
 
   virtual bool ReadAt(int64_t aOffset, void* aData, size_t aLength,
                       size_t* aBytesRead) override;
   virtual bool CachedReadAt(int64_t aOffset, void* aData, size_t aLength,
                             size_t* aBytesRead) override;
   virtual bool Length(int64_t* aLength) override;
 
   virtual void DiscardBefore(int64_t aOffset) override;
 
   bool AppendBytes(const uint8_t* aData, size_t aLength);
 
   mozilla::MediaByteRange GetByteRange();
 
 private:
   ~BufferStream();
   int64_t mStartOffset;
-  nsRefPtr<mozilla::MediaLargeByteBuffer> mData;
+  nsRefPtr<mozilla::MediaByteBuffer> mData;
 };
 }
 
 #endif
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1855,17 +1855,17 @@ pref("intl.hyphenation-alias.bs-*", "sh"
 // Norwegian has two forms, Bokmål and Nynorsk, with "no" as a macrolanguage encompassing both.
 // For "no", we'll alias to "nb" (Bokmål) as that is the more widely used written form.
 pref("intl.hyphenation-alias.no", "nb");
 pref("intl.hyphenation-alias.no-*", "nb");
 pref("intl.hyphenation-alias.nb-*", "nb");
 pref("intl.hyphenation-alias.nn-*", "nn");
 
 pref("font.name.serif.x-math", "Latin Modern Math");
-pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Standard Symbols L, serif");
+pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, STIXGeneral, DejaVu Serif, DejaVu Sans, serif");
 pref("font.name.sans-serif.x-math", "sans-serif");
 pref("font.name.monospace.x-math", "monospace");
 
 // Some CJK fonts have bad underline offset, their CJK character glyphs are overlapped (or adjoined)  to its underline.
 // These fonts are ignored the underline offset, instead of it, the underline is lowered to bottom of its em descent.
 pref("font.blacklist.underline_offset", "FangSong,Gulim,GulimChe,MingLiU,MingLiU-ExtB,MingLiU_HKSCS,MingLiU-HKSCS-ExtB,MS Gothic,MS Mincho,MS PGothic,MS PMincho,MS UI Gothic,PMingLiU,PMingLiU-ExtB,SimHei,SimSun,SimSun-ExtB,Hei,Kai,Apple LiGothic,Apple LiSung,Osaka");
 
 #ifdef MOZ_B2G
@@ -2971,17 +2971,17 @@ pref("font.name-list.serif.x-tibt", "Tib
 pref("font.name-list.sans-serif.x-tibt", "Tibetan Machine Uni, Jomolhari, Microsoft Himalaya");
 pref("font.name-list.monospace.x-tibt", "Tibetan Machine Uni, Jomolhari, Microsoft Himalaya");
 
 pref("font.minimum-size.th", 10);
 
 pref("font.default.x-devanagari", "sans-serif");
 pref("font.name.serif.x-math", "Latin Modern Math");
 // We have special support for Monotype Symbol on Windows.
-pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Symbol, Times New Roman");
+pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, STIXGeneral, DejaVu Serif, DejaVu Sans, Symbol, Times New Roman");
 pref("font.name.sans-serif.x-math", "Arial");
 pref("font.name.monospace.x-math", "Courier New");
 pref("font.name.cursive.x-math", "Comic Sans MS");
 
 // cleartype settings - false implies default system settings
 
 // use cleartype rendering for downloadable fonts (win xp only)
 pref("gfx.font_rendering.cleartype.use_for_downloadable_fonts", true);
@@ -3402,17 +3402,17 @@ pref("font.name-list.monospace.zh-HK", "
 // XP_MACOSX changes to default font sizes
 pref("font.minimum-size.th", 10);
 pref("font.size.variable.zh-CN", 15);
 pref("font.size.variable.zh-HK", 15);
 pref("font.size.variable.zh-TW", 15);
 
 pref("font.name.serif.x-math", "Latin Modern Math");
 // Apple's Symbol is Unicode so use it
-pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Symbol, Times");
+pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, STIXGeneral, DejaVu Serif, DejaVu Sans, Symbol, Times");
 pref("font.name.sans-serif.x-math", "Helvetica");
 pref("font.name.monospace.x-math", "Courier");
 pref("font.name.cursive.x-math", "Apple Chancery");
 pref("font.name.fantasy.x-math", "Papyrus");
 
 // individual font faces to be treated as independent families
 // names are Postscript names of each face
 pref("font.single-face-list", "Osaka-Mono");
@@ -3828,17 +3828,17 @@ pref("font.name.monospace.zh-HK", "Fira 
 pref("font.name-list.sans-serif.zh-HK", "Fira Sans,Droid Sans Fallback");
 
 pref("font.name.serif.zh-TW", "Charis SIL Compact");
 pref("font.name.sans-serif.zh-TW", "Fira Sans");
 pref("font.name.monospace.zh-TW", "Fira Mono");
 pref("font.name-list.sans-serif.zh-TW", "Fira Sans,Droid Sans Fallback");
 
 pref("font.name.serif.x-math", "Latin Modern Math");
-pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Charis SIL Compact");
+pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, STIXGeneral, DejaVu Serif, DejaVu Sans, Charis SIL Compact");
 pref("font.name.sans-serif.x-math", "Fira Sans");
 pref("font.name.monospace.x-math", "Fira Mono");
 
 #elif defined(ANDROID)
 // We use the bundled fonts for Firefox for Android
 
 // ar
 
@@ -3906,17 +3906,17 @@ pref("font.name-list.monospace.zh-HK", "
 pref("font.name.serif.zh-TW", "Charis SIL Compact");
 pref("font.name.sans-serif.zh-TW", "Clear Sans");
 pref("font.name.monospace.zh-TW", "Droid Sans Mono");
 pref("font.name-list.serif.zh-TW", "Droid Serif, Droid Sans Fallback");
 pref("font.name-list.sans-serif.zh-TW", "Roboto, Droid Sans, Noto Sans TC, Noto Sans SC, Droid Sans Fallback");
 pref("font.name-list.monospace.zh-TW", "Droid Sans Fallback");
 
 pref("font.name.serif.x-math", "Latin Modern Math");
-pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Charis SIL Compact");
+pref("font.name-list.serif.x-math", "Latin Modern Math, XITS Math, Cambria Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, STIXGeneral, DejaVu Serif, DejaVu Sans, Charis SIL Compact");
 pref("font.name.sans-serif.x-math", "Clear Sans");
 pref("font.name.monospace.x-math", "Droid Sans Mono");
 
 #endif
 
 #if OS_ARCH==AIX
 
 // Override default Japanese fonts
--- a/netwerk/test/moz.build
+++ b/netwerk/test/moz.build
@@ -43,17 +43,16 @@ GeckoSimplePrograms([
 #    TestStreamPump',
 #    TestStreamTransport',
 #    TestUDPSocketProvider',
 #]
 
 CppUnitTests([
     'TestBind',
     'TestCookie',
-    'TestSTSParser',
     'TestUDPSocket',
 ])
 
 RESOURCE_FILES += [
     'urlparse.dat',
     'urlparse_unx.dat',
 ]
 
rename from netwerk/test/TestSTSParser.cpp
rename to security/manager/ssl/tests/compiled/TestSTSParser.cpp
--- a/security/manager/ssl/tests/compiled/moz.build
+++ b/security/manager/ssl/tests/compiled/moz.build
@@ -1,9 +1,13 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
+CppUnitTests([
+    'TestSTSParser',
+])
+
 GeckoCppUnitTests([
-  'TestCertDB',
+    'TestCertDB',
 ])
--- a/security/manager/ssl/tests/mochitest/bugs/mochitest.ini
+++ b/security/manager/ssl/tests/mochitest/bugs/mochitest.ini
@@ -1,8 +1,6 @@
 [DEFAULT]
 tags = psm
 skip-if = buildapp == 'b2g' || e10s
 
 [test_bug480509.html]
 skip-if = toolkit == 'android'
-[test_bug483440.html]
-skip-if = toolkit == 'android'
rename from security/manager/ssl/tests/mochitest/bugs/test_bug483440.html
rename to security/manager/ssl/tests/unit/test_certviewer_invalid_oids.js
--- a/security/manager/ssl/tests/mochitest/bugs/test_bug483440.html
+++ b/security/manager/ssl/tests/unit/test_certviewer_invalid_oids.js
@@ -1,62 +1,62 @@
-<html>
-<head>
-  <title>Test bug 483437 and bug 480509</title>
-  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-</head>
-<body>
-
-<script class="testbody" type="text/javascript">
-
-var certdb = SpecialPowers.Cc["@mozilla.org/security/x509certdb;1"]
-  .getService(SpecialPowers.Ci.nsIX509CertDB);
-
-function test(certNick, expected)
-{
-  var cert1 = certdb.findCertByNickname(null, certNick);
-  var certDumpTree1 = SpecialPowers.Cc["@mozilla.org/security/nsASN1Tree;1"]
-                     .createInstance(SpecialPowers.Ci.nsIASN1Tree);
-  certDumpTree1.loadASN1Structure(cert1.ASN1Structure);
-  var value1 = certDumpTree1.getDisplayData(9);
-  
-  is(value1, expected, "Incorrect OID recognized");
-}
-
-test("bug483440-attack2b", 
-     "Object Identifier (2 5 4 Unknown) = www.bank.com\n"+
-     "OU = Hacking Division\n"+
-     "CN = www.badguy.com\nO = Badguy Inc\n");
-
-test("bug483440-pk10oflo",
-     "Object Identifier (2 5 4 Unknown) = www.bank.com\n"+
-     "OU = Hacking Division\n"+
-     "CN = www.badguy.com\nO = Badguy Inc\n");
-
-test("bug483440-attack7",
-
-     // Check 88 80 80 80 01, not leading, have to pass
-     "Object Identifier (2 5 4 2147483649) = attack1\n"+
-     
-     // Check 90 80 80 80 01, not leading, have to fail
-     "Object Identifier (2 5 4 Unknown) = attack2\n"+
-     
-     // Check 80 80 80 80 80, not leading, have to fail
-     "Object Identifier (2 5 4 Unknown) = attack3\n"+
-     
-     // Check 81 81, trailing, have to fail
-     "Object Identifier (2 5 4 3 Unknown) = attack4\n"+
-     
-     // Check FF FF FF 7F, not leading, have to pass
-     "Object Identifier (2 5 4 268435455) = attack5\n"+
-     
-     // Check 80 leading, have to fail
-     "Object Identifier (Unknown 3) = attack6\n"+
-     
-     // Check 14757 = 2*40 + 14677 leading single byle encoded as F325, 
-     // have to pass
-     "Object Identifier (2 14677 4 3) = attack7\n");
-
-</script>
-
-</body>
-</html>
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+"use strict";
+
+// Checks that invalid OID encodings are detected in the Cert Viewer Details tab.
+
+do_get_profile(); // Must be called before getting nsIX509CertDB
+const certDB = Cc["@mozilla.org/security/x509certdb;1"]
+                 .getService(Ci.nsIX509CertDB);
+
+function certFromFile(filename) {
+  return constructCertFromFile(`test_certviewer_invalid_oids/${filename}.pem`);
+}
+
+function test(certFilename, expectedOIDText) {
+  let cert = certFromFile(certFilename);
+  let certDumpTree = Cc["@mozilla.org/security/nsASN1Tree;1"]
+                       .createInstance(Ci.nsIASN1Tree);
+  certDumpTree.loadASN1Structure(cert.ASN1Structure);
+  let actualOIDText = certDumpTree.getDisplayData(9);
+
+  equal(actualOIDText, expectedOIDText,
+        "Actual and expected OID text should match");
+}
+
+function run_test() {
+  test("bug483440-attack2b",
+       "Object Identifier (2 5 4 Unknown) = www.bank.com\n" +
+       "OU = Hacking Division\n" +
+       "CN = www.badguy.com\nO = Badguy Inc\n");
+
+  test("bug483440-pk10oflo",
+       "Object Identifier (2 5 4 Unknown) = www.bank.com\n" +
+       "OU = Hacking Division\n" +
+       "CN = www.badguy.com\nO = Badguy Inc\n");
+
+  test("bug483440-attack7",
+
+       // Check 88 80 80 80 01, not leading, have to pass
+       "Object Identifier (2 5 4 2147483649) = attack1\n" +
+
+       // Check 90 80 80 80 01, not leading, have to fail
+       "Object Identifier (2 5 4 Unknown) = attack2\n" +
+
+       // Check 80 80 80 80 80, not leading, have to fail
+       "Object Identifier (2 5 4 Unknown) = attack3\n" +
+
+       // Check 81 81, trailing, have to fail
+       "Object Identifier (2 5 4 3 Unknown) = attack4\n" +
+
+       // Check FF FF FF 7F, not leading, have to pass
+       "Object Identifier (2 5 4 268435455) = attack5\n" +
+
+       // Check 80 leading, have to fail
+       "Object Identifier (Unknown 3) = attack6\n" +
+
+       // Check 14757 = 2*40 + 14677 leading single byte encoded as F325,
+       // have to pass
+       "Object Identifier (2 14677 4 3) = attack7\n");
+}
rename from build/pgo/certs/bug483440-attack2b.ca
rename to security/manager/ssl/tests/unit/test_certviewer_invalid_oids/bug483440-attack2b.pem
rename from build/pgo/certs/bug483440-attack7.ca
rename to security/manager/ssl/tests/unit/test_certviewer_invalid_oids/bug483440-attack7.pem
rename from build/pgo/certs/bug483440-pk10oflo.ca
rename to security/manager/ssl/tests/unit/test_certviewer_invalid_oids/bug483440-pk10oflo.pem
--- a/security/manager/ssl/tests/unit/xpcshell.ini
+++ b/security/manager/ssl/tests/unit/xpcshell.ini
@@ -2,16 +2,17 @@
 head = head_psm.js
 tail =
 tags = psm
 support-files =
   test_cert_keyUsage/**
   test_signed_apps/**
   tlsserver/**
   test_cert_signatures/**
+  test_certviewer_invalid_oids/**
   test_client_cert/**
   test_ev_certs/**
   test_getchain/**
   test_intermediate_basic_usage_constraints/**
   test_name_constraints/**
   test_cert_trust/**
   test_cert_version/**
   test_cert_eku/**
@@ -124,8 +125,10 @@ run-sequentially = hardcoded ports
 [test_cert_chains.js]
 run-sequentially = hardcoded ports
 [test_client_cert.js]
 run-sequentially = hardcoded ports
 [test_nsCertType.js]
 run-sequentially = hardcoded ports
 [test_nsIX509Cert_utf8.js]
 [test_constructX509FromBase64.js]
+[test_certviewer_invalid_oids.js]
+skip-if = toolkit == 'android' || buildapp == 'b2g'
--- a/testing/mochitest/browser-test.js
+++ b/testing/mochitest/browser-test.js
@@ -761,18 +761,20 @@ Tester.prototype = {
           throw "Cannot run both a generator test and a normal test at the same time.";
         }
 
         // This test is a generator. It will not finish immediately.
         this.currentTest.scope.waitForExplicitFinish();
         var result = this.currentTest.scope.generatorTest();
         this.currentTest.scope.__generator = result;
         result.next();
+      } else if (typeof this.currentTest.scope.test == "function") {
+        this.currentTest.scope.test();
       } else {
-        this.currentTest.scope.test();
+        throw "This test didn't call add_task, nor did it define a generatorTest() function, nor did it define a test() function, so we don't know how to run it.";
       }
     } catch (ex) {
       let isExpected = !!this.SimpleTest.isExpectingUncaughtException();
       if (!this.SimpleTest.isIgnoringAllUncaughtExceptions()) {
         this.currentTest.addResult(new testResult(isExpected, "Exception thrown", ex, false));
         this.SimpleTest.expectUncaughtException(false);
       } else {
         this.currentTest.addResult(new testMessage("Exception thrown: " + ex));
--- a/testing/mochitest/tests/Harness_sanity/mochitest.ini
+++ b/testing/mochitest/tests/Harness_sanity/mochitest.ini
@@ -7,16 +7,18 @@ skip-if = true #depends on fix for bug 1
 [test_sanityException2.html]
 [test_sanityParams.html]
 [test_sanityWindowSnapshot.html]
 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only
 [test_SpecialPowersExtension.html]
 [test_SpecialPowersExtension2.html]
 support-files = file_SpecialPowersFrame1.html
 [test_SpecialPowersPushPermissions.html]
+support-files =
+    specialPowers_framescript.js
 [test_SpecialPowersPushAppPermissions.html]
 support-files =
     file_app.sjs
     file_app.template.webapp
     app.html
 [test_SpecialPowersPushPrefEnv.html]
 [test_SimpletestGetTestFileURL.html]
 [test_SpecialPowersLoadChromeScript.html]
new file mode 100644
--- /dev/null
+++ b/testing/mochitest/tests/Harness_sanity/specialPowers_framescript.js
@@ -0,0 +1,13 @@
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+var permChangedObs = {
+  observe: function(subject, topic, data) {
+    if (topic == 'perm-changed') {
+      var permission = subject.QueryInterface(Components.interfaces.nsIPermission);
+      var msg = { op: data, type: permission.type };
+      sendAsyncMessage('perm-changed', msg);
+    }
+  }
+};
+
+Services.obs.addObserver(permChangedObs, 'perm-changed', false);
--- a/testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushPermissions.html
+++ b/testing/mochitest/tests/Harness_sanity/test_SpecialPowersPushPermissions.html
@@ -12,16 +12,27 @@
 const ALLOW_ACTION = SpecialPowers.Ci.nsIPermissionManager.ALLOW_ACTION;
 const DENY_ACTION = SpecialPowers.Ci.nsIPermissionManager.DENY_ACTION;
 const UNKNOWN_ACTION = SpecialPowers.Ci.nsIPermissionManager.UNKNOWN_ACTION;
 const PROMPT_ACTION = SpecialPowers.Ci.nsIPermissionManager.PROMPT_ACTION;
 const ACCESS_SESSION = SpecialPowers.Ci.nsICookiePermission.ACCESS_SESSION;
 const ACCESS_ALLOW_FIRST_PARTY_ONLY = SpecialPowers.Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY;
 const ACCESS_LIMIT_THIRD_PARTY = SpecialPowers.Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY;
 
+const EXPIRE_TIME = SpecialPowers.Ci.nsIPermissionManager.EXPIRE_TIME;
+var start;
+const DELAY = 500;
+// PR_Now() that called in nsPermissionManager to get the system time and
+// Date.now() are out of sync on win32 platform(XP/win7). The PR_Now() is
+// 15~20ms less than Date.now(). Unfortunately, this time skew can't be
+// avoided, so it needs to add a time buffer to compensate.
+const TIME_SKEW = 100;
+var gScript = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('specialPowers_framescript.js'));
+SimpleTest.requestFlakyTimeout("untriaged");
+
 function starttest(){
   SpecialPowers.addPermission("pPROMPT", PROMPT_ACTION, document);
   SpecialPowers.addPermission("pALLOW", ALLOW_ACTION, document);
   SpecialPowers.addPermission("pDENY", DENY_ACTION, document);
   SpecialPowers.addPermission("pREMOVE", ALLOW_ACTION, document);
   SpecialPowers.addPermission("pSESSION", ACCESS_SESSION, document);
   SpecialPowers.addPermission("pFIRSTPARTY", ACCESS_ALLOW_FIRST_PARTY_ONLY, document);
   SpecialPowers.addPermission("pTHIRDPARTY", ACCESS_LIMIT_THIRD_PARTY, document);
@@ -131,16 +142,77 @@ function test6() {
     setTimeout(test6, 0);
   } else if (!SpecialPowers.testPermission('pFIRSTPARTY', UNKNOWN_ACTION, document)) {
     dump('/**** pFIRSTPARTY still set ****/\n');
     setTimeout(test6, 0);
   } else if (!SpecialPowers.testPermission('pTHIRDPARTY', UNKNOWN_ACTION, document)) {
     dump('/**** pTHIRDPARTY still set ****/\n');
     setTimeout(test6, 0);
   } else {
-    SimpleTest.finish();
+    test7();
   }
 }
+
+function test7() {
+  afterPermissionChanged('pEXPIRE', 'deleted', test8);
+  afterPermissionChanged('pEXPIRE', 'added', permissionPollingCheck);
+  start = Number(Date.now());
+  SpecialPowers.addPermission('pEXPIRE', true, document, EXPIRE_TIME, start + DELAY);
+}
+
+function test8() {
+  afterPermissionChanged('pEXPIRE', 'deleted', SimpleTest.finish);
+  afterPermissionChanged('pEXPIRE', 'added', permissionPollingCheck);
+  start = Number(Date.now());
+  SpecialPowers.pushPermissions([
+    { 'type': 'pEXPIRE',
+      'allow': true,
+      'expireType': EXPIRE_TIME,
+      'expireTime': start + DELAY,
+      'context': document
+    }], function() {
+      info("Wait permission changed signal!");
+    }
+  );
+}
+
+function afterPermissionChanged(type, op, callback) {
+  // handle the message from specialPowers_framescript.js
+  gScript.addMessageListener('perm-changed', function onChange(msg) {
+    if (msg.type == type && msg.op == op) {
+      gScript.removeMessageListener('perm-changed', onChange);
+      callback();
+    }
+  });
+}
+
+function permissionPollingCheck() {
+  var now = Number(Date.now());
+  if (now < start + DELAY) {
+    ok(SpecialPowers.testPermission('pEXPIRE', ALLOW_ACTION, document),
+       'unexpired permission is still there!');
+    setTimeout(permissionPollingCheck, DELAY);
+    return;
+  }
+
+  if (SpecialPowers.testPermission('pEXPIRE', ALLOW_ACTION, document) &&
+      (now < start + DELAY + TIME_SKEW) &&
+      isWin32()) {
+    setTimeout(permissionPollingCheck, DELAY);
+    return;
+  }
+
+  // The permission is already expired!
+  ok(!SpecialPowers.testPermission('pEXPIRE', ALLOW_ACTION, document),
+     'expired permission should be removed!');
+}
+
+function isWin32() {
+  var version = SpecialPowers.Services.sysinfo.getProperty('version');
+  version = parseFloat(version);
+  // version 5.1 is win XP, 6.1 is win7
+  return (navigator.platform.indexOf('Win') == 0) && (version <= 6.1);
+}
 </script>
 </pre>
 </body>
 </html>
 
--- a/testing/mozharness/mozharness.json
+++ b/testing/mozharness/mozharness.json
@@ -1,4 +1,4 @@
 {
     "repo": "https://hg.mozilla.org/build/mozharness",
-    "revision": "42a7a9e793f4"
+    "revision": "526075bc2e35"
 }
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -313,17 +313,17 @@ SpecialPowersObserverAPI.prototype = {
       case "SPPermissionManager": {
         let msg = aMessage.json;
 
         let secMan = Services.scriptSecurityManager;
         let principal = secMan.getAppCodebasePrincipal(this._getURI(msg.url), msg.appId, msg.isInBrowserElement);
 
         switch (msg.op) {
           case "add":
-            Services.perms.addFromPrincipal(principal, msg.type, msg.permission);
+            Services.perms.addFromPrincipal(principal, msg.type, msg.permission, msg.expireType, msg.expireTime);
             break;
           case "remove":
             Services.perms.removeFromPrincipal(principal, msg.type);
             break;
           case "has":
             let hasPerm = Services.perms.testPermissionFromPrincipal(principal, msg.type);
             if (hasPerm == Ci.nsIPermissionManager.ALLOW_ACTION) 
               return true;
--- a/testing/specialpowers/content/specialpowersAPI.js
+++ b/testing/specialpowers/content/specialpowersAPI.js
@@ -801,24 +801,36 @@ SpecialPowersAPI.prototype = {
 
         if (permission.remove == true)
           perm = Ci.nsIPermissionManager.UNKNOWN_ACTION;
 
         if (originalValue == perm) {
           continue;
         }
 
-        var todo = {'op': 'add', 'type': permission.type, 'permission': perm, 'value': perm, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement};
+        var todo = {'op': 'add',
+                    'type': permission.type,
+                    'permission': perm,
+                    'value': perm,
+                    'url': url,
+                    'appId': appId,
+                    'isInBrowserElement': isInBrowserElement,
+                    'expireType': (typeof permission.expireType === "number") ?
+                      permission.expireType : 0, // default: EXPIRE_NEVER
+                    'expireTime': (typeof permission.expireTime === "number") ?
+                      permission.expireTime : 0};
+
+        var cleanupTodo = Object.assign({}, todo);
+
         if (permission.remove == true)
           todo.op = 'remove';
 
         pendingPermissions.push(todo);
 
         /* Push original permissions value or clear into cleanup array */
-        var cleanupTodo = {'op': 'add', 'type': permission.type, 'permission': perm, 'value': perm, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement};
         if (originalValue == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
           cleanupTodo.op = 'remove';
         } else {
           cleanupTodo.value = originalValue;
           cleanupTodo.permission = originalValue;
         }
         cleanupPermissions.push(cleanupTodo);
     }
@@ -1861,17 +1873,17 @@ SpecialPowersAPI.prototype = {
       url = arg.url;
       appId = arg.appId;
       isInBrowserElement = arg.isInBrowserElement;
     }
 
     return [ url, appId, isInBrowserElement, isSystem ];
   },
 
-  addPermission: function(type, allow, arg) {
+  addPermission: function(type, allow, arg, expireType, expireTime) {
     let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
       return; // nothing to do
     }
 
     let permission;
     if (typeof allow !== 'boolean') {
       permission = allow;
@@ -1881,17 +1893,19 @@ SpecialPowersAPI.prototype = {
     }
 
     var msg = {
       'op': 'add',
       'type': type,
       'permission': permission,
       'url': url,
       'appId': appId,
-      'isInBrowserElement': isInBrowserElement
+      'isInBrowserElement': isInBrowserElement,
+      'expireType': (typeof expireType === "number") ? expireType : 0,
+      'expireTime': (typeof expireTime === "number") ? expireTime : 0
     };
 
     this._sendSyncMessage('SPPermissionManager', msg);
   },
 
   removePermission: function(type, arg) {
     let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg);
     if (isSystem) {
--- a/tools/profiler/LulDwarfExt.h
+++ b/tools/profiler/LulDwarfExt.h
@@ -1057,17 +1057,17 @@ class CallFrameInfo::Handler {
   virtual bool SignalHandler() { return true; }
 };
 
 
 // The CallFrameInfo class makes calls on an instance of this class to
 // report errors or warn about problems in the data it is parsing.
 // These messages are sent to the message sink |aLog| provided to the
 // constructor.
-class CallFrameInfo::Reporter final {
+class CallFrameInfo::Reporter {
  public:
   // Create an error reporter which attributes troubles to the section
   // named SECTION in FILENAME.
   //
   // Normally SECTION would be .debug_frame, but the Mac puts CFI data
   // in a Mach-O section named __debug_frame. If we support
   // Linux-style exception handling data, we could be reading an
   // .eh_frame section.
--- a/tools/profiler/tests/gtest/LulTest.cpp
+++ b/tools/profiler/tests/gtest/LulTest.cpp
@@ -11,37 +11,37 @@
 
 // Set this to 0 to make LUL be completely silent during tests.
 // Set it to 1 to get logging output from LUL, presumably for
 // the purpose of debugging it.
 #define DEBUG_LUL_TEST 0
 
 // LUL needs a callback for its logging sink.
 static void
-gtest_logging_sink_for_LUL(const char* str) {
+gtest_logging_sink_for_LulIntegration(const char* str) {
   if (DEBUG_LUL_TEST == 0) {
     return;
   }
   // Ignore any trailing \n, since LOG will add one anyway.
   size_t n = strlen(str);
   if (n > 0 && str[n-1] == '\n') {
     char* tmp = strdup(str);
     tmp[n-1] = 0;
     fprintf(stderr, "LUL-in-gtest: %s\n", tmp);
     free(tmp);
   } else {
     fprintf(stderr, "LUL-in-gtest: %s\n", str);
   }
 }
 
-TEST(LUL, unwind_consistency) {
+TEST(LulIntegration, unwind_consistency) {
   // Set up LUL and get it to read unwind info for libxul.so, which is
   // all we care about here, plus (incidentally) practically every
   // other object in the process too.
-  lul::LUL* lul = new lul::LUL(gtest_logging_sink_for_LUL);
+  lul::LUL* lul = new lul::LUL(gtest_logging_sink_for_LulIntegration);
   read_procmaps(lul);
 
   // Run unwind tests and receive information about how many there
   // were and how many were successful.
   lul->EnableUnwinding();
   int nTests = 0, nTestsPassed = 0;
   RunLulUnitTests(&nTests, &nTestsPassed, lul);
   EXPECT_TRUE(nTests == 6) << "Unexpected number of tests";
new file mode 100644
--- /dev/null
+++ b/tools/profiler/tests/gtest/LulTestDwarf.cpp
@@ -0,0 +1,2293 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+#include "LulCommonExt.h"
+#include "LulDwarfExt.h"
+#include "LulDwarfInt.h"
+#include "LulTestInfrastructure.h"
+
+using testing::Test;
+using testing::Return;
+using testing::Sequence;
+using testing::InSequence;
+using testing::_;
+using lul_test::CFISection;
+using lul_test::test_assembler::kBigEndian;
+using lul_test::test_assembler::kLittleEndian;
+using lul_test::test_assembler::Label;
+
+#define PERHAPS_WRITE_DEBUG_FRAME_FILE(name, section) /**/
+#define PERHAPS_WRITE_EH_FRAME_FILE(name, section)    /**/
+
+// Set this to 0 to make LUL be completely silent during tests.
+// Set it to 1 to get logging output from LUL, presumably for
+// the purpose of debugging it.
+#define DEBUG_LUL_TEST_DWARF 0
+
+// LUL needs a callback for its logging sink.
+static void
+gtest_logging_sink_for_LulTestDwarf(const char* str) {
+  if (DEBUG_LUL_TEST_DWARF == 0) {
+    return;
+  }
+  // Ignore any trailing \n, since LOG will add one anyway.
+  size_t n = strlen(str);
+  if (n > 0 && str[n-1] == '\n') {
+    char* tmp = strdup(str);
+    tmp[n-1] = 0;
+    fprintf(stderr, "LUL-in-gtest: %s\n", tmp);
+    free(tmp);
+  } else {
+    fprintf(stderr, "LUL-in-gtest: %s\n", str);
+  }
+}
+
+namespace lul {
+
+class MockCallFrameInfoHandler : public CallFrameInfo::Handler {
+ public:
+  MOCK_METHOD6(Entry, bool(size_t offset, uint64 address, uint64 length,
+                           uint8 version, const std::string &augmentation,
+                           unsigned return_address));
+  MOCK_METHOD2(UndefinedRule, bool(uint64 address, int reg));
+  MOCK_METHOD2(SameValueRule, bool(uint64 address, int reg));
+  MOCK_METHOD4(OffsetRule, bool(uint64 address, int reg, int base_register,
+                                long offset));
+  MOCK_METHOD4(ValOffsetRule, bool(uint64 address, int reg, int base_register,
+                                   long offset));
+  MOCK_METHOD3(RegisterRule, bool(uint64 address, int reg, int base_register));
+  MOCK_METHOD3(ExpressionRule, bool(uint64 address, int reg,
+                                    const std::string &expression));
+  MOCK_METHOD3(ValExpressionRule, bool(uint64 address, int reg,
+                                       const std::string &expression));
+  MOCK_METHOD0(End, bool());
+  MOCK_METHOD2(PersonalityRoutine, bool(uint64 address, bool indirect));
+  MOCK_METHOD2(LanguageSpecificDataArea, bool(uint64 address, bool indirect));
+  MOCK_METHOD0(SignalHandler, bool());
+};
+
+class MockCallFrameErrorReporter : public CallFrameInfo::Reporter {
+ public:
+  MockCallFrameErrorReporter()
+     : Reporter(gtest_logging_sink_for_LulTestDwarf,
+                "mock filename", "mock section")
+  { }
+  MOCK_METHOD2(Incomplete, void(uint64, CallFrameInfo::EntryKind));
+  MOCK_METHOD1(EarlyEHTerminator, void(uint64));
+  MOCK_METHOD2(CIEPointerOutOfRange, void(uint64, uint64));
+  MOCK_METHOD2(BadCIEId, void(uint64, uint64));
+  MOCK_METHOD2(UnrecognizedVersion, void(uint64, int version));
+  MOCK_METHOD2(UnrecognizedAugmentation, void(uint64, const string &));
+  MOCK_METHOD2(InvalidPointerEncoding, void(uint64, uint8));
+  MOCK_METHOD2(UnusablePointerEncoding, void(uint64, uint8));
+  MOCK_METHOD2(RestoreInCIE, void(uint64, uint64));
+  MOCK_METHOD3(BadInstruction, void(uint64, CallFrameInfo::EntryKind, uint64));
+  MOCK_METHOD3(NoCFARule, void(uint64, CallFrameInfo::EntryKind, uint64));
+  MOCK_METHOD3(EmptyStateStack, void(uint64, CallFrameInfo::EntryKind, uint64));
+  MOCK_METHOD3(ClearingCFARule, void(uint64, CallFrameInfo::EntryKind, uint64));
+};
+
+struct CFIFixture {
+
+  enum { kCFARegister = CallFrameInfo::Handler::kCFARegister };
+
+  CFIFixture() {
+    // Default expectations for the data handler.
+    //
+    // - Leave Entry and End without expectations, as it's probably a
+    //   good idea to set those explicitly in each test.
+    //
+    // - Expect the *Rule functions to not be called, 
+    //   so that each test can simply list the calls they expect.
+    //
+    // I gather I could use StrictMock for this, but the manual seems
+    // to suggest using that only as a last resort, and this isn't so
+    // bad.
+    EXPECT_CALL(handler, UndefinedRule(_, _)).Times(0);
+    EXPECT_CALL(handler, SameValueRule(_, _)).Times(0);
+    EXPECT_CALL(handler, OffsetRule(_, _, _, _)).Times(0);
+    EXPECT_CALL(handler, ValOffsetRule(_, _, _, _)).Times(0);
+    EXPECT_CALL(handler, RegisterRule(_, _, _)).Times(0);
+    EXPECT_CALL(handler, ExpressionRule(_, _, _)).Times(0);
+    EXPECT_CALL(handler, ValExpressionRule(_, _, _)).Times(0);
+    EXPECT_CALL(handler, PersonalityRoutine(_, _)).Times(0);
+    EXPECT_CALL(handler, LanguageSpecificDataArea(_, _)).Times(0);
+    EXPECT_CALL(handler, SignalHandler()).Times(0);
+
+    // Default expectations for the error/warning reporer.
+    EXPECT_CALL(reporter, Incomplete(_, _)).Times(0);
+    EXPECT_CALL(reporter, EarlyEHTerminator(_)).Times(0);
+    EXPECT_CALL(reporter, CIEPointerOutOfRange(_, _)).Times(0);
+    EXPECT_CALL(reporter, BadCIEId(_, _)).Times(0);
+    EXPECT_CALL(reporter, UnrecognizedVersion(_, _)).Times(0);
+    EXPECT_CALL(reporter, UnrecognizedAugmentation(_, _)).Times(0);
+    EXPECT_CALL(reporter, InvalidPointerEncoding(_, _)).Times(0);
+    EXPECT_CALL(reporter, UnusablePointerEncoding(_, _)).Times(0);
+    EXPECT_CALL(reporter, RestoreInCIE(_, _)).Times(0);
+    EXPECT_CALL(reporter, BadInstruction(_, _, _)).Times(0);
+    EXPECT_CALL(reporter, NoCFARule(_, _, _)).Times(0);
+    EXPECT_CALL(reporter, EmptyStateStack(_, _, _)).Times(0);
+    EXPECT_CALL(reporter, ClearingCFARule(_, _, _)).Times(0);
+  }
+
+  MockCallFrameInfoHandler handler;
+  MockCallFrameErrorReporter reporter;
+};
+
+class LulDwarfCFI: public CFIFixture, public Test { };
+
+TEST_F(LulDwarfCFI, EmptyRegion) {
+  EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, End()).Times(0);
+  static const char data[1] = { 42 };
+
+  ByteReader reader(ENDIANNESS_BIG);
+  CallFrameInfo parser(data, 0, &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+TEST_F(LulDwarfCFI, IncompleteLength32) {
+  CFISection section(kBigEndian, 8);
+  section
+      // Not even long enough for an initial length.
+      .D16(0xa0f)
+      // Padding to keep valgrind happy. We subtract these off when we
+      // construct the parser.
+      .D16(0);
+
+  EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, End()).Times(0);
+
+  EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown))
+      .WillOnce(Return());
+
+  string contents;
+  ASSERT_TRUE(section.GetContents(&contents));
+
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(8);
+  CallFrameInfo parser(contents.data(), contents.size() - 2,
+                       &reader, &handler, &reporter);
+  EXPECT_FALSE(parser.Start());
+}
+
+TEST_F(LulDwarfCFI, IncompleteLength64) {
+  CFISection section(kLittleEndian, 4);
+  section
+      // An incomplete 64-bit DWARF initial length.
+      .D32(0xffffffff).D32(0x71fbaec2)
+      // Padding to keep valgrind happy. We subtract these off when we
+      // construct the parser.
+      .D32(0);
+
+  EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, End()).Times(0);
+
+  EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown))
+      .WillOnce(Return());
+
+  string contents;
+  ASSERT_TRUE(section.GetContents(&contents));
+
+  ByteReader reader(ENDIANNESS_LITTLE);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size() - 4,
+                       &reader, &handler, &reporter);
+  EXPECT_FALSE(parser.Start());
+}
+
+TEST_F(LulDwarfCFI, IncompleteId32) {
+  CFISection section(kBigEndian, 8);
+  section
+      .D32(3)                      // Initial length, not long enough for id
+      .D8(0xd7).D8(0xe5).D8(0xf1)  // incomplete id
+      .CIEHeader(8727, 3983, 8889, 3, "")
+      .FinishEntry();
+
+  EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, End()).Times(0);
+
+  EXPECT_CALL(reporter, Incomplete(_, CallFrameInfo::kUnknown))
+      .WillOnce(Return());
+
+  string contents;
+  ASSERT_TRUE(section.GetContents(&contents));
+
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(8);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_FALSE(parser.Start());
+}
+
+TEST_F(LulDwarfCFI, BadId32) {
+  CFISection section(kBigEndian, 8);
+  section
+      .D32(0x100)                       // Initial length
+      .D32(0xe802fade)                  // bogus ID
+      .Append(0x100 - 4, 0x42);         // make the length true
+  section
+      .CIEHeader(1672, 9872, 8529, 3, "")
+      .FinishEntry();
+
+  EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, End()).Times(0);
+
+  EXPECT_CALL(reporter, CIEPointerOutOfRange(_, 0xe802fade))
+      .WillOnce(Return());
+
+  string contents;
+  ASSERT_TRUE(section.GetContents(&contents));
+
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(8);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_FALSE(parser.Start());
+}
+
+// A lone CIE shouldn't cause any handler calls.
+TEST_F(LulDwarfCFI, SingleCIE) {
+  CFISection section(kLittleEndian, 4);
+  section.CIEHeader(0xffe799a8, 0x3398dcdd, 0x6e9683de, 3, "");
+  section.Append(10, lul::DW_CFA_nop);
+  section.FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("SingleCIE", section);
+
+  EXPECT_CALL(handler, Entry(_, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, End()).Times(0);
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_LITTLE);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+// One FDE, one CIE.
+TEST_F(LulDwarfCFI, OneFDE) {
+  CFISection section(kBigEndian, 4);
+  Label cie;
+  section
+      .Mark(&cie)
+      .CIEHeader(0x4be22f75, 0x2492236e, 0x6b6efb87, 3, "")
+      .FinishEntry()
+      .FDEHeader(cie, 0x7714740d, 0x3d5a10cd)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("OneFDE", section);
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, 0x7714740d, 0x3d5a10cd, 3, "", 0x6b6efb87))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+// Two FDEs share a CIE.
+TEST_F(LulDwarfCFI, TwoFDEsOneCIE) {
+  CFISection section(kBigEndian, 4);
+  Label cie;
+  section
+      // First FDE. readelf complains about this one because it makes
+      // a forward reference to its CIE.
+      .FDEHeader(cie, 0xa42744df, 0xa3b42121)
+      .FinishEntry()
+      // CIE.
+      .Mark(&cie)
+      .CIEHeader(0x04f7dc7b, 0x3d00c05f, 0xbd43cb59, 3, "")
+      .FinishEntry()
+      // Second FDE.
+      .FDEHeader(cie, 0x6057d391, 0x700f608d)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("TwoFDEsOneCIE", section);
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, 0xa42744df, 0xa3b42121, 3, "", 0xbd43cb59))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, 0x6057d391, 0x700f608d, 3, "", 0xbd43cb59))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+// Two FDEs, two CIEs.
+TEST_F(LulDwarfCFI, TwoFDEsTwoCIEs) {
+  CFISection section(kLittleEndian, 8);
+  Label cie1, cie2;
+  section
+      // First CIE.
+      .Mark(&cie1)
+      .CIEHeader(0x694d5d45, 0x4233221b, 0xbf45e65a, 3, "")
+      .FinishEntry()
+      // First FDE which cites second CIE. readelf complains about
+      // this one because it makes a forward reference to its CIE.
+      .FDEHeader(cie2, 0x778b27dfe5871f05ULL, 0x324ace3448070926ULL)
+      .FinishEntry()
+      // Second FDE, which cites first CIE.
+      .FDEHeader(cie1, 0xf6054ca18b10bf5fULL, 0x45fdb970d8bca342ULL)
+      .FinishEntry()
+      // Second CIE.
+      .Mark(&cie2)
+      .CIEHeader(0xfba3fad7, 0x6287e1fd, 0x61d2c581, 2, "")
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("TwoFDEsTwoCIEs", section);
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, 0x778b27dfe5871f05ULL, 0x324ace3448070926ULL, 2,
+                      "", 0x61d2c581))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, 0xf6054ca18b10bf5fULL, 0x45fdb970d8bca342ULL, 3,
+                      "", 0xbf45e65a))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_LITTLE);
+  reader.SetAddressSize(8);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+// An FDE whose CIE specifies a version we don't recognize.
+TEST_F(LulDwarfCFI, BadVersion) {
+  CFISection section(kBigEndian, 4);
+  Label cie1, cie2;
+  section
+      .Mark(&cie1)
+      .CIEHeader(0xca878cf0, 0x7698ec04, 0x7b616f54, 0x52, "")
+      .FinishEntry()
+      // We should skip this entry, as its CIE specifies a version we
+      // don't recognize.
+      .FDEHeader(cie1, 0x08852292, 0x2204004a)
+      .FinishEntry()
+      // Despite the above, we should visit this entry.
+      .Mark(&cie2)
+      .CIEHeader(0x7c3ae7c9, 0xb9b9a512, 0x96cb3264, 3, "")
+      .FinishEntry()
+      .FDEHeader(cie2, 0x2094735a, 0x6e875501)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("BadVersion", section);
+
+  EXPECT_CALL(reporter, UnrecognizedVersion(_, 0x52))
+    .WillOnce(Return());
+
+  {
+    InSequence s;
+    // We should see no mention of the first FDE, but we should get
+    // a call to Entry for the second.
+    EXPECT_CALL(handler, Entry(_, 0x2094735a, 0x6e875501, 3, "",
+                               0x96cb3264))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End())
+        .WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_FALSE(parser.Start());
+}
+
+// An FDE whose CIE specifies an augmentation we don't recognize.
+TEST_F(LulDwarfCFI, BadAugmentation) {
+  CFISection section(kBigEndian, 4);
+  Label cie1, cie2;
+  section
+      .Mark(&cie1)
+      .CIEHeader(0x4be22f75, 0x2492236e, 0x6b6efb87, 3, "spaniels!")
+      .FinishEntry()
+      // We should skip this entry, as its CIE specifies an
+      // augmentation we don't recognize.
+      .FDEHeader(cie1, 0x7714740d, 0x3d5a10cd)
+      .FinishEntry()
+      // Despite the above, we should visit this entry.
+      .Mark(&cie2)
+      .CIEHeader(0xf8bc4399, 0x8cf09931, 0xf2f519b2, 3, "")
+      .FinishEntry()
+      .FDEHeader(cie2, 0x7bf0fda0, 0xcbcd28d8)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("BadAugmentation", section);
+
+  EXPECT_CALL(reporter, UnrecognizedAugmentation(_, "spaniels!"))
+    .WillOnce(Return());
+
+  {
+    InSequence s;
+    // We should see no mention of the first FDE, but we should get
+    // a call to Entry for the second.
+    EXPECT_CALL(handler, Entry(_, 0x7bf0fda0, 0xcbcd28d8, 3, "",
+                               0xf2f519b2))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End())
+        .WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_FALSE(parser.Start());
+}
+
+// The return address column field is a byte in CFI version 1
+// (DWARF2), but a ULEB128 value in version 3 (DWARF3).
+TEST_F(LulDwarfCFI, CIEVersion1ReturnColumn) {
+  CFISection section(kBigEndian, 4);
+  Label cie;
+  section
+      // CIE, using the version 1 format: return column is a ubyte.
+      .Mark(&cie)
+      // Use a value for the return column that is parsed differently
+      // as a ubyte and as a ULEB128.
+      .CIEHeader(0xbcdea24f, 0x5be28286, 0x9f, 1, "")
+      .FinishEntry()
+      // FDE, citing that CIE.
+      .FDEHeader(cie, 0xb8d347b5, 0x825e55dc)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion1ReturnColumn", section);
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler, Entry(_, 0xb8d347b5, 0x825e55dc, 1, "", 0x9f))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+// The return address column field is a byte in CFI version 1
+// (DWARF2), but a ULEB128 value in version 3 (DWARF3).
+TEST_F(LulDwarfCFI, CIEVersion3ReturnColumn) {
+  CFISection section(kBigEndian, 4);
+  Label cie;
+  section
+      // CIE, using the version 3 format: return column is a ULEB128.
+      .Mark(&cie)
+      // Use a value for the return column that is parsed differently
+      // as a ubyte and as a ULEB128.
+      .CIEHeader(0x0ab4758d, 0xc010fdf7, 0x89, 3, "")
+      .FinishEntry()
+      // FDE, citing that CIE.
+      .FDEHeader(cie, 0x86763f2b, 0x2a66dc23)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("CIEVersion3ReturnColumn", section);
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler, Entry(_, 0x86763f2b, 0x2a66dc23, 3, "", 0x89))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+
+  string contents;
+  EXPECT_TRUE(section.GetContents(&contents));
+  ByteReader reader(ENDIANNESS_BIG);
+  reader.SetAddressSize(4);
+  CallFrameInfo parser(contents.data(), contents.size(),
+                       &reader, &handler, &reporter);
+  EXPECT_TRUE(parser.Start());
+}
+
+struct CFIInsnFixture: public CFIFixture {
+  CFIInsnFixture() : CFIFixture() {
+    data_factor = 0xb6f;
+    return_register = 0x9be1ed9f;
+    version = 3;
+    cfa_base_register = 0x383a3aa;
+    cfa_offset = 0xf748;
+  }
+  
+  // Prepare SECTION to receive FDE instructions.
+  //
+  // - Append a stock CIE header that establishes the fixture's
+  //   code_factor, data_factor, return_register, version, and
+  //   augmentation values.
+  // - Have the CIE set up a CFA rule using cfa_base_register and
+  //   cfa_offset.
+  // - Append a stock FDE header, referring to the above CIE, for the
+  //   fde_size bytes at fde_start. Choose fde_start and fde_size
+  //   appropriately for the section's address size.
+  // - Set appropriate expectations on handler in sequence s for the
+  //   frame description entry and the CIE's CFA rule.
+  //
+  // On return, SECTION is ready to have FDE instructions appended to
+  // it, and its FinishEntry member called.
+  void StockCIEAndFDE(CFISection *section) {
+    // Choose appropriate constants for our address size.
+    if (section->AddressSize() == 4) {
+      fde_start = 0xc628ecfbU;
+      fde_size = 0x5dee04a2;
+      code_factor = 0x60b;
+    } else {
+      assert(section->AddressSize() == 8);
+      fde_start = 0x0005c57ce7806bd3ULL;
+      fde_size = 0x2699521b5e333100ULL;
+      code_factor = 0x01008e32855274a8ULL;
+    }
+
+    // Create the CIE.
+    (*section)
+        .Mark(&cie_label)
+        .CIEHeader(code_factor, data_factor, return_register, version,
+                   "")
+        .D8(lul::DW_CFA_def_cfa)
+        .ULEB128(cfa_base_register)
+        .ULEB128(cfa_offset)
+        .FinishEntry();
+
+    // Create the FDE.
+    section->FDEHeader(cie_label, fde_start, fde_size);
+
+    // Expect an Entry call for the FDE and a ValOffsetRule call for the
+    // CIE's CFA rule.
+    EXPECT_CALL(handler, Entry(_, fde_start, fde_size, version, "",
+                               return_register))
+        .InSequence(s)
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, ValOffsetRule(fde_start, kCFARegister,
+                                       cfa_base_register, cfa_offset))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  }
+
+  // Run the contents of SECTION through a CallFrameInfo parser,
+  // expecting parser.Start to return SUCCEEDS.  Caller may optionally
+  // supply, via READER, its own ByteReader.  If that's absent, a
+  // local one is used.
+  void ParseSection(CFISection *section,
+                    bool succeeds = true, ByteReader* reader = nullptr) {
+    string contents;
+    EXPECT_TRUE(section->GetContents(&contents));
+    lul::Endianness endianness;
+    if (section->endianness() == kBigEndian)
+      endianness = ENDIANNESS_BIG;
+    else {
+      assert(section->endianness() == kLittleEndian);
+      endianness = ENDIANNESS_LITTLE;
+    }
+    ByteReader local_reader(endianness);
+    ByteReader* reader_to_use = reader ? reader : &local_reader;
+    reader_to_use->SetAddressSize(section->AddressSize());
+    CallFrameInfo parser(contents.data(), contents.size(),
+                         reader_to_use, &handler, &reporter);
+    if (succeeds)
+      EXPECT_TRUE(parser.Start());
+    else
+      EXPECT_FALSE(parser.Start());
+  }
+
+  Label cie_label;
+  Sequence s;
+  uint64 code_factor;
+  int data_factor;
+  unsigned return_register;
+  unsigned version;
+  unsigned cfa_base_register;
+  int cfa_offset;
+  uint64 fde_start, fde_size;
+};
+
+class LulDwarfCFIInsn: public CFIInsnFixture, public Test { };
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_set_loc) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_set_loc).D32(0xb1ee3e7a)
+      // Use DW_CFA_def_cfa to force a handler call that we can use to
+      // check the effect of the DW_CFA_set_loc.
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x4defb431).ULEB128(0x6d17b0ee)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_set_loc", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(0xb1ee3e7a, kCFARegister, 0x4defb431, 0x6d17b0ee))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_advance_loc) {
+  CFISection section(kBigEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_advance_loc | 0x2a)
+      // Use DW_CFA_def_cfa to force a handler call that we can use to
+      // check the effect of the DW_CFA_advance_loc.
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x5bbb3715).ULEB128(0x0186c7bf)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start + 0x2a * code_factor,
+                            kCFARegister, 0x5bbb3715, 0x0186c7bf))
+        .InSequence(s)
+        .WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_advance_loc1) {
+  CFISection section(kLittleEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_advance_loc1).D8(0xd8)
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x69d5696a).ULEB128(0x1eb7fc93)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc1", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule((fde_start + 0xd8 * code_factor),
+                            kCFARegister, 0x69d5696a, 0x1eb7fc93))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_advance_loc2) {
+  CFISection section(kLittleEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_advance_loc2).D16(0x3adb)
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x3a368bed).ULEB128(0x3194ee37)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc2", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule((fde_start + 0x3adb * code_factor),
+                            kCFARegister, 0x3a368bed, 0x3194ee37))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_advance_loc4) {
+  CFISection section(kBigEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_advance_loc4).D32(0x15813c88)
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x135270c5).ULEB128(0x24bad7cb)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc4", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule((fde_start + 0x15813c88ULL * code_factor),
+                            kCFARegister, 0x135270c5, 0x24bad7cb))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_MIPS_advance_loc8) {
+  code_factor = 0x2d;
+  CFISection section(kBigEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_MIPS_advance_loc8).D64(0x3c4f3945b92c14ULL)
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0xe17ed602).ULEB128(0x3d162e7f)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_advance_loc8", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule((fde_start + 0x3c4f3945b92c14ULL * code_factor),
+                            kCFARegister, 0xe17ed602, 0x3d162e7f))
+      .InSequence(s)
+      .WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa) {
+  CFISection section(kLittleEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x4e363a85).ULEB128(0x815f9aa7)
+      .FinishEntry();
+
+  PERHAPS_WRITE_DEBUG_FRAME_FILE("DW_CFA_def_cfa", section);
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, 0x4e363a85, 0x815f9aa7))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_sf) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_sf).ULEB128(0x8ccb32b7).LEB128(0x9ea)
+      .D8(lul::DW_CFA_def_cfa_sf).ULEB128(0x9b40f5da).LEB128(-0x40a2)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, 0x8ccb32b7,
+                            0x9ea * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, 0x9b40f5da,
+                            -0x40a2 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_register) {
+  CFISection section(kLittleEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_register).ULEB128(0x3e7e9363)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, 0x3e7e9363, cfa_offset))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+// DW_CFA_def_cfa_register should have no effect when applied to a
+// non-base/offset rule.
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_registerBadRule) {
+  ByteReader reader(ENDIANNESS_BIG);
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_expression).Block("needle in a haystack")
+      .D8(lul::DW_CFA_def_cfa_register).ULEB128(0xf1b49e49)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValExpressionRule(fde_start, kCFARegister,
+              "needle in a haystack"))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section, true, &reader);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_offset) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_offset).ULEB128(0x1e8e3b9b)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, cfa_base_register,
+                            0x1e8e3b9b))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_offset_sf) {
+  CFISection section(kLittleEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_offset_sf).LEB128(0x970)
+      .D8(lul::DW_CFA_def_cfa_offset_sf).LEB128(-0x2cd)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, cfa_base_register,
+                            0x970 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, kCFARegister, cfa_base_register,
+                            -0x2cd * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+// DW_CFA_def_cfa_offset should have no effect when applied to a
+// non-base/offset rule.
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_offsetBadRule) {
+  ByteReader reader(ENDIANNESS_BIG);
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_expression).Block("six ways to Sunday")
+      .D8(lul::DW_CFA_def_cfa_offset).ULEB128(0x1e8e3b9b)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+      ValExpressionRule(fde_start, kCFARegister, "six ways to Sunday"))
+      .WillRepeatedly(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section, true, &reader);
+}
+
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_def_cfa_expression) {
+  ByteReader reader(ENDIANNESS_LITTLE);
+  CFISection section(kLittleEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_def_cfa_expression).Block("eating crow")
+      .FinishEntry();
+
+  EXPECT_CALL(handler, ValExpressionRule(fde_start, kCFARegister,
+                                         "eating crow"))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section, true, &reader);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_undefined) {
+  CFISection section(kLittleEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_undefined).ULEB128(0x300ce45d)
+      .FinishEntry();
+
+  EXPECT_CALL(handler, UndefinedRule(fde_start, 0x300ce45d))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_same_value) {
+  CFISection section(kLittleEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_same_value).ULEB128(0x3865a760)
+      .FinishEntry();
+
+  EXPECT_CALL(handler, SameValueRule(fde_start, 0x3865a760))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_offset) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_offset | 0x2c).ULEB128(0x9f6)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              OffsetRule(fde_start, 0x2c, kCFARegister, 0x9f6 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_offset_extended) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_offset_extended).ULEB128(0x402b).ULEB128(0xb48)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              OffsetRule(fde_start,
+                         0x402b, kCFARegister, 0xb48 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_offset_extended_sf) {
+  CFISection section(kBigEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_offset_extended_sf)
+          .ULEB128(0x997c23ee).LEB128(0x2d00)
+      .D8(lul::DW_CFA_offset_extended_sf)
+          .ULEB128(0x9519eb82).LEB128(-0xa77)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              OffsetRule(fde_start, 0x997c23ee,
+                         kCFARegister, 0x2d00 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler,
+              OffsetRule(fde_start, 0x9519eb82,
+                         kCFARegister, -0xa77 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_val_offset) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_val_offset).ULEB128(0x623562fe).ULEB128(0x673)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, 0x623562fe,
+                            kCFARegister, 0x673 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_val_offset_sf) {
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_val_offset_sf).ULEB128(0x6f4f).LEB128(0xaab)
+      .D8(lul::DW_CFA_val_offset_sf).ULEB128(0x2483).LEB128(-0x8a2)
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, 0x6f4f,
+                            kCFARegister, 0xaab * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler,
+              ValOffsetRule(fde_start, 0x2483,
+                            kCFARegister, -0x8a2 * data_factor))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_register) {
+  CFISection section(kLittleEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_register).ULEB128(0x278d18f9).ULEB128(0x1a684414)
+      .FinishEntry();
+
+  EXPECT_CALL(handler, RegisterRule(fde_start, 0x278d18f9, 0x1a684414))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_expression) {
+  ByteReader reader(ENDIANNESS_BIG);
+  CFISection section(kBigEndian, 8);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_expression).ULEB128(0xa1619fb2)
+      .Block("plus ça change, plus c'est la même chose")
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ExpressionRule(fde_start, 0xa1619fb2,
+                             "plus ça change, plus c'est la même chose"))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section, true, &reader);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_val_expression) {
+  ByteReader reader(ENDIANNESS_BIG);
+  CFISection section(kBigEndian, 4);
+  StockCIEAndFDE(&section);
+  section
+      .D8(lul::DW_CFA_val_expression).ULEB128(0xc5e4a9e3)
+      .Block("he who has the gold makes the rules")
+      .FinishEntry();
+
+  EXPECT_CALL(handler,
+              ValExpressionRule(fde_start, 0xc5e4a9e3,
+                                "he who has the gold makes the rules"))
+      .InSequence(s).WillOnce(Return(true));
+  EXPECT_CALL(handler, End()).InSequence(s).WillOnce(Return(true));
+
+  ParseSection(&section, true, &reader);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_restore) {
+  CFISection section(kLittleEndian, 8);
+  code_factor = 0x01bd188a9b1fa083ULL;
+  data_factor = -0x1ac8;
+  return_register = 0x8c35b049;
+  version = 2;
+  fde_start = 0x2d70fe998298bbb1ULL;
+  fde_size = 0x46ccc2e63cf0b108ULL;
+  Label cie;
+  section
+      .Mark(&cie)
+      .CIEHeader(code_factor, data_factor, return_register, version,
+                 "")
+      // Provide a CFA rule, because register rules require them.
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x6ca1d50e).ULEB128(0x372e38e8)
+      // Provide an offset(N) rule for register 0x3c.
+      .D8(lul::DW_CFA_offset | 0x3c).ULEB128(0xb348)
+      .FinishEntry()
+      // In the FDE...
+      .FDEHeader(cie, fde_start, fde_size)
+      // At a second address, provide a new offset(N) rule for register 0x3c.
+      .D8(lul::DW_CFA_advance_loc | 0x13)
+      .D8(lul::DW_CFA_offset | 0x3c).ULEB128(0x9a50)
+      // At a third address, restore the original rule for register 0x3c.
+      .D8(lul::DW_CFA_advance_loc | 0x01)
+      .D8(lul::DW_CFA_restore | 0x3c)
+      .FinishEntry();
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, fde_start, fde_size, version, "", return_register))
+        .WillOnce(Return(true));
+    // CIE's CFA rule.
+    EXPECT_CALL(handler,
+                ValOffsetRule(fde_start,
+                              kCFARegister, 0x6ca1d50e, 0x372e38e8))
+        .WillOnce(Return(true));
+    // CIE's rule for register 0x3c.
+    EXPECT_CALL(handler,
+                OffsetRule(fde_start, 0x3c,
+                           kCFARegister, 0xb348 * data_factor))
+        .WillOnce(Return(true));
+    // FDE's rule for register 0x3c.
+    EXPECT_CALL(handler,
+                OffsetRule(fde_start + 0x13 * code_factor, 0x3c,
+                           kCFARegister, 0x9a50 * data_factor))
+        .WillOnce(Return(true));
+    // Restore CIE's rule for register 0x3c.
+    EXPECT_CALL(handler,
+                OffsetRule(fde_start + (0x13 + 0x01) * code_factor, 0x3c,
+                           kCFARegister, 0xb348 * data_factor))
+        .WillOnce(Return(true));
+    EXPECT_CALL(handler, End()).WillOnce(Return(true));
+  }
+    
+  ParseSection(&section);
+}
+
+TEST_F(LulDwarfCFIInsn, DW_CFA_restoreNoRule) {
+  CFISection section(kBigEndian, 4);
+  code_factor = 0x005f78143c1c3b82ULL;
+  data_factor = 0x25d0;
+  return_register = 0xe8;
+  version = 1;
+  fde_start = 0x4062e30f;
+  fde_size = 0x5302a389;
+  Label cie;
+  section
+      .Mark(&cie)
+      .CIEHeader(code_factor, data_factor, return_register, version, "")
+      // Provide a CFA rule, because register rules require them.
+      .D8(lul::DW_CFA_def_cfa).ULEB128(0x470aa334).ULEB128(0x099ef127)
+      .FinishEntry()
+      // In the FDE...
+      .FDEHeader(cie, fde_start, fde_size)
+      // At a second address, provide an offset(N) rule for register 0x2c.
+      .D8(lul::DW_CFA_advance_loc | 0x7)
+      .D8(lul::DW_CFA_offset | 0x2c).ULEB128(0x1f47)
+      // At a third address, restore the (missing) CIE rule for register 0x2c.
+      .D8(lul::DW_CFA_advance_loc | 0xb)
+      .D8(lul::DW_CFA_restore | 0x2c)
+      .FinishEntry();
+
+  {
+    InSequence s;
+    EXPECT_CALL(handler,
+                Entry(_, fde_start, fde_size, version, "", return_register))
+        .WillOnce(Return(true));
+    // CIE's CFA rule.
+    EXPECT_CALL(handler,
+                ValOffsetRule(fde_start,
+                              kCFARegister, 0x470aa334, 0x099ef127))
+        .WillOnce(Return(true));
+    // FDE's rule for register 0x2c.
+    EXPECT_CALL(handler,
+                OffsetRule(fde_start + 0x7 * code_factor, 0x2c,
+                           kCFARegister, 0x1f47 * data_factor))
+        .WillOnce(Return(true));