Merge m-c to fx-team. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Sat, 09 Apr 2016 10:09:49 -0400
changeset 292516 d62963756d9a9d19cbbb5d8f3dd3c7cfa8fdef88
parent 292515 3b77c02a3e6e309834e9e3e52315c75c7e601906 (current diff)
parent 292475 25c3b46ed101c4f423d40cd802eea282e239ecf3 (diff)
child 292517 ee048ce0f8d5d6570b7582728b3ac540634a367c
child 292529 1af4c669349718874f6a366f3f1f52ff2f86adfc
push id74863
push userryanvm@gmail.com
push dateSat, 09 Apr 2016 19:23:17 +0000
treeherdermozilla-inbound@ee048ce0f8d5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone48.0a1
first release with
nightly linux32
d62963756d9a / 48.0a1 / 20160410030224 / files
nightly linux64
d62963756d9a / 48.0a1 / 20160410030224 / files
nightly mac
d62963756d9a / 48.0a1 / 20160410030224 / files
nightly win32
d62963756d9a / 48.0a1 / 20160410030224 / files
nightly win64
d62963756d9a / 48.0a1 / 20160410030224 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team. a=merge
b2g/config/aries/releng-aries.tt
b2g/config/dolphin/releng-dolphin.tt
b2g/config/emulator-ics/releng-emulator-ics.tt
b2g/config/emulator-jb/releng-emulator-jb.tt
b2g/config/emulator-kk/releng-emulator-kk.tt
b2g/config/emulator-l/releng-emulator-l.tt
b2g/config/emulator-x86-kk/releng-emulator-kk.tt
b2g/config/emulator-x86-l/releng-emulator-l.tt
b2g/config/emulator/releng-emulator.tt
b2g/config/flame-kk/releng-flame-kk.tt
b2g/config/flame/releng-flame.tt
b2g/config/nexus-4-kk/releng-mako.tt
b2g/config/nexus-4/releng-mako.tt
b2g/config/nexus-5-l/releng-nexus5.tt
browser/locales/en-US/chrome/browser/browser.properties
dom/manifest/test/test_ManifestProcessor_splash_screens.html
media/mtransport/stun_udp_socket_filter.cpp
media/mtransport/stun_udp_socket_filter.h
netwerk/base/nsIUDPSocketFilter.idl
testing/taskcluster/scripts/builder/build-shell-haz-linux.sh
testing/web-platform/meta/workers/semantics/encodings/003.html.ini
testing/web-platform/meta/workers/semantics/encodings/004.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/ServiceWorkerGlobalScope/__dir__.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/__dir__.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-event.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-css-base-url.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/fetch-request-css-images.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/performance-timeline.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/resource-timing.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/service-worker-csp-connect.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/service-worker-csp-default.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/service-worker-csp-script.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/shared-worker-controlled.https.html.ini
testing/web-platform/mozilla/meta/service-workers/service-worker/update-after-oneday.https.html.ini
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/activate-event-after-install-state-change.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/activation-after-registration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/active.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/appcache-ordering-main.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/claim-not-using-registration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/claim-using-registration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/clients-get-cross-origin.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/clients-get.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/clients-matchall-client-types.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/clients-matchall.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/controller-on-load.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/controller-on-reload.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/extendable-event-async-waituntil.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/extendable-event-waituntil.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-canvas-tainting.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-cors-xhr.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-csp.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-event-async-respond-with.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-event-network-error.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-event-redirect.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-event.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-frame-resource.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-header-visibility.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-css-base-url.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-css-images.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-fallback.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-no-freshness-headers.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-redirect.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-resources.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-request-xhr.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-response-xhr.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/fetch-waits-for-activate.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/getregistration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/getregistrations.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/indexeddb.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/install-event-type.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/installing.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/interfaces.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/invalid-blobtype.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/invalid-header.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/multiple-register.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/multiple-update.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/navigation-redirect.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/onactivate-script-error.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/oninstall-script-error.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/performance-timeline.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/postmessage-msgport-to-client.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/postmessage-to-client.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/postmessage.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/ready.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/referer.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/register-closed-window.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/register-default-scope.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/register-same-scope-different-script-url.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/register-wait-forever-in-install-worker.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/registration-end-to-end.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/registration-events.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/registration-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/registration-service-worker-attributes.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/registration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/rejections.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/request-end-to-end.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resource-timing.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/404.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/appcache-ordering.install.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/appcache-ordering.manifest
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/blank.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/claim-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/clients-get-frame.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/clients-get-other-origin.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/clients-get-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/clients-matchall-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/dummy-worker-interceptor.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/dummy-worker-script.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/dummy.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/dummy.txt
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/empty-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/empty.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/end-to-end-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/events-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/extendable-event-waituntil.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fail-on-fetch-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-access-control-login.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-access-control.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-csp-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-network-error-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-redirect-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-event-test-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-header-visibility-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-mixed-content-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-css-base-url-style.css
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-fallback-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-fallback-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-resources-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-response-xhr-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-rewrite-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/frame-for-getregistrations.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/get-host-info.sub.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/indexeddb-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/install-event-type-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/interfaces-worker.sub.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/interfaces.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/invalid-blobtype-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/invalid-chunked-encoding.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/invalid-header-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/invalid-header-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/load_worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/malformed-worker.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/mime-type-worker.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/navigation-redirect-scope1.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/navigation-redirect-scope2.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/navigation-redirect-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/onactivate-throw-error-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/oninstall-throw-error-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/other.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/override_assert_object_equals.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/performance-timeline-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/postmessage-to-client-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/postmessage-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/redirect.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/referer-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/register-closed-window-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/registration-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/reject-install-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/request-end-to-end-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/request-headers.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/resource-timing-iframe.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/resource-timing-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/service-worker-csp-worker.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/shared-worker-controlled.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/shared-worker-import.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/silence.oga
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/simple-intercept-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/simple.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/simple.txt
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/skip-waiting-installed-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/skip-waiting-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/square.png
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/success.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/test-helpers.sub.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/testharness-helpers.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/unregister-controller-page.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/update-nocookie-worker.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/update-worker.py
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/update/update-after-oneday.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/wait-forever-in-install-worker.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/websocket.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/worker-interception-iframe.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/worker-load-interceptor.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/worker-testharness.js
testing/web-platform/mozilla/tests/service-workers/service-worker/resources/xhr.js
testing/web-platform/mozilla/tests/service-workers/service-worker/service-worker-csp-connect.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/service-worker-csp-default.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/service-worker-csp-script.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/serviceworkerobject-scripturl.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/shared-worker-controlled.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/skip-waiting-installed.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/skip-waiting-using-registration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/skip-waiting-without-client.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/skip-waiting.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/state.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/synced-state.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/uncontrolled-page.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/unregister-controller.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/unregister-then-register-new-script.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/unregister-then-register.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/unregister.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/update-after-oneday.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/update.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/waiting.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/websocket.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/worker-interception.https.html
testing/web-platform/mozilla/tests/service-workers/service-worker/xhr.https.html
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -35,16 +35,20 @@ InterfacesFor(Accessible* aAcc)
     interfaces |= Interfaces::HYPERLINK;
 
   if (aAcc->HasNumericValue())
     interfaces |= Interfaces::VALUE;
 
   if (aAcc->IsImage())
     interfaces |= Interfaces::IMAGE;
 
+  if (aAcc->IsTable()) {
+    interfaces |= Interfaces::TABLE;
+  }
+
   if (aAcc->IsTableCell())
     interfaces |= Interfaces::TABLECELL;
 
   if (aAcc->IsDoc())
     interfaces |= Interfaces::DOCUMENT;
 
   if (aAcc->IsSelect()) {
     interfaces |= Interfaces::SELECTION;
--- a/b2g/config/aries/config.json
+++ b/b2g/config/aries/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-aries.tt",
+    "tooltool_manifest": "releng-aries.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["", "blobfree"],
     "upload_files": [
rename from b2g/config/dolphin/releng-dolphin.tt
rename to b2g/config/aries/releng-aries.manifest
--- a/b2g/config/dolphin/releng-dolphin.tt
+++ b/b2g/config/aries/releng-aries.manifest
@@ -1,10 +1,10 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }
 ]
--- a/b2g/config/dolphin/config.json
+++ b/b2g/config/dolphin/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-dolphin.tt",
+    "tooltool_manifest": "releng-dolphin.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "bc"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["kernelheader", ""],
     "upload_files": [
rename from b2g/config/aries/releng-aries.tt
rename to b2g/config/dolphin/releng-dolphin.manifest
--- a/b2g/config/aries/releng-aries.tt
+++ b/b2g/config/dolphin/releng-dolphin.manifest
@@ -1,10 +1,10 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }
 ]
--- a/b2g/config/emulator-ics/config.json
+++ b/b2g/config/emulator-ics/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator-ics.tt",
+    "tooltool_manifest": "releng-emulator-ics.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator/releng-emulator.tt
rename to b2g/config/emulator-ics/releng-emulator-ics.manifest
--- a/b2g/config/emulator/releng-emulator.tt
+++ b/b2g/config/emulator-ics/releng-emulator-ics.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/emulator-jb/config.json
+++ b/b2g/config/emulator-jb/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator-jb.tt",
+    "tooltool_manifest": "releng-emulator-jb.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator-x86-l/releng-emulator-l.tt
rename to b2g/config/emulator-jb/releng-emulator-jb.manifest
--- a/b2g/config/emulator-x86-l/releng-emulator-l.tt
+++ b/b2g/config/emulator-jb/releng-emulator-jb.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/emulator-kk/config.json
+++ b/b2g/config/emulator-kk/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator-kk.tt",
+    "tooltool_manifest": "releng-emulator-kk.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator-x86-kk/releng-emulator-kk.tt
rename to b2g/config/emulator-kk/releng-emulator-kk.manifest
--- a/b2g/config/emulator-x86-kk/releng-emulator-kk.tt
+++ b/b2g/config/emulator-kk/releng-emulator-kk.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/emulator-l/config.json
+++ b/b2g/config/emulator-l/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator-l.tt",
+    "tooltool_manifest": "releng-emulator-l.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator-l/releng-emulator-l.tt
rename to b2g/config/emulator-l/releng-emulator-l.manifest
--- a/b2g/config/emulator-l/releng-emulator-l.tt
+++ b/b2g/config/emulator-l/releng-emulator-l.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/emulator-x86-kk/config.json
+++ b/b2g/config/emulator-x86-kk/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator-kk.tt",
+    "tooltool_manifest": "releng-emulator-kk.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator-kk/releng-emulator-kk.tt
rename to b2g/config/emulator-x86-kk/releng-emulator-kk.manifest
--- a/b2g/config/emulator-kk/releng-emulator-kk.tt
+++ b/b2g/config/emulator-x86-kk/releng-emulator-kk.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/emulator-x86-l/config.json
+++ b/b2g/config/emulator-x86-l/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator-l.tt",
+    "tooltool_manifest": "releng-emulator-l.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator-jb/releng-emulator-jb.tt
rename to b2g/config/emulator-x86-l/releng-emulator-l.manifest
--- a/b2g/config/emulator-jb/releng-emulator-jb.tt
+++ b/b2g/config/emulator-x86-l/releng-emulator-l.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/emulator/config.json
+++ b/b2g/config/emulator/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-emulator.tt",
+    "tooltool_manifest": "releng-emulator.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["droid", "package-emulator", "package-tests"],
     "upload_files": [
rename from b2g/config/emulator-ics/releng-emulator-ics.tt
rename to b2g/config/emulator/releng-emulator.manifest
--- a/b2g/config/emulator-ics/releng-emulator-ics.tt
+++ b/b2g/config/emulator/releng-emulator.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/b2g/config/flame-kk/config.json
+++ b/b2g/config/flame-kk/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-flame-kk.tt",
+    "tooltool_manifest": "releng-flame-kk.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools", "java-1.6.0-openjdk"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["", "blobfree"],
     "upload_files": [
rename from b2g/config/flame-kk/releng-flame-kk.tt
rename to b2g/config/flame-kk/releng-flame-kk.manifest
--- a/b2g/config/flame-kk/releng-flame-kk.tt
+++ b/b2g/config/flame-kk/releng-flame-kk.manifest
@@ -2,16 +2,16 @@
 {
 "size": 135359412,
 "digest": "45e677c9606cc4eec44ef4761df47ff431df1ffad17a5c6d21ce700a1c47f79e87a4aa9f30ae47ff060bd64f5b775d995780d88211f9a759ffa0d076beb4816b",
 "algorithm": "sha512",
 "filename": "backup-flame.tar.xz",
 "comment": "v18D"
 },
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }
 ]
--- a/b2g/config/flame/config.json
+++ b/b2g/config/flame/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-flame.tt",
+    "tooltool_manifest": "releng-flame.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2", "dosfstools"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": [],
     "upload_files": [
rename from b2g/config/flame/releng-flame.tt
rename to b2g/config/flame/releng-flame.manifest
--- a/b2g/config/flame/releng-flame.tt
+++ b/b2g/config/flame/releng-flame.manifest
@@ -1,15 +1,15 @@
 [
 {"size": 149922032,
 "digest": "8d1a71552ffee561e93b5b3f1bb47866592ab958f908007c75561156430eb1b85a265bfc4dc2038e58dda0264daa9854877a84ef3b591c9ac2f1ab97c098e61e",
 "filename": "backup-flame.tar.xz",
 "algorithm": "sha512"
 },
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }
 ]
--- a/b2g/config/nexus-4-kk/config.json
+++ b/b2g/config/nexus-4-kk/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-mako.tt",
+    "tooltool_manifest": "releng-mako.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["", "blobfree"],
     "upload_files": [
rename from b2g/config/nexus-4-kk/releng-mako.tt
rename to b2g/config/nexus-4-kk/releng-mako.manifest
--- a/b2g/config/nexus-4-kk/releng-mako.tt
+++ b/b2g/config/nexus-4-kk/releng-mako.manifest
@@ -13,17 +13,17 @@
 },
 {
 "size": 163277,
 "digest": "e58aad76e6395a1a82fe886783842c4676c12d065e2f65bce6ce19cab2488be767aaea27fa2f46f48a0bf8d9714a6b453b474d2f9df5de158c49e6cbde0a359e",
 "algorithm": "sha512",
 "filename": "lge-mako-kot49h-f59c98be.tgz"
 },
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }
 ]
 
--- a/b2g/config/nexus-4/config.json
+++ b/b2g/config/nexus-4/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-mako.tt",
+    "tooltool_manifest": "releng-mako.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": [],
     "upload_files": [
rename from b2g/config/nexus-4/releng-mako.tt
rename to b2g/config/nexus-4/releng-mako.manifest
--- a/b2g/config/nexus-4/releng-mako.tt
+++ b/b2g/config/nexus-4/releng-mako.manifest
@@ -13,17 +13,17 @@
 },
 {
 "size": 378532,
 "digest": "27aced8feb0e757d61df37839e62410ff30a059cfa8f04897d29ab74b787c765313acf904b1f9cf311c3e682883514df7da54197665251ef9b8bdad6bd0f62c5",
 "algorithm": "sha512",
 "filename": "lge-mako-jwr66v-985845e4.tgz"
 },
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }
 ]
 
--- a/b2g/config/nexus-5-l/config.json
+++ b/b2g/config/nexus-5-l/config.json
@@ -1,11 +1,11 @@
 {
     "config_version": 2,
-    "tooltool_manifest": "releng-nexus5.tt",
+    "tooltool_manifest": "releng-nexus5.manifest",
     "mock_target": "mozilla-centos6-x86_64",
     "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git", "libxml2"],
     "mock_files": [
         ["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"],
         ["/builds/crash-stats-api.token", "/builds/crash-stats-api.token"]
     ],
     "build_targets": ["", "blobfree"],
     "upload_files": [
rename from b2g/config/nexus-5-l/releng-nexus5.tt
rename to b2g/config/nexus-5-l/releng-nexus5.manifest
--- a/b2g/config/nexus-5-l/releng-nexus5.tt
+++ b/b2g/config/nexus-5-l/releng-nexus5.manifest
@@ -1,8 +1,8 @@
 [{
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": "True"
 }]
--- a/b2g/config/tooltool-manifests/linux32/releng.manifest
+++ b/b2g/config/tooltool-manifests/linux32/releng.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 11189216,
 "digest": "18bc52b0599b1308b667e282abb45f47597bfc98a5140cfcab8da71dacf89dd76d0dee22a04ce26fe7ad1f04e2d6596991f9e5b01fd2aaaab5542965f596b0e6",
 "algorithm": "sha512",
--- a/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
+++ b/b2g/dev/config/tooltool-manifests/linux64/hazard.manifest
@@ -3,21 +3,21 @@
 "version": "gcc 4.9.3",
 "size": 102421980,
 "digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
-"hg_id" : "ec7b7d2442e8",
+"hg_id" : "cd93f15a30ce",
 "algorithm" : "sha512",
-"digest" : "49627d734df52cb9e7319733da5a6be1812b9373355dc300ee5600b431122570e00d380d50c7c5b5003c462c2c2cb022494b42c4ad00f8eba01c2259cbe6e502",
+"digest" : "541eb3842ab6b91bd87223cad7a5e4387ef3e496e5b580c8047b8b586bc7eb69fecf3c9eb8c45a1e0deebb53554f0e8acedfe1b4ca64d93b6d008f3f2eb11389",
 "filename" : "sixgill.tar.xz",
-"size" : 2628868,
+"size" : 2626640,
 "unpack" : true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
 "filename": "gtk3.tar.xz",
 "setup": "setup.sh",
--- a/browser/app/blocklist.xml
+++ b/browser/app/blocklist.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0"?>
-<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1458315314000">
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1459441171000">
   <emItems>
       <emItem  blockID="i58" id="webmaster@buzzzzvideos.info">
                         <versionRange  minVersion="0" maxVersion="*">
                     </versionRange>
                     <prefs>
               </prefs>
     </emItem>
       <emItem  blockID="i71" id="youtube@2youtube.com">
@@ -3436,16 +3436,40 @@
       <pluginItem  blockID="p1139">
                   <match name="filename" exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" />                      <versionRange  minVersion="18.0.0.326" maxVersion="18.0.0.329" severity="0" vulnerabilitystatus="1"></versionRange>
                             <infoURL>https://get.adobe.com/flashplayer/</infoURL>
           </pluginItem>
       <pluginItem  blockID="p1140">
                   <match name="filename" exp="(NPSWF32.*\.dll)|(NPSWF64.*\.dll)|(Flash\ Player\.plugin)" />                      <versionRange  minVersion="20.0.0.286" maxVersion="20.0.0.306" severity="0" vulnerabilitystatus="1"></versionRange>
                             <infoURL>https://get.adobe.com/flashplayer/</infoURL>
           </pluginItem>
+      <pluginItem  blockID="p1141">
+                  <match name="filename" exp="JavaAppletPlugin\.plugin" />                      <versionRange  minVersion="Java 7 Update 91" maxVersion="Java 7 Update 97" severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://java.com/</infoURL>
+          </pluginItem>
+      <pluginItem  blockID="p1142">
+                  <match name="filename" exp="JavaAppletPlugin\.plugin" />                      <versionRange  minVersion="Java 8 Update 64" maxVersion="Java 8 Update 76" severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://java.com/</infoURL>
+          </pluginItem>
+      <pluginItem  blockID="p1143">
+      <match name="name" exp="Java\(TM\) Platform SE 7 U(9[1-7])(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://java.com/</infoURL>
+          </pluginItem>
+      <pluginItem  blockID="p1144">
+      <match name="name" exp="Java\(TM\) Platform SE 8 U(6[4-9]|7[0-6])(\s[^\d\._U]|$)" />            <match name="filename" exp="npjp2\.dll" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://java.com/</infoURL>
+          </pluginItem>
+      <pluginItem  blockID="p1145">
+      <match name="name" exp="Java(\(TM\))? Plug-in 10\.(9[1-7])(\.[0-9]+)?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://java.com/</infoURL>
+          </pluginItem>
+      <pluginItem  blockID="p1146">
+      <match name="name" exp="Java(\(TM\))? Plug-in 11\.(6[4-9]|7[0-6])(\.[0-9]+)?([^\d\._]|$)" />            <match name="filename" exp="libnpjp2\.so" />                      <versionRange  severity="0" vulnerabilitystatus="1"></versionRange>
+                            <infoURL>https://java.com/</infoURL>
+          </pluginItem>
     </pluginItems>
 
   <gfxItems>
     <gfxBlacklistEntry  blockID="g35">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
                       <device>0x0a6c</device>
                   </devices>
             <feature>DIRECT2D</feature>      <featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>      <driverVersion>8.17.12.5896</driverVersion>      <driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>    </gfxBlacklistEntry>
     <gfxBlacklistEntry  blockID="g36">      <os>WINNT 6.1</os>      <vendor>0x10de</vendor>              <devices>
@@ -3741,18 +3765,17 @@
       <serialNumber>BAAAAAABHkSl7L4=</serialNumber>
     </certItem>
         <certItem issuerName="MIGBMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTElMCMGA1UECxMcUHJpbWFyeSBPYmplY3QgUHVibGlzaGluZyBDQTEwMC4GA1UEAxMnR2xvYmFsU2lnbiBQcmltYXJ5IE9iamVjdCBQdWJsaXNoaW5nIENB">
       <serialNumber>BAAAAAABI54PryQ=</serialNumber>
     </certItem>
         <certItem issuerName="MGExCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlJZGVuVHJ1c3QxIDAeBgNVBAsTF0lkZW5UcnVzdCBQdWJsaWMgU2VjdG9yMRwwGgYDVQQDExNJZGVuVHJ1c3QgQUNFUyBDQSAx">
       <serialNumber>fwAAAQAAAUrz/HmrAAAAAg==</serialNumber>
     </certItem>
-        <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=
-">
+        <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>By7fBTreouRwX/qrpgSUsg==</serialNumber>
     </certItem>
         <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>Gd/pPu+qLnXUdvP9sW73CQ==</serialNumber>
     </certItem>
         <certItem issuerName="MIG8MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhIChjKTEwMTYwNAYDVQQDEy1WZXJpU2lnbiBDbGFzcyAzIEludGVybmF0aW9uYWwgU2VydmVyIENBIC0gRzM=">
       <serialNumber>LdbnCbsA9sOgI4mkUpWXPw==</serialNumber>
     </certItem>
--- a/browser/base/content/browser-eme.js
+++ b/browser/base/content/browser-eme.js
@@ -59,31 +59,29 @@ var gEMEHandler = {
 
       case "api-disabled":
       case "cdm-disabled":
         notificationId = "drmContentDisabled";
         buttonCallback = gEMEHandler.ensureEMEEnabled.bind(gEMEHandler, browser, keySystem)
         params = [this.getLearnMoreLink(notificationId)];
         break;
 
-      case "cdm-not-supported":
-        notificationId = "drmContentCDMNotSupported";
-        params = [this._brandShortName, this.getLearnMoreLink(notificationId)];
-        break;
-
       case "cdm-insufficient-version":
         notificationId = "drmContentCDMInsufficientVersion";
         params = [this._brandShortName];
         break;
 
       case "cdm-not-installed":
         notificationId = "drmContentCDMInstalling";
         params = [this._brandShortName];
         break;
 
+      case "cdm-not-supported":
+        // Not to pop up user-level notification because they cannot do anything
+        // about it.
       case "error":
         // Fall through and do the same for unknown messages:
       default:
         let typeOfIssue = status == "error" ? "error" : "message ('" + status + "')";
         Cu.reportError("Unknown " + typeOfIssue + " dealing with EME key request: " + data);
         return;
     }
 
@@ -93,26 +91,16 @@ var gEMEHandler = {
     let box = gBrowser.getNotificationBox(browser);
     if (box.getNotificationWithValue(notificationId)) {
       return;
     }
 
     let msgPrefix = "emeNotifications." + notificationId + ".";
     let msgId = msgPrefix + "message";
 
-    // Special-case Adobe's CDM message on unsupported platforms to be more informative:
-    if (notificationId == "drmContentCDMNotSupported" &&
-        keySystem.startsWith("com.adobe")) {
-      let os = Services.appinfo.OS.toLowerCase();
-      if (os.startsWith("linux") || os.startsWith("darwin")) {
-        msgId = msgPrefix + "unsupportedOS.message";
-        labelParams.splice(1, 0, os.startsWith("linux") ? "Linux" : "Mac OS X");
-      }
-    }
-
     let message = labelParams.length ?
                   gNavigatorBundle.getFormattedString(msgId, labelParams) :
                   gNavigatorBundle.getString(msgId);
 
     let buttons = [];
     if (callback) {
       let btnLabelId = msgPrefix + "button.label";
       let btnAccessKeyId = msgPrefix + "button.accesskey";
@@ -135,17 +123,16 @@ var gEMEHandler = {
 
     box.appendNotification(fragment, notificationId, iconURL, box.PRIORITY_WARNING_MEDIUM,
                            buttons);
   },
   showPopupNotificationForSuccess: function(browser, keySystem) {
     // We're playing EME content! Remove any "we can't play because..." messages.
     var box = gBrowser.getNotificationBox(browser);
     ["drmContentDisabled",
-     "drmContentCDMNotSupported",
      "drmContentCDMInsufficientVersion",
      "drmContentCDMInstalling"
      ].forEach(function (value) {
         var notification = box.getNotificationWithValue(value);
         if (notification)
           box.removeNotification(notification);
       });
 
--- a/browser/base/content/social-content.js
+++ b/browser/base/content/social-content.js
@@ -41,17 +41,17 @@ addEventListener("Social:Notification", 
   sendAsyncMessage("Social:Notification", {
     "origin": origin,
     "detail": JSON.parse(event.detail)
   });
 });
 
 // Error handling class used to listen for network errors in the social frames
 // and replace them with a social-specific error page
-SocialErrorListener = {
+const SocialErrorListener = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
                                          Ci.nsIWebProgressListener,
                                          Ci.nsISupportsWeakReference,
                                          Ci.nsISupports]),
 
   defaultTemplate: "about:socialerror?mode=tryAgainOnly&url=%{url}&origin=%{origin}",
   urlTemplate: null,
 
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3820,23 +3820,23 @@
                 return;
 
               let accum = prefix + " ";
               for (let i = 0; i < this.tabbrowser.tabs.length; i++) {
                 let tab = this.tabbrowser.tabs[i];
                 let state = this.getTabState(tab);
 
                 accum += i + ":";
-                if (tab === this.lastVisibleTab) dump("V");
-                if (tab === this.loadingTab) dump("L");
-                if (tab === this.requestedTab) dump("R");
-                if (state == this.STATE_LOADED) dump("(+)");
-                if (state == this.STATE_LOADING) dump("(+?)");
-                if (state == this.STATE_UNLOADED) dump("(-)");
-                if (state == this.STATE_UNLOADING) dump("(-?)");
+                if (tab === this.lastVisibleTab) accum += "V";
+                if (tab === this.loadingTab) accum += "L";
+                if (tab === this.requestedTab) accum += "R";
+                if (state == this.STATE_LOADED) accum += "(+)";
+                if (state == this.STATE_LOADING) accum += "(+?)";
+                if (state == this.STATE_UNLOADED) accum += "(-)";
+                if (state == this.STATE_UNLOADING) accum += "(-?)";
                 accum += " ";
               }
               if (this._useDumpForLogging) {
                 dump(accum + "\n");
               } else {
                 Services.console.logStringMessage(accum);
               }
             },
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -1,9 +1,10 @@
 [DEFAULT]
+skip-if = (os == "win" && debug && e10s) # Bug 1253956
 support-files =
   POSTSearchEngine.xml
   accounts_testRemoteCommands.html
   alltabslistener.html
   app_bug575561.html
   app_subframe_bug575561.html
   authenticate.sjs
   aboutHome_content_script.js
--- a/browser/config/tooltool-manifests/linux32/releng.manifest
+++ b/browser/config/tooltool-manifests/linux32/releng.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512", 
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 11189216,
 "digest": "18bc52b0599b1308b667e282abb45f47597bfc98a5140cfcab8da71dacf89dd76d0dee22a04ce26fe7ad1f04e2d6596991f9e5b01fd2aaaab5542965f596b0e6",
 "algorithm": "sha512",
--- a/browser/config/tooltool-manifests/linux64/hazard.manifest
+++ b/browser/config/tooltool-manifests/linux64/hazard.manifest
@@ -1,24 +1,23 @@
 [
 {
 "version": "gcc 4.9.3",
 "size": 102421980,
-"visibility": "public",
 "digest": "f25292aa93dc449e0472eee511c0ac15b5f1a4272ab76cf53ce5d20dc57f29e83da49ae1a9d9e994192647f75e13ae60f75ba2ac3cb9d26d5f5d6cabf88de921",
 "algorithm": "sha512",
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
-"hg_id" : "ec7b7d2442e8",
+"hg_id" : "cd93f15a30ce",
 "algorithm" : "sha512",
-"digest" : "49627d734df52cb9e7319733da5a6be1812b9373355dc300ee5600b431122570e00d380d50c7c5b5003c462c2c2cb022494b42c4ad00f8eba01c2259cbe6e502",
+"digest" : "541eb3842ab6b91bd87223cad7a5e4387ef3e496e5b580c8047b8b586bc7eb69fecf3c9eb8c45a1e0deebb53554f0e8acedfe1b4ca64d93b6d008f3f2eb11389",
 "filename" : "sixgill.tar.xz",
-"size" : 2628868,
+"size" : 2626640,
 "unpack" : true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
 "filename": "gtk3.tar.xz",
 "setup": "setup.sh",
--- a/browser/config/tooltool-manifests/linux64/releng.manifest
+++ b/browser/config/tooltool-manifests/linux64/releng.manifest
@@ -1,13 +1,13 @@
 [
 {
-"version": "gcc 4.8.5",
-"size": 81065660,
-"digest": "db26f498ab56a3b5c65d7cda290cbb74174af9f2d021ca9c158f53b0382924ccf5ed9638d41eef449434aa9383a9113994d9729d9dd910321d1f35f9411eae38",
+"version": "gcc 4.8.5 + PR64905",
+"size": 80160264,
+"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
 "algorithm": "sha512", 
 "filename": "gcc.tar.xz",
 "unpack": true
 },
 {
 "size": 12072532,
 "digest": "3915f8ec396c56a8a92e6f9695b70f09ce9d1582359d1258e37e3fd43a143bc974410e4cfc27f500e095f34a8956206e0ebf799b7287f0f38def0d5e34ed71c9",
 "algorithm": "sha512",
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/e10srollout/bootstrap.js
@@ -90,17 +90,19 @@ function getUserSample() {
   let val = Math.floor(Math.random() * 100);
   Preferences.set(PREF_COHORT_SAMPLE, val);
   return val;
 }
 
 function setCohort(cohortName) {
   Preferences.set(PREF_COHORT_NAME, cohortName);
   try {
-    Services.appinfo.QueryInterface(Ci.nsICrashReporter).annotateCrashReport("E10SCohort", cohortName);
+    if (Ci.nsICrashReporter) {
+      Services.appinfo.QueryInterface(Ci.nsICrashReporter).annotateCrashReport("E10SCohort", cohortName);
+    }
   } catch (e) {}
 }
 
 function optedIn() {
   return Preferences.get(PREF_E10S_OPTED_IN, false) ||
          Preferences.get(PREF_E10S_FORCE_ENABLED, false);
 }
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -637,30 +637,22 @@ emeNotifications.drmContentPlaying.butto
 
 # LOCALIZATION NOTE(emeNotifications.drmContentDisabled.message): NB: inserted via innerHTML, so please don't use <, > or & in this string. %S will be the 'learn more' link
 emeNotifications.drmContentDisabled.message = You must enable DRM to play some audio or video on this page. %S
 emeNotifications.drmContentDisabled.button.label = Enable DRM
 emeNotifications.drmContentDisabled.button.accesskey = E
 # LOCALIZATION NOTE(emeNotifications.drmContentDisabled.learnMoreLabel): NB: inserted via innerHTML, so please don't use <, > or & in this string.
 emeNotifications.drmContentDisabled.learnMoreLabel = Learn More
 
-# LOCALIZATION NOTE(emeNotifications.drmContentCDMNotSupported.message): NB: inserted via innerHTML, so please don't use <, > or & in this string. %1$S is brandShortName, %2$S will be the 'learn more' link
-emeNotifications.drmContentCDMNotSupported.message = The audio or video on this page requires DRM software that %1$S does not support. %2$S
-# LOCALIZATION NOTE(emeNotifications.drmContentCDMNotSupported.learnMoreLabel): NB: inserted via innerHTML, so please don't use <, > or & in this string.
-emeNotifications.drmContentCDMNotSupported.learnMoreLabel = Learn More
-
 # LOCALIZATION NOTE(emeNotifications.drmContentCDMInsufficientVersion.message): NB: inserted via innerHTML, so please don't use <, > or & in this string. %S is brandShortName
 emeNotifications.drmContentCDMInsufficientVersion.message = %S is installing updates needed to play the audio or video on this page. Please try again later.
 
 # LOCALIZATION NOTE(emeNotifications.drmContentCDMInstalling.message): NB: inserted via innerHTML, so please don't use <, > or & in this string. %S is brandShortName
 emeNotifications.drmContentCDMInstalling.message = %S is installing components needed to play the audio or video on this page. Please try again later.
 
-# LOCALIZATION NOTE(emeNotifications.drmContentCDMNotSupported.unsupportedOS.message): NB: inserted via innerHTML, so please don't use <, > or & in this string. %1$S is brandShortName, %2$S is the name of the user's OS (Windows, Linux, Mac OS X), %3$S will be the 'learn more' link
-emeNotifications.drmContentCDMNotSupported.unsupportedOS.message = The audio or video on this page requires DRM software that %1$S does not support on %2$S. %3$S
-
 emeNotifications.unknownDRMSoftware = Unknown
 
 # LOCALIZATION NOTE - %S is brandShortName
 slowStartup.message = %S seems slow… to… start.
 slowStartup.helpButton.label = Learn How to Speed It Up
 slowStartup.helpButton.accesskey = L
 slowStartup.disableNotificationButton.label = Don’t Tell Me Again
 slowStartup.disableNotificationButton.accesskey = A
@@ -767,8 +759,15 @@ revokeOverride.accesskey = D
 certErrorDetailsHSTS.label = HTTP Strict Transport Security: %S
 certErrorDetailsKeyPinning.label = HTTP Public Key Pinning: %S
 certErrorDetailsCertChain.label = Certificate chain:
 
 # LOCALIZATION NOTE (tabgroups.migration.anonGroup):
 # %S is the group number/ID
 tabgroups.migration.anonGroup = Group %S
 tabgroups.migration.tabGroupBookmarkFolderName = Bookmarked Tab Groups
+
+decoder.noCodecs.button = Learn how
+decoder.noCodecs.accesskey = L
+decoder.noCodecs.message = To play video, you may need to install Microsoft’s Media Feature Pack.
+decoder.noCodecsXP.message = To play video, you may need to enable Adobe’s Primetime Content Decryption Module.
+decoder.noCodecsLinux.message = To play video, you may need to install the required video codecs.
+decoder.noHWAcceleration.message = To improve video quality, you may need to install Microsoft’s Media Feature Pack.
--- a/browser/modules/ProcessHangMonitor.jsm
+++ b/browser/modules/ProcessHangMonitor.jsm
@@ -17,58 +17,46 @@ Cu.import("resource://gre/modules/Servic
 /**
  * This JSM is responsible for observing content process hang reports
  * and asking the user what to do about them. See nsIHangReport for
  * the platform interface.
  */
 
 var ProcessHangMonitor = {
   /**
-   * If a hang hasn't been reported for more than 10 seconds, assume the
-   * content process has gotten unstuck (and hide the hang notification).
-   */
-  get HANG_EXPIRATION_TIME() {
-    try {
-      return Services.prefs.getIntPref("browser.hangNotification.expiration");
-    } catch (ex) {
-      return 10000;
-    }
-  },
-
-  /**
    * This timeout is the wait period applied after a user selects "Wait" in
    * an existing notification.
    */
   get WAIT_EXPIRATION_TIME() {
     try {
       return Services.prefs.getIntPref("browser.hangNotification.waitPeriod");
     } catch (ex) {
       return 10000;
     }
   },
 
   /**
    * Collection of hang reports that haven't expired or been dismissed
-   * by the user. The keys are nsIHangReports and values keys are
-   * timers. Each time the hang is reported, the timer is refreshed so
-   * it expires after HANG_EXPIRATION_TIME.
+   * by the user. These are nsIHangReports.
    */
-  _activeReports: new Map(),
+  _activeReports: new Set(),
 
   /**
-   * Collection of hang reports that have been suppressed for a
-   * short period of time.
+   * Collection of hang reports that have been suppressed for a short
+   * period of time. Value is an nsITimer for when the wait time
+   * expires.
    */
   _pausedReports: new Map(),
 
   /**
    * Initialize hang reporting. Called once in the parent process.
    */
   init: function() {
     Services.obs.addObserver(this, "process-hang-report", false);
+    Services.obs.addObserver(this, "clear-hang-report", false);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
     Services.ww.registerNotification(this);
   },
 
   /**
    * Terminate JavaScript associated with the hang being reported for
    * the selected browser in |win|.
    */
@@ -127,42 +115,35 @@ var ProcessHangMonitor = {
    * Dismiss the notification, clear the report from the active list and set up
    * a new timer to track a wait period during which we won't notify.
    */
   waitLonger: function(win) {
     let report = this.findActiveReport(win.gBrowser.selectedBrowser);
     if (!report) {
       return;
     }
-    // Remove the report from the active list and cancel its timer.
+    // Remove the report from the active list.
     this.removeActiveReport(report);
 
     // NOTE, we didn't call userCanceled on nsIHangReport here. This insures
     // we don't repeatedly generate and cache crash report data for this hang
     // in the process hang reporter. It already has one report for the browser
     // process we want it hold onto.
 
     // Create a new wait timer with notify callback
     let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
     timer.initWithCallback(() => {
       for (let [stashedReport, otherTimer] of this._pausedReports) {
         if (otherTimer === timer) {
           this.removePausedReport(stashedReport);
 
-          // Create a new notification display timeout timer
-          let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-          timer.initWithCallback(this, this.HANG_EXPIRATION_TIME, timer.TYPE_ONE_SHOT);
-
-          // Store the timer in the active reports map. If we receive a new
-          // observer notification for this hang, we'll redisplay the browser
-          // notification in reportHang below. If we do not receive a new
-          // observer, timer will take care fo cleaning up resources associated
-          // with this hang. The observer for active hangs fires about once
-          // a second.
-          this._activeReports.set(report, timer);
+          // We're still hung, so move the report back to the active
+          // list and update the UI.
+          this._activeReports.add(report);
+          this.updateWindows();
           break;
         }
       }
     }, this.WAIT_EXPIRATION_TIME, timer.TYPE_ONE_SHOT);
 
     this._pausedReports.set(report, timer);
 
     // remove the browser notification associated with this hang
@@ -184,23 +165,28 @@ var ProcessHangMonitor = {
     return func(report);
   },
 
   observe: function(subject, topic, data) {
     switch (topic) {
       case "xpcom-shutdown":
         Services.obs.removeObserver(this, "xpcom-shutdown");
         Services.obs.removeObserver(this, "process-hang-report");
+        Services.obs.removeObserver(this, "clear-hang-report");
         Services.ww.unregisterNotification(this);
         break;
 
       case "process-hang-report":
         this.reportHang(subject.QueryInterface(Ci.nsIHangReport));
         break;
 
+      case "clear-hang-report":
+        this.clearHang(subject.QueryInterface(Ci.nsIHangReport));
+        break;
+
       case "domwindowopened":
         // Install event listeners on the new window in case one of
         // its tabs is already hung.
         let win = subject.QueryInterface(Ci.nsIDOMWindow);
         let listener = (ev) => {
           win.removeEventListener("load", listener, true);
           this.updateWindows();
         };
@@ -209,17 +195,17 @@ var ProcessHangMonitor = {
     }
   },
 
   /**
    * Find a active hang report for the given <browser> element.
    */
   findActiveReport: function(browser) {
     let frameLoader = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
-    for (let [report, timer] of this._activeReports) {
+    for (let report of this._activeReports) {
       if (report.isReportForBrowser(frameLoader)) {
         return report;
       }
     }
     return null;
   },
 
   /**
@@ -235,20 +221,16 @@ var ProcessHangMonitor = {
     return null;
   },
 
   /**
    * Remove an active hang report from the active list and cancel the timer
    * associated with it.
    */
   removeActiveReport: function(report) {
-    let timer = this._activeReports.get(report);
-    if (timer) {
-      timer.cancel();
-    }
     this._activeReports.delete(report);
     this.updateWindows();
   },
 
   /**
    * Remove a paused hang report from the paused list and cancel the timer
    * associated with it.
    */
@@ -377,19 +359,16 @@ var ProcessHangMonitor = {
 
   /**
    * Handle a potentially new hang report. If it hasn't been seen
    * before, show a notification for it in all open XUL windows.
    */
   reportHang: function(report) {
     // If this hang was already reported reset the timer for it.
     if (this._activeReports.has(report)) {
-      let timer = this._activeReports.get(report);
-      timer.cancel();
-      timer.initWithCallback(this, this.HANG_EXPIRATION_TIME, timer.TYPE_ONE_SHOT);
       // if this report is in active but doesn't have a notification associated
       // with it, display a notification.
       this.updateWindows();
       return;
     }
 
     // If this hang was already reported and paused by the user ignore it.
     if (this._pausedReports.has(report)) {
@@ -402,29 +381,18 @@ var ProcessHangMonitor = {
       // On non-e10s, SLOW_SCRIPT_NOTICE_COUNT is probed at nsGlobalWindow.cpp
       Services.telemetry.getHistogramById("SLOW_SCRIPT_NOTICE_COUNT").add();
     } else if (report.hangType == report.PLUGIN_HANG) {
       // On non-e10s we have sufficient plugin telemetry probes,
       // so PLUGIN_HANG_NOTICE_COUNT is only probed on e10s.
       Services.telemetry.getHistogramById("PLUGIN_HANG_NOTICE_COUNT").add();
     }
 
-    // Otherwise create a new timer and display the report.
-    let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    timer.initWithCallback(this, this.HANG_EXPIRATION_TIME, timer.TYPE_ONE_SHOT);
-
-    this._activeReports.set(report, timer);
+    this._activeReports.add(report);
     this.updateWindows();
   },
 
-  /**
-   * Callback for when HANG_EXPIRATION_TIME has elapsed.
-   */
-  notify: function(timer) {
-    for (let [otherReport, otherTimer] of this._activeReports) {
-      if (otherTimer === timer) {
-        this.removeActiveReport(otherReport);
-        otherReport.userCanceled();
-        break;
-      }
-    }
+  clearHang: function(report) {
+    this.removeActiveReport(report);
+    this.removePausedReport(report);
+    report.userCanceled();
   },
 };
--- a/browser/modules/test/browser_ProcessHangNotifications.js
+++ b/browser/modules/test/browser_ProcessHangNotifications.js
@@ -121,52 +121,53 @@ add_task(function* waitForScriptTest() {
   let promise = promiseNotificationShown(window, "process-hang");
   Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
   let notification = yield promise;
 
   let buttons = notification.currentNotification.getElementsByTagName("button");
   // Fails on aurora on-push builds, bug 1232204
   // is(buttons.length, buttonCount, "proper number of buttons");
 
-  yield pushPrefs(["browser.hangNotification.waitPeriod", 1000],
-                  ["browser.hangNotification.expiration", 2000]);
+  yield pushPrefs(["browser.hangNotification.waitPeriod", 1000]);
 
   function nocbcheck() {
     ok(false, "received a callback?");
   }
   let oldcb = gTestHangReport.testCallback;
   gTestHangReport.testCallback = nocbcheck;
   // Click the "Wait" button this time, we shouldn't get a callback at all.
   buttons[1].click();
   gTestHangReport.testCallback = oldcb;
 
   // send another hang pulse, we should not get a notification here
   Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
   is(notification.currentNotification, null, "no notification should be visible");
 
-  // After selecting Wait, we should get a userCanceled callback after
-  // HANG_EXPIRATION_TIME.
-  yield promiseReportCallMade(gTestHangReport.TEST_CALLBACK_CANCELED);
+  gTestHangReport.testCallback = function() {};
+  Services.obs.notifyObservers(gTestHangReport, "clear-hang-report", null);
+  gTestHangReport.testCallback = oldcb;
 
   yield popPrefs();
 });
 
 /**
  * Test if hang reports receive user canceled callbacks after the content
  * process stops sending hang notifications.
  */
 
 add_task(function* hangGoesAwayTest() {
   yield pushPrefs(["browser.hangNotification.expiration", 1000]);
 
   let promise = promiseNotificationShown(window, "process-hang");
   Services.obs.notifyObservers(gTestHangReport, "process-hang-report", null);
   yield promise;
 
-  yield promiseReportCallMade(gTestHangReport.TEST_CALLBACK_CANCELED);
+  promise = promiseReportCallMade(gTestHangReport.TEST_CALLBACK_CANCELED);
+  Services.obs.notifyObservers(gTestHangReport, "clear-hang-report", null);
+  yield promise;
 
   yield popPrefs();
 });
 
 /**
  * Tests if hang reports receive a terminate plugin callback when the user selects
  * stop in response to a plugin hang.
  */
new file mode 100644
--- /dev/null
+++ b/build/unix/build-gcc/PR64905.patch
@@ -0,0 +1,11 @@
+--- trunk/gcc/lra-eliminations.c	2015/02/04 20:00:48	220415
++++ trunk/gcc/lra-eliminations.c	2015/02/04 20:02:21	220416
+@@ -182,6 +182,8 @@
+   if (! value
+       && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM)
+     frame_pointer_needed = 1;
++  if (!frame_pointer_needed)
++    REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0;
+ }
+ 
+ /* Map: eliminable "from" register -> its current elimination,
--- a/build/unix/build-gcc/build-gcc.sh
+++ b/build/unix/build-gcc/build-gcc.sh
@@ -34,16 +34,18 @@ case "$gcc_version" in
   wget -c -P $TMPDIR ftp://ftp.gnu.org/gnu/gcc/gcc-$gcc_version/gcc-$gcc_version.tar.bz2 || exit 1
   ;;
 esac
 tar xjf $TMPDIR/gcc-$gcc_version.tar.bz2
 cd gcc-$gcc_version
 
 ./contrib/download_prerequisites
 
+patch -p1 < "${this_path}/PR64905.patch" || exit 1
+
 cd ..
 mkdir gcc-objdir
 cd gcc-objdir
 ../gcc-$gcc_version/configure --prefix=/tools/gcc --enable-languages=c,c++  --disable-nls --disable-gnu-unique-object --enable-__cxa_atexit --with-arch-32=pentiumpro || exit 1
 make $make_flags || exit 1
 make $make_flags install DESTDIR=$root_dir || exit 1
 
 cd $root_dir/tools
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -3641,16 +3641,63 @@ Element::InsertAdjacentHTML(const nsAStr
       static_cast<nsINode*>(this)->AppendChild(*fragment, aError);
       break;
     case eAfterEnd:
       destination->InsertBefore(*fragment, GetNextSibling(), aError);
       break;
   }
 }
 
+nsINode*
+Element::InsertAdjacent(const nsAString& aWhere,
+                        nsINode* aNode,
+                        ErrorResult& aError)
+{
+  if (aWhere.LowerCaseEqualsLiteral("beforebegin")) {
+    nsCOMPtr<nsINode> parent = GetParentNode();
+    if (!parent) {
+      return nullptr;
+    }
+    parent->InsertBefore(*aNode, this, aError);
+  } else if (aWhere.LowerCaseEqualsLiteral("afterbegin")) {
+    static_cast<nsINode*>(this)->InsertBefore(*aNode, GetFirstChild(), aError);
+  } else if (aWhere.LowerCaseEqualsLiteral("beforeend")) {
+    static_cast<nsINode*>(this)->AppendChild(*aNode, aError);
+  } else if (aWhere.LowerCaseEqualsLiteral("afterend")) {
+    nsCOMPtr<nsINode> parent = GetParentNode();
+    if (!parent) {
+      return nullptr;
+    }
+    parent->InsertBefore(*aNode, GetNextSibling(), aError);
+  } else {
+    aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+    return nullptr;
+  }
+
+  return aError.Failed() ? nullptr : aNode;
+}
+
+Element*
+Element::InsertAdjacentElement(const nsAString& aWhere,
+                               Element& aElement,
+                               ErrorResult& aError) {
+  nsINode* newNode = InsertAdjacent(aWhere, &aElement, aError);
+  MOZ_ASSERT(!newNode || newNode->IsElement());
+
+  return newNode ? newNode->AsElement() : nullptr;
+}
+
+void
+Element::InsertAdjacentText(
+  const nsAString& aWhere, const nsAString& aData, ErrorResult& aError)
+{
+  RefPtr<nsTextNode> textNode = OwnerDoc()->CreateTextNode(aData);
+  InsertAdjacent(aWhere, textNode, aError);
+}
+
 nsIEditor*
 Element::GetEditorInternal()
 {
   nsCOMPtr<nsITextControlElement> textCtrl = do_QueryInterface(this);
   return textCtrl ? textCtrl->GetTextEditor() : nullptr;
 }
 
 nsresult
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -674,16 +674,36 @@ public:
   already_AddRefed<nsIHTMLCollection>
     GetElementsByTagName(const nsAString& aQualifiedName);
   already_AddRefed<nsIHTMLCollection>
     GetElementsByTagNameNS(const nsAString& aNamespaceURI,
                            const nsAString& aLocalName,
                            ErrorResult& aError);
   already_AddRefed<nsIHTMLCollection>
     GetElementsByClassName(const nsAString& aClassNames);
+
+private:
+  /**
+   * Implement the algorithm specified at
+   * https://dom.spec.whatwg.org/#insert-adjacent for both
+   * |insertAdjacentElement()| and |insertAdjacentText()| APIs.
+   */
+  nsINode* InsertAdjacent(const nsAString& aWhere,
+                          nsINode* aNode,
+                          ErrorResult& aError);
+
+public:
+  Element* InsertAdjacentElement(const nsAString& aWhere,
+                                 Element& aElement,
+                                 ErrorResult& aError);
+
+  void InsertAdjacentText(const nsAString& aWhere,
+                          const nsAString& aData,
+                          ErrorResult& aError);
+
   void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
   {
     bool activeState = false;
     if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
       aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
       return;
     }
     if (!IsInDoc()) {
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -96,17 +96,17 @@ CallbackObject::CallSetup::CallSetup(Cal
       } else {
         // No DOM Window. Store the global.
         JSObject* glob = js::GetGlobalForObjectCrossCompartment(realCallback);
         globalObject = xpc::NativeGlobal(glob);
         MOZ_ASSERT(globalObject);
       }
     } else {
       JSObject *global = js::GetGlobalForObjectCrossCompartment(realCallback);
-      globalObject = workers::GetGlobalObjectForGlobal(global);
+      globalObject = xpc::NativeGlobal(global);
       MOZ_ASSERT(globalObject);
     }
 
     // Bail out if there's no useful global. This seems to happen intermittently
     // on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning
     // null in some kind of teardown state.
     if (!globalObject->GetGlobalJSObject()) {
       return;
--- a/dom/canvas/test/webgl-mochitest.ini
+++ b/dom/canvas/test/webgl-mochitest.ini
@@ -86,8 +86,9 @@ skip-if = toolkit == 'android' #bug 8654
 [webgl-mochitest/test_webgl_request_mismatch.html]
 skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
 [webgl-mochitest/test_webgl2_not_exposed.html]
 skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
 [webgl-mochitest/test_webgl2_invalidate_framebuffer.html]
 skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
 [webgl-mochitest/test_webgl2_alpha_luminance.html]
 skip-if = toolkit == 'android' #bug 865443- seperate suite - the non_conf* tests pass except for one on armv6 tests
+[webgl-mochitest/test_fuzzing_bugs.html]
new file mode 100644
--- /dev/null
+++ b/dom/canvas/test/webgl-mochitest/test_fuzzing_bugs.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>
+<title>WebGL fuzzy bugs</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css">
+<script src="driver-info.js"></script>
+<script src="webgl-util.js"></script>
+<body>
+<script>
+
+// Test the framebufferTexture2D() call with a unbound texture.
+function framebufferTexture2D_bug1257593() {
+  var canvas = document.createElement('canvas');
+
+  var gl = null;
+  gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
+  if (!gl) {
+    todo(false, 'WebGL framebufferTexture2D test, webgl is unavailable.');
+    return;
+  }
+
+  var texture = gl.createTexture(); // only createTexture(), but no bindBuffer()
+  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, texture, 0);
+
+  ok(true, 'WebGL framebufferTexture2D with unbound texture');
+}
+
+// Test to call ClearBufferXXX() during context lost.
+function webGL2ClearBufferXXX_bug1252414() {
+  var canvas = document.createElement('canvas');
+
+  var gl = canvas.getContext('webgl2');
+  if (!gl) {
+    todo(false, 'WebGL2 is not supported');
+    return;
+  }
+
+  var ext = gl.getExtension('WEBGL_lose_context');
+  if (!ext) {
+    todo(false, 'WebGL ClearBufferXXX test, ext WEBGL_lose_context is unavailable.');
+    return;
+  }
+
+  // Force to lose context.
+  ext.loseContext();
+
+  // Even thought the context is lost, all clearBuffer* function should still
+  // work without crash.
+  gl.clearBufferiv(gl.COLOR, 0, new Int32Array(10));
+  gl.clearBufferuiv(gl.COLOR, 0, new Uint32Array(10));
+  gl.clearBufferfv(gl.DEPTH, 0, new Float32Array(10));
+  gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 0.0, 0);
+
+  ok(true, 'WebGL2 clearBufferXXX call during loseContext');
+}
+
+function run() {
+  webGL2ClearBufferXXX_bug1252414();
+  framebufferTexture2D_bug1257593();
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+try {
+  var prefArrArr = [
+    ['webgl.force-enabled', true],
+    ['webgl.enable-prototype-webgl2', true],
+  ];
+  var prefEnv = {'set': prefArrArr};
+  SpecialPowers.pushPrefEnv(prefEnv, run);
+} catch (e) {
+  warning('No SpecialPowers, but trying WebGL2 anyway...');
+  run();
+}
+</script>
+
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3171,29 +3171,16 @@ EventStateManager::PostHandleEvent(nsPre
       nsPluginFrame* pluginFrame = do_QueryFrame(frameToScroll);
 
       // When APZ is enabled, the actual scroll animation might be handled by
       // the compositor.
       WheelPrefs::Action action;
       if (pluginFrame) {
         MOZ_ASSERT(pluginFrame->WantsToHandleWheelEventAsDefaultAction());
         action = WheelPrefs::ACTION_SEND_TO_PLUGIN;
-      } else if (!wheelEvent->mMayHaveMomentum &&
-            nsLayoutUtils::IsScrollFrameWithSnapping(frameToScroll)) {
-        // If the target has scroll-snapping points then we want to handle
-        // the wheel event on the main thread even if we have APZ enabled. Do
-        // so and let the APZ know that it should ignore this event. However,
-        // if the wheel event is synthesized from a Mac trackpad or other device
-        // that can generate additional momentum events, then we should allow
-        // APZ to handle it, because it will track the velocity and predicted
-        // destination from the momentum.
-        if (wheelEvent->mFlags.mHandledByAPZ) {
-          wheelEvent->PreventDefault();
-        }
-        action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
       } else if (wheelEvent->mFlags.mHandledByAPZ) {
         action = WheelPrefs::ACTION_NONE;
       } else {
         action = WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent);
       }
       switch (action) {
         case WheelPrefs::ACTION_SCROLL: {
           // For scrolling of default action, we should honor the mouse wheel
--- a/dom/fetch/Fetch.cpp
+++ b/dom/fetch/Fetch.cpp
@@ -149,16 +149,24 @@ already_AddRefed<Promise>
 FetchRequest(nsIGlobalObject* aGlobal, const RequestOrUSVString& aInput,
              const RequestInit& aInit, ErrorResult& aRv)
 {
   RefPtr<Promise> p = Promise::Create(aGlobal, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
+  // Double check that we have chrome privileges if the Request's content
+  // policy type has been overridden.  Note, we must do this before
+  // entering the global below.  Otherwise the IsCallerChrome() will
+  // always fail.
+  MOZ_ASSERT_IF(aInput.IsRequest() &&
+                aInput.GetAsRequest().IsContentPolicyTypeOverridden(),
+                nsContentUtils::IsCallerChrome());
+
   AutoJSAPI jsapi;
   jsapi.Init(aGlobal);
   JSContext* cx = jsapi.cx();
 
   JS::Rooted<JSObject*> jsGlobal(cx, aGlobal->GetGlobalJSObject());
   GlobalObject global(cx, jsGlobal);
 
   RefPtr<Request> request = Request::Constructor(global, aInput, aInit, aRv);
--- a/dom/fetch/InternalRequest.cpp
+++ b/dom/fetch/InternalRequest.cpp
@@ -34,22 +34,25 @@ InternalRequest::GetRequestConstructorCo
   // The "client" is not stored in our implementation. Fetch API users should
   // use the appropriate window/document/principal and other Gecko security
   // mechanisms as appropriate.
   copy->mSameOriginDataURL = true;
   copy->mPreserveContentCodings = true;
   // The default referrer is already about:client.
   copy->mReferrerPolicy = mReferrerPolicy;
 
-  copy->mContentPolicyType = nsIContentPolicy::TYPE_FETCH;
+  copy->mContentPolicyType = mContentPolicyTypeOverridden ?
+                             mContentPolicyType :
+                             nsIContentPolicy::TYPE_FETCH;
   copy->mMode = mMode;
   copy->mCredentialsMode = mCredentialsMode;
   copy->mCacheMode = mCacheMode;
   copy->mRedirectMode = mRedirectMode;
   copy->mCreatedByFetchEvent = mCreatedByFetchEvent;
+  copy->mContentPolicyTypeOverridden = mContentPolicyTypeOverridden;
   return copy.forget();
 }
 
 already_AddRefed<InternalRequest>
 InternalRequest::Clone()
 {
   RefPtr<InternalRequest> clone = new InternalRequest(*this);
 
@@ -88,30 +91,38 @@ InternalRequest::InternalRequest(const I
   , mForceOriginHeader(aOther.mForceOriginHeader)
   , mPreserveContentCodings(aOther.mPreserveContentCodings)
   , mSameOriginDataURL(aOther.mSameOriginDataURL)
   , mSkipServiceWorker(aOther.mSkipServiceWorker)
   , mSynchronous(aOther.mSynchronous)
   , mUnsafeRequest(aOther.mUnsafeRequest)
   , mUseURLCredentials(aOther.mUseURLCredentials)
   , mCreatedByFetchEvent(aOther.mCreatedByFetchEvent)
+  , mContentPolicyTypeOverridden(aOther.mContentPolicyTypeOverridden)
 {
   // NOTE: does not copy body stream... use the fallible Clone() for that
 }
 
 InternalRequest::~InternalRequest()
 {
 }
 
 void
 InternalRequest::SetContentPolicyType(nsContentPolicyType aContentPolicyType)
 {
   mContentPolicyType = aContentPolicyType;
 }
 
+void
+InternalRequest::OverrideContentPolicyType(nsContentPolicyType aContentPolicyType)
+{
+  SetContentPolicyType(aContentPolicyType);
+  mContentPolicyTypeOverridden = true;
+}
+
 /* static */
 RequestContext
 InternalRequest::MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType)
 {
   RequestContext context = RequestContext::Internal;
   switch (aContentPolicyType) {
   case nsIContentPolicy::TYPE_OTHER:
     context = RequestContext::Internal;
--- a/dom/fetch/InternalRequest.h
+++ b/dom/fetch/InternalRequest.h
@@ -330,16 +330,19 @@ public:
   ContentPolicyType() const
   {
     return mContentPolicyType;
   }
 
   void
   SetContentPolicyType(nsContentPolicyType aContentPolicyType);
 
+  void
+  OverrideContentPolicyType(nsContentPolicyType aContentPolicyType);
+
   RequestContext
   Context() const
   {
     return MapContentPolicyTypeToRequestContext(mContentPolicyType);
   }
 
   bool
   UnsafeRequest() const
@@ -423,16 +426,22 @@ public:
   IsWorkerRequest() const;
 
   bool
   IsClientRequest() const;
 
   void
   MaybeSkipCacheIfPerformingRevalidation();
 
+  bool
+  IsContentPolicyTypeOverridden() const
+  {
+    return mContentPolicyTypeOverridden;
+  }
+
   static RequestMode
   MapChannelToRequestMode(nsIChannel* aChannel);
 
   static RequestCredentials
   MapChannelToRequestCredentials(nsIChannel* aChannel);
 
 private:
   // Does not copy mBodyStream.  Use fallible Clone() for complete copy.
@@ -476,14 +485,18 @@ private:
   bool mSkipServiceWorker;
   bool mSynchronous;
   bool mUnsafeRequest;
   bool mUseURLCredentials;
   // This is only set when a Request object is created by a fetch event.  We
   // use it to check if Service Workers are simply fetching intercepted Request
   // objects without modifying them.
   bool mCreatedByFetchEvent = false;
+  // This is only set when Request.overrideContentPolicyType() has been set.
+  // It is illegal to pass such a Request object to a fetch() method unless
+  // if the caller has chrome privileges.
+  bool mContentPolicyTypeOverridden = false;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_InternalRequest_h
--- a/dom/fetch/Request.cpp
+++ b/dom/fetch/Request.cpp
@@ -277,16 +277,17 @@ Request::Constructor(const GlobalObject&
       aRv.ThrowTypeError<MSG_FETCH_BODY_CONSUMED_ERROR>();
       return nullptr;
     }
     if (body) {
       temporaryBody = body;
     }
 
     request = inputReq->GetInternalRequest();
+
   } else {
     request = new InternalRequest();
   }
 
   request = request->GetRequestConstructorCopy(global, aRv);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
--- a/dom/fetch/Request.h
+++ b/dom/fetch/Request.h
@@ -81,19 +81,25 @@ public:
 
   RequestContext
   Context() const
   {
     return mRequest->Context();
   }
 
   void
-  SetContentPolicyType(nsContentPolicyType aContentPolicyType)
+  OverrideContentPolicyType(nsContentPolicyType aContentPolicyType)
   {
-    mRequest->SetContentPolicyType(aContentPolicyType);
+    mRequest->OverrideContentPolicyType(aContentPolicyType);
+  }
+
+  bool
+  IsContentPolicyTypeOverridden() const
+  {
+    return mRequest->IsContentPolicyTypeOverridden();
   }
 
   void
   GetReferrer(nsAString& aReferrer) const
   {
     mRequest->GetReferrer(aReferrer);
   }
 
--- a/dom/geolocation/nsGeolocation.cpp
+++ b/dom/geolocation/nsGeolocation.cpp
@@ -487,16 +487,32 @@ nsGeolocationRequest::Cancel()
 NS_IMETHODIMP
 nsGeolocationRequest::Allow(JS::HandleValue aChoices)
 {
   MOZ_ASSERT(aChoices.isUndefined());
 
   if (mRequester) {
     // Record the number of granted requests for regular web content.
     Telemetry::Accumulate(Telemetry::GEOLOCATION_REQUEST_GRANTED, mProtocolType + 10);
+
+    // Record whether a location callback is fulfilled while the owner window
+    // is not visible.
+    bool isVisible = false;
+    nsCOMPtr<nsPIDOMWindowInner> window = mLocator->GetParentObject();
+
+    if (window) {
+      nsCOMPtr<nsIDocument> doc = window->GetDoc();
+      isVisible = doc && !doc->Hidden();
+    }
+
+    if (IsWatch()) {
+      mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_WATCHPOSITION_VISIBLE, isVisible);
+    } else {
+      mozilla::Telemetry::Accumulate(mozilla::Telemetry::GEOLOCATION_GETCURRENTPOSITION_VISIBLE, isVisible);
+    }
   }
 
   if (mLocator->ClearPendingRequest(this)) {
     return NS_OK;
   }
 
   RefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3133,16 +3133,37 @@ ContentParent::Observe(nsISupports* aSub
     // data (e.g. telemetry) from the child before we quit.
     // This loop terminate prematurely based on mForceKillTimer.
     while (mIPCOpen && !mCalledKillHard) {
       NS_ProcessNextEvent(nullptr, true);
     }
     NS_ASSERTION(!mSubprocess, "Close should have nulled mSubprocess");
   }
 
+#ifdef MOZ_ENABLE_PROFILER_SPS
+  // Need to do this before the mIsAlive check to avoid missing profiles.
+  if (!strcmp(aTopic, "profiler-subprocess-gather")) {
+    if (mGatherer) {
+      mGatherer->WillGatherOOPProfile();
+      if (mIsAlive && mSubprocess) {
+        Unused << SendGatherProfile();
+      }
+    }
+  }
+  else if (!strcmp(aTopic, "profiler-subprocess")) {
+    nsCOMPtr<nsIProfileSaveEvent> pse = do_QueryInterface(aSubject);
+    if (pse) {
+      if (!mProfile.IsEmpty()) {
+        pse->AddSubProfile(mProfile.get());
+        mProfile.Truncate();
+      }
+    }
+  }
+#endif
+
   if (!mIsAlive || !mSubprocess)
     return NS_OK;
 
   // The Nuwa process unregisters the topics after it becomes ready except for
   // the ones listed in sNuwaSafeObserverTopics. If the topic needs to be
   // observed by the Nuwa process, either for:
   // 1. The topic is safe for the Nuwa process, either:
   // 1.1 The state can safely happen (only run on the main thread) in the Nuwa
@@ -3294,31 +3315,16 @@ ContentParent::Observe(nsISupports* aSub
     Unused << SendStopProfiler();
   }
   else if (!strcmp(aTopic, "profiler-paused")) {
     Unused << SendPauseProfiler(true);
   }
   else if (!strcmp(aTopic, "profiler-resumed")) {
     Unused << SendPauseProfiler(false);
   }
-  else if (!strcmp(aTopic, "profiler-subprocess-gather")) {
-    if (mGatherer) {
-      mGatherer->WillGatherOOPProfile();
-      Unused << SendGatherProfile();
-    }
-  }
-  else if (!strcmp(aTopic, "profiler-subprocess")) {
-    nsCOMPtr<nsIProfileSaveEvent> pse = do_QueryInterface(aSubject);
-    if (pse) {
-      if (!mProfile.IsEmpty()) {
-        pse->AddSubProfile(mProfile.get());
-        mProfile.Truncate();
-      }
-    }
-  }
 #endif
   else if (!strcmp(aTopic, "gmp-changed")) {
     Unused << SendNotifyGMPsChanged();
   }
   return NS_OK;
 }
 
 PGMPServiceParent*
--- a/dom/ipc/PProcessHangMonitor.ipdl
+++ b/dom/ipc/PProcessHangMonitor.ipdl
@@ -28,16 +28,17 @@ union HangData
   SlowScriptData;
   PluginHangData;
 };
 
 protocol PProcessHangMonitor
 {
 parent:
   async HangEvidence(HangData data);
+  async ClearHang();
 
 child:
   async TerminateScript();
 
   async BeginStartingDebugger();
   async EndStartingDebugger();
 };
 
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -85,16 +85,17 @@ class HangMonitorChild
                              unsigned aLineNo);
 
   bool IsDebuggerStartupComplete();
 
   void NotifyPluginHang(uint32_t aPluginId);
   void NotifyPluginHangAsync(uint32_t aPluginId);
 
   void ClearHang();
+  void ClearHangAsync();
 
   virtual bool RecvTerminateScript() override;
   virtual bool RecvBeginStartingDebugger() override;
   virtual bool RecvEndStartingDebugger() override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   void Shutdown();
@@ -161,16 +162,21 @@ public:
     mActor = nullptr;
   }
 
   void SetHangData(const HangData& aHangData) { mHangData = aHangData; }
   void SetBrowserDumpId(nsAutoString& aId) {
     mBrowserDumpId = aId;
   }
 
+  void ClearHang() {
+    mHangData = HangData();
+    mBrowserDumpId.Truncate();
+  }
+
 private:
   ~HangMonitoredProcess() {}
 
   // Everything here is main thread-only.
   HangMonitorParent* mActor;
   ContentParent* mContentParent;
   HangData mHangData;
   nsAutoString mBrowserDumpId;
@@ -181,16 +187,17 @@ class HangMonitorParent
 {
 public:
   explicit HangMonitorParent(ProcessHangMonitor* aMonitor);
   virtual ~HangMonitorParent();
 
   void Open(Transport* aTransport, ProcessId aPid, MessageLoop* aIOLoop);
 
   virtual bool RecvHangEvidence(const HangData& aHangData) override;
+  virtual bool RecvClearHang() override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   void SetProcess(HangMonitoredProcess* aProcess) { mProcess = aProcess; }
 
   void Shutdown();
 
   void TerminateScript();
@@ -434,24 +441,40 @@ HangMonitorChild::NotifyPluginHangAsync(
 }
 
 void
 HangMonitorChild::ClearHang()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mSentReport) {
+    // bounce to background thread
+    MonitorLoop()->PostTask(
+      FROM_HERE,
+      NewRunnableMethod(this, &HangMonitorChild::ClearHangAsync));
+
     MonitorAutoLock lock(mMonitor);
     mSentReport = false;
     mTerminateScript = false;
     mStartDebugger = false;
     mFinishedStartingDebugger = false;
   }
 }
 
+void
+HangMonitorChild::ClearHangAsync()
+{
+  MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
+
+  // bounce back to parent on background thread
+  if (mIPCOpen) {
+    Unused << SendClearHang();
+  }
+}
+
 /* HangMonitorParent implementation */
 
 HangMonitorParent::HangMonitorParent(ProcessHangMonitor* aMonitor)
  : mHangMonitor(aMonitor),
    mIPCOpen(true),
    mMonitor("HangMonitorParent lock"),
    mShutdownDone(false),
    mBrowserCrashDumpHashLock("mBrowserCrashDumpIds lock")
@@ -609,16 +632,61 @@ HangMonitorParent::RecvHangEvidence(cons
 
   nsCOMPtr<nsIRunnable> notifier =
     new HangObserverNotifier(mProcess, aHangData, crashId);
   NS_DispatchToMainThread(notifier);
 
   return true;
 }
 
+class ClearHangNotifier final : public nsRunnable
+{
+public:
+  explicit ClearHangNotifier(HangMonitoredProcess* aProcess)
+    : mProcess(aProcess)
+  {}
+
+  NS_IMETHOD
+  Run()
+  {
+    // chrome process, main thread
+    MOZ_RELEASE_ASSERT(NS_IsMainThread());
+    mProcess->ClearHang();
+
+    nsCOMPtr<nsIObserverService> observerService =
+      mozilla::services::GetObserverService();
+    observerService->NotifyObservers(mProcess, "clear-hang-report", nullptr);
+    return NS_OK;
+  }
+
+private:
+  RefPtr<HangMonitoredProcess> mProcess;
+};
+
+bool
+HangMonitorParent::RecvClearHang()
+{
+  // chrome process, background thread
+  MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
+
+  if (!mReportHangs) {
+    return true;
+  }
+
+  mHangMonitor->InitiateCPOWTimeout();
+
+  MonitorAutoLock lock(mMonitor);
+
+  nsCOMPtr<nsIRunnable> notifier =
+    new ClearHangNotifier(mProcess);
+  NS_DispatchToMainThread(notifier);
+
+  return true;
+}
+
 void
 HangMonitorParent::TerminateScript()
 {
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
 
   if (mIPCOpen) {
     Unused << SendTerminateScript();
   }
--- a/dom/manifest/ManifestObtainer.jsm
+++ b/dom/manifest/ManifestObtainer.jsm
@@ -61,17 +61,22 @@ this.ManifestObtainer = { // jshint igno
    * Public interface for obtaining a web manifest from a XUL browser.
    * @param  {Window} The content Window from which to extract the manifest.
    * @return {Promise<Object>} The processed manifest.
    */
   contentObtainManifest: Task.async(function* (aContent) {
     if (!aContent || isXULBrowser(aContent)) {
       throw new TypeError("Invalid input. Expected a DOM Window.");
     }
-    const manifest = yield fetchManifest(aContent);
+    let manifest;
+    try {
+      manifest = yield fetchManifest(aContent);
+    } catch (err) {
+      throw err;
+    }
     return manifest;
   }
 )};
 
 function toError(aErrorClone) {
   let error;
   switch (aErrorClone.name) {
   case "TypeError":
@@ -129,47 +134,27 @@ const fetchManifest = Task.async(functio
   }
   const elem = aWindow.document.querySelector("link[rel~='manifest']");
   if (!elem || !elem.getAttribute("href")) {
     let msg = `No manifest to fetch at ${aWindow.location}`;
     throw new Error(msg);
   }
   // Throws on malformed URLs
   const manifestURL = new aWindow.URL(elem.href, elem.baseURI);
-  if (!canLoadManifest(elem)) {
-    let msg = `Content Security Policy: The page's settings blocked the `;
-    msg += `loading of a resource at ${elem.href}`;
-    throw new Error(msg);
-  }
   const reqInit = {
     mode: "cors"
   };
   if (elem.crossOrigin === "use-credentials") {
     reqInit.credentials = "include";
   }
-  const req = new aWindow.Request(manifestURL, reqInit);
-  req.setContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
-  const response = yield aWindow.fetch(req);
+  const request = new aWindow.Request(manifestURL, reqInit);
+  request.overrideContentPolicyType(Ci.nsIContentPolicy.TYPE_WEB_MANIFEST);
+  let response;
+  try {
+    response = yield aWindow.fetch(request);
+  } catch (err) {
+    throw err;
+  }
   const manifest = yield processResponse(response, aWindow);
   return manifest;
 });
 
-/**
- * Checks against security manager if we can load the web manifest.
- * @param  {HTMLLinkElement} aElem The HTML element to security check.
- * @return {Boolean} True if it can, false if it can't.
- */
-function canLoadManifest(aElem) {
-  const contentPolicy = Cc["@mozilla.org/layout/content-policy;1"]
-    .getService(Ci.nsIContentPolicy);
-  const mimeType = aElem.type || "application/manifest+json";
-  const elemURI = BrowserUtils.makeURI(
-    aElem.href, aElem.ownerDocument.characterSet
-  );
-  const shouldLoad = contentPolicy.shouldLoad(
-    Ci.nsIContentPolicy.TYPE_WEB_MANIFEST, elemURI,
-    aElem.ownerDocument.documentURIObject,
-    aElem, mimeType, null
-  );
-  return shouldLoad === Ci.nsIContentPolicy.ACCEPT;
-}
-
 this.EXPORTED_SYMBOLS = ["ManifestObtainer"]; // jshint ignore:line
--- a/dom/manifest/ManifestProcessor.jsm
+++ b/dom/manifest/ManifestProcessor.jsm
@@ -82,19 +82,16 @@ this.ManifestProcessor = { // jshint ign
       'lang': processLangMember(),
       'start_url': processStartURLMember(),
       'display': processDisplayMember.call(this),
       'orientation': processOrientationMember.call(this),
       'name': processNameMember(),
       'icons': imgObjProcessor.process(
         rawManifest, manifestURL, 'icons'
       ),
-      'splash_screens': imgObjProcessor.process(
-        rawManifest, manifestURL, 'splash_screens'
-      ),
       'short_name': processShortNameMember(),
       'theme_color': processThemeColorMember(),
       'background_color': processBackgroundColorMember(),
     };
     processedManifest.scope = processScopeMember();
     return processedManifest;
 
     function processNameMember() {
--- a/dom/manifest/test/mochitest.ini
+++ b/dom/manifest/test/mochitest.ini
@@ -11,12 +11,11 @@ support-files =
 [test_ManifestProcessor_background_color.html]
 [test_ManifestProcessor_display.html]
 [test_ManifestProcessor_icons.html]
 [test_ManifestProcessor_JSON.html]
 [test_ManifestProcessor_lang.html]
 [test_ManifestProcessor_name_and_short_name.html]
 [test_ManifestProcessor_orientation.html]
 [test_ManifestProcessor_scope.html]
-[test_ManifestProcessor_splash_screens.html]
 [test_ManifestProcessor_start_url.html]
 [test_ManifestProcessor_theme_color.html]
 [test_ManifestProcessor_warnings.html]
deleted file mode 100644
--- a/dom/manifest/test/test_ManifestProcessor_splash_screens.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1162808
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 1162808</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script src="common.js"></script>
-  <script>
-/**
- * Manifest splash_screens member
- * http://www.w3.org/TR/appmanifest/#splash_screens-member
- **/
-
-'use strict';
-
-typeTests.forEach((type) => {
-  var expected = `Expect non-array splash_screens to be empty: ${typeof type}.`;
-  data.jsonText = JSON.stringify({
-    splash_screens: type
-  });
-  var result = processor.process(data);
-  is(result.splash_screens.length, 0, expected);
-});
-</script>
-</head>
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -780,17 +780,21 @@ MediaDecoderStateMachine::OnNotDecoded(M
     MOZ_ASSERT(mReader->IsWaitForDataSupported(),
                "Readers that send WAITING_FOR_DATA need to implement WaitForData");
     RefPtr<MediaDecoderStateMachine> self = this;
     WaitRequestRef(aType).Begin(InvokeAsync(DecodeTaskQueue(), mReader.get(), __func__,
                                             &MediaDecoderReader::WaitForData, aType)
       ->Then(OwnerThread(), __func__,
              [self] (MediaData::Type aType) -> void {
                self->WaitRequestRef(aType).Complete();
-               self->DispatchDecodeTasksIfNeeded();
+               if (aType == MediaData::AUDIO_DATA) {
+                 self->EnsureAudioDecodeTaskQueued();
+               } else {
+                 self->EnsureVideoDecodeTaskQueued();
+               }
              },
              [self] (WaitForDataRejectValue aRejection) -> void {
                self->WaitRequestRef(aRejection.mType).Complete();
              }));
 
     // We are out of data to decode and will enter buffering mode soon.
     // We want to play the frames we have already decoded, so we stop pre-rolling
     // and ensure that loadeddata is fired as required.
@@ -801,17 +805,21 @@ MediaDecoderStateMachine::OnNotDecoded(M
     }
     if (mState == DECODER_STATE_BUFFERING || mState == DECODER_STATE_DECODING) {
         MaybeFinishDecodeFirstFrame();
     }
     return;
   }
 
   if (aReason == MediaDecoderReader::CANCELED) {
-    DispatchDecodeTasksIfNeeded();
+    if (isAudio) {
+      EnsureAudioDecodeTaskQueued();
+    } else {
+      EnsureVideoDecodeTaskQueued();
+    }
     return;
   }
 
   // This is an EOS. Finish off the queue, and then handle things based on our
   // state.
   MOZ_ASSERT(aReason == MediaDecoderReader::END_OF_STREAM);
   if (!isAudio && mState == DECODER_STATE_SEEKING &&
       mCurrentSeek.Exists() && mFirstVideoFrameAfterSeek) {
--- a/dom/media/bridge/MediaModule.cpp
+++ b/dom/media/bridge/MediaModule.cpp
@@ -9,41 +9,45 @@
 
 #include "PeerConnectionImpl.h"
 
 #define PEERCONNECTION_CID \
 {0xb93af7a1, 0x3411, 0x44a8, {0xbd, 0x0a, 0x8a, 0xf3, 0xdd, 0xe4, 0xd8, 0xd8}}
 
 #define PEERCONNECTION_CONTRACTID "@mozilla.org/peerconnection;1"
 
-#include "stun_udp_socket_filter.h"
+#include "stun_socket_filter.h"
 
 NS_DEFINE_NAMED_CID(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CID)
+NS_DEFINE_NAMED_CID(NS_STUN_TCP_SOCKET_FILTER_HANDLER_CID)
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStunUDPSocketFilterHandler)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsStunTCPSocketFilterHandler)
 
 
 namespace mozilla
 {
 // Factory defined in mozilla::, defines mozilla::PeerConnectionImplConstructor
 NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
 }
 
 // Defines kPEERCONNECTION_CID
 NS_DEFINE_NAMED_CID(PEERCONNECTION_CID);
 
 static const mozilla::Module::CIDEntry kCIDs[] = {
   { &kPEERCONNECTION_CID, false, nullptr, mozilla::PeerConnectionImplConstructor },
   { &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID, false, nullptr, nsStunUDPSocketFilterHandlerConstructor },
+  { &kNS_STUN_TCP_SOCKET_FILTER_HANDLER_CID, false, nullptr, nsStunTCPSocketFilterHandlerConstructor },
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kContracts[] = {
   { PEERCONNECTION_CONTRACTID, &kPEERCONNECTION_CID },
   { NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID, &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID },
+  { NS_STUN_TCP_SOCKET_FILTER_HANDLER_CONTRACTID, &kNS_STUN_TCP_SOCKET_FILTER_HANDLER_CID },
   { nullptr }
 };
 
 static const mozilla::Module kModule = {
   mozilla::Module::kVersion,
   kCIDs,
   kContracts
 };
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -572,22 +572,16 @@ MediaKeySystemAccess::GetSupportedConfig
 
 
 /* static */
 void
 MediaKeySystemAccess::NotifyObservers(nsPIDOMWindowInner* aWindow,
                                       const nsAString& aKeySystem,
                                       MediaKeySystemStatus aStatus)
 {
-  if (aStatus == MediaKeySystemStatus::Cdm_not_supported) {
-    // Ignore, since there's nothing the user can do to rectify this, and we
-    // don't want the prompt to confuse them.
-    // TODO: Remove places that call with this entirely.
-    return;
-  }
   RequestMediaKeySystemAccessNotification data;
   data.mKeySystem = aKeySystem;
   data.mStatus = aStatus;
   nsAutoString json;
   data.ToJSON(json);
   EME_LOG("MediaKeySystemAccess::NotifyObservers() %s", NS_ConvertUTF16toUTF8(json).get());
   nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
   if (obs) {
--- a/dom/media/eme/MediaKeySystemAccessManager.cpp
+++ b/dom/media/eme/MediaKeySystemAccessManager.cpp
@@ -74,41 +74,39 @@ MediaKeySystemAccessManager::Request(Det
 
 void
 MediaKeySystemAccessManager::Request(DetailedPromise* aPromise,
                                      const nsAString& aKeySystem,
                                      const Sequence<MediaKeySystemConfiguration>& aConfigs,
                                      RequestType aType)
 {
   EME_LOG("MediaKeySystemAccessManager::Request %s", NS_ConvertUTF16toUTF8(aKeySystem).get());
+
+  // Parse keysystem, split it out into keySystem prefix, and version suffix.
+  nsAutoString keySystem;
+  int32_t minCdmVersion = NO_CDM_VERSION;
+  if (!ParseKeySystem(aKeySystem, keySystem, minCdmVersion)) {
+    // Not to inform user, because nothing to do if the keySystem is not
+    // supported.
+    aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
+                          NS_LITERAL_CSTRING("Key system string is invalid,"
+                                             " or key system is unsupported"));
+    return;
+  }
+
   if (!Preferences::GetBool("media.eme.enabled", false)) {
-    // EME disabled by user, send notification to chrome so UI can
-    // inform user.
+    // EME disabled by user, send notification to chrome so UI can inform user.
     MediaKeySystemAccess::NotifyObservers(mWindow,
                                           aKeySystem,
                                           MediaKeySystemStatus::Api_disabled);
     aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
                           NS_LITERAL_CSTRING("EME has been preffed off"));
     return;
   }
 
-  // Parse keysystem, split it out into keySystem prefix, and version suffix.
-  nsAutoString keySystem;
-  int32_t minCdmVersion = NO_CDM_VERSION;
-  if (!ParseKeySystem(aKeySystem,
-                      keySystem,
-                      minCdmVersion)) {
-    // Invalid keySystem string, or unsupported keySystem. Send notification
-    // to chrome to show a failure notice.
-    MediaKeySystemAccess::NotifyObservers(mWindow, aKeySystem, MediaKeySystemStatus::Cdm_not_supported);
-    aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
-                          NS_LITERAL_CSTRING("Key system string is invalid, or key system is unsupported"));
-    return;
-  }
-
   nsAutoCString message;
   nsAutoCString cdmVersion;
   MediaKeySystemStatus status =
     MediaKeySystemAccess::GetKeySystemStatus(keySystem, minCdmVersion, message, cdmVersion);
 
   nsPrintfCString msg("MediaKeySystemAccess::GetKeySystemStatus(%s, minVer=%d) "
                       "result=%s version='%s' msg='%s'",
                       NS_ConvertUTF16toUTF8(keySystem).get(),
@@ -163,19 +161,20 @@ MediaKeySystemAccessManager::Request(Det
   // compatibility with initial implementation...
   if (MediaKeySystemAccess::GetSupportedConfig(keySystem, aConfigs, config) ||
       MediaKeySystemAccess::IsSupported(keySystem, aConfigs)) {
     RefPtr<MediaKeySystemAccess> access(
       new MediaKeySystemAccess(mWindow, keySystem, NS_ConvertUTF8toUTF16(cdmVersion), config));
     aPromise->MaybeResolve(access);
     return;
   }
-
+  // Not to inform user, because nothing to do if the corresponding keySystem
+  // configuration is not supported.
   aPromise->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR,
-                        NS_LITERAL_CSTRING("Key system is not supported"));
+                        NS_LITERAL_CSTRING("Key system configuration is not supported"));
 }
 
 MediaKeySystemAccessManager::PendingRequest::PendingRequest(DetailedPromise* aPromise,
                                                             const nsAString& aKeySystem,
                                                             const Sequence<MediaKeySystemConfiguration>& aConfigs,
                                                             nsITimer* aTimer)
   : mPromise(aPromise)
   , mKeySystem(aKeySystem)
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -189,17 +189,17 @@ skip-if = toolkit == 'gonk' || buildapp 
 [test_peerConnection_twoAudioVideoStreamsCombined.html]
 # b2g(Bug 960442, video support for WebRTC is disabled on b2g), Bug 1127828 for Linux debug e10s, android(Bug 1189784, timeouts on 4.3 emulator)
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (os == 'linux' && debug && e10s) || android_version == '18'
 [test_peerConnection_twoVideoStreams.html]
 # b2g(Bug 960442, video support for WebRTC is disabled on b2g), Bug 1180000 for Linux debug e10s, android(Bug 1189784, timeouts on 4.3 emulator)
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18'
 [test_peerConnection_twoVideoTracksInOneStream.html]
 # b2g(Bug 960442, video support for WebRTC is disabled on b2g), Bug 1180000 for Linux debug e10s, android(Bug 1189784, timeouts on 4.3 emulator)
-skip-if = toolkit == 'gonk' || buildapp == 'mulet' || (android_version == '18' && debug)
+skip-if = toolkit == 'gonk' || buildapp == 'mulet' || os == "android"
 [test_peerConnection_addSecondAudioStream.html]
 skip-if = toolkit == 'gonk' # B2G emulator is too slow to finish a renegotiation test in under 5 minutes
 [test_peerConnection_answererAddSecondAudioStream.html]
 skip-if = toolkit == 'gonk' # B2G emulator is too slow to finish a renegotiation test in under 5 minutes
 [test_peerConnection_removeAudioTrack.html]
 skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
 [test_peerConnection_removeThenAddAudioTrack.html]
 skip-if = toolkit == 'gonk' || (android_version == '18' && debug) # B2G emulator is too slow to finish a renegotiation test in under 5 minutes, android(Bug 1189784, timeouts on 4.3 emulator)
--- a/dom/network/PTCPSocket.ipdl
+++ b/dom/network/PTCPSocket.ipdl
@@ -40,17 +40,17 @@ parent:
   // is expanded to |useSSL| (from TCPOptions.useSecureTransport) and
   // |binaryType| (from TCPOption.binaryType).
   async Open(nsString host, uint16_t port, bool useSSL, bool useArrayBuffers);
 
   // Ask parent to open a socket and bind the newly-opened socket to a local
   // address specified in |localAddr| and |localPort|.
   async OpenBind(nsCString host, uint16_t port,
                  nsCString localAddr, uint16_t localPort,
-                 bool useSSL, bool aUseArrayBuffers);
+                 bool useSSL, bool aUseArrayBuffers, nsCString aFilter);
 
   // When child's send() is called, this message requrests parent to send
   // data and update it's trackingNumber.
   async Data(SendableData data, uint32_t trackingNumber);
 
   // Forward calling to child's upgradeToSecure() method to parent.
   async StartTLS();
 
--- a/dom/network/TCPSocketChild.cpp
+++ b/dom/network/TCPSocketChild.cpp
@@ -97,33 +97,34 @@ TCPSocketChild::TCPSocketChild(const nsA
 
 void
 TCPSocketChild::SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL, bool aUseArrayBuffers)
 {
   mSocket = aSocket;
 
   AddIPDLReference();
   gNeckoChild->SendPTCPSocketConstructor(this, mHost, mPort);
+  MOZ_ASSERT(mFilterName.IsEmpty()); // Currently nobody should use this
   PTCPSocketChild::SendOpen(mHost, mPort, aUseSSL, aUseArrayBuffers);
 }
 
 void
 TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
                                        const nsACString& aRemoteHost, uint16_t aRemotePort,
                                        const nsACString& aLocalHost, uint16_t aLocalPort,
                                        bool aUseSSL)
 {
   mSocket = aSocket;
   AddIPDLReference();
   gNeckoChild->SendPTCPSocketConstructor(this,
                                          NS_ConvertUTF8toUTF16(aRemoteHost),
                                          aRemotePort);
   PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
                                 nsCString(aLocalHost), aLocalPort,
-                                aUseSSL, true);
+                                aUseSSL, true, mFilterName);
 }
 
 void
 TCPSocketChildBase::ReleaseIPDLReference()
 {
   MOZ_ASSERT(mIPCOpen);
   mIPCOpen = false;
   this->Release();
@@ -225,16 +226,27 @@ TCPSocketChild::GetHost(nsAString& aHost
 }
 
 void
 TCPSocketChild::GetPort(uint16_t* aPort)
 {
   *aPort = mPort;
 }
 
+nsresult
+TCPSocketChild::SetFilterName(const nsACString& aFilterName)
+{
+  if (!mFilterName.IsEmpty()) {
+    // filter name can only be set once.
+    return NS_ERROR_FAILURE;
+  }
+  mFilterName = aFilterName;
+  return NS_OK;
+}
+
 bool
 TCPSocketChild::RecvRequestDelete()
 {
   mozilla::Unused << Send__delete__(this);
   return true;
 }
 
 } // namespace dom
--- a/dom/network/TCPSocketChild.h
+++ b/dom/network/TCPSocketChild.h
@@ -71,17 +71,19 @@ public:
   void GetPort(uint16_t* aPort);
 
   virtual bool RecvCallback(const nsString& aType,
                             const CallbackData& aData,
                             const uint32_t& aReadyState) override;
   virtual bool RecvRequestDelete() override;
   virtual bool RecvUpdateBufferedAmount(const uint32_t& aBufferred,
                                         const uint32_t& aTrackingNumber) override;
+  nsresult SetFilterName(const nsACString& aFilterName);
 private:
   nsString mHost;
   uint16_t mPort;
+  nsCString mFilterName;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/network/TCPSocketParent.cpp
+++ b/dom/network/TCPSocketParent.cpp
@@ -16,16 +16,23 @@
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/HoldDropJSObjects.h"
 #include "nsISocketTransportService.h"
 #include "nsISocketTransport.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
 
+//
+// set NSPR_LOG_MODULES=TCPSocket:5
+//
+extern mozilla::LazyLogModule gTCPSocketLog;
+#define TCPSOCKET_LOG(args)     MOZ_LOG(gTCPSocketLog, mozilla::LogLevel::Debug, args)
+#define TCPSOCKET_LOG_ENABLED() MOZ_LOG_TEST(gTCPSocketLog, mozilla::LogLevel::Debug)
+
 namespace IPC {
 
 //Defined in TCPSocketChild.cpp
 extern bool
 DeserializeArrayBuffer(JSContext* aCx,
                        const InfallibleTArray<uint8_t>& aBuffer,
                        JS::MutableHandle<JS::Value> aVal);
 
@@ -171,17 +178,18 @@ TCPSocketParent::RecvOpen(const nsString
 }
 
 bool
 TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
                               const uint16_t& aRemotePort,
                               const nsCString& aLocalAddr,
                               const uint16_t& aLocalPort,
                               const bool&     aUseSSL,
-                              const bool&     aUseArrayBuffers)
+                              const bool&     aUseArrayBuffers,
+                              const nsCString& aFilter)
 {
   if (net::UsingNeckoIPCSecurity() &&
       !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) {
     FireInteralError(this, __LINE__);
     return true;
   }
 
   nsresult rv;
@@ -214,16 +222,34 @@ TCPSocketParent::RecvOpenBind(const nsCS
   mozilla::net::NetAddr addr;
   PRNetAddrToNetAddr(&prAddr, &addr);
   rv = socketTransport->Bind(&addr);
   if (NS_FAILED(rv)) {
     FireInteralError(this, __LINE__);
     return true;
   }
 
+  if (!aFilter.IsEmpty()) {
+    nsAutoCString contractId(NS_NETWORK_TCP_SOCKET_FILTER_HANDLER_PREFIX);
+    contractId.Append(aFilter);
+    nsCOMPtr<nsISocketFilterHandler> filterHandler =
+      do_GetService(contractId.get());
+    if (!filterHandler) {
+      NS_ERROR("Content doesn't have a valid filter");
+      FireInteralError(this, __LINE__);
+      return true;
+    }
+    rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
+    if (NS_FAILED(rv)) {
+      NS_ERROR("Cannot create filter that content specified");
+      FireInteralError(this, __LINE__);
+      return true;
+    }
+  }
+
   // Obtain App ID
   uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
   bool     inIsolatedMozBrowser = false;
   const PContentParent *content = Manager()->Manager();
   if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) {
     // appId's are for B2G only currently, where managees.Count() == 1
     // This is not guaranteed currently in Desktop, so skip this there.
     TabParent *tab = TabParent::GetFrom(browser);
@@ -267,16 +293,35 @@ TCPSocketParent::RecvResume()
   return true;
 }
 
 bool
 TCPSocketParent::RecvData(const SendableData& aData,
                           const uint32_t& aTrackingNumber)
 {
   ErrorResult rv;
+
+  if (mFilter) {
+    mozilla::net::NetAddr addr; // dummy value
+    bool allowed;
+    MOZ_ASSERT(aData.type() == SendableData::TArrayOfuint8_t,
+               "Unsupported data type for filtering");
+    const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t());
+    nsresult nsrv = mFilter->FilterPacket(&addr, data.Elements(),
+                                          data.Length(),
+                                          nsISocketFilter::SF_OUTGOING,
+                                          &allowed);
+
+    // Reject sending of unallowed data
+    if (NS_WARN_IF(NS_FAILED(nsrv)) || !allowed) {
+      TCPSOCKET_LOG(("%s: Dropping outgoing TCP packet", __FUNCTION__));
+      return false;
+    }
+  }
+
   switch (aData.type()) {
     case SendableData::TArrayOfuint8_t: {
       AutoSafeJSContext autoCx;
       JS::Rooted<JS::Value> val(autoCx);
       const nsTArray<uint8_t>& buffer = aData.get_ArrayOfuint8_t();
       bool ok = IPC::DeserializeArrayBuffer(autoCx, buffer, &val);
       NS_ENSURE_TRUE(ok, true);
       RootedTypedArray<ArrayBuffer> data(autoCx);
@@ -319,24 +364,42 @@ TCPSocketParent::FireEvent(const nsAStri
   return SendEvent(aType, mozilla::void_t(), aReadyState);
 }
 
 void
 TCPSocketParent::FireArrayBufferDataEvent(nsTArray<uint8_t>& aBuffer, TCPReadyState aReadyState)
 {
   InfallibleTArray<uint8_t> arr;
   arr.SwapElements(aBuffer);
+
+  if (mFilter) {
+    bool allowed;
+    mozilla::net::NetAddr addr;
+    nsresult nsrv = mFilter->FilterPacket(&addr, arr.Elements(), arr.Length(),
+                                          nsISocketFilter::SF_INCOMING,
+                                          &allowed);
+    // receiving unallowed data, drop it.
+    if (NS_WARN_IF(NS_FAILED(nsrv)) || !allowed) {
+      TCPSOCKET_LOG(("%s: Dropping incoming TCP packet", __FUNCTION__));
+      return;
+    }
+  }
+
   SendableData data(arr);
   SendEvent(NS_LITERAL_STRING("data"), data, aReadyState);
 }
 
 void
 TCPSocketParent::FireStringDataEvent(const nsACString& aData, TCPReadyState aReadyState)
 {
-  SendEvent(NS_LITERAL_STRING("data"), SendableData(nsCString(aData)), aReadyState);
+  SendableData data((nsCString(aData)));
+
+  MOZ_ASSERT(!mFilter, "Socket filtering doesn't support nsCString");
+
+  SendEvent(NS_LITERAL_STRING("data"), data, aReadyState);
 }
 
 void
 TCPSocketParent::SendEvent(const nsAString& aType, CallbackData aData, TCPReadyState aReadyState)
 {
   mozilla::Unused << PTCPSocketParent::SendCallback(nsString(aType), aData,
                                                     static_cast<uint32_t>(aReadyState));
 }
--- a/dom/network/TCPSocketParent.h
+++ b/dom/network/TCPSocketParent.h
@@ -6,16 +6,17 @@
 
 #ifndef mozilla_dom_TCPSocketParent_h
 #define mozilla_dom_TCPSocketParent_h
 
 #include "mozilla/dom/TCPSocketBinding.h"
 #include "mozilla/net/PTCPSocketParent.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsCOMPtr.h"
+#include "nsISocketFilter.h"
 #include "js/TypeDecls.h"
 #include "mozilla/net/OfflineObserver.h"
 
 #define TCPSOCKETPARENT_CID \
   { 0x4e7246c6, 0xa8b3, 0x426d, { 0x9c, 0x17, 0x76, 0xda, 0xb1, 0xe1, 0xe1, 0x4a } }
 
 namespace mozilla {
 namespace dom {
@@ -52,17 +53,18 @@ public:
   virtual bool RecvOpen(const nsString& aHost, const uint16_t& aPort,
                         const bool& useSSL, const bool& aUseArrayBuffers) override;
 
   virtual bool RecvOpenBind(const nsCString& aRemoteHost,
                             const uint16_t& aRemotePort,
                             const nsCString& aLocalAddr,
                             const uint16_t& aLocalPort,
                             const bool&     aUseSSL,
-                            const bool& aUseArrayBuffers) override;
+                            const bool& aUseArrayBuffers,
+                            const nsCString& aFilter) override;
 
   virtual bool RecvStartTLS() override;
   virtual bool RecvSuspend() override;
   virtual bool RecvResume() override;
   virtual bool RecvClose() override;
   virtual bool RecvData(const SendableData& aData,
                         const uint32_t& aTrackingNumber) override;
   virtual bool RecvRequestDelete() override;
@@ -77,14 +79,17 @@ public:
 
   void SetSocket(TCPSocket *socket);
   nsresult GetHost(nsAString& aHost);
   nsresult GetPort(uint16_t* aPort);
 
 private:
   virtual void ActorDestroy(ActorDestroyReason why) override;
   void SendEvent(const nsAString& aType, CallbackData aData, TCPReadyState aReadyState);
+  nsresult SetFilter(const nsCString& aFilter);
+
+  nsCOMPtr<nsISocketFilter> mFilter;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/network/UDPSocketParent.cpp
+++ b/dom/network/UDPSocketParent.cpp
@@ -128,17 +128,17 @@ UDPSocketParent::Init(const IPC::Princip
     if (permission != nsIPermissionManager::ALLOW_ACTION) {
       return false;
     }
   }
 
   if (!aFilter.IsEmpty()) {
     nsAutoCString contractId(NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX);
     contractId.Append(aFilter);
-    nsCOMPtr<nsIUDPSocketFilterHandler> filterHandler =
+    nsCOMPtr<nsISocketFilterHandler> filterHandler =
       do_GetService(contractId.get());
     if (filterHandler) {
       nsresult rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
       if (NS_FAILED(rv)) {
         printf_stderr("Cannot create filter that content specified. "
                       "filter name: %s, error code: %u.", aFilter.BeginReading(),  static_cast<uint32_t>(rv));
         return false;
       }
@@ -377,31 +377,29 @@ UDPSocketParent::ConnectInternal(const n
 bool
 UDPSocketParent::RecvOutgoingData(const UDPData& aData,
                                   const UDPSocketAddr& aAddr)
 {
   MOZ_ASSERT(mSocket);
 
   nsresult rv;
   if (mFilter) {
-    // TODO, Bug 933102, filter packets that are sent with hostname.
-    // Until then we simply throw away packets that are sent to a hostname.
     if (aAddr.type() != UDPSocketAddr::TNetAddr) {
       return true;
     }
 
     // TODO, Packet filter doesn't support input stream yet.
     if (aData.type() != UDPData::TArrayOfuint8_t) {
       return true;
     }
 
     bool allowed;
     const InfallibleTArray<uint8_t>& data(aData.get_ArrayOfuint8_t());
     rv = mFilter->FilterPacket(&aAddr.get_NetAddr(), data.Elements(),
-                               data.Length(), nsIUDPSocketFilter::SF_OUTGOING,
+                               data.Length(), nsISocketFilter::SF_OUTGOING,
                                &allowed);
 
     // Sending unallowed data, kill content.
     if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
       return false;
     }
   }
 
@@ -566,17 +564,17 @@ UDPSocketParent::OnPacketReceived(nsIUDP
   UDPSOCKET_LOG(("%s: %s:%u, length %u", __FUNCTION__, ip.get(), port, len));
 
   if (mFilter) {
     bool allowed;
     mozilla::net::NetAddr addr;
     fromAddr->GetNetAddr(&addr);
     nsresult rv = mFilter->FilterPacket(&addr,
                                         (const uint8_t*)buffer, len,
-                                        nsIUDPSocketFilter::SF_INCOMING,
+                                        nsISocketFilter::SF_INCOMING,
                                         &allowed);
     // Receiving unallowed data, drop.
     if (NS_WARN_IF(NS_FAILED(rv)) || !allowed) {
       if (!allowed) {
         UDPSOCKET_LOG(("%s: not allowed", __FUNCTION__));
       }
       return NS_OK;
     }
--- a/dom/network/UDPSocketParent.h
+++ b/dom/network/UDPSocketParent.h
@@ -5,17 +5,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_UDPSocketParent_h__
 #define mozilla_dom_UDPSocketParent_h__
 
 #include "mozilla/net/PUDPSocketParent.h"
 #include "nsCOMPtr.h"
 #include "nsIUDPSocket.h"
-#include "nsIUDPSocketFilter.h"
+#include "nsISocketFilter.h"
 #include "mozilla/net/OfflineObserver.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 
 namespace mozilla {
 namespace net {
 class PNeckoParent;
 } // namespace net
 
@@ -71,17 +71,17 @@ private:
                          uint32_t aLineNo);
 
   // One of these will be null and the other non-null.
   PBackgroundParent* mBackgroundManager;
   PNeckoParent* mNeckoManager;
 
   bool mIPCOpen;
   nsCOMPtr<nsIUDPSocket> mSocket;
-  nsCOMPtr<nsIUDPSocketFilter> mFilter;
+  nsCOMPtr<nsISocketFilter> mFilter;
   RefPtr<mozilla::net::OfflineObserver> mObserver;
   nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // !defined(mozilla_dom_UDPSocketParent_h__)
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -291,16 +291,22 @@ DoContentSecurityChecks(nsIURI* aURI, ns
       break;
     }
 
     case nsIContentPolicy::TYPE_IMAGESET: {
       MOZ_ASSERT(false, "contentPolicyType not supported yet");
       break;
     }
 
+    case nsIContentPolicy::TYPE_WEB_MANIFEST: {
+      mimeTypeGuess = NS_LITERAL_CSTRING("application/manifest+json");
+      requestingContext = aLoadInfo->LoadingNode();
+      break;
+    }
+
     default:
       // nsIContentPolicy::TYPE_INVALID
       MOZ_ASSERT(false, "can not perform security check without a valid contentType");
   }
 
   int16_t shouldLoad = nsIContentPolicy::ACCEPT;
   nsresult rv = NS_CheckContentLoadPolicy(internalContentPolicyType,
                                           aURI,
--- a/dom/security/test/csp/browser.ini
+++ b/dom/security/test/csp/browser.ini
@@ -1,5 +1,13 @@
 [DEFAULT]
 support-files =
   !/dom/security/test/csp/file_testserver.sjs
+  !/dom/security/test/csp/file_web_manifest.html
+  !/dom/security/test/csp/file_web_manifest.json
+  !/dom/security/test/csp/file_web_manifest.json^headers^
+  !/dom/security/test/csp/file_web_manifest_https.html
+  !/dom/security/test/csp/file_web_manifest_https.json
+  !/dom/security/test/csp/file_web_manifest_mixed_content.html
+  !/dom/security/test/csp/file_web_manifest_remote.html
 [browser_test_web_manifest.js]
 [browser_test_web_manifest_mixed_content.js]
+[browser_manifest-src-override-default-src.js]
new file mode 100644
--- /dev/null
+++ b/dom/security/test/csp/browser_manifest-src-override-default-src.js
@@ -0,0 +1,108 @@
+/*
+ * Description of the tests:
+ * Tests check that default-src can be overridden by manifest-src.
+ */
+/*globals Cu, is, ok*/
+"use strict";
+const {
+  ManifestObtainer
+} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
+const path = "/tests/dom/security/test/csp/";
+const testFile = `${path}file_web_manifest.html`;
+const mixedContentFile = `${path}file_web_manifest_mixed_content.html`;
+const server = `${path}file_testserver.sjs`;
+const defaultURL = new URL(`http://example.org${server}`);
+const mixedURL = new URL(`http://mochi.test:8888${server}`);
+const tests = [
+  // Check interaction with default-src and another origin,
+  // CSP allows fetching from example.org, so manifest should load.
+  {
+    expected: `CSP manifest-src overrides default-src of elsewhere.com`,
+    get tabURL() {
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("cors", "*");
+      url.searchParams.append("csp", "default-src http://elsewhere.com; manifest-src http://example.org");
+      return url.href;
+    },
+    run(manifest) {
+      is(manifest.name, "loaded", this.expected);
+    }
+  },
+  // Check interaction with default-src none,
+  // CSP allows fetching manifest from example.org, so manifest should load.
+  {
+    expected: `CSP manifest-src overrides default-src`,
+    get tabURL() {
+      const url = new URL(mixedURL);
+      url.searchParams.append("file", mixedContentFile);
+      url.searchParams.append("cors", "http://test:80");
+      url.searchParams.append("csp", "default-src 'self'; manifest-src http://test:80");
+      return url.href;
+    },
+    run(manifest) {
+      is(manifest.name, "loaded", this.expected);
+    }
+  },
+];
+
+//jscs:disable
+add_task(function* () {
+  //jscs:enable
+  const testPromises = tests.map((test) => {
+    const tabOptions = {
+      gBrowser,
+      url: test.tabURL,
+      skipAnimation: true,
+    };
+    return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
+  });
+  yield Promise.all(testPromises);
+});
+
+function* testObtainingManifest(aBrowser, aTest) {
+  const expectsBlocked = aTest.expected.includes("block");
+  const observer = (expectsBlocked) ? createNetObserver(aTest) : null;
+  // Expect an exception (from promise rejection) if there a content policy
+  // that is violated.
+  try {
+    const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
+    aTest.run(manifest);
+  } catch (e) {
+    const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
+    ok(wasBlocked,`Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
+    if (observer) {
+      yield observer.untilFinished;
+    }
+  }
+}
+
+// Helper object used to observe policy violations. It waits 1 seconds
+// for a response, and then times out causing its associated test to fail.
+function createNetObserver(test) {
+  let finishedTest;
+  let success = false;
+  const finished = new Promise((resolver) => {
+    finishedTest = resolver;
+  });
+  const timeoutId = setTimeout(() => {
+    if (!success) {
+      test.run("This test timed out.");
+      finishedTest();
+    }
+  }, 1000);
+  var observer = {
+    get untilFinished(){
+      return finished;
+    },
+    observe(subject, topic) {
+      SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
+      test.run(topic);
+      finishedTest();
+      clearTimeout(timeoutId);
+      success = true;
+    },
+  };
+  SpecialPowers.addObserver(observer, "csp-on-violate-policy", false);
+  return observer;
+}
--- a/dom/security/test/csp/browser_test_web_manifest.js
+++ b/dom/security/test/csp/browser_test_web_manifest.js
@@ -1,249 +1,237 @@
 /*
  * Description of the tests:
  *   These tests check for conformance to the CSP spec as they relate to Web Manifests.
  *
  *   In particular, the tests check that default-src and manifest-src directives are
  *   are respected by the ManifestObtainer.
  */
 /*globals Cu, is, ok*/
-'use strict';
-requestLongerTimeout(10); // e10s tests take time.
+"use strict";
 const {
   ManifestObtainer
-} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
-const path = '/tests/dom/security/test/csp/';
-const testFile = `file=${path}file_web_manifest.html`;
-const remoteFile = `file=${path}file_web_manifest_remote.html`;
-const httpsManifest = `file=${path}file_web_manifest_https.html`;
-const server = 'file_testserver.sjs';
-const defaultURL = `http://example.org${path}${server}`;
-const secureURL = `https://example.com:443${path}${server}`;
+} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
+const path = "/tests/dom/security/test/csp/";
+const testFile = `${path}file_web_manifest.html`;
+const remoteFile = `${path}file_web_manifest_remote.html`;
+const httpsManifest = `${path}file_web_manifest_https.html`;
+const server = `${path}file_testserver.sjs`;
+const defaultURL = new URL(`http://example.org${server}`);
+const secureURL = new URL(`https://example.com:443${server}`);
 const tests = [
   // CSP block everything, so trying to load a manifest
   // will result in a policy violation.
   {
-    expected: `default-src 'none' blocks fetching manifest.`,
+    expected: "default-src 'none' blocks fetching manifest.",
     get tabURL() {
-      let queryParts = [
-        `csp=default-src 'none'`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("csp", "default-src 'none'");
+      return url.href;
     },
     run(topic) {
-      is(topic, 'csp-on-violate-policy', this.expected);
+      is(topic, "csp-on-violate-policy", this.expected);
     }
   },
   // CSP allows fetching only from mochi.test:8888,
   // so trying to load a manifest from same origin
   // triggers a CSP violation.
   {
-    expected: `default-src mochi.test:8888 blocks manifest fetching.`,
+    expected: "default-src mochi.test:8888 blocks manifest fetching.",
     get tabURL() {
-      let queryParts = [
-        `csp=default-src mochi.test:8888`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("csp", "default-src mochi.test:8888");
+      return url.href;
     },
     run(topic) {
-      is(topic, 'csp-on-violate-policy', this.expected);
+      is(topic, "csp-on-violate-policy", this.expected);
     }
   },
   // CSP restricts fetching to 'self', so allowing the manifest
   // to load. The name of the manifest is then checked.
   {
-    expected: `CSP default-src 'self' allows fetch of manifest.`,
+    expected: "CSP default-src 'self' allows fetch of manifest.",
     get tabURL() {
-      let queryParts = [
-        `csp=default-src 'self'`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("csp", "default-src 'self'");
+      return url.href;
     },
     run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
+      is(manifest.name, "loaded", this.expected);
     }
   },
   // CSP only allows fetching from mochi.test:8888 and remoteFile
   // requests a manifest from that origin, so manifest should load.
   {
-    expected: 'CSP default-src mochi.test:8888 allows fetching manifest.',
+    expected: "CSP default-src mochi.test:8888 allows fetching manifest.",
     get tabURL() {
-      let queryParts = [
-        `csp=default-src http://mochi.test:8888`,
-        remoteFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", remoteFile);
+      url.searchParams.append("csp", "default-src http://mochi.test:8888");
+      return url.href;
     },
     run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
+      is(manifest.name, "loaded", this.expected);
     }
   },
   // default-src blocks everything, so any attempt to
   // fetch a manifest from another origin will trigger a
   // policy violation.
   {
-    expected: `default-src 'none' blocks mochi.test:8888`,
+    expected: "default-src 'none' blocks mochi.test:8888",
     get tabURL() {
-      let queryParts = [
-        `csp=default-src 'none'`,
-        remoteFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", remoteFile);
+      url.searchParams.append("csp", "default-src 'none'");
+      return url.href;
     },
     run(topic) {
-      is(topic, 'csp-on-violate-policy', this.expected);
+      is(topic, "csp-on-violate-policy", this.expected);
     }
   },
   // CSP allows fetching from self, so manifest should load.
   {
-    expected: `CSP manifest-src allows self`,
+    expected: "CSP manifest-src allows self",
     get tabURL() {
-      let queryParts = [
-        `csp=manifest-src 'self'`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("csp", "manifest-src 'self'");
+      return url.href;
     },
     run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
+      is(manifest.name, "loaded", this.expected);
     }
   },
   // CSP allows fetching from example.org, so manifest should load.
   {
-    expected: `CSP manifest-src allows http://example.org`,
+    expected: "CSP manifest-src allows http://example.org",
     get tabURL() {
-      let queryParts = [
-        `csp=manifest-src http://example.org`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("csp", "manifest-src http://example.org");
+      return url.href;
     },
     run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
+      is(manifest.name, "loaded", this.expected);
     }
-  },
-  {
-    expected: `CSP manifest-src allows mochi.test:8888`,
+  }, {
+    expected: "CSP manifest-src allows mochi.test:8888",
     get tabURL() {
-      let queryParts = [
-        `cors=*`,
-        `csp=default-src *; manifest-src http://mochi.test:8888`,
-        remoteFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", remoteFile);
+      url.searchParams.append("cors", "*");
+      url.searchParams.append("csp", "default-src *; manifest-src http://mochi.test:8888");
+      return url.href;
     },
     run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
+      is(manifest.name, "loaded", this.expected);
     }
   },
   // CSP restricts fetching to mochi.test:8888, but the test
   // file is at example.org. Hence, a policy violation is
   // triggered.
   {
-    expected: `CSP blocks manifest fetching from example.org.`,
+    expected: "CSP blocks manifest fetching from example.org.",
     get tabURL() {
-      let queryParts = [
-        `csp=manifest-src mochi.test:8888`,
-        testFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", testFile);
+      url.searchParams.append("csp", "manifest-src mochi.test:8888");
+      return url.href;
     },
     run(topic) {
-      is(topic, 'csp-on-violate-policy', this.expected);
+      is(topic, "csp-on-violate-policy", this.expected);
     }
   },
   // CSP is set to only allow manifest to be loaded from same origin,
   // but the remote file attempts to load from a different origin. Thus
   // this causes a CSP violation.
   {
-    expected: `CSP manifest-src 'self' blocks cross-origin fetch.`,
+    expected: "CSP manifest-src 'self' blocks cross-origin fetch.",
     get tabURL() {
-      let queryParts = [
-        `csp=manifest-src 'self'`,
-        remoteFile
-      ];
-      return `${defaultURL}?${queryParts.join('&')}`;
+      const url = new URL(defaultURL);
+      url.searchParams.append("file", remoteFile);
+      url.searchParams.append("csp", "manifest-src 'self'");
+      return url.href;
     },
     run(topic) {
-      is(topic, 'csp-on-violate-policy', this.expected);
+      is(topic, "csp-on-violate-policy", this.expected);
     }
   },
   // CSP allows fetching over TLS from example.org, so manifest should load.
   {
-    expected: `CSP manifest-src allows example.com over TLS`,
+    expected: "CSP manifest-src allows example.com over TLS",
     get tabURL() {
-      let queryParts = [
-        'cors=*',
-        'csp=manifest-src https://example.com:443',
-        httpsManifest
-      ];
       // secureURL loads https://example.com:443
       // and gets manifest from https://example.org:443
-      return `${secureURL}?${queryParts.join('&')}`;
+      const url = new URL(secureURL);
+      url.searchParams.append("file", httpsManifest);
+      url.searchParams.append("cors", "*");
+      url.searchParams.append("csp", "manifest-src https://example.com:443");
+      return url.href;
     },
     run(manifest) {
-      is(manifest.name, 'loaded', this.expected);
+      is(manifest.name, "loaded", this.expected);
     }
   },
 ];
 //jscs:disable
 add_task(function* () {
   //jscs:enable
-  var testPromises = tests.map(
-      (test) => ([test, {gBrowser, url: test.tabURL, skipAnimation: true}])
-    ).map(
-      ([test, tabOptions]) => BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test))
-    );
+  const testPromises = tests.map((test) => {
+    const tabOptions = {
+      gBrowser,
+      url: test.tabURL,
+      skipAnimation: true,
+    };
+    return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
+  });
   yield Promise.all(testPromises);
 });
 
 function* testObtainingManifest(aBrowser, aTest) {
-  const expectsBlocked = aTest.expected.includes('block');
+  const expectsBlocked = aTest.expected.includes("block");
   const observer = (expectsBlocked) ? createNetObserver(aTest) : null;
   // Expect an exception (from promise rejection) if there a content policy
   // that is violated.
   try {
     const manifest = yield ManifestObtainer.browserObtainManifest(aBrowser);
     aTest.run(manifest);
   } catch (e) {
-    const wasBlocked = e.message.includes('blocked the loading of a resource');
-    ok(wasBlocked,`Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
+    const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
+    ok(wasBlocked, `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
     if (observer) {
       yield observer.untilFinished;
-      return;
     }
-    throw e;
   }
 }
 
 // Helper object used to observe policy violations. It waits 1 seconds
 // for a response, and then times out causing its associated test to fail.
 function createNetObserver(test) {
   let finishedTest;
   let success = false;
   const finished = new Promise((resolver) => {
     finishedTest = resolver;
   });
   const timeoutId = setTimeout(() => {
     if (!success) {
-      test.run('This test timed out.');
+      test.run("This test timed out.");
       finishedTest();
     }
   }, 1000);
   var observer = {
-    get untilFinished(){
+    get untilFinished() {
       return finished;
     },
     observe(subject, topic) {
-      SpecialPowers.removeObserver(observer, 'csp-on-violate-policy');
+      SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
       test.run(topic);
       finishedTest();
       clearTimeout(timeoutId);
       success = true;
     },
   };
-  SpecialPowers.addObserver(observer, 'csp-on-violate-policy', false);
+  SpecialPowers.addObserver(observer, "csp-on-violate-policy", false);
   return observer;
-}
+}
\ No newline at end of file
--- a/dom/security/test/csp/browser_test_web_manifest_mixed_content.js
+++ b/dom/security/test/csp/browser_test_web_manifest_mixed_content.js
@@ -1,54 +1,53 @@
 /*
  * Description of the test:
  *   Check that mixed content blocker works prevents fetches of
  *   mixed content manifests.
  */
-'use strict';
+/*globals Cu, ok*/
+"use strict";
 const {
   ManifestObtainer
-} = Cu.import('resource://gre/modules/ManifestObtainer.jsm', {});
-const path = '/tests/dom/security/test/csp/';
-const mixedContent = `file=${path}file_web_manifest_mixed_content.html`;
-const server = 'file_testserver.sjs';
-const secureURL = `https://example.com${path}${server}`;
+} = Cu.import("resource://gre/modules/ManifestObtainer.jsm", {});
+const path = "/tests/dom/security/test/csp/";
+const mixedContent = `${path}file_web_manifest_mixed_content.html`;
+const server = `${path}file_testserver.sjs`;
+const secureURL = new URL(`https://example.com${server}`);
 const tests = [
   // Trying to load mixed content in file_web_manifest_mixed_content.html
   // needs to result in an error.
   {
-    expected: `Mixed Content Blocker prevents fetching manifest.`,
+    expected: "Mixed Content Blocker prevents fetching manifest.",
     get tabURL() {
-      let queryParts = [
-        mixedContent
-      ];
-      return `${secureURL}?${queryParts.join('&')}`;
+      const url = new URL(secureURL);
+      url.searchParams.append("file", mixedContent);
+      return url.href;
     },
     run(error) {
       // Check reason for error.
-      const check = /blocked the loading of a resource/.test(error.message);
+      const check = /NetworkError when attempting to fetch resource/.test(error.message);
       ok(check, this.expected);
     }
   }
 ];
 
 //jscs:disable
-add_task(function*() {
+add_task(function* () {
   //jscs:enable
-  for (let test of tests) {
-    let tabOptions = {
-      gBrowser: gBrowser,
+  const testPromises = tests.map((test) => {
+    const tabOptions = {
+      gBrowser,
       url: test.tabURL,
+      skipAnimation: true,
     };
-    yield BrowserTestUtils.withNewTab(
-      tabOptions,
-      browser => testObtainingManifest(browser, test)
-    );
-  }
+    return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
+  });
+  yield Promise.all(testPromises);
+});
 
-  function* testObtainingManifest(aBrowser, aTest) {
-    try {
-      yield ManifestObtainer.browserObtainManifest(aBrowser);
-    } catch (e) {
-      aTest.run(e)
-    }
+function* testObtainingManifest(aBrowser, aTest) {
+  try {
+    yield ManifestObtainer.browserObtainManifest(aBrowser);
+  } catch (e) {
+    aTest.run(e);
   }
-});
+}
--- a/dom/security/test/csp/file_testserver.sjs
+++ b/dom/security/test/csp/file_testserver.sjs
@@ -1,53 +1,50 @@
 // SJS file for CSP mochitests
-
+"use strict";
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
+Components.utils.importGlobalProperties(["URLSearchParams"]);
 
 function loadHTMLFromFile(path) {
   // Load the HTML to return in the response from file.
   // Since it's relative to the cwd of the test runner, we start there and
   // append to get to the actual path of the file.
-  var testHTMLFile =
+  const testHTMLFile =
     Components.classes["@mozilla.org/file/directory_service;1"].
     getService(Components.interfaces.nsIProperties).
     get("CurWorkD", Components.interfaces.nsILocalFile);
-  var dirs = path.split("/");
-  for (var i = 0; i < dirs.length; i++) {
-    testHTMLFile.append(dirs[i]);
-  }
-  var testHTMLFileStream =
+
+  const testHTMLFileStream =
     Components.classes["@mozilla.org/network/file-input-stream;1"].
     createInstance(Components.interfaces.nsIFileInputStream);
+
+  path
+    .split("/")
+    .filter(path => path)
+    .reduce((file, path) => {
+      testHTMLFile.append(path)
+      return testHTMLFile;
+    }, testHTMLFile);
   testHTMLFileStream.init(testHTMLFile, -1, 0, 0);
-  var testHTML = NetUtil.readInputStreamToString(testHTMLFileStream, testHTMLFileStream.available());
-  return testHTML;
+  const isAvailable = testHTMLFileStream.available();
+  return NetUtil.readInputStreamToString(testHTMLFileStream, isAvailable);
 }
 
-
-function handleRequest(request, response)
-{
-  var query = {};
-  request.queryString.split('&').forEach(function (val) {
-    var [name, value] = val.split('=');
-    query[name] = unescape(value);
-  });
-
-  var csp = (query['csp']) ? unescape(query['csp']) : "";
-  var file = unescape(query['file']);
-  var cors = unescape(query['cors']);
+function handleRequest(request, response) {
+  const query = new URLSearchParams(request.queryString);
 
   // avoid confusing cache behaviors
   response.setHeader("Cache-Control", "no-cache", false);
 
-  // Deliver the CSP policy encoded in the URI
-  if(csp){
-    response.setHeader("Content-Security-Policy", csp, false);
+  // Deliver the CSP policy encoded in the URL
+  if(query.has("csp")){
+    response.setHeader("Content-Security-Policy", query.get("csp"), false);
   }
-  // Deliver the CORS header in the URI
-  if(cors){
-    response.setHeader("Access-Control-Allow-Origin", cors, false);
+
+  // Deliver the CORS header in the URL
+  if(query.has("cors")){
+    response.setHeader("Access-Control-Allow-Origin", query.get("cors"), false);
   }
+
   // Send HTML to test allowed/blocked behaviors
   response.setHeader("Content-Type", "text/html", false);
-
-  response.write(loadHTMLFromFile(file));
+  response.write(loadHTMLFromFile(query.get("file")));
 }
--- a/dom/system/gonk/Volume.cpp
+++ b/dom/system/gonk/Volume.cpp
@@ -51,17 +51,17 @@ VolumeObserverList Volume::sEventObserve
 // state, it gets assigned a new generation number. Whenever the state
 // of a Volume changes, we send the updated state and current generation
 // number to the main thread where it gets updated in the nsVolume.
 //
 // Since WakeLocks can only be queried from the main-thread, the
 // nsVolumeService looks for WakeLock status changes, and forwards
 // the results to the IOThread.
 //
-// If the Volume (IOThread) recieves a volume update where the generation
+// If the Volume (IOThread) receives a volume update where the generation
 // number mismatches, then the update is simply ignored.
 //
 // When a Volume (IOThread) initially becomes mounted, we assume it to
 // be locked until we get our first update from nsVolume (MainThread).
 static int32_t sMountGeneration = 0;
 
 static uint32_t sNextId = 1;
 
--- a/dom/tests/mochitest/dom-level1-core/mochitest.ini
+++ b/dom/tests/mochitest/dom-level1-core/mochitest.ini
@@ -1,10 +1,9 @@
 [DEFAULT]
-skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 932350 - Frequent timeouts
 support-files =
   DOMTestCase.js
   activity-home.css
   exclusions.js
   files/hc_nodtdstaff.html
   files/hc_nodtdstaff.xhtml
   files/hc_staff.html
   files/hc_staff.xhtml
--- a/dom/tests/mochitest/dom-level2-core/mochitest.ini
+++ b/dom/tests/mochitest/dom-level2-core/mochitest.ini
@@ -1,10 +1,9 @@
 [DEFAULT]
-skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 932350 - Frequent timeouts
 support-files =
   DOMTestCase.js
   exclusions.js
   files/hc_staff.html
   files/hc_staff.svg
   files/hc_staff.xhtml
   files/hc_staff.xml
   files/internalSubset01.js
--- a/dom/tests/mochitest/dom-level2-html/mochitest.ini
+++ b/dom/tests/mochitest/dom-level2-html/mochitest.ini
@@ -1,10 +1,9 @@
 [DEFAULT]
-skip-if = toolkit == 'gonk' || toolkit == 'android' # Bug 932350 - Frequent timeouts
 support-files =
   DOMTestCase.js
   files/anchor.html
   files/anchor.xhtml
   files/anchor.xml
   files/anchor2.html
   files/anchor2.xhtml
   files/anchor2.xml
@@ -280,18 +279,17 @@ support-files =
 [test_HTMLDocument03.html]
 [test_HTMLDocument04.html]
 [test_HTMLDocument05.html]
 [test_HTMLDocument07.html]
 [test_HTMLDocument08.html]
 [test_HTMLDocument09.html]
 [test_HTMLDocument10.html]
 [test_HTMLDocument11.html]
-# [test_HTMLDocument12.html]
-# This test is failing on all platforms -- bug 471139
+[test_HTMLDocument12.html]
 [test_HTMLDocument13.html]
 [test_HTMLDocument14.html]
 [test_HTMLDocument15.html]
 [test_HTMLDocument16.html]
 [test_HTMLDocument17.html]
 [test_HTMLDocument18.html]
 [test_HTMLDocument19.html]
 [test_HTMLDocument20.html]
--- a/dom/tests/mochitest/dom-level2-html/test_HTMLDocument12.html
+++ b/dom/tests/mochitest/dom-level2-html/test_HTMLDocument12.html
@@ -1,11 +1,17 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
+
+<!--
+This test relies on that no cookies exist when the test starts.
+If this test is failing, add code to clear all cookies to the beginning of the test.
+-->
+
 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
 <title>http://www.w3.org/2001/DOM-Test-Suite/level2/html/HTMLDocument12</title>
 <link type="text/css" rel="stylesheet" href="/tests/SimpleTest/test.css">
 <script src="/tests/SimpleTest/SimpleTest.js" type="text/javascript"></script>
 <script src="DOMTestCase.js" type="text/javascript"></script>
 <script type="text/javascript">
 // expose test function names
--- a/dom/webidl/Element.webidl
+++ b/dom/webidl/Element.webidl
@@ -66,16 +66,22 @@ interface Element : Node {
 
   [Pure]
   HTMLCollection getElementsByTagName(DOMString localName);
   [Throws, Pure]
   HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
   [Pure]
   HTMLCollection getElementsByClassName(DOMString classNames);
 
+  [Throws, Pure]
+  Element? insertAdjacentElement(DOMString where, Element element); // historical
+
+  [Throws]
+  void insertAdjacentText(DOMString where, DOMString data); // historical
+
   /**
    * The ratio of font-size-inflated text font size to computed font
    * size for this element. This will query the element for its primary frame,
    * and then use this to get font size inflation information about the frame.
    * This will be 1.0 if font size inflation is not enabled, and -1.0 if an
    * error occurred during the retrieval of the font size inflation.
    *
    * @note The font size inflation ratio that is returned is actually the
--- a/dom/webidl/Request.webidl
+++ b/dom/webidl/Request.webidl
@@ -26,17 +26,17 @@ interface Request {
   readonly attribute RequestCache cache;
   readonly attribute RequestRedirect redirect;
 
   [Throws,
    NewObject] Request clone();
 
   // Bug 1124638 - Allow chrome callers to set the context.
   [ChromeOnly]
-  void setContentPolicyType(nsContentPolicyType context);
+  void overrideContentPolicyType(nsContentPolicyType context);
 };
 Request implements Body;
 
 dictionary RequestInit {
   ByteString method;
   HeadersInit headers;
   BodyInit? body;
   USVString referrer;
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -283,17 +283,17 @@ WorkerRunnable::Run()
   if (targetIsWorkerThread) {
     JSContext* cx = GetCurrentThreadJSContext();
     if (NS_WARN_IF(!cx)) {
       return NS_ERROR_FAILURE;
     }
 
     JSObject* global = JS::CurrentGlobalOrNull(cx);
     if (global) {
-      globalObject = GetGlobalObjectForGlobal(global);
+      globalObject = xpc::NativeGlobal(global);
     } else {
       globalObject = DefaultGlobalObject();
     }
 
     // We may still not have a globalObject here: in the case of
     // CompileScriptRunnable, we don't actually create the global object until
     // we have the script data, which happens in a syncloop under
     // CompileScriptRunnable::WorkerRun, so we can't assert that it got created
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -858,36 +858,16 @@ WorkerDebuggerGlobalScope::Dump(JSContex
                                 const Optional<nsAString>& aString) const
 {
   WorkerGlobalScope* scope = mWorkerPrivate->GetOrCreateGlobalScope(aCx);
   if (scope) {
     scope->Dump(aString);
   }
 }
 
-nsIGlobalObject*
-GetGlobalObjectForGlobal(JSObject* global)
-{
-  nsIGlobalObject* globalObject = nullptr;
-  UNWRAP_WORKER_OBJECT(WorkerGlobalScope, global, globalObject);
-
-  if (!globalObject) {
-    UNWRAP_OBJECT(WorkerDebuggerGlobalScope, global, globalObject);
-
-    if (!globalObject) {
-      MOZ_ASSERT(IsDebuggerSandbox(global));
-      globalObject = static_cast<SimpleGlobalObject*>(JS_GetPrivate(global));
-
-      MOZ_ASSERT(globalObject);
-    }
-  }
-
-  return globalObject;
-}
-
 bool
 IsWorkerGlobal(JSObject* object)
 {
   nsIGlobalObject* globalObject = nullptr;
   return NS_SUCCEEDED(UNWRAP_WORKER_OBJECT(WorkerGlobalScope, object,
                                            globalObject)) && !!globalObject;
 }
 
--- a/dom/workers/Workers.h
+++ b/dom/workers/Workers.h
@@ -356,19 +356,16 @@ const uint32_t kJSPrincipalsDebugToken =
 namespace exceptions {
 
 // Implemented in Exceptions.cpp
 void
 ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult);
 
 } // namespace exceptions
 
-nsIGlobalObject*
-GetGlobalObjectForGlobal(JSObject* global);
-
 bool
 IsWorkerGlobal(JSObject* global);
 
 bool
 IsDebuggerGlobal(JSObject* global);
 
 bool
 IsDebuggerSandbox(JSObject* object);
--- a/dom/workers/test/serviceworkers/mochitest.ini
+++ b/dom/workers/test/serviceworkers/mochitest.ini
@@ -205,34 +205,54 @@ support-files =
 
 [test_bug1151916.html]
 [test_claim.html]
 [test_claim_fetch.html]
 [test_claim_oninstall.html]
 [test_close.html]
 [test_controller.html]
 [test_cross_origin_url_after_redirect.html]
+[test_csp_upgrade-insecure_intercept.html]
 [test_empty_serviceworker.html]
+[test_escapedSlashes.html]
 [test_eval_allowed.html]
+[test_eventsource_intercept.html]
 [test_fetch_event.html]
+skip-if = (debug && e10s) # Bug 1262224
+[test_file_blob_response.html]
+[test_file_blob_upload.html]
 [test_force_refresh.html]
 [test_gzip_redirect.html]
+[test_hsts_upgrade_intercept.html]
 [test_https_fetch.html]
 [test_https_fetch_cloned_response.html]
 [test_https_origin_after_redirect.html]
 [test_https_origin_after_redirect_cached.html]
 [test_https_synth_fetch_from_cached_sw.html]
+[test_imagecache.html]
+[test_imagecache_max_age.html]
 [test_importscript.html]
+[test_importscript_mixedcontent.html]
+tags = mcb
 [test_install_event.html]
 [test_installation_simple.html]
 [test_match_all.html]
 [test_match_all_advanced.html]
 [test_match_all_client_id.html]
 [test_match_all_client_properties.html]
 [test_navigator.html]
+[test_not_intercept_plugin.html]
+[test_notification_constructor_error.html]
+[test_notification_get.html]
+[test_notificationclick.html]
+[test_notificationclick_focus.html]
+skip-if = (toolkit == "android" && debug) # Bug 1259338
+[test_notificationclick-otherwindow.html]
+[test_opaque_intercept.html]
+[test_openWindow.html]
 [test_origin_after_redirect.html]
 [test_origin_after_redirect_cached.html]
 [test_origin_after_redirect_to_https.html]
 [test_origin_after_redirect_to_https_cached.html]
 [test_post_message.html]
 [test_post_message_advanced.html]
 [test_post_message_source.html]
 [test_register_base.html]
@@ -258,51 +278,25 @@ support-files =
 [test_request_context_script.html]
 [test_request_context_sharedworker.html]
 [test_request_context_style.html]
 [test_request_context_track.html]
 [test_request_context_video.html]
 [test_request_context_worker.html]
 [test_request_context_xhr.html]
 [test_request_context_xslt.html]
+[test_sandbox_intercept.html]
 [test_scopes.html]
-[test_sandbox_intercept.html]
-skip-if = e10s && debug && os == 'win'
-[test_notificationclick.html]
-skip-if = e10s && debug && os == 'win'
-[test_notificationclick-otherwindow.html]
-skip-if = e10s && debug && os == 'win'
-[test_notificationclick_focus.html]
-skip-if = toolkit == "android" || toolkit == "gonk" || (e10s && debug && os == 'win')
-[test_notification_constructor_error.html]
-skip-if = e10s && debug && os == 'win'
-[test_notification_get.html]
-skip-if = e10s && debug && os == 'win'
 [test_sanitize.html]
 [test_sanitize_domain.html]
 [test_service_worker_allowed.html]
+[test_serviceworker_header.html]
 [test_serviceworker_interfaces.html]
 [test_serviceworker_not_sharedworker.html]
 [test_skip_waiting.html]
 [test_strict_mode_warning.html]
 [test_third_party_iframes.html]
 [test_unregister.html]
+[test_unresolved_fetch_interception.html]
 [test_workerUnregister.html]
 [test_workerUpdate.html]
 [test_workerupdatefoundevent.html]
-[test_opaque_intercept.html]
 [test_xslt.html]
-skip-if = e10s && debug && os == 'win'
-[test_escapedSlashes.html]
-[test_eventsource_intercept.html]
-[test_not_intercept_plugin.html]
-[test_file_blob_upload.html]
-[test_unresolved_fetch_interception.html]
-[test_hsts_upgrade_intercept.html]
-[test_csp_upgrade-insecure_intercept.html]
-[test_serviceworker_header.html]
-[test_openWindow.html]
-skip-if = toolkit == "gonk" || (e10s && debug && os == 'win')
-[test_imagecache.html]
-[test_imagecache_max_age.html]
-[test_importscript_mixedcontent.html]
-tags = mcb
-[test_file_blob_response.html]
--- a/embedding/components/printingui/win/nsPrintDialogUtil.cpp
+++ b/embedding/components/printingui/win/nsPrintDialogUtil.cpp
@@ -50,16 +50,18 @@ WIN_LIBS=                               
 #include "nsIStringBundle.h"
 
 // For NS_CopyUnicodeToNative
 #include "nsNativeCharsetUtils.h"
 
 // This is for extending the dialog
 #include <dlgs.h>
 
+#include "nsWindowsHelpers.h"
+
 // Default labels for the radio buttons
 static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen";
 static const char* kTheSelectedFrameStr  = "The selected &frame";
 static const char* kEachFrameSeparately  = "&Each frame separately";
 
 
 //-----------------------------------------------
 // Global Data
@@ -457,89 +459,79 @@ static UINT CALLBACK PrintHookProc(HWND 
 //----------------------------------------------------------------------------------
 // Returns a Global Moveable Memory Handle to a DevMode
 // from the Printer by the name of aPrintName
 //
 // NOTE:
 //   This function assumes that aPrintName has already been converted from 
 //   unicode
 //
-HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
+static nsReturnRef<HGLOBAL> CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName,
+                                                       nsIPrintSettings* aPS)
 {
-  HGLOBAL hGlobalDevMode = nullptr;
-
-  HANDLE hPrinter = nullptr;
+  HPRINTER hPrinter = nullptr;
   // const cast kludge for silly Win32 api's
   LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
   BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
-  if (status) {
-
-    LPDEVMODEW  pNewDevMode;
-    DWORD       dwNeeded, dwRet;
-
-    // Get the buffer size
-    dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr, nullptr, 0);
-    if (dwNeeded == 0) {
-      return nullptr;
-    }
-
-    // Allocate a buffer of the correct size.
-    pNewDevMode = (LPDEVMODEW)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, dwNeeded);
-    if (!pNewDevMode) return nullptr;
+  if (!status) {
+    return nullptr;
+  }
 
-    hGlobalDevMode = (HGLOBAL)::GlobalAlloc(GHND, dwNeeded);
-    if (!hGlobalDevMode) {
-      ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
-      return nullptr;
-    }
-
-    dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, pNewDevMode, nullptr, DM_OUT_BUFFER);
-
-    if (dwRet != IDOK) {
-      ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
-      ::GlobalFree(hGlobalDevMode);
-      ::ClosePrinter(hPrinter);
-      return nullptr;
-    }
+  // Make sure hPrinter is closed on all paths
+  nsAutoPrinter autoPrinter(hPrinter);
 
-    // Lock memory and copy contents from DEVMODE (current printer)
-    // to Global Memory DEVMODE
-    LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hGlobalDevMode);
-    if (devMode) {
-      memcpy(devMode, pNewDevMode, dwNeeded);
-      // Initialize values from the PrintSettings
-      nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
-      MOZ_ASSERT(psWin);
-      psWin->CopyToNative(devMode);
+  // Get the buffer size
+  DWORD dwNeeded = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr,
+                                         nullptr, 0);
+  if (dwNeeded == 0) {
+    return nullptr;
+  }
 
-      // Sets back the changes we made to the DevMode into the Printer Driver
-      dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode, DM_IN_BUFFER | DM_OUT_BUFFER);
-      if (dwRet != IDOK) {
-        ::GlobalUnlock(hGlobalDevMode);
-        ::GlobalFree(hGlobalDevMode);
-        ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
-        ::ClosePrinter(hPrinter);
-        return nullptr;
-      }
+  // Allocate a buffer of the correct size.
+  nsAutoDevMode newDevMode((LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                                   dwNeeded));
+  if (!newDevMode) {
+    return nullptr;
+  }
 
-      ::GlobalUnlock(hGlobalDevMode);
-    } else {
-      ::GlobalFree(hGlobalDevMode);
-      hGlobalDevMode = nullptr;
-    }
-
-    ::HeapFree(::GetProcessHeap(), 0, pNewDevMode);
-
-    ::ClosePrinter(hPrinter);
-
-  } else {
+  nsAutoGlobalMem globalDevMode((HGLOBAL)::GlobalAlloc(GHND, dwNeeded));
+  if (!globalDevMode) {
     return nullptr;
   }
 
-  return hGlobalDevMode;
+  DWORD dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode,
+                                      nullptr, DM_OUT_BUFFER);
+  if (dwRet != IDOK) {
+    return nullptr;
+  }
+
+  // Lock memory and copy contents from DEVMODE (current printer)
+  // to Global Memory DEVMODE
+  LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(globalDevMode);
+  if (!devMode) {
+    return nullptr;
+  }
+
+  memcpy(devMode, newDevMode.get(), dwNeeded);
+  // Initialize values from the PrintSettings
+  nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
+  MOZ_ASSERT(psWin);
+  psWin->CopyToNative(devMode);
+
+  // Sets back the changes we made to the DevMode into the Printer Driver
+  dwRet = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode,
+                                DM_IN_BUFFER | DM_OUT_BUFFER);
+  if (dwRet != IDOK) {
+    ::GlobalUnlock(globalDevMode);
+    return nullptr;
+  }
+
+  ::GlobalUnlock(globalDevMode);
+
+  return globalDevMode.out();
 }
 
 //------------------------------------------------------------------
 // helper
 static void GetDefaultPrinterNameFromGlobalPrinters(nsXPIDLString &printerName)
 {
   nsCOMPtr<nsIPrinterEnumerator> prtEnum = do_GetService("@mozilla.org/gfx/printerenumerator;1");
   if (prtEnum) {
@@ -571,74 +563,69 @@ static nsresult
 ShowNativePrintDialog(HWND              aHWnd,
                       nsIPrintSettings* aPrintSettings)
 {
   //NS_ENSURE_ARG_POINTER(aHWnd);
   NS_ENSURE_ARG_POINTER(aPrintSettings);
 
   gDialogWasExtended  = false;
 
-  HGLOBAL hGlobalDevMode = nullptr;
-  HGLOBAL hDevNames      = nullptr;
-
   // Get the Print Name to be used
   nsXPIDLString printerName;
   aPrintSettings->GetPrinterName(getter_Copies(printerName));
 
   // If there is no name then use the default printer
   if (printerName.IsEmpty()) {
     GetDefaultPrinterNameFromGlobalPrinters(printerName);
   } else {
     HANDLE hPrinter = nullptr;
-    if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())), &hPrinter, nullptr)) {
+    if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())),
+                       &hPrinter, nullptr)) {
       // If the last used printer is not found, we should use default printer.
       GetDefaultPrinterNameFromGlobalPrinters(printerName);
     } else {
       ::ClosePrinter(hPrinter);
     }
   }
 
   // Now create a DEVNAMES struct so the the dialog is initialized correctly.
 
   uint32_t len = printerName.Length();
-  hDevNames = (HGLOBAL)::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) + 
-                                     sizeof(DEVNAMES));
-  if (!hDevNames) {
+  nsAutoGlobalMem autoDevNames((HGLOBAL)::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1) +
+                                                      sizeof(DEVNAMES)));
+  if (!autoDevNames) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);
+  DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(autoDevNames);
   if (!pDevNames) {
-    ::GlobalFree(hDevNames);
     return NS_ERROR_FAILURE;
   }
   pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
   pDevNames->wDeviceOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
   pDevNames->wOutputOffset = sizeof(DEVNAMES)/sizeof(wchar_t)+len;
   pDevNames->wDefault      = 0;
 
   memcpy(pDevNames+1, printerName, (len + 1) * sizeof(wchar_t));
-  ::GlobalUnlock(hDevNames);
+  ::GlobalUnlock(autoDevNames);
 
   // Create a Moveable Memory Object that holds a new DevMode
   // from the Printer Name
   // The PRINTDLG.hDevMode requires that it be a moveable memory object
-  // NOTE: We only need to free hGlobalDevMode when the dialog is cancelled
-  // When the user prints, it comes back in the printdlg struct and 
-  // is used and cleaned up later
-  hGlobalDevMode = CreateGlobalDevModeAndInit(printerName, aPrintSettings);
+  // NOTE: autoDevMode is automatically freed when any error occurred
+  nsAutoGlobalMem autoDevMode(CreateGlobalDevModeAndInit(printerName, aPrintSettings));
 
   // Prepare to Display the Print Dialog
   PRINTDLGW  prntdlg;
   memset(&prntdlg, 0, sizeof(PRINTDLGW));
 
   prntdlg.lStructSize = sizeof(prntdlg);
   prntdlg.hwndOwner   = aHWnd;
-  prntdlg.hDevMode    = hGlobalDevMode;
-  prntdlg.hDevNames   = hDevNames;
+  prntdlg.hDevMode    = autoDevMode;
+  prntdlg.hDevNames   = autoDevNames;
   prntdlg.hDC         = nullptr;
   prntdlg.Flags       = PD_ALLPAGES | PD_RETURNIC | 
                         PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
 
   // if there is a current selection then enable the "Selection" radio button
   int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;
   bool isOn;
   aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);
@@ -677,23 +664,21 @@ ShowNativePrintDialog(HWND              
 
   BOOL result = ::PrintDlgW(&prntdlg);
 
   if (TRUE == result) {
     // check to make sure we don't have any nullptr pointers
     NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE);
 
     if (prntdlg.hDevNames == nullptr) {
-      ::GlobalFree(hGlobalDevMode);
       return NS_ERROR_FAILURE;
     }
     // Lock the deviceNames and check for nullptr
     DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);
     if (devnames == nullptr) {
-      ::GlobalFree(hGlobalDevMode);
       return NS_ERROR_FAILURE;
     }
 
     char16_t* device = &(((char16_t *)devnames)[devnames->wDeviceOffset]);
     char16_t* driver = &(((char16_t *)devnames)[devnames->wDriverOffset]);
 
     // Check to see if the "Print To File" control is checked
     // then take the name from devNames and set it in the PrintSettings
@@ -711,17 +696,16 @@ ShowNativePrintDialog(HWND              
     } else {
       // clear "print to file" info
       aPrintSettings->SetPrintToFile(false);
       aPrintSettings->SetToFileName(nullptr);
     }
 
     nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
     if (!psWin) {
-      ::GlobalFree(hGlobalDevMode);
       return NS_ERROR_FAILURE;
     }
 
     // Setup local Data members
     psWin->SetDeviceName(device);
     psWin->SetDriverName(driver);
 
 #if defined(DEBUG_rods) || defined(DEBUG_dcone)
@@ -767,17 +751,16 @@ ShowNativePrintDialog(HWND              
       aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames);
     }
     // Unlock DeviceNames
     ::GlobalUnlock(prntdlg.hDevNames);
 
     // Transfer the settings from the native data to the PrintSettings
     LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode);
     if (!devMode || !prntdlg.hDC) {
-      ::GlobalFree(hGlobalDevMode);
       return NS_ERROR_FAILURE;
     }
     psWin->SetDevMode(devMode); // copies DevMode
     psWin->CopyFromNative(prntdlg.hDC, devMode);
     ::GlobalUnlock(prntdlg.hDevMode);
     ::DeleteDC(prntdlg.hDC);
 
 #if defined(DEBUG_rods) || defined(DEBUG_dcone)
@@ -800,17 +783,16 @@ ShowNativePrintDialog(HWND              
     } else {
       printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum);
     }
 #endif
     
   } else {
     ::SetFocus(aHWnd);
     aPrintSettings->SetIsCancelled(true);
-    if (hGlobalDevMode) ::GlobalFree(hGlobalDevMode);
     return NS_ERROR_ABORT;
   }
 
   return NS_OK;
 }
 
 //------------------------------------------------------------------
 static void 
--- a/embedding/components/printingui/win/nsPrintDialogUtil.h
+++ b/embedding/components/printingui/win/nsPrintDialogUtil.h
@@ -4,11 +4,9 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef nsFlyOwnDialog_h___
 #define nsFlyOwnDialog_h___
 
 nsresult NativeShowPrintDialog(HWND                aHWnd,
                                nsIWebBrowserPrint* aWebBrowserPrint,
                                nsIPrintSettings*   aPrintSettings);
 
-HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS);
-
 #endif /* nsFlyOwnDialog_h___ */
--- a/gfx/2d/SourceSurfaceCairo.cpp
+++ b/gfx/2d/SourceSurfaceCairo.cpp
@@ -17,16 +17,18 @@ static SurfaceFormat
 CairoFormatToSurfaceFormat(cairo_format_t format)
 {
   switch (format)
   {
     case CAIRO_FORMAT_ARGB32:
       return SurfaceFormat::B8G8R8A8;
     case CAIRO_FORMAT_RGB24:
       return SurfaceFormat::B8G8R8X8;
+    case CAIRO_FORMAT_RGB16_565:
+      return SurfaceFormat::R5G6B5_UINT16;
     case CAIRO_FORMAT_A8:
       return SurfaceFormat::A8;
     default:
       return SurfaceFormat::B8G8R8A8;
   }
 }
 
 SourceSurfaceCairo::SourceSurfaceCairo(cairo_surface_t* aSurface,
--- a/gfx/graphite2/README.mozilla
+++ b/gfx/graphite2/README.mozilla
@@ -1,6 +1,3 @@
-This directory contains the Graphite2 library release 1.3.7 from
-https://github.com/silnrsi/graphite/releases/download/1.3.7/graphite2-minimal-1.3.7.tgz
+This directory contains the Graphite2 library release 1.3.8 from
+https://github.com/silnrsi/graphite/releases/download/1.3.8/graphite2-minimal-1.3.8.tgz
 See gfx/graphite2/moz-gr-update.sh for update procedure.
-
-Also cherry-picked the post-1.3.7 commit 7dc29f3e4665b17f6e825957b707db6da36ae7d8
-to keep our reftests happy (affects the PigLatin test font).
\ No newline at end of file
--- a/gfx/graphite2/include/graphite2/Font.h
+++ b/gfx/graphite2/include/graphite2/Font.h
@@ -25,17 +25,17 @@
     either version 2 of the License or (at your option) any later version.
 */
 #pragma once
 
 #include "graphite2/Types.h"
 
 #define GR2_VERSION_MAJOR   1
 #define GR2_VERSION_MINOR   3
-#define GR2_VERSION_BUGFIX  7
+#define GR2_VERSION_BUGFIX  8
 
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
 typedef struct gr_face          gr_face;
 typedef struct gr_font          gr_font;
--- a/gfx/graphite2/src/Code.cpp
+++ b/gfx/graphite2/src/Code.cpp
@@ -92,17 +92,17 @@ public:
     
 private:
     void        set_ref(int index) throw();
     void        set_noref(int index) throw();
     void        set_changed(int index) throw();
     opcode      fetch_opcode(const byte * bc);
     void        analyse_opcode(const opcode, const int8 * const dp) throw();
     bool        emit_opcode(opcode opc, const byte * & bc);
-    bool        validate_opcode(const opcode opc, const byte * const bc);
+    bool        validate_opcode(const byte opc, const byte * const bc);
     bool        valid_upto(const uint16 limit, const uint16 x) const throw();
     bool        test_context() const throw();
     bool        test_ref(int8 index) const throw();
     void        failure(const status_t s) const throw() { _code.failure(s); }
     
     Code              & _code;
     int                 _out_index;
     uint16              _out_length;
@@ -261,23 +261,23 @@ bool Machine::Code::decoder::load(const 
     return bool(_code);
 }
 
 // Validation check and fixups.
 //
 
 opcode Machine::Code::decoder::fetch_opcode(const byte * bc)
 {
-    const opcode opc = opcode(*bc++);
+    const byte opc = *bc++;
 
     // Do some basic sanity checks based on what we know about the opcode
     if (!validate_opcode(opc, bc))  return MAX_OPCODE;
 
     // And check it's arguments as far as possible
-    switch (opc)
+    switch (opcode(opc))
     {
         case NOP :
             break;
         case PUSH_BYTE :
         case PUSH_BYTEU :
         case PUSH_SHORT :
         case PUSH_SHORTU :
         case PUSH_LONG :
@@ -465,17 +465,17 @@ opcode Machine::Code::decoder::fetch_opc
             valid_upto(_max.features, bc[0]);
             test_ref(int8(bc[1]));
             break;
         default:
             failure(invalid_opcode);
             break;
     }
 
-    return bool(_code) ? opc : MAX_OPCODE;
+    return bool(_code) ? opcode(opc) : MAX_OPCODE;
 }
 
 
 void Machine::Code::decoder::analyse_opcode(const opcode opc, const int8  * arg) throw()
 {
   switch (opc)
   {
     case DELETE :
@@ -624,17 +624,17 @@ void Machine::Code::decoder::apply_analy
         _code._delete = true;
     }
     
     _code._instr_count = code_end - code;
 }
 
 
 inline
-bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * const bc)
+bool Machine::Code::decoder::validate_opcode(const byte opc, const byte * const bc)
 {
     if (opc >= MAX_OPCODE)
     {
         failure(invalid_opcode);
         return false;
     }
     const opcode_t & op = Machine::getOpcodeTable()[opc];
     if (op.impl[_code._constraint] == 0)
@@ -662,17 +662,27 @@ bool Machine::Code::decoder::valid_upto(
     const bool t = (limit != 0) && (x < limit);
     if (!t) failure(out_of_range_data);
     return t;
 }
 
 inline
 bool Machine::Code::decoder::test_ref(int8 index) const throw()
 {
-    return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
+    if (_code._constraint && !_in_ctxt_item)
+    {
+        if (index > 0 || -index > _max.pre_context)
+        {
+            failure(out_of_range_data);
+            return false;
+        }
+    }
+    else
+        return valid_upto(_max.rule_length, _slotref + _max.pre_context + index);
+    return true;
 }
 
 bool Machine::Code::decoder::test_context() const throw()
 {
     if (_out_index >= _out_length || _out_index < 0 || _slotref >= NUMCONTEXTS - 1)
     {
         failure(out_of_range_data);
         return false;
--- a/gfx/graphite2/src/Collider.cpp
+++ b/gfx/graphite2/src/Collider.cpp
@@ -824,43 +824,43 @@ bool KernCollider::initSlot(Segment *seg
     if (margin < 10) margin = 10;
 
     _limit = limit;
     _offsetPrev = offsetPrev; // kern from a previous pass
     
     // Calculate the height of the glyph and how many horizontal slices to use.
     if (_maxy >= 1e37f)
     {
-        _maxy = ymax;
-        _miny = ymin;
         _sliceWidth = margin / 1.5f;
+        _maxy = ymax + margin;
+        _miny = ymin - margin;
         numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f);  // +2 helps with rounding errors
         _edges.clear();
         _edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
         _xbound = (dir & 1) ? (float)1e38f : (float)-1e38f;
     }
     else if (_maxy != ymax || _miny != ymin)
     {
         if (_miny != ymin)
         {
-            numSlices = int((ymin - _miny) / _sliceWidth - 1);
+            numSlices = int((ymin - margin - _miny) / _sliceWidth - 1);
             _miny += numSlices * _sliceWidth;
             if (numSlices < 0)
                 _edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
             else if ((unsigned)numSlices < _edges.size())    // this shouldn't fire since we always grow the range
             {
                 Vector<float>::iterator e = _edges.begin();
                 while (numSlices--)
                     ++e;
                 _edges.erase(_edges.begin(), e);
             }
         }
         if (_maxy != ymax)
         {
-            numSlices = int((ymax - _miny) / _sliceWidth + 1);
+            numSlices = int((ymax + margin - _miny) / _sliceWidth + 1);
             _maxy = numSlices * _sliceWidth + _miny;
             if (numSlices > (int)_edges.size())
                 _edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
             else if (numSlices < (int)_edges.size())   // this shouldn't fire since we always grow the range
             {
                 while ((int)_edges.size() > numSlices)
                     _edges.pop_back();
             }
@@ -930,53 +930,60 @@ bool KernCollider::initSlot(Segment *seg
 // Return false if we know there is no collision, true if we think there might be one.
 bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, GR_MAYBE_UNUSED json * const dbgout)
 {
     int rtl = (dir & 1) * 2 - 1;
     if (!seg->getFace()->glyphs().check(slot->gid()))
         return false;
     const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
     const float sx = slot->origin().x + currShift.x;
-    float x = sx + (rtl > 0 ? bb.tr.x : bb.bl.x);
+    float x = (sx + (rtl > 0 ? bb.tr.x : bb.bl.x)) * rtl;
     // this isn't going to reduce _mingap so skip
-    if ((rtl > 0 && x < _xbound - _mingap - currSpace) || (rtl <= 0 && x > _xbound + _mingap + currSpace))
+    if (x < rtl * (_xbound - _mingap - currSpace))
         return false;
 
     const float sy = slot->origin().y + currShift.y;
-    int smin = max(0, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1));
-    int smax = min((int)_edges.size() - 1, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1));
+    int smin = max(1, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1)) - 1;
+    int smax = min((int)_edges.size() - 2, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1)) + 1;
+    if (smin > smax)
+        return false;
     bool collides = false;
+    float below = smin > 0 ? _edges[smin-1] * rtl : 1e38f;
+    float here = _edges[smin] * rtl;
+    float above = smin < (int)_edges.size() - 1 ? _edges[smin+1] * rtl : 1e38f;
 
     for (int i = smin; i <= smax; ++i)
     {
         float t;
         float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth);  // vertical center of slice
-        if (x * rtl > _edges[i] * rtl - _mingap - currSpace)
+        if (    (x > here - _mingap - currSpace)
+             || (x > below - _mingap - currSpace)
+             || (x > above - _mingap - currSpace))
         {
             // 2 * currSpace to account for the space that is already separating them and the space we want to add
-            float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) + 2 * rtl * currSpace;
-            t = rtl * (_edges[i] - m);
+            float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) * rtl + 2 * currSpace;
             // Check slices above and below (if any).
-            if (i < (int)_edges.size() - 1) t = min(t, rtl * (_edges[i+1] - m));
-            if (i > 0) t = min(t, rtl * (_edges[i-1] - m));
+            t = min(min(here, below), above) - m;
             // _mingap is positive to shrink
             if (t < _mingap)
             {
                 _mingap = t;
                 collides = true;
             }
 #if !defined GRAPHITE2_NTRACING
             // Debugging - remember the closest neighboring edge for this slice.
-            if (rtl * m > rtl * _nearEdges[i])
+            if (m > rtl * _nearEdges[i])
             {
                 _slotNear[i] = slot;
-                _nearEdges[i] = m;
+                _nearEdges[i] = m * rtl;
             }
 #endif
         }
+        below = here; here = above;
+        above = i < (int)_edges.size() - 2 ? _edges[i+2] * rtl : 1e38f;
     }
     return collides;   // note that true is not a necessarily reliable value
     
 }   // end of KernCollider::mergeSlot
 
 
 // Return the amount to kern by.
 Position KernCollider::resolve(GR_MAYBE_UNUSED Segment *seg, GR_MAYBE_UNUSED Slot *slot,
--- a/gfx/graphite2/src/GlyphCache.cpp
+++ b/gfx/graphite2/src/GlyphCache.cpp
@@ -206,16 +206,18 @@ GlyphCache::~GlyphCache()
             free(_boxes[0]);
         free(_boxes);
     }
     delete _glyph_loader;
 }
 
 const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const      //result may be changed by subsequent call with a different glyphid
 { 
+    if (glyphid >= numGlyphs())
+        return _glyphs[0];
     const GlyphFace * & p = _glyphs[glyphid];
     if (p == 0 && _glyph_loader)
     {
         int numsubs = 0;
         GlyphFace * g = new GlyphFace();
         if (g)  p = _glyph_loader->read_glyph(glyphid, *g, &numsubs);
         if (!p)
         {
@@ -384,22 +386,24 @@ const GlyphFace * GlyphCache::Loader::re
         }
         else
         {
             be::skip<uint16>(gloc, glyphid);
             glocs = be::read<uint16>(gloc);
             gloce = be::peek<uint16>(gloc);
         }
 
-        if (glocs + 1 >= m_pGlat.size() || gloce > m_pGlat.size())
+        if (glocs >= m_pGlat.size() - 1 || gloce > m_pGlat.size())
             return 0;
 
         const uint32 glat_version = be::peek<uint32>(m_pGlat);
         if (glat_version >= 0x00030000)
         {
+            if (glocs >= gloce)
+                return 0;
             const byte * p = m_pGlat + glocs;
             uint16 bmap = be::read<uint16>(p);
             int num = bit_set_count((uint32)bmap);
             if (numsubs) *numsubs += num;
             glocs += 6 + 8 * num;
             if (glocs > gloce)
                 return 0;
         }
--- a/gfx/graphite2/src/Justifier.cpp
+++ b/gfx/graphite2/src/Justifier.cpp
@@ -95,62 +95,63 @@ float Segment::justify(Slot *pSlot, cons
 
     end = pLast->nextSibling();
     pFirst = pFirst->nextSibling();
 
     int icount = 0;
     int numLevels = silf()->numJustLevels();
     if (!numLevels)
     {
-        for (s = pSlot; s != end; s = s->next())
+        for (s = pSlot; s && s != end; s = s->nextSibling())
         {
             CharInfo *c = charinfo(s->before());
             if (isWhitespace(c->unicodeChar()))
             {
                 s->setJustify(this, 0, 3, 1);
                 s->setJustify(this, 0, 2, 1);
                 s->setJustify(this, 0, 0, -1);
                 ++icount;
             }
         }
         if (!icount)
         {
-            for (s = pSlot; s != end; s = s->nextSibling())
+            for (s = pSlot; s && s != end; s = s->nextSibling())
             {
                 s->setJustify(this, 0, 3, 1);
                 s->setJustify(this, 0, 2, 1);
                 s->setJustify(this, 0, 0, -1);
             }
         }
         ++numLevels;
     }
 
     Vector<JustifyTotal> stats(numLevels);
-    for (s = pFirst; s != end; s = s->nextSibling())
+    for (s = pFirst; s && s != end; s = s->nextSibling())
     {
         float w = s->origin().x / scale + s->advance() - base;
         if (w > currWidth) currWidth = w;
         for (int j = 0; j < numLevels; ++j)
             stats[j].accumulate(s, this, j);
         s->just(0);
     }
 
     for (int i = (width < 0.0f) ? -1 : numLevels - 1; i >= 0; --i)
     {
         float diff;
         float error = 0.;
         float diffpw;
         int tWeight = stats[i].weight();
+        if (tWeight == 0) continue;
 
         do {
             error = 0.;
             diff = width - currWidth;
             diffpw = diff / tWeight;
             tWeight = 0;
-            for (s = pFirst; s != end; s = s->nextSibling()) // don't include final glyph
+            for (s = pFirst; s && s != end; s = s->nextSibling()) // don't include final glyph
             {
                 int w = s->getJustify(this, i, 3);
                 float pref = diffpw * w + error;
                 int step = s->getJustify(this, i, 2);
                 if (!step) step = 1;        // handle lazy font developers
                 if (pref > 0)
                 {
                     float max = uint16(s->getJustify(this, i, 0));
--- a/gfx/graphite2/src/Pass.cpp
+++ b/gfx/graphite2/src/Pass.cpp
@@ -334,17 +334,17 @@ bool Pass::readStates(const byte * start
 
     // load state transition table.
     for (uint16 * t = m_transitions,
                 * const t_end = t + m_numTransition*m_numColumns; t != t_end; ++t)
     {
         *t = be::read<uint16>(states);
         if (e.test(*t >= m_numStates, E_BADSTATE))
         {
-            face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 24));
+            face.error_context((face.error_context() & 0xFFFF00) + EC_ATRANS + (((t - m_transitions) / m_numColumns) << 8));
             return face.error(e);
         }
     }
 
     State * s = m_states,
           * const success_begin = m_states + m_numStates - m_numSuccess;
     const RuleEntry * rule_map_end = m_ruleMap + be::peek<uint16>(o_rule_map + m_numSuccess*sizeof(uint16));
     for (size_t n = m_numStates; n; --n, ++s)
@@ -856,17 +856,16 @@ bool Pass::collisionShift(Segment *seg, 
             }
         }
     }
     return true;
 }
 
 bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
 {
-    KernCollider kerncoll(dbgout);
     Slot *start = seg->first();
     float ymin = 1e38f;
     float ymax = -1e38f;
     const GlyphCache &gc = seg->getFace()->glyphs();
 
     // phase 3 : handle kerning of clusters
 #if !defined GRAPHITE2_NTRACING
     if (dbgout)
@@ -879,17 +878,17 @@ bool Pass::collisionKern(Segment *seg, i
             return false;
         const SlotCollision * c = seg->collisionInfo(s);
         const Rect &bbox = seg->theGlyphBBoxTemporary(s->gid());
         float y = s->origin().y + c->shift().y;
         ymax = max(y + bbox.tr.y, ymax);
         ymin = min(y + bbox.bl.y, ymin);
         if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
                         == (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
-            resolveKern(seg, s, start, kerncoll, dir, ymin, ymax, dbgout);
+            resolveKern(seg, s, start, dir, ymin, ymax, dbgout);
         if (c->flags() & SlotCollision::COLL_END)
             start = NULL;
         if (c->flags() & SlotCollision::COLL_START)
             start = s;
     }
 
 #if !defined GRAPHITE2_NTRACING
     if (dbgout)
@@ -1018,17 +1017,17 @@ bool Pass::resolveCollisions(Segment *se
     if (isCol)
     { cFix->setFlags(cFix->flags() | SlotCollision::COLL_ISCOL | SlotCollision::COLL_KNOWN); }
     else
     { cFix->setFlags((cFix->flags() & ~SlotCollision::COLL_ISCOL) | SlotCollision::COLL_KNOWN); }
     hasCol |= isCol;
     return true;
 }
 
-float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, KernCollider &coll, int dir,
+float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, int dir,
     float &ymin, float &ymax, json *const dbgout) const
 {
     Slot *nbor; // neighboring slot
     float currSpace = 0.;
     bool collides = false;
     unsigned int space_count = 0;
     Slot *base = slotFix;
     while (base->attachedTo())
@@ -1038,16 +1037,17 @@ float Pass::resolveKern(Segment *seg, Sl
 
     if (base != slotFix)
     {
         cFix->setFlags(cFix->flags() | SlotCollision::COLL_KERN | SlotCollision::COLL_FIX);
         return 0;
     }
     bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
     bool isInit = false;
+    KernCollider coll(dbgout);
 
     for (nbor = slotFix->next(); nbor; nbor = nbor->next())
     {
         if (nbor->isChildOf(base))
             continue;
         if (!gc.check(nbor->gid()))
             return 0.;
         const Rect &bb = seg->theGlyphBBoxTemporary(nbor->gid());
--- a/gfx/graphite2/src/inc/Machine.h
+++ b/gfx/graphite2/src/inc/Machine.h
@@ -179,17 +179,17 @@ inline SlotMap& Machine::slotMap() const
     return _map;
 }
 
 inline Machine::status_t Machine::status() const throw()
 {
     return _status;
 }
 
-inline void Machine::check_final_stack(const int32 * const sp)
+inline void Machine::check_final_stack(const stack_t * const sp)
 {
     stack_t const * const base  = _stack + STACK_GUARD,
                   * const limit = base + STACK_MAX;
     if      (sp <  base)    _status = stack_underflow;       // This should be impossible now.
     else if (sp >= limit)   _status = stack_overflow;        // So should this.
     else if (sp != base)    _status = stack_not_empty;
 }
 
--- a/gfx/graphite2/src/inc/Pass.h
+++ b/gfx/graphite2/src/inc/Pass.h
@@ -76,17 +76,17 @@ private:
     void    dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const;
     void    dumpRuleEventOutput(const FiniteStateMachine & fsm, vm::Machine & m, const Rule & r, Slot * os) const;
     void    adjustSlot(int delta, Slot * & slot_out, SlotMap &) const;
     bool    collisionShift(Segment *seg, int dir, json * const dbgout) const;
     bool    collisionKern(Segment *seg, int dir, json * const dbgout) const;
     bool    collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
     bool    resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
                      int dir, bool &moved, bool &hasCol, json * const dbgout) const;
-    float   resolveKern(Segment *seg, Slot *slot, Slot *start, KernCollider &coll, int dir,
+    float   resolveKern(Segment *seg, Slot *slot, Slot *start, int dir,
                      float &ymin, float &ymax, json *const dbgout) const;
 
     const Silf        * m_silf;
     uint16            * m_cols;
     Rule              * m_rules; // rules
     RuleEntry         * m_ruleMap;
     uint16            * m_startStates; // prectxt length
     uint16            * m_transitions;
--- a/gfx/graphite2/src/inc/opcodes.h
+++ b/gfx/graphite2/src/inc/opcodes.h
@@ -62,17 +62,18 @@ of the License or (at your option) any l
 //        ip        = The current instruction pointer
 //        endPos    = Position of advance of last cluster
 //        dir       = writing system directionality of the font
      
 
 // #define NOT_IMPLEMENTED     assert(false)
 #define NOT_IMPLEMENTED
 
-#define binop(op)           const int32 a = pop(); *sp = int32(*sp) op a
+#define binop(op)           const uint32 a = pop(); *sp = uint32(*sp) op a
+#define sbinop(op)          const int32 a = pop(); *sp = int32(*sp) op a
 #define use_params(n)       dp += n
 
 #define declare_params(n)   const byte * param = dp; \
                             use_params(n);
 
 #define push(n)             { *++sp = n; }
 #define pop()               (*sp--)
 #define slotat(x)           (map[(x)])
@@ -125,17 +126,17 @@ STARTOP(sub)
 ENDOP
 
 STARTOP(mul)
     binop(*);
 ENDOP
 
 STARTOP(div_)
     if (*sp == 0) DIE;
-    binop(/);
+    sbinop(/);
 ENDOP
 
 STARTOP(min_)
     const int32 a = pop(), b = *sp;
     if (a < b) *sp = a;
 ENDOP
 
 STARTOP(max_)
@@ -176,29 +177,29 @@ STARTOP(equal)
     binop(==);
 ENDOP
 
 STARTOP(not_eq_)
     binop(!=);
 ENDOP
 
 STARTOP(less)
-    binop(<);
+    sbinop(<);
 ENDOP
 
 STARTOP(gtr)
-    binop(>);
+    sbinop(>);
 ENDOP
 
 STARTOP(less_eq)
-    binop(<=);
+    sbinop(<=);
 ENDOP
 
 STARTOP(gtr_eq)
-    binop(>=);
+    sbinop(>=);
 ENDOP
 
 STARTOP(next)
     if (map - &smap[0] >= int(smap.size())) DIE
     if (is)
     {
         if (is == smap.highwater())
             smap.highpassed(true);
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -632,36 +632,27 @@ SourceSurfaceImage::GetTextureClient(Com
   }
 
   RefPtr<SourceSurface> surface = GetAsSourceSurface();
   MOZ_ASSERT(surface);
   if (!surface) {
     return nullptr;
   }
 
-
-// XXX windows' TextureClients do not hold ISurfaceAllocator,
-// recycler does not work on windows.
-#ifndef XP_WIN
-
-// XXX only gonk ensure when TextureClient is recycled,
-// TextureHost is not used by CompositableHost.
 #ifdef MOZ_WIDGET_GONK
   RefPtr<TextureClientRecycleAllocator> recycler =
     aClient->GetTextureClientRecycler();
   if (recycler) {
     textureClient =
       recycler->CreateOrRecycle(surface->GetFormat(),
                                 surface->GetSize(),
                                 BackendSelector::Content,
                                 aClient->GetTextureFlags());
   }
 #endif
-
-#endif
   if (!textureClient) {
     // gfx::BackendType::NONE means default to content backend
     textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
                                                            surface->GetSize(),
                                                            BackendSelector::Content,
                                                            TextureFlags::DEFAULT);
   }
   if (!textureClient) {
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -742,16 +742,24 @@ public:
    * frame. Returns true if the smooth scroll should be advanced by one frame,
    * or false if the smooth scroll has ended.
    */
   bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) {
     nsPoint oneParentLayerPixel =
       CSSPoint::ToAppUnits(ParentLayerPoint(1, 1) / aFrameMetrics.GetZoom());
     if (mXAxisModel.IsFinished(oneParentLayerPixel.x) &&
         mYAxisModel.IsFinished(oneParentLayerPixel.y)) {
+      // Set the scroll offset to the exact destination. If we allow the scroll
+      // offset to end up being a bit off from the destination, we can get
+      // artefacts like "scroll to the next snap point in this direction"
+      // scrolling to the snap point we're already supposed to be at.
+      aFrameMetrics.SetScrollOffset(
+          aFrameMetrics.CalculateScrollRange().ClampPoint(
+              CSSPoint::FromAppUnits(nsPoint(mXAxisModel.GetDestination(),
+                                             mYAxisModel.GetDestination()))));
       return false;
     }
 
     mXAxisModel.Simulate(aDelta);
     mYAxisModel.Simulate(aDelta);
 
     CSSPoint position = CSSPoint::FromAppUnits(nsPoint(mXAxisModel.GetPosition(),
                                                        mYAxisModel.GetPosition()));
@@ -1814,16 +1822,21 @@ nsEventStatus AsyncPanZoomController::On
   if (delta.x == 0 && delta.y == 0) {
     // Avoid spurious state changes and unnecessary work
     return nsEventStatus_eIgnore;
   }
 
   mozilla::Telemetry::Accumulate(mozilla::Telemetry::SCROLL_INPUT_METHODS,
       (uint32_t) ScrollInputMethodForWheelDeltaType(aEvent.mDeltaType));
 
+  // Wheel events from "clicky" mouse wheels trigger scroll snapping to the
+  // next snap point. Check for this, and adjust the delta to take into
+  // account the snap point.
+  bool scrollSnapping = MaybeAdjustDeltaForScrollSnapping(delta, aEvent);
+
   switch (aEvent.mScrollMode) {
     case ScrollWheelInput::SCROLLMODE_INSTANT: {
       ScreenPoint distance = ToScreenCoordinates(
         ParentLayerPoint(fabs(delta.x), fabs(delta.y)), aEvent.mLocalOrigin);
 
       CancelAnimation();
 
       OverscrollHandoffState handoffState(
@@ -1845,34 +1858,43 @@ nsEventStatus AsyncPanZoomController::On
     }
 
     case ScrollWheelInput::SCROLLMODE_SMOOTH: {
       // The lock must be held across the entire update operation, so the
       // compositor doesn't end the animation before we get a chance to
       // update it.
       ReentrantMonitorAutoEnter lock(mMonitor);
 
-      if (mState != WHEEL_SCROLL) {
-        CancelAnimation();
-        SetState(WHEEL_SCROLL);
-
-        nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
-        StartAnimation(new WheelScrollAnimation(
-          *this, initialPosition, aEvent.mDeltaType));
+      if (scrollSnapping) {
+        // If we're scroll snapping use a smooth scroll animation to get
+        // the desired physics. Note that SmoothScrollTo() will re-use an
+        // existing smooth scroll animation if there is one.
+        CSSPoint snapPoint = mFrameMetrics.GetScrollOffset() + (delta / mFrameMetrics.GetZoom());
+        SmoothScrollTo(snapPoint);
+      } else {
+        // Otherwise, use a wheel scroll animation, also reusing one if possible.
+        if (mState != WHEEL_SCROLL) {
+          CancelAnimation();
+          SetState(WHEEL_SCROLL);
+
+          nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
+          StartAnimation(new WheelScrollAnimation(
+            *this, initialPosition, aEvent.mDeltaType));
+        }
+
+        nsPoint deltaInAppUnits =
+          CSSPoint::ToAppUnits(delta / mFrameMetrics.GetZoom());
+        // Cast velocity from ParentLayerPoints/ms to CSSPoints/ms then convert to
+        // appunits/second
+        nsPoint velocity =
+          CSSPoint::ToAppUnits(CSSPoint(mX.GetVelocity(), mY.GetVelocity())) * 1000.0f;
+
+        WheelScrollAnimation* animation = mAnimation->AsWheelScrollAnimation();
+        animation->Update(aEvent.mTimeStamp, deltaInAppUnits, nsSize(velocity.x, velocity.y));
       }
-
-      nsPoint deltaInAppUnits =
-        CSSPoint::ToAppUnits(delta / mFrameMetrics.GetZoom());
-      // Cast velocity from ParentLayerPoints/ms to CSSPoints/ms then convert to
-      // appunits/second
-      nsPoint velocity =
-        CSSPoint::ToAppUnits(CSSPoint(mX.GetVelocity(), mY.GetVelocity())) * 1000.0f;
-
-      WheelScrollAnimation* animation = mAnimation->AsWheelScrollAnimation();
-      animation->Update(aEvent.mTimeStamp, deltaInAppUnits, nsSize(velocity.x, velocity.y));
       break;
     }
   }
 
   return nsEventStatus_eConsumeNoDefault;
 }
 
 void
@@ -3932,34 +3954,42 @@ void AsyncPanZoomController::ShareCompos
       // so the content process know which APZC sent this shared FrameMetrics.
       if (!compositor->SendSharedCompositorFrameMetrics(mem, handle, mLayersId, mAPZCId)) {
         APZC_LOG("%p failed to share FrameMetrics with content process.", this);
       }
     }
   }
 }
 
-void AsyncPanZoomController::ScrollSnapNear(const CSSPoint& aDestination) {
+Maybe<CSSPoint> AsyncPanZoomController::FindSnapPointNear(
+    const CSSPoint& aDestination, nsIScrollableFrame::ScrollUnit aUnit) {
   mMonitor.AssertCurrentThreadIn();
   APZC_LOG("%p scroll snapping near %s\n", this, Stringify(aDestination).c_str());
   CSSRect scrollRange = mFrameMetrics.CalculateScrollRange();
   if (Maybe<nsPoint> snapPoint = ScrollSnapUtils::GetSnapPointForDestination(
           mScrollMetadata.GetSnapInfo(),
-          nsIScrollableFrame::DEVICE_PIXELS,
+          aUnit,
           CSSSize::ToAppUnits(mFrameMetrics.CalculateCompositedSizeInCssPixels()),
           CSSRect::ToAppUnits(scrollRange),
           CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset()),
           CSSPoint::ToAppUnits(aDestination))) {
     CSSPoint cssSnapPoint = CSSPoint::FromAppUnits(snapPoint.ref());
     // GetSnapPointForDestination() can produce a destination that's outside
     // of the scroll frame's scroll range. Clamp it here (this matches the
     // behaviour of the main-thread code path, which clamps it in
     // nsGfxScrollFrame::ScrollTo()).
-    cssSnapPoint = scrollRange.ClampPoint(cssSnapPoint);
-    SmoothScrollTo(cssSnapPoint);
+    return Some(scrollRange.ClampPoint(cssSnapPoint));
+  }
+  return Nothing();
+}
+
+void AsyncPanZoomController::ScrollSnapNear(const CSSPoint& aDestination) {
+  if (Maybe<CSSPoint> snapPoint =
+        FindSnapPointNear(aDestination, nsIScrollableFrame::DEVICE_PIXELS)) {
+    SmoothScrollTo(*snapPoint);
   }
 }
 
 void AsyncPanZoomController::ScrollSnap() {
   ReentrantMonitorAutoEnter lock(mMonitor);
   ScrollSnapNear(mFrameMetrics.GetScrollOffset());
 }
 
@@ -3991,10 +4021,34 @@ void AsyncPanZoomController::ScrollSnapT
              (float)predictedDelta.y, (float)mFrameMetrics.GetScrollOffset().x,
              (float)mFrameMetrics.GetScrollOffset().y,
              (float)predictedDestination.x, (float)predictedDestination.y);
 
     ScrollSnapNear(predictedDestination);
   }
 }
 
+bool AsyncPanZoomController::MaybeAdjustDeltaForScrollSnapping(
+    ParentLayerPoint& aDelta, const ScrollWheelInput& aEvent)
+{
+  // Don't scroll snap for pixel scrolls. This matches the main thread
+  // behaviour in EventStateManager::DoScrollText().
+  if (aEvent.mDeltaType == ScrollWheelInput::SCROLLDELTA_PIXEL) {
+    return false;
+  }
+
+  ReentrantMonitorAutoEnter lock(mMonitor);
+  CSSPoint scrollOffset = mFrameMetrics.GetScrollOffset();
+  CSSToParentLayerScale2D zoom = mFrameMetrics.GetZoom();
+  CSSPoint destination = mFrameMetrics.CalculateScrollRange().ClampPoint(
+      scrollOffset + (aDelta / zoom));
+  nsIScrollableFrame::ScrollUnit unit =
+      ScrollWheelInput::ScrollUnitForDeltaType(aEvent.mDeltaType);
+
+  if (Maybe<CSSPoint> snapPoint = FindSnapPointNear(destination, unit)) {
+    aDelta = (*snapPoint - scrollOffset) * zoom;
+    return true;
+  }
+  return false;
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -20,16 +20,17 @@
 #include "mozilla/Atomics.h"
 #include "InputData.h"
 #include "Axis.h"
 #include "InputQueue.h"
 #include "APZUtils.h"
 #include "Layers.h"                     // for Layer::ScrollDirection
 #include "LayersTypes.h"
 #include "mozilla/gfx/Matrix.h"
+#include "nsIScrollableFrame.h"
 #include "nsRegion.h"
 #include "PotentialCheckerboardDurationTracker.h"
 
 #include "base/message_loop.h"
 
 namespace mozilla {
 
 namespace ipc {
@@ -617,25 +618,16 @@ protected:
   static AxisLockMode GetAxisLockMode();
 
   // Helper function for OnSingleTapUp() and OnSingleTapConfirmed().
   nsEventStatus GenerateSingleTap(const ScreenIntPoint& aPoint, mozilla::Modifiers aModifiers);
 
   // Common processing at the end of a touch block.
   void OnTouchEndOrCancel();
 
-  // Snap to a snap position nearby the current scroll position, if appropriate.
-  void ScrollSnap();
-  // Snap to a snap position nearby the destination predicted based on the
-  // current velocity, if appropriate.
-  void ScrollSnapToDestination();
-
-  // Helper function for ScrollSnap() and ScrollSnapToDestination().
-  void ScrollSnapNear(const CSSPoint& aDestination);
-
   uint64_t mLayersId;
   RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
 
   /* Access to the following two fields is protected by the mRefPtrMonitor,
      since they are accessed on the UI thread but can be cleared on the
      compositor thread. */
   RefPtr<GeckoContentController> mGeckoContentController;
   RefPtr<GestureEventListener> mGestureEventListener;
@@ -758,17 +750,16 @@ public:
 
   /**
    * Returns the same transform as GetCurrentAsyncTransform(), but includes
    * any transform due to axis over-scroll.
    */
   AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(AsyncMode aMode) const;
 
 
-
   /* ===================================================================
    * The functions and members in this section are used to manage
    * the state that tracks what this APZC is doing with the input events.
    */
 protected:
   enum PanZoomState {
     NOTHING,                  /* no touch-start events received */
     FLING,                    /* all touches removed, but we're still scrolling page */
@@ -1151,14 +1142,43 @@ private:
   // This is created when this APZC instance is first included as part of a
   // composite. If a checkerboard event takes place, this is destroyed at the
   // end of the event, and a new one is created on the next composite.
   UniquePtr<CheckerboardEvent> mCheckerboardEvent;
   // This is used to track the total amount of time that we could reasonably
   // be checkerboarding. Combined with other info, this allows us to meaningfully
   // say how frequently users actually encounter checkerboarding.
   PotentialCheckerboardDurationTracker mPotentialCheckerboardTracker;
+
+
+  /* ===================================================================
+   * The functions in this section are used for CSS scroll snapping.
+   */
+
+  // If |aEvent| should trigger scroll snapping, adjust |aDelta| to reflect
+  // the snapping (that is, make it a delta that will take us to the desired
+  // snap point). Returns true iff. the delta was so adjusted.
+  bool MaybeAdjustDeltaForScrollSnapping(ParentLayerPoint& aDelta,
+                                         const ScrollWheelInput& aEvent);
+
+  // Snap to a snap position nearby the current scroll position, if appropriate.
+  void ScrollSnap();
+
+  // Snap to a snap position nearby the destination predicted based on the
+  // current velocity, if appropriate.
+  void ScrollSnapToDestination();
+
+  // Snap to a snap position nearby the provided destination, if appropriate.
+  void ScrollSnapNear(const CSSPoint& aDestination);
+
+  // Find a snap point near |aDestination| that we should snap to.
+  // Returns the snap point if one was found, or an empty Maybe otherwise.
+  // |aUnit| affects the snapping behaviour (see ScrollSnapUtils::
+  // GetSnapPointForDestination). It should generally be determined by the
+  // type of event that's triggering the scroll.
+  Maybe<CSSPoint> FindSnapPointNear(const CSSPoint& aDestination,
+                                    nsIScrollableFrame::ScrollUnit aUnit);
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_PanZoomController_h
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -4,16 +4,17 @@
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 libevent_path_prefix = 'src/third_party'
 include(libevent_path_prefix + '/libeventcommon.mozbuild')
 
 UNIFIED_SOURCES += [
     'src/base/at_exit.cc',
+    'src/base/buffer.cc',
     'src/base/command_line.cc',
     'src/base/file_path.cc',
     'src/base/file_util.cc',
     'src/base/histogram.cc',
     'src/base/lock.cc',
     'src/base/logging.cc',
     'src/base/message_loop.cc',
     'src/base/message_pump_default.cc',
new file mode 100644
--- /dev/null
+++ b/ipc/chromium/src/base/buffer.cc
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "buffer.h"
+
+Buffer::Buffer()
+ : mBuffer(nullptr),
+   mSize(0),
+   mReserved(0)
+{
+}
+
+Buffer::~Buffer()
+{
+  if (mBuffer) {
+    free(mBuffer);
+  }
+}
+
+bool
+Buffer::empty() const
+{
+  return mSize == 0;
+}
+
+size_t
+Buffer::size() const
+{
+  return mSize;
+}
+
+const char*
+Buffer::data() const
+{
+  return mBuffer;
+}
+
+void
+Buffer::clear()
+{
+  free(mBuffer);
+  mBuffer = nullptr;
+  mSize = 0;
+  mReserved = 0;
+}
+
+void
+Buffer::try_realloc(size_t newlength)
+{
+  char* buffer = (char*)realloc(mBuffer, newlength);
+  if (buffer) {
+    mBuffer = buffer;
+    mReserved = newlength;
+    return;
+  }
+
+  // If we're growing the buffer, crash. If we're shrinking, then we continue to
+  // use the old (larger) buffer.
+  MOZ_RELEASE_ASSERT(newlength <= mReserved);
+}
+
+void
+Buffer::append(const char* bytes, size_t length)
+{
+  if (mSize + length > mReserved) {
+    try_realloc(mSize + length);
+  }
+
+  memcpy(mBuffer + mSize, bytes, length);
+  mSize += length;
+}
+
+void
+Buffer::assign(const char* bytes, size_t length)
+{
+  if (bytes >= mBuffer && bytes < mBuffer + mReserved) {
+    MOZ_RELEASE_ASSERT(bytes + length <= mBuffer + mSize);
+    memmove(mBuffer, bytes, length);
+    mSize = length;
+    try_realloc(length);
+  } else {
+    try_realloc(length);
+    mSize = length;
+    memcpy(mBuffer, bytes, length);
+  }
+}
+
+void
+Buffer::erase(size_t start, size_t count)
+{
+  mSize -= count;
+  memmove(mBuffer + start, mBuffer + start + count, mSize - start);
+  try_realloc(mSize);
+}
+
+void
+Buffer::reserve(size_t size)
+{
+  if (mReserved < size) {
+    try_realloc(size);
+  }
+}
+
+char*
+Buffer::trade_bytes(size_t count)
+{
+  char* result = mBuffer;
+  mSize = mReserved = mSize - count;
+  mBuffer = mReserved ? (char*)malloc(mReserved) : nullptr;
+  MOZ_RELEASE_ASSERT(!mReserved || mBuffer);
+  if (mSize) {
+    memcpy(mBuffer, result + count, mSize);
+  }
+
+  // Try to resize the buffer down, but ignore failure. This can cause extra
+  // copies, but so be it.
+  char* resized = (char*)realloc(result, count);
+  if (resized) {
+    return resized;
+  }
+  return result;
+}
new file mode 100644
--- /dev/null
+++ b/ipc/chromium/src/base/buffer.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef CHROME_BASE_BUFFER_H_
+#define CHROME_BASE_BUFFER_H_
+
+// Buffer is a simple std::string-like class for buffering up IPC messages. Its
+// main distinguishing characteristic is the trade_bytes function.
+class Buffer {
+public:
+  Buffer();
+  ~Buffer();
+
+  bool empty() const;
+  const char* data() const;
+  size_t size() const;
+
+  void clear();
+  void append(const char* bytes, size_t length);
+  void assign(const char* bytes, size_t length);
+  void erase(size_t start, size_t count);
+
+  void reserve(size_t size);
+
+  // This function should be used by a caller who wants to extract the first
+  // |count| bytes from the buffer. Rather than copying the bytes out, this
+  // function returns the entire buffer. The bytes in range [count, size()) are
+  // copied out to a new buffer which becomes the current buffer. The
+  // presumption is that |count| is very large and approximately equal to size()
+  // so not much needs to be copied.
+  char* trade_bytes(size_t count);
+
+private:
+  void try_realloc(size_t newlength);
+
+  char* mBuffer;
+  size_t mSize;
+  size_t mReserved;
+};
+
+#endif // CHROME_BASE_BUFFER_H_
--- a/ipc/chromium/src/base/pickle.cc
+++ b/ipc/chromium/src/base/pickle.cc
@@ -117,20 +117,20 @@ Pickle::Pickle(int header_size)
   DCHECK(header_size <= kPayloadUnit);
   Resize(kPayloadUnit);
   if (!header_) {
     NS_ABORT_OOM(kPayloadUnit);
   }
   header_->payload_size = 0;
 }
 
-Pickle::Pickle(const char* data, int data_len)
+Pickle::Pickle(const char* data, int data_len, Ownership ownership)
     : header_(reinterpret_cast<Header*>(const_cast<char*>(data))),
       header_size_(0),
-      capacity_(kCapacityReadOnly),
+      capacity_(ownership == BORROWS ? kCapacityReadOnly : data_len),
       variable_buffer_offset_(0) {
   if (data_len >= static_cast<int>(sizeof(Header)))
     header_size_ = data_len - header_->payload_size;
 
   if (header_size_ > static_cast<unsigned int>(data_len))
     header_size_ = 0;
 
   if (header_size_ != AlignInt(header_size_))
@@ -634,8 +634,28 @@ const char* Pickle::FindNext(uint32_t he
     return nullptr;
 
   const Header* hdr = reinterpret_cast<const Header*>(start);
   if (length < header_size || length - header_size < hdr->payload_size)
     return nullptr;
 
   return start + header_size + hdr->payload_size;
 }
+
+// static
+uint32_t Pickle::GetLength(uint32_t header_size,
+			   const char* start,
+			   const char* end) {
+  DCHECK(header_size == AlignInt(header_size));
+  DCHECK(header_size <= static_cast<memberAlignmentType>(kPayloadUnit));
+
+  if (end < start)
+    return 0;
+  size_t length = static_cast<size_t>(end - start);
+  if (length < sizeof(Header))
+    return 0;
+
+  const Header* hdr = reinterpret_cast<const Header*>(start);
+  if (length < header_size)
+    return 0;
+
+  return header_size + hdr->payload_size;
+}
--- a/ipc/chromium/src/base/pickle.h
+++ b/ipc/chromium/src/base/pickle.h
@@ -27,31 +27,38 @@
 //
 // The Pickle's data has a header which contains the size of the Pickle's
 // payload.  It can optionally support additional space in the header.  That
 // space is controlled by the header_size parameter passed to the Pickle
 // constructor.
 //
 class Pickle {
  public:
+  enum Ownership {
+    BORROWS,
+    OWNS,
+  };
+
   ~Pickle();
 
   // Initialize a Pickle object using the default header size.
   Pickle();
 
   // Initialize a Pickle object with the specified header size in bytes, which
   // must be greater-than-or-equal-to sizeof(Pickle::Header).  The header size
   // will be rounded up to ensure that the header size is 32bit-aligned.
   explicit Pickle(int header_size);
 
-  // Initializes a Pickle from a const block of data.  The data is not copied;
-  // instead the data is merely referenced by this Pickle.  Only const methods
-  // should be used on the Pickle when initialized this way.  The header
-  // padding size is deduced from the data length.
-  Pickle(const char* data, int data_len);
+  // Initializes a Pickle from a const block of data. If ownership == BORROWS,
+  // the data is not copied; instead the data is merely referenced by this
+  // Pickle. Only const methods should be used on the Pickle when initialized
+  // this way. The header padding size is deduced from the data length.  If
+  // ownership == OWNS, then again no copying takes place. However, the buffer
+  // is writable and will be freed when this Pickle is destroyed.
+  Pickle(const char* data, int data_len, Ownership ownership = BORROWS);
 
   // Initializes a Pickle as a deep copy of another Pickle.
   Pickle(const Pickle& other);
 
   Pickle(Pickle&& other);
 
   // Performs a deep copy.
   Pickle& operator=(const Pickle& other);
@@ -275,16 +282,22 @@ class Pickle {
   }
 
   // Find the end of the pickled data that starts at range_start.  Returns NULL
   // if the entire Pickle is not found in the given data range.
   static const char* FindNext(uint32_t header_size,
                               const char* range_start,
                               const char* range_end);
 
+  // If the given range contains at least header_size bytes, return the length
+  // of the pickled data including the header.
+  static uint32_t GetLength(uint32_t header_size,
+                            const char* range_start,
+                            const char* range_end);
+
   // The allocation granularity of the payload.
   static const int kPayloadUnit;
 
  private:
   Header* header_;
   uint32_t header_size_;
   uint32_t capacity_;
   uint32_t variable_buffer_offset_;
--- a/ipc/chromium/src/chrome/common/child_process_host.cc
+++ b/ipc/chromium/src/chrome/common/child_process_host.cc
@@ -149,23 +149,23 @@ void ChildProcessHost::OnWaitableEventSi
 #endif
 }
 
 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host)
     : host_(host) {
 }
 
 void ChildProcessHost::ListenerHook::OnMessageReceived(
-    const IPC::Message& msg) {
+    IPC::Message&& msg) {
 
   bool msg_is_ok = true;
   bool handled = false;
 
   if (!handled) {
-      host_->OnMessageReceived(msg);
+      host_->OnMessageReceived(mozilla::Move(msg));
   }
 
   if (!msg_is_ok)
     base::KillProcess(host_->handle(), ResultCodes::KILLED_BAD_MESSAGE, false);
 
 }
 
 void ChildProcessHost::ListenerHook::OnChannelConnected(int32_t peer_pid) {
--- a/ipc/chromium/src/chrome/common/child_process_host.h
+++ b/ipc/chromium/src/chrome/common/child_process_host.h
@@ -70,17 +70,17 @@ class ChildProcessHost :
   // Once the subclass gets a handle to the process, it needs to tell
   // ChildProcessHost using this function.
   void SetHandle(base::ProcessHandle handle);
 
   // Notifies us that an instance has been created on this child process.
   void InstanceCreated();
 
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg) { }
+  virtual void OnMessageReceived(IPC::Message&& msg) { }
   virtual void OnChannelConnected(int32_t peer_pid) { }
   virtual void OnChannelError() { }
 
   bool opening_channel() { return opening_channel_; }
   const std::wstring& channel_id() { return channel_id_; }
 
   base::WaitableEvent* GetProcessEvent() { return process_event_.get(); }
 
@@ -97,17 +97,17 @@ class ChildProcessHost :
 
  private:
   // By using an internal class as the IPC::Channel::Listener, we can intercept
   // OnMessageReceived/OnChannelConnected and do our own processing before
   // calling the subclass' implementation.
   class ListenerHook : public IPC::Channel::Listener {
    public:
     explicit ListenerHook(ChildProcessHost* host);
-    virtual void OnMessageReceived(const IPC::Message& msg);
+    virtual void OnMessageReceived(IPC::Message&& msg);
     virtual void OnChannelConnected(int32_t peer_pid);
     virtual void OnChannelError();
     virtual void GetQueuedMessages(std::queue<IPC::Message>& queue);
    private:
     ChildProcessHost* host_;
   };
 
   ListenerHook listener_;
--- a/ipc/chromium/src/chrome/common/child_thread.cc
+++ b/ipc/chromium/src/chrome/common/child_thread.cc
@@ -57,17 +57,17 @@ bool ChildThread::Send(IPC::Message* msg
   if (!channel_.get()) {
     delete msg;
     return false;
   }
 
   return channel_->Send(msg);
 }
 
-void ChildThread::OnMessageReceived(const IPC::Message& msg) {
+void ChildThread::OnMessageReceived(IPC::Message&& msg) {
   if (msg.routing_id() == MSG_ROUTING_CONTROL) {
     OnControlMessageReceived(msg);
   }
 }
 
 ChildThread* ChildThread::current() {
   return ChildProcess::current()->child_thread();
 }
--- a/ipc/chromium/src/chrome/common/child_thread.h
+++ b/ipc/chromium/src/chrome/common/child_thread.h
@@ -53,17 +53,17 @@ class ChildThread : public IPC::Channel:
   IPC::Channel* channel() { return channel_.get(); }
 
   // Thread implementation.
   virtual void Init();
   virtual void CleanUp();
 
  private:
   // IPC::Channel::Listener implementation:
-  virtual void OnMessageReceived(const IPC::Message& msg);
+  virtual void OnMessageReceived(IPC::Message&& msg);
   virtual void OnChannelError();
 
 #ifdef MOZ_NUWA_PROCESS
   static void MarkThread();
 #endif
 
   // The message loop used to run tasks on the thread that started this thread.
   MessageLoop* owner_loop_;
--- a/ipc/chromium/src/chrome/common/ipc_channel.h
+++ b/ipc/chromium/src/chrome/common/ipc_channel.h
@@ -20,17 +20,17 @@ class Channel : public Message::Sender {
 
  public:
   // Implemented by consumers of a Channel to receive messages.
   class Listener {
    public:
     virtual ~Listener() {}
 
     // Called when a message is received.
-    virtual void OnMessageReceived(const Message& message) = 0;
+    virtual void OnMessageReceived(Message&& message) = 0;
 
     // Called when the channel is connected and we have received the internal
     // Hello message from the peer.
     virtual void OnChannelConnected(int32_t peer_pid) {}
 
     // Called when an error is detected that causes the channel to close.
     // This method is not called when a channel is closed normally.
     virtual void OnChannelError() {}
@@ -46,17 +46,20 @@ class Channel : public Message::Sender {
   };
 
   enum {
     // The maximum message size in bytes. Attempting to receive a
     // message of this size or bigger results in a channel error.
     kMaximumMessageSize = 256 * 1024 * 1024,
 
     // Ammount of data to read at once from the pipe.
-    kReadBufferSize = 4 * 1024
+    kReadBufferSize = 4 * 1024,
+
+    // Maximum size of a message that we allow to be copied (rather than moved).
+    kMaxCopySize = 32 * 1024,
   };
 
   // Initialize a Channel.
   //
   // |channel_id| identifies the communication Channel.
   // |mode| specifies whether this Channel is to operate in server mode or
   // client mode.  In server mode, the Channel is responsible for setting up the
   // IPC object, whereas in client mode, the Channel merely connects to the
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.cc
@@ -258,28 +258,17 @@ bool Channel::ChannelImpl::EnqueueHelloM
   }
 
   OutputQueuePush(msg.release());
   return true;
 }
 
 void Channel::ChannelImpl::ClearAndShrinkInputOverflowBuf()
 {
-  // If input_overflow_buf_ has grown, shrink it back to its normal size.
-  static size_t previousCapacityAfterClearing = 0;
-  if (input_overflow_buf_.capacity() > previousCapacityAfterClearing) {
-    // This swap trick is the closest thing C++ has to a guaranteed way
-    // to shrink the capacity of a string.
-    std::string tmp;
-    tmp.reserve(Channel::kReadBufferSize);
-    input_overflow_buf_.swap(tmp);
-    previousCapacityAfterClearing = input_overflow_buf_.capacity();
-  } else {
-    input_overflow_buf_.clear();
-  }
+  input_overflow_buf_.clear();
 }
 
 bool Channel::ChannelImpl::Connect() {
   if (pipe_ == -1) {
     return false;
   }
 
   MessageLoopForIO::current()->WatchFileDescriptor(
@@ -391,19 +380,33 @@ bool Channel::ChannelImpl::ProcessIncomi
       end = p + bytes_read;
     } else {
       if (input_overflow_buf_.size() >
          static_cast<size_t>(kMaximumMessageSize - bytes_read)) {
         ClearAndShrinkInputOverflowBuf();
         CHROMIUM_LOG(ERROR) << "IPC message is too big";
         return false;
       }
+
       input_overflow_buf_.append(input_buf_, bytes_read);
       overflowp = p = input_overflow_buf_.data();
       end = p + input_overflow_buf_.size();
+
+      // If we've received the entire header, then we know the message
+      // length. In that case, reserve enough space to hold the entire
+      // message. This is more efficient than repeatedly enlarging the buffer as
+      // more data comes in.
+      uint32_t length = Message::GetLength(p, end);
+      if (length) {
+        input_overflow_buf_.reserve(length + kReadBufferSize);
+
+        // Recompute these pointers in case the buffer moved.
+        overflowp = p = input_overflow_buf_.data();
+        end = p + input_overflow_buf_.size();
+      }
     }
 
     // A pointer to an array of |num_fds| file descriptors which includes any
     // fds that have spilled over from a previous read.
     const int* fds;
     unsigned num_fds;
     unsigned fds_i = 0;  // the index of the first unused descriptor
 
@@ -418,17 +421,41 @@ bool Channel::ChannelImpl::ProcessIncomi
       fds = &input_overflow_fds_[0];
       num_fds = input_overflow_fds_.size();
     }
 
     while (p < end) {
       const char* message_tail = Message::FindNext(p, end);
       if (message_tail) {
         int len = static_cast<int>(message_tail - p);
-        Message m(p, len);
+        char* buf;
+
+        // The Message |m| allocated below needs to own its data. We can either
+        // copy the data out of the buffer or else steal the buffer and move the
+        // remaining data elsewhere. If len is large enough, we steal. Otherwise
+        // we copy.
+        if (len > kMaxCopySize) {
+          // Since len > kMaxCopySize > kReadBufferSize, we know that we must be
+          // using the overflow buffer. And since we always shift everything to
+          // the left at the end of a read, we must be at the start of the
+          // overflow buffer.
+          MOZ_RELEASE_ASSERT(p == overflowp);
+          buf = input_overflow_buf_.trade_bytes(len);
+
+          // At this point the remaining data is at the front of
+          // input_overflow_buf_. p will get fixed up at the end of the
+          // loop. Set it to null here to make sure no one uses it.
+          p = nullptr;
+          overflowp = message_tail = input_overflow_buf_.data();
+          end = overflowp + input_overflow_buf_.size();
+        } else {
+          buf = (char*)malloc(len);
+          memcpy(buf, p, len);
+        }
+        Message m(buf, len, Message::OWNS);
         if (m.header()->num_fds) {
           // the message has file descriptors
           const char* error = NULL;
           if (m.header()->num_fds > num_fds - fds_i) {
             // the message has been completely received, but we didn't get
             // enough file descriptors.
             error = "Message needs unreceived descriptors";
           }
@@ -487,17 +514,17 @@ bool Channel::ChannelImpl::ProcessIncomi
           listener_->OnChannelConnected(MessageIterator(m).NextInt());
 #if defined(OS_MACOSX)
         } else if (m.routing_id() == MSG_ROUTING_NONE &&
                    m.type() == RECEIVED_FDS_MESSAGE_TYPE) {
           DCHECK(m.fd_cookie() != 0);
           CloseDescriptors(m.fd_cookie());
 #endif
         } else {
-          listener_->OnMessageReceived(m);
+          listener_->OnMessageReceived(mozilla::Move(m));
         }
         p = message_tail;
       } else {
         // Last message is partial.
         break;
       }
     }
     if (end == p) {
--- a/ipc/chromium/src/chrome/common/ipc_channel_posix.h
+++ b/ipc/chromium/src/chrome/common/ipc_channel_posix.h
@@ -9,16 +9,17 @@
 
 #include <sys/socket.h>  // for CMSG macros
 
 #include <queue>
 #include <string>
 #include <vector>
 #include <list>
 
+#include "base/buffer.h"
 #include "base/message_loop.h"
 #include "chrome/common/file_descriptor_set_posix.h"
 
 #include "nsAutoPtr.h"
 
 namespace IPC {
 
 // An implementation of ChannelImpl for POSIX systems that works via
@@ -122,17 +123,17 @@ class Channel::ChannelImpl : public Mess
   // kReadBufferSize / sizeof(int) file descriptors. Since a file descriptor
   // takes sizeof(int) bytes, the control buffer must be
   // Channel::kReadBufferSize bytes. We add kControlBufferSlopBytes bytes
   // for the control header.
   char input_cmsg_buf_[Channel::kReadBufferSize + kControlBufferSlopBytes];
 
   // Large messages that span multiple pipe buffers, get built-up using
   // this buffer.
-  std::string input_overflow_buf_;
+  Buffer input_overflow_buf_;
   std::vector<int> input_overflow_fds_;
 
   // In server-mode, we have to wait for the client to connect before we
   // can begin reading.  We make use of the input_state_ when performing
   // the connect operation in overlapped mode.
   bool waiting_connect_;
 
   // This flag is set when processing incoming messages.  It is used to
--- a/ipc/chromium/src/chrome/common/ipc_channel_win.cc
+++ b/ipc/chromium/src/chrome/common/ipc_channel_win.cc
@@ -345,26 +345,63 @@ bool Channel::ChannelImpl::ProcessIncomi
       p = input_buf_;
       end = p + bytes_read;
     } else {
       if (input_overflow_buf_.size() > (kMaximumMessageSize - bytes_read)) {
         input_overflow_buf_.clear();
         CHROMIUM_LOG(ERROR) << "IPC message is too big";
         return false;
       }
+
       input_overflow_buf_.append(input_buf_, bytes_read);
       p = input_overflow_buf_.data();
       end = p + input_overflow_buf_.size();
+
+      // If we've received the entire header, then we know the message
+      // length. In that case, reserve enough space to hold the entire
+      // message. This is more efficient than repeatedly enlarging the buffer as
+      // more data comes in.
+      uint32_t length = Message::GetLength(p, end);
+      if (length) {
+        input_overflow_buf_.reserve(length + kReadBufferSize);
+
+        // Recompute these pointers in case the buffer moved.
+        p = input_overflow_buf_.data();
+        end = p + input_overflow_buf_.size();
+      }
     }
 
     while (p < end) {
       const char* message_tail = Message::FindNext(p, end);
       if (message_tail) {
         int len = static_cast<int>(message_tail - p);
-        const Message m(p, len);
+        char* buf;
+
+        // The Message |m| allocated below needs to own its data. We can either
+        // copy the data out of the buffer or else steal the buffer and move the
+        // remaining data elsewhere. If len is large enough, we steal. Otherwise
+        // we copy.
+        if (len > kMaxCopySize) {
+          // Since len > kMaxCopySize > kReadBufferSize, we know that we must be
+          // using the overflow buffer. And since we always shift everything to
+          // the left at the end of a read, we must be at the start of the
+          // overflow buffer.
+          buf = input_overflow_buf_.trade_bytes(len);
+
+          // At this point the remaining data is at the front of
+          // input_overflow_buf_. p will get fixed up at the end of the
+          // loop. Set it to null here to make sure no one uses it.
+          p = nullptr;
+          message_tail = input_overflow_buf_.data();
+          end = message_tail + input_overflow_buf_.size();
+        } else {
+          buf = (char*)malloc(len);
+          memcpy(buf, p, len);
+        }
+        Message m(buf, len, Message::OWNS);
 #ifdef IPC_MESSAGE_DEBUG_EXTRA
         DLOG(INFO) << "received message on channel @" << this <<
                       " with type " << m.type();
 #endif
         if (m.routing_id() == MSG_ROUTING_NONE &&
             m.type() == HELLO_MESSAGE_TYPE) {
           // The Hello message contains the process id and must include the
           // shared secret, if we are waiting for it.
@@ -375,17 +412,17 @@ bool Channel::ChannelImpl::ProcessIncomi
             // Something went wrong. Abort connection.
             Close();
             listener_->OnChannelError();
             return false;
           }
           waiting_for_shared_secret_ = false;
           listener_->OnChannelConnected(claimed_pid);
         } else {
-          listener_->OnMessageReceived(m);
+          listener_->OnMessageReceived(mozilla::Move(m));
         }
         p = message_tail;
       } else {
         // Last message is partial.
         break;
       }
     }
     input_overflow_buf_.assign(p, end - p);
--- a/ipc/chromium/src/chrome/common/ipc_channel_win.h
+++ b/ipc/chromium/src/chrome/common/ipc_channel_win.h
@@ -5,16 +5,17 @@
 #ifndef CHROME_COMMON_IPC_CHANNEL_WIN_H_
 #define CHROME_COMMON_IPC_CHANNEL_WIN_H_
 
 #include "chrome/common/ipc_channel.h"
 
 #include <queue>
 #include <string>
 
+#include "base/buffer.h"
 #include "base/message_loop.h"
 #include "mozilla/UniquePtr.h"
 
 class NonThreadSafe;
 
 namespace IPC {
 
 class Channel::ChannelImpl : public MessageLoopForIO::IOHandler {
@@ -81,17 +82,17 @@ class Channel::ChannelImpl : public Mess
   // Messages to be sent are queued here.
   std::queue<Message*> output_queue_;
 
   // We read from the pipe into this buffer
   char input_buf_[Channel::kReadBufferSize];
 
   // Large messages that span multiple pipe buffers, get built-up using
   // this buffer.
-  std::string input_overflow_buf_;
+  Buffer input_overflow_buf_;
 
   // In server-mode, we have to wait for the client to connect before we
   // can begin reading.  We make use of the input_state_ when performing
   // the connect operation in overlapped mode.
   bool waiting_connect_;
 
   // This flag is set when processing incoming messages.  It is used to
   // avoid recursing through ProcessIncomingMessages, which could cause
--- a/ipc/chromium/src/chrome/common/ipc_message.cc
+++ b/ipc/chromium/src/chrome/common/ipc_message.cc
@@ -66,17 +66,19 @@ Message::Message(int32_t routing_id, msg
 #ifdef MOZ_TASK_TRACER
   header()->source_event_id = 0;
   header()->parent_task_id = 0;
   header()->source_event_type = SourceEventType::Unknown;
 #endif
   InitLoggingVariables(aName);
 }
 
-Message::Message(const char* data, int data_len) : Pickle(data, data_len) {
+Message::Message(const char* data, int data_len, Ownership ownership)
+  : Pickle(data, data_len, ownership)
+{
   MOZ_COUNT_CTOR(IPC::Message);
   InitLoggingVariables();
 }
 
 Message::Message(const Message& other) : Pickle(other) {
   MOZ_COUNT_CTOR(IPC::Message);
   InitLoggingVariables(other.name_);
 #if defined(OS_POSIX)
--- a/ipc/chromium/src/chrome/common/ipc_message.h
+++ b/ipc/chromium/src/chrome/common/ipc_message.h
@@ -65,20 +65,22 @@ class Message : public Pickle {
   Message();
 
   // Initialize a message with a user-defined type, priority value, and
   // destination WebView ID.
   Message(int32_t routing_id, msgid_t type, PriorityValue priority,
           MessageCompression compression = COMPRESSION_NONE,
           const char* const name="???");
 
-  // Initializes a message from a const block of data.  The data is not copied;
-  // instead the data is merely referenced by this message.  Only const methods
-  // should be used on the message when initialized this way.
-  Message(const char* data, int data_len);
+  // Initializes a message from a const block of data. If ownership == BORROWS,
+  // the data is not copied; instead the data is merely referenced by this
+  // message. Only const methods should be used on the message when initialized
+  // this way. If ownership == OWNS, then again no copying takes place. However,
+  // the buffer is writable and will be freed when the message is destroyed.
+  Message(const char* data, int data_len, Ownership ownership = BORROWS);
 
   Message(const Message& other);
   Message(Message&& other);
   Message& operator=(const Message& other);
   Message& operator=(Message&& other);
 
   PriorityValue priority() const {
     return static_cast<PriorityValue>(header()->flags & PRIORITY_MASK);
@@ -237,16 +239,22 @@ class Message : public Pickle {
   }
 
   // Find the end of the message data that starts at range_start.  Returns NULL
   // if the entire message is not found in the given data range.
   static const char* FindNext(const char* range_start, const char* range_end) {
     return Pickle::FindNext(sizeof(Header), range_start, range_end);
   }
 
+  // If the given range contains at least header_size bytes, return the length
+  // of the message including the header.
+  static uint32_t GetLength(const char* range_start, const char* range_end) {
+    return Pickle::GetLength(sizeof(Header), range_start, range_end);
+  }
+
 #if defined(OS_POSIX)
   // On POSIX, a message supports reading / writing FileDescriptor objects.
   // This is used to pass a file descriptor to the peer of an IPC channel.
 
   // Add a descriptor to the end of the set. Returns false iff the set is full.
   bool WriteFileDescriptor(const base::FileDescriptor& descriptor);
   // Get a file descriptor from the message. Returns false on error.
   //   iter: a Pickle iterator to the current location in the message.
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -413,19 +413,19 @@ BackgroundParentImpl::RecvPUDPSocketCons
     return false;
   }
   // No principal - This must be from mtransport (WebRTC/ICE) - We'd want
   // to DispatchToMainThread() here, but if we do we must block RecvBind()
   // until Init() gets run.  Since we don't have a principal, and we verify
   // we have a filter, we can safely skip the Dispatch and just invoke Init()
   // to install the filter.
 
-  // For mtransport, this will always be "stun", which doesn't allow outbound packets if
-  // they aren't STUN packets until a STUN response is seen.
-  if (!aFilter.EqualsASCII("stun")) {
+  // For mtransport, this will always be "stun", which doesn't allow outbound
+  // packets if they aren't STUN packets until a STUN response is seen.
+  if (!aFilter.EqualsASCII(NS_NETWORK_SOCKET_FILTER_HANDLER_STUN_SUFFIX)) {
     return false;
   }
 
   IPC::Principal principal;
   if (!static_cast<UDPSocketParent*>(aActor)->Init(principal, aFilter)) {
     MOZ_CRASH("UDPSocketCallback - failed init");
   }
 
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -1135,21 +1135,21 @@ GeckoChildProcessHost::OnChannelConnecte
   {
     MonitorAutoLock lock(mMonitor);
     mProcessState = PROCESS_CONNECTED;
     lock.Notify();
   }
 }
 
 void
-GeckoChildProcessHost::OnMessageReceived(const IPC::Message& aMsg)
+GeckoChildProcessHost::OnMessageReceived(IPC::Message&& aMsg)
 {
   // We never process messages ourself, just save them up for the next
   // listener.
-  mQueue.push(aMsg);
+  mQueue.push(Move(aMsg));
 }
 
 void
 GeckoChildProcessHost::OnChannelError()
 {
   // Update the process state to an error state if we have a channel
   // error before we're connected. This fixes certain failures,
   // but does not address the full range of possible issues described
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -77,17 +77,17 @@ public:
   bool SyncLaunch(StringVector aExtraOpts=StringVector(),
                   int32_t timeoutMs=0,
                   base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
 
   virtual bool PerformAsyncLaunch(StringVector aExtraOpts=StringVector(),
                                   base::ProcessArchitecture aArch=base::GetCurrentProcessArchitecture());
 
   virtual void OnChannelConnected(int32_t peer_pid);
-  virtual void OnMessageReceived(const IPC::Message& aMsg);
+  virtual void OnMessageReceived(IPC::Message&& aMsg);
   virtual void OnChannelError();
   virtual void GetQueuedMessages(std::queue<IPC::Message>& queue);
 
   virtual void InitializeChannel();
 
   virtual bool CanShutdown() { return true; }
 
   virtual void OnWaitableEventSignaled(base::WaitableEvent *event);
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -870,17 +870,17 @@ public:
     MatchingKinds(Message::msgid_t aType, int32_t aRoutingId) :
         mType(aType), mRoutingId(aRoutingId) {}
     bool operator()(const Message &msg) {
         return msg.type() == mType && msg.routing_id() == mRoutingId;
     }
 };
 
 void
-MessageChannel::OnMessageReceivedFromLink(const Message& aMsg)
+MessageChannel::OnMessageReceivedFromLink(Message&& aMsg)
 {
     AssertLinkThread();
     mMonitor->AssertCurrentThreadOwns();
 
     if (MaybeInterceptSpecialIOMessage(aMsg))
         return;
 
     // Regardless of the Interrupt stack, if we're awaiting a sync reply,
@@ -967,17 +967,17 @@ MessageChannel::OnMessageReceivedFromLin
     //
     // (3) We are not waiting on a reply.
     //   - We post a task to the main event loop.
     //
     // Note that, we may notify the main thread even though the monitor is not
     // blocked. This is okay, since we always check for pending events before
     // blocking again.
 
-    mPending.push_back(aMsg);
+    mPending.push_back(Move(aMsg));
 
     if (shouldWakeUp) {
         NotifyWorkerThread();
     }
 
     if (shouldPostTask) {
         if (!compress) {
             // If we compressed away the previous message, we'll re-use
--- a/ipc/glue/MessageChannel.h
+++ b/ipc/glue/MessageChannel.h
@@ -426,17 +426,17 @@ class MessageChannel : HasResultCodes
 
     void OnChannelConnected(int32_t peer_id);
 
     // Tell the IO thread to close the channel and wait for it to ACK.
     void SynchronouslyClose();
 
     bool WasTransactionCanceled(int transaction);
     bool ShouldDeferMessage(const Message& aMsg);
-    void OnMessageReceivedFromLink(const Message& aMsg);
+    void OnMessageReceivedFromLink(Message&& aMsg);
     void OnChannelErrorFromLink();
 
   private:
     // Run on the not current thread.
     void NotifyChannelClosed();
     void NotifyMaybeChannelError();
 
   private:
--- a/ipc/glue/MessageLink.cpp
+++ b/ipc/glue/MessageLink.cpp
@@ -266,28 +266,28 @@ ThreadLink::~ThreadLink()
 }
 
 void
 ThreadLink::EchoMessage(Message *msg)
 {
     mChan->AssertWorkerThread();
     mChan->mMonitor->AssertCurrentThreadOwns();
 
-    mChan->OnMessageReceivedFromLink(*msg);
+    mChan->OnMessageReceivedFromLink(Move(*msg));
     delete msg;
 }
 
 void
 ThreadLink::SendMessage(Message *msg)
 {
     mChan->AssertWorkerThread();
     mChan->mMonitor->AssertCurrentThreadOwns();
 
     if (mTargetChan)
-        mTargetChan->OnMessageReceivedFromLink(*msg);
+        mTargetChan->OnMessageReceivedFromLink(Move(*msg));
     delete msg;
 }
 
 void
 ThreadLink::SendClose()
 {
     mChan->AssertWorkerThread();
     mChan->mMonitor->AssertCurrentThreadOwns();
@@ -317,29 +317,29 @@ ThreadLink::Unsound_NumQueuedMessages() 
     return 0;
 }
 
 //
 // The methods below run in the context of the IO thread
 //
 
 void
-ProcessLink::OnMessageReceived(const Message& msg)
+ProcessLink::OnMessageReceived(Message&& msg)
 {
     AssertIOThread();
     NS_ASSERTION(mChan->mChannelState != ChannelError, "Shouldn't get here!");
     MonitorAutoLock lock(*mChan->mMonitor);
-    mChan->OnMessageReceivedFromLink(msg);
+    mChan->OnMessageReceivedFromLink(Move(msg));
 }
 
 void
 ProcessLink::OnEchoMessage(Message* msg)
 {
     AssertIOThread();
-    OnMessageReceived(*msg);
+    OnMessageReceived(Move(*msg));
     delete msg;
 }
 
 void
 ProcessLink::OnChannelOpened()
 {
     AssertIOThread();
 
@@ -376,17 +376,17 @@ ProcessLink::OnTakeConnectedChannel()
         if (mExistingListener) {
             mExistingListener->GetQueuedMessages(pending);
         }
         lock.Notify();
     }
 
     // Dispatch whatever messages the previous listener had queued up.
     while (!pending.empty()) {
-        OnMessageReceived(pending.front());
+        OnMessageReceived(Move(pending.front()));
         pending.pop();
     }
 }
 
 void
 ProcessLink::OnChannelConnected(int32_t peer_pid)
 {
     AssertIOThread();
--- a/ipc/glue/MessageLink.h
+++ b/ipc/glue/MessageLink.h
@@ -199,17 +199,17 @@ class ProcessLink
     // or a pipe error) the chain will be destroyed and the original listener
     // will again be registered.
     void Open(Transport* aTransport, MessageLoop *aIOLoop, Side aSide);
     
     // Run on the I/O thread, only when using inter-process link.
     // These methods acquire the monitor and forward to the
     // similarly named methods in AsyncChannel below
     // (OnMessageReceivedFromLink(), etc)
-    virtual void OnMessageReceived(const Message& msg) override;
+    virtual void OnMessageReceived(Message&& msg) override;
     virtual void OnChannelConnected(int32_t peer_pid) override;
     virtual void OnChannelError() override;
 
     virtual void EchoMessage(Message *msg) override;
     virtual void SendMessage(Message *msg) override;
     virtual void SendClose() override;
 
     virtual bool Unsound_IsClosed() const override;
--- a/js/public/Initialization.h
+++ b/js/public/Initialization.h
@@ -57,16 +57,24 @@ JS_SetICUMemoryFunctions(JS_ICUAllocFn a
  * It is currently not possible to initialize SpiderMonkey multiple times (that
  * is, calling JS_Init/JSAPI methods/JS_ShutDown in that order, then doing so
  * again).  This restriction may eventually be lifted.
  */
 extern JS_PUBLIC_API(bool)
 JS_Init(void);
 
 /**
+ * A variant of JS_Init. On success it returns nullptr. On failure it returns a
+ * pointer to a string literal that describes how initialization failed, which
+ * can be useful for debugging purposes.
+ */
+extern JS_PUBLIC_API(const char*)
+JS_InitWithFailureDiagnostic(void);
+
+/**
  * Destroy free-standing resources allocated by SpiderMonkey, not associated
  * with any runtime, context, or other structure.
  *
  * This method should be called after all other JSAPI data has been properly
  * cleaned up: every new runtime must have been destroyed, every new context
  * must have been destroyed, and so on.  Calling this method before all other
  * resources have been destroyed has undefined behavior.
  *
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -37,16 +37,35 @@ function IsDetachedBuffer(buffer) {
 
 function GetAttachedArrayBuffer(tarray) {
     var buffer = ViewedArrayBufferIfReified(tarray);
     if (IsDetachedBuffer(buffer))
         ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
     return buffer;
 }
 
+// A function which ensures that the argument is either a typed array or a
+// cross-compartment wrapper for a typed array and that the typed array involved
+// has an attached array buffer.  If one of those conditions doesn't hold (wrong
+// kind of argument, or detached array buffer), an exception is thrown.  The
+// return value is `true` if the argument is a typed array, `false` if it's a
+// cross-compartment wrapper for a typed array.
+function IsTypedArrayEnsuringArrayBuffer(arg) {
+    if (IsObject(arg) && IsTypedArray(arg)) {
+        GetAttachedArrayBuffer(arg);
+        return true;
+    }
+
+    // This is a bit hacky but gets the job done: the first `arg` is used to
+    // test for a wrapped typed array, the second as an argument to
+    // GetAttachedArrayBuffer.
+    callFunction(CallTypedArrayMethodIfWrapped, arg, arg, "GetAttachedArrayBuffer");
+    return false;
+}
+
 // ES6 draft 20150304 %TypedArray%.prototype.copyWithin
 function TypedArrayCopyWithin(target, start, end = undefined) {
     // This function is not generic.
     if (!IsObject(this) || !IsTypedArray(this)) {
         return callFunction(CallTypedArrayMethodIfWrapped, this, target, start, end,
                             "TypedArrayCopyWithin");
     }
 
@@ -117,53 +136,51 @@ function TypedArrayCopyWithin(target, st
 // ES6 draft rev30 (2014/12/24) 22.2.3.6 %TypedArray%.prototype.entries()
 function TypedArrayEntries() {
     // Step 1.
     var O = this;
 
     // We need to be a bit careful here, because in the Xray case we want to
     // create the iterator in our current compartment.
     //
-    // Before doing that, though, we want to check that we have a typed
-    // array and it does not have a detached array buffer.  We do the latter by
-    // just calling GetAttachedArrayBuffer() and letting it throw if there isn't
-    // one.  In the case when we're not sure we have a typed array (e.g. we
-    // might have a cross-compartment wrapper for one), we can go ahead and call
-    // GetAttachedArrayBuffer via CallTypedArrayMethodIfWrapped; that will throw
-    // if we're not actually a wrapped typed array, or if we have a detached
-    // array buffer.
+    // Before doing that, though, we want to check that we have a typed array
+    // and it does not have a detached array buffer.  We do the latter by just
+    // calling GetAttachedArrayBuffer() and letting it throw if there isn't one.
+    // In the case when we're not sure we have a typed array (e.g. we might have
+    // a cross-compartment wrapper for one), we can go ahead and call
+    // GetAttachedArrayBuffer via IsTypedArrayEnsuringArrayBuffer; that will
+    // throw if we're not actually a wrapped typed array, or if we have a
+    // detached array buffer.
 
-    // Step 2-3.
-    if (!IsObject(O) || !IsTypedArray(O)) {
-        // And also step 4-6.
-        callFunction(CallTypedArrayMethodIfWrapped, O, O, "GetAttachedArrayBuffer");
-    } else {
-        // Step 4-6.
-        GetAttachedArrayBuffer(O);
-    }
+    // Step 2-6.
+    IsTypedArrayEnsuringArrayBuffer(O);
 
     // Step 7.
     return CreateArrayIterator(O, ITEM_KIND_KEY_AND_VALUE);
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.7 %TypedArray%.prototype.every(callbackfn[, thisArg]).
 function TypedArrayEvery(callbackfn, thisArg = undefined) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
-                            "TypedArrayEvery");
-    }
-
-    GetAttachedArrayBuffer(this);
-
     // Steps 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Steps 3-5.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.every");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -230,25 +247,29 @@ function TypedArrayFill(value, start = 0
 
 // ES6 draft 32 (2015-02-02) 22.2.3.9 %TypedArray%.prototype.filter(callbackfn[, thisArg])
 function TypedArrayFilter(callbackfn, thisArg = undefined) {
     // Step 1.
     var O = this;
 
     // Steps 2-3.
     // This function is not generic.
-    if (!IsObject(O) || !IsTypedArray(O)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
-                           "TypedArrayFilter");
-    }
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
 
-    GetAttachedArrayBuffer(O);
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
 
     // Step 4.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 5.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.filter");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 6.
@@ -291,29 +312,33 @@ function TypedArrayFilter(callbackfn, th
     }
 
     // Step 18.
     return A;
 }
 
 // ES6 draft rev28 (2014/10/14) 22.2.3.10 %TypedArray%.prototype.find(predicate[, thisArg]).
 function TypedArrayFind(predicate, thisArg = undefined) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, predicate, thisArg,
-                            "TypedArrayFind");
-    }
-
-    GetAttachedArrayBuffer(this);
-
     // Steps 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Steps 3-5.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find");
     if (!IsCallable(predicate))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
 
     // Step 7.
@@ -330,29 +355,33 @@ function TypedArrayFind(predicate, thisA
     }
 
     // Step 10.
     return undefined;
 }
 
 // ES6 draft rev28 (2014/10/14) 22.2.3.11 %TypedArray%.prototype.findIndex(predicate[, thisArg]).
 function TypedArrayFindIndex(predicate, thisArg = undefined) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, predicate, thisArg,
-                            "TypedArrayFindIndex");
-    }
-
-    GetAttachedArrayBuffer(this);
-
     // Steps 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Steps 3-5.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findIndex");
     if (!IsCallable(predicate))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
 
     // Step 7.
@@ -367,29 +396,33 @@ function TypedArrayFindIndex(predicate, 
     }
 
     // Step 10.
     return -1;
 }
 
 // ES6 draft rev31 (2015-01-15) 22.1.3.10 %TypedArray%.prototype.forEach(callbackfn[,thisArg])
 function TypedArrayForEach(callbackfn, thisArg = undefined) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
-                            "TypedArrayForEach");
-    }
-
-    GetAttachedArrayBuffer(this);
-
     // Step 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Step 3-4.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 5.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'TypedArray.prototype.forEach');
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 6.
@@ -511,20 +544,17 @@ function TypedArrayJoin(separator) {
 // ES6 draft (2016/1/11) 22.2.3.15 %TypedArray%.prototype.keys()
 function TypedArrayKeys() {
     // Step 1.
     var O = this;
 
     // See the big comment in TypedArrayEntries for what we're doing here.
 
     // Step 2.
-    if (!IsObject(O) || !IsTypedArray(O))
-        callFunction(CallTypedArrayMethodIfWrapped, O, O, "GetAttachedArrayBuffer");
-    else
-        GetAttachedArrayBuffer(O);
+    IsTypedArrayEnsuringArrayBuffer(O);
 
     // Step 3.
     return CreateArrayIterator(O, ITEM_KIND_KEY);
 }
 
 // ES6 draft rev29 (2014/12/06) 22.2.3.16 %TypedArray%.prototype.lastIndexOf(searchElement [,fromIndex]).
 function TypedArrayLastIndexOf(searchElement, fromIndex = undefined) {
     // This function is not generic.
@@ -564,25 +594,29 @@ function TypedArrayLastIndexOf(searchEle
 
 // ES6 draft rev32 (2015-02-02) 22.2.3.18 %TypedArray%.prototype.map(callbackfn [, thisArg]).
 function TypedArrayMap(callbackfn, thisArg = undefined) {
     // Step 1.
     var O = this;
 
     // Steps 2-3.
     // This function is not generic.
-    if (!IsObject(O) || !IsTypedArray(O)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
-                            "TypedArrayMap");
-    }
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
 
-    GetAttachedArrayBuffer(O);
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
 
     // Step 4.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 5.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, '%TypedArray%.prototype.map');
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 6.
@@ -606,27 +640,33 @@ function TypedArrayMap(callbackfn, thisA
     }
 
     // Step 14.
     return A;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.19 %TypedArray%.prototype.reduce(callbackfn[, initialValue]).
 function TypedArrayReduce(callbackfn/*, initialValue*/) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this))
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduce");
-
-    GetAttachedArrayBuffer(this);
-
     // Steps 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Steps 3-5.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -647,27 +687,33 @@ function TypedArrayReduce(callbackfn/*, 
     }
 
     // Step 12.
     return accumulator;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.20 %TypedArray%.prototype.reduceRight(callbackfn[, initialValue]).
 function TypedArrayReduceRight(callbackfn/*, initialValue*/) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this))
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduceRight");
-
-    GetAttachedArrayBuffer(this);
-
     // Steps 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Steps 3-5.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduceRight");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -908,29 +954,33 @@ function TypedArraySlice(start, end) {
     }
 
     // Step 19.
     return A;
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.25 %TypedArray%.prototype.some(callbackfn[, thisArg]).
 function TypedArraySome(callbackfn, thisArg = undefined) {
-    // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
-                            "TypedArraySome");
-    }
-
-    GetAttachedArrayBuffer(this);
-
     // Steps 1-2.
     var O = this;
 
+    // This function is not generic.
+    // We want to make sure that we have an attached buffer, per spec prose.
+    var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+    // If we got here, `this` is either a typed array or a cross-compartment
+    // wrapper for one.
+
     // Steps 3-5.
-    var len = TypedArrayLength(O);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(O);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+    }
 
     // Step 6.
     if (arguments.length === 0)
         ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.some");
     if (!IsCallable(callbackfn))
         ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
 
     // Step 7.
@@ -981,29 +1031,36 @@ function TypedArrayCompare(x, y) {
     if (Number_isNaN(x) || Number_isNaN(y))
         return Number_isNaN(x) ? 1 : -1;
 
 }
 
 // ES6 draft 20151210 22.2.3.26 %TypedArray%.prototype.sort ( comparefn ).
 function TypedArraySort(comparefn) {
     // This function is not generic.
-    if (!IsObject(this) || !IsTypedArray(this)) {
-        return callFunction(CallTypedArrayMethodIfWrapped, this, comparefn,
-                            "TypedArraySort");
-    }
 
     // Step 1.
     var obj = this;
 
     // Step 2.
-    var buffer = GetAttachedArrayBuffer(obj);
+    var isTypedArray = IsObject(obj) && IsTypedArray(obj);
+
+    var buffer;
+    if (isTypedArray)
+        buffer = GetAttachedArrayBuffer(obj);
+    else
+        buffer = callFunction(CallTypedArrayMethodIfWrapped, obj, obj, "GetAttachedArrayBuffer");
 
     // Step 3.
-    var len = TypedArrayLength(obj);
+    var len;
+    if (isTypedArray) {
+        len = TypedArrayLength(obj);
+    } else {
+        len = callFunction(CallTypedArrayMethodIfWrapped, obj, obj, "TypedArrayLength");
+    }
 
     if (comparefn === undefined) {
         comparefn = TypedArrayCompare;
         // CountingSort doesn't invoke the comparefn
         if (IsUint8TypedArray(obj)) {
             return CountingSort(obj, len, false /* signed */);
         } else if (IsInt8TypedArray(obj)) {
             return CountingSort(obj, len, true /* signed */);
@@ -1013,30 +1070,40 @@ function TypedArraySort(comparefn) {
             return RadixSort(obj, len, 2 /* nbytes */, true /* signed */, false /* floating */, comparefn);
         } else if (IsUint32TypedArray(obj)) {
             return RadixSort(obj, len, 4 /* nbytes */, false /* signed */, false /* floating */, comparefn);
         } else if (IsInt32TypedArray(obj)) {
             return RadixSort(obj, len, 4 /* nbytes */, true /* signed */, false /* floating */, comparefn);
         } else if (IsFloat32TypedArray(obj)) {
             return RadixSort(obj, len, 4 /* nbytes */, true /* signed */, true /* floating */, comparefn);
         }
-        // To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
-        // the user supplied comparefn is wrapped.
-        var wrappedCompareFn = comparefn;
-        comparefn = function(x, y) {
-            // Step a.
-            var v = wrappedCompareFn(x, y);
-            // Step b.
-            if (IsDetachedBuffer(buffer))
-                ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
-            // Step c. is redundant, see:
-            // https://bugzilla.mozilla.org/show_bug.cgi?id=1121937#c36
-            // Step d.
-            return v;
+    }
+
+    // To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
+    // the user supplied comparefn is wrapped.
+    var wrappedCompareFn = comparefn;
+    comparefn = function(x, y) {
+        // Step a.
+        var v = wrappedCompareFn(x, y);
+        // Step b.
+        var bufferDetached;
+        if (isTypedArray) {
+            bufferDetached = IsDetachedBuffer(buffer);
+        } else {
+            // This is totally cheating and only works because we know `this`
+            // and `buffer` are same-compartment".
+            bufferDetached = callFunction(CallTypedArrayMethodIfWrapped, this,
+                                          buffer, "IsDetachedBuffer");
         }
+        if (bufferDetached)
+            ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+        // Step c. is redundant, see:
+        // https://bugzilla.mozilla.org/show_bug.cgi?id=1121937#c36
+        // Step d.
+        return v;
     }
 
     return QuickSort(obj, len, comparefn);
 }
 
 // ES6 draft 20150304 %TypedArray%.prototype.subarray
 function TypedArraySubarray(begin, end) {
     // Step 1.
@@ -1084,25 +1151,17 @@ function TypedArraySubarray(begin, end) 
 }
 
 // ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
 function TypedArrayValues() {
     // Step 1.
     var O = this;
 
     // See the big comment in TypedArrayEntries for what we're doing here.
-
-    // Steps 2-6.
-    if (!IsObject(O) || !IsTypedArray(O)) {
-        // And also steps 4-6.
-        callFunction(CallTypedArrayMethodIfWrapped, O, O, "GetAttachedArrayBuffer");
-    } else {
-        // Steps 4-6.
-        GetAttachedArrayBuffer(O);
-    }
+    IsTypedArrayEnsuringArrayBuffer(O);
 
     // Step 7.
     return CreateArrayIterator(O, ITEM_KIND_VALUE);
 }
 _SetCanonicalName(TypedArrayValues, "values");
 
 // Proposed for ES7:
 // https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md
--- a/js/src/devtools/automation/autospider.sh
+++ b/js/src/devtools/automation/autospider.sh
@@ -112,17 +112,17 @@ elif [ "$OSTYPE" = "linux-gnu" ]; then
     *)
       if [ "$UNAME_M" = "x86_64" ]; then
         USE_64BIT=true
       fi
       ;;
     esac
   fi
 
-  if [ "$UNAME_M" != "arm" ] && [ -n "$AUTOMATION" ]; then
+  if [ -n "$AUTOMATION" ]; then
     export CC=$GCCDIR/bin/gcc
     export CXX=$GCCDIR/bin/g++
     if $USE_64BIT; then
       export LD_LIBRARY_PATH=$GCCDIR/lib64
     else
       export LD_LIBRARY_PATH=$GCCDIR/lib
     fi
   fi
--- a/js/src/devtools/rootAnalysis/build/sixgill.manifest
+++ b/js/src/devtools/rootAnalysis/build/sixgill.manifest
@@ -1,10 +1,10 @@
 [
-{
-"hg_id" : "ec7b7d2442e8",
-"algorithm" : "sha512",
-"digest" : "49627d734df52cb9e7319733da5a6be1812b9373355dc300ee5600b431122570e00d380d50c7c5b5003c462c2c2cb022494b42c4ad00f8eba01c2259cbe6e502",
-"filename" : "sixgill.tar.xz",
-"size" : 2628868,
-"unpack" : true
-}
+   {
+      "hg_id" : "cd93f15a30ce",
+      "algorithm" : "sha512",
+      "digest" : "541eb3842ab6b91bd87223cad7a5e4387ef3e496e5b580c8047b8b586bc7eb69fecf3c9eb8c45a1e0deebb53554f0e8acedfe1b4ca64d93b6d008f3f2eb11389",
+      "filename" : "sixgill.tar.xz",
+      "size" : 2626640,
+      "unpack" : true
+   }
 ]
--- a/js/src/devtools/rootAnalysis/run_complete
+++ b/js/src/devtools/rootAnalysis/run_complete
@@ -245,16 +245,21 @@ sub run_build
             if ($ann_file ne "" && -e $ann_file);
         print CONFIG join(" ", @extra) . "\n";
         close(CONFIG);
 
 	# Tell the wrapper where to find the config
 	$ENV{"XGILL_CONFIG"} = Cwd::abs_path($config_file);
 
         # update the PATH so that the build will see the wrappers.
+        if (exists $ENV{CC}) {
+            $ENV{PATH} = dirname($ENV{CC}) . ":$ENV{PATH}";
+            delete $ENV{CC};
+            delete $ENV{CXX};
+        }
         $ENV{"PATH"} = "$wrap_dir:" . $ENV{"PATH"};
 
         # do the build, cleaning if necessary.
         chdir $build_dir;
         clean_project() if ($do_clean);
         my $exit_status = build_project();
 
         # signal the manager that it's over.
--- a/js/src/vm/DateTime.h
+++ b/js/src/vm/DateTime.h
@@ -114,17 +114,17 @@ class DateTimeInfo
                 continue;
         }
         ~AcquireLock() {
             MOZ_ASSERT(spinLock, "spinlock should have been acquired");
             spinLock = false;
         }
     };
 
-    friend bool ::JS_Init();
+    friend const char* ::JS_InitWithFailureDiagnostic();
 
     // Initialize global date/time tracking state.  This operation occurs
     // during, and is restricted to, SpiderMonkey initialization.
     static void init();
 
   public:
     /*
      * Get the DST offset in milliseconds at a UTC time.  This is usually
--- a/js/src/vm/Initialization.cpp
+++ b/js/src/vm/Initialization.cpp
@@ -54,66 +54,73 @@ CheckMessageParameterCounts()
     // parameters.
 # define MSG_DEF(name, count, exception, format)           \
         MOZ_ASSERT(MessageParameterCount(format) == count);
 # include "js.msg"
 # undef MSG_DEF
 }
 #endif /* DEBUG */
 
-JS_PUBLIC_API(bool)
-JS_Init(void)
+JS_PUBLIC_API(const char*)
+JS_InitWithFailureDiagnostic(void)
 {
     MOZ_ASSERT(libraryInitState == InitState::Uninitialized,
                "must call JS_Init once before any JSAPI operation except "
                "JS_SetICUMemoryFunctions");
     MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
                "how do we have live runtimes before JS_Init?");
 
     PRMJ_NowInit();
 
 #ifdef DEBUG
     CheckMessageParameterCounts();
 #endif
 
     using js::TlsPerThreadData;
     if (!TlsPerThreadData.init())
-        return false;
+        return "JS_InitWithFailureDiagnostic: TlsPerThreadData.init() failed";
 
 #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
     if (!js::oom::InitThreadType())
-        return false;
+        return "JS_InitWithFailureDiagnostic: js::oom::InitThreadType() failed";
     js::oom::SetThreadType(js::oom::THREAD_TYPE_MAIN);
 #endif
 
     js::jit::ExecutableAllocator::initStatic();
 
     if (!js::jit::InitializeIon())
-        return false;
+        return "JS_InitWithFailureDiagnostic: js::jit::InitializeIon() failed";
 
     js::DateTimeInfo::init();
 
 #if EXPOSE_INTL_API
     UErrorCode err = U_ZERO_ERROR;
     u_init(&err);
     if (U_FAILURE(err))
-        return false;
+        return "JS_InitWithFailureDiagnostic: u_init() failed";
 #endif // EXPOSE_INTL_API
 
     if (!js::CreateHelperThreadsState())
-        return false;
+        return "JS_InitWithFailureDiagnostic: js::CreateHelperThreadState() failed";
 
     if (!FutexRuntime::initialize())
-        return false;
+        return "JS_InitWithFailureDiagnostic: FutexRuntime::initialize() failed";
 
     if (!js::gcstats::Statistics::initialize())
-        return false;
+        return "JS_InitWithFailureDiagnostic: js::gcstats::Statistics::initialize() failed";
 
     libraryInitState = InitState::Running;
-    return true;
+    return nullptr;
+}
+
+JS_PUBLIC_API(bool)
+JS_Init(void)
+{
+    const char* failure = JS_InitWithFailureDiagnostic();
+    return !failure;
 }
 
 JS_PUBLIC_API(void)
 JS_ShutDown(void)
 {
     MOZ_ASSERT(libraryInitState == InitState::Running,
                "JS_ShutDown must only be called after JS_Init and can't race with it");
 #ifdef DEBUG
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1064,16 +1064,17 @@ bool
 SavedStacks::saveCurrentStack(JSContext* cx, MutableHandleSavedFrame frame, unsigned maxFrameCount)
 {
     MOZ_ASSERT(initialized());
     MOZ_RELEASE_ASSERT(cx->compartment());
     assertSameCompartment(cx, this);
 
     if (creatingSavedFrame ||
         cx->isExceptionPending() ||
+        !cx->global() ||
         !cx->global()->isStandardClassResolved(JSProto_Object))
     {
         frame.set(nullptr);
         return true;
     }
 
     AutoSPSEntry psuedoFrame(cx->runtime(), "js::SavedStacks::saveCurrentStack");
     FrameIter iter(cx, FrameIter::ALL_CONTEXTS, FrameIter::GO_THROUGH_SAVED);
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -1770,26 +1770,41 @@ js::IsCallSelfHostedNonGenericMethod(Nat
 bool
 js::ReportIncompatibleSelfHostedMethod(JSContext* cx, const CallArgs& args)
 {
     // The contract for this function is the same as CallSelfHostedNonGenericMethod.
     // The normal ReportIncompatible function doesn't work for selfhosted functions,
     // because they always call the different CallXXXMethodIfWrapped methods,
     // which would be reported as the called function instead.
 
-    // Lookup the selfhosted method that was invoked.
+    // Lookup the selfhosted method that was invoked.  But skip over
+    // IsTypedArrayEnsuringArrayBuffer frames, because those are never the
+    // actual self-hosted callee from external code.  We can't just skip
+    // self-hosted things until we find a non-self-hosted one because of cases
+    // like array.sort(somethingSelfHosted), where we want to report the error
+    // in the somethingSelfHosted, not in the sort() call.
     ScriptFrameIter iter(cx);
     MOZ_ASSERT(iter.isFunctionFrame());
 
-    JSAutoByteString funNameBytes;
-    if (const char* funName = GetFunctionNameBytes(cx, iter.callee(cx), &funNameBytes)) {
-        JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
-                             funName, "method", InformalValueTypeName(args.thisv()));
+    while (!iter.done()) {
+        MOZ_ASSERT(iter.callee(cx)->isSelfHostedOrIntrinsic() &&
+                   !iter.callee(cx)->isBoundFunction());
+        JSAutoByteString funNameBytes;
+        const char* funName = GetFunctionNameBytes(cx, iter.callee(cx), &funNameBytes);
+        if (!funName)
+            return false;
+        if (strcmp(funName, "IsTypedArrayEnsuringArrayBuffer") != 0) {
+            JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_METHOD,
+                                 funName, "method", InformalValueTypeName(args.thisv()));
+            return false;
+        }
+        ++iter;
     }
 
+    MOZ_ASSERT_UNREACHABLE("How did we not find a useful self-hosted frame?");
     return false;
 }
 
 // ES6, 25.4.1.6.
 static bool
 intrinsic_EnqueuePromiseJob(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
@@ -1892,19 +1907,21 @@ intrinsic_IsConstructing(JSContext* cx, 
 }
 
 static bool
 intrinsic_ConstructorForTypedArray(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isObject());
-    MOZ_ASSERT(args[0].toObject().is<TypedArrayObject>());
 
     RootedObject object(cx, &args[0].toObject());
+    object = CheckedUnwrap(object);
+    MOZ_ASSERT(object->is<TypedArrayObject>());
+
     JSProtoKey protoKey = StandardProtoKeyOrNull(object);
     MOZ_ASSERT(protoKey);
 
     // While it may seem like an invariant that in any compartment,
     // seeing a typed array object implies that the TypedArray constructor
     // for that type is initialized on the compartment's global, this is not
     // the case. When we construct a typed array given a cross-compartment
     // ArrayBuffer, we put the constructed TypedArray in the same compartment
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -329,21 +329,22 @@ GetScopeForXBLExecution(JSContext* cx, H
     MOZ_RELEASE_ASSERT(!IsInAddonScope(contentScope));
 
     RootedObject global(cx, js::GetGlobalForObjectCrossCompartment(contentScope));
     if (IsInContentXBLScope(contentScope))
         return global;
 
     JSAutoCompartment ac(cx, contentScope);
     XPCWrappedNativeScope* nativeScope = CompartmentPrivate::Get(contentScope)->scope;
+    bool isSystem = nsContentUtils::IsSystemPrincipal(nativeScope->GetPrincipal());
 
     RootedObject scope(cx);
     if (nativeScope->UseContentXBLScope())
         scope = nativeScope->EnsureContentXBLScope(cx);
-    else if (addonId && CompartmentPerAddon())
+    else if (addonId && CompartmentPerAddon() && isSystem)
         scope = nativeScope->EnsureAddonScope(cx, addonId);
     else
         scope = global;
 
     NS_ENSURE_TRUE(scope, nullptr); // See bug 858642.
     scope = js::UncheckedUnwrap(scope);
     JS::ExposeObjectToActiveJS(scope);
     return scope;
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xul
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul
@@ -431,16 +431,57 @@ https://bugzilla.mozilla.org/show_bug.cg
     arraysEqual([...arrayLike.entries()], [...equivalentArray.entries()],
                 \`\${reason}; entries\`);
     arraysEqual([...arrayLike.keys()], [...equivalentArray.keys()],
                 \`\${reason}; keys\`);
     if (arrayLike.values) {
       arraysEqual([...arrayLike.values()], equivalentArray,
                   \`\${reason}; values\`);
     }
+
+    var forEachCopy = [];
+    arrayLike.forEach(function(arg) { forEachCopy.push(arg); });
+    arraysEqual(forEachCopy, equivalentArray, \`\${reason}; forEach copy\`);
+
+    var everyCopy = [];
+    arrayLike.every(function(arg) { everyCopy.push(arg); return true; });
+    arraysEqual(everyCopy, equivalentArray, \`\${reason}; every() copy\`);
+
+    var filterCopy = [];
+    var filterResult = arrayLike.filter(function(arg) {
+      filterCopy.push(arg);
+      return true;
+    });
+    arraysEqual(filterCopy, equivalentArray, \`\${reason}; filter copy\`);
+    arraysEqual([...filterResult], equivalentArray, \`\${reason}; filter result\`);
+
+    var findCopy = [];
+    arrayLike.find(function(arg) { findCopy.push(arg); return false; });
+    arraysEqual(findCopy, equivalentArray, \`\${reason}; find() copy\`);
+
+    var findIndexCopy = [];
+    arrayLike.findIndex(function(arg) { findIndexCopy.push(arg); return false; });
+    arraysEqual(findIndexCopy, equivalentArray, \`\${reason}; findIndex() copy\`);
+
+    var mapCopy = [];
+    var mapResult = arrayLike.map(function(arg) { mapCopy.push(arg); return arg});
+    arraysEqual(mapCopy, equivalentArray, \`\${reason}; map() copy\`);
+    arraysEqual([...mapResult], equivalentArray, \`\${reason}; map() result\`);
+
+    var reduceCopy = [];
+    arrayLike.reduce(function(_, arg) { reduceCopy.push(arg); }, 0);
+    arraysEqual(reduceCopy, equivalentArray, \`\${reason}; reduce() copy\`);
+
+    var reduceRightCopy = [];
+    arrayLike.reduceRight(function(_, arg) { reduceRightCopy.unshift(arg); }, 0);
+    arraysEqual(reduceRightCopy, equivalentArray, \`\${reason}; reduceRight() copy\`);
+
+    var someCopy = [];
+    arrayLike.some(function(arg) { someCopy.push(arg); return false; });
+    arraysEqual(someCopy, equivalentArray, \`\${reason}; some() copy\`);
   }`;
   eval(testArrayIteratorsSource);
 
   function testDate() {
     // toGMTString is handled oddly in the engine. We don't bother to support
     // it over Xrays.
     let propsToSkip = ['toGMTString'];
 
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -3525,22 +3525,16 @@ nsDisplayLayerEventRegions::AddFrame(nsD
     mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox);
   } else if (aFrame->GetType() == nsGkAtoms::objectFrame) {
     // If the frame is a plugin frame and wants to handle wheel events as
     // default action, we should add the frame to dispatch-to-content region.
     nsPluginFrame* pluginFrame = do_QueryFrame(aFrame);
     if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) {
       mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox);
     }
-  } else if (gfxPlatform::GetPlatform()->SupportsApzWheelInput() &&
-             nsLayoutUtils::IsScrollFrameWithSnapping(aFrame->GetParent())) {
-    // If the frame is the inner content of a scrollable frame with snap-points
-    // then we want to handle wheel events for it on the main thread. Add it to
-    // the d-t-c region so that APZ waits for the main thread.
-    mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox);
   }
 
   // Touch action region
 
   uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(aFrame);
   if (touchAction & NS_STYLE_TOUCH_ACTION_NONE) {
     mNoActionRegion.Or(mNoActionRegion, borderBox);
   } else {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -8963,26 +8963,16 @@ nsLayoutUtils::GetSelectionBoundingRect(
     }
     res = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
       accumulator.mResultRect;
   }
 
   return res;
 }
 
-/* static */ bool
-nsLayoutUtils::IsScrollFrameWithSnapping(nsIFrame* aFrame)
-{
-  nsIScrollableFrame* sf = do_QueryFrame(aFrame);
-  if (!sf) {
-    return false;
-  }
-  return sf->IsScrollFrameWithSnapping();
-}
-
 /* static */ nsBlockFrame*
 nsLayoutUtils::GetFloatContainingBlock(nsIFrame* aFrame)
 {
   nsIFrame* ancestor = aFrame->GetParent();
   while (ancestor && !ancestor->IsFloatContainingBlock()) {
     ancestor = ancestor->GetParent();
   }
   MOZ_ASSERT(!ancestor || GetAsBlock(ancestor),
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2788,20 +2788,16 @@ public:
    * Takes a selection, and returns selection's bounding rect which is relative
    * to its root frame.
    *
    * @param aSel      Selection to check
    */
   static nsRect GetSelectionBoundingRect(mozilla::dom::Selection* aSel);
 
   /**
-   * Returns true if the given frame is a scrollframe and it has snap points.
-   */
-  static bool IsScrollFrameWithSnapping(nsIFrame* aFrame);
-  /**
    * Calculate the bounding rect of |aContent|, relative to the origin
    * of the scrolled content of |aRootScrollFrame|.
    * Where the element is contained inside a scrollable subframe, the
    * bounding rect is clipped to the bounds of the subframe.
    */
   static CSSRect GetBoundingContentRect(const nsIContent* aContent,
                                         const nsIScrollableFrame* aRootScrollFrame);
 
--- a/layout/forms/nsListControlFrame.h
+++ b/layout/forms/nsListControlFrame.h
@@ -103,19 +103,16 @@ public:
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const override;
 #endif
 
     // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) override;
   virtual void SetFocus(bool aOn = true, bool aRepaint = false) override;
 
-  virtual bool IsScrollFrameWithSnapping() const override {
-    return false;
-  }
   virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override;
   virtual bool ShouldPropagateComputedBSizeToScrolledContent() const override;
 
     // for accessibility purposes
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() override;
 #endif
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3627,36 +3627,16 @@ static void HandleScrollPref(nsIScrollab
       aValue = NS_STYLE_OVERFLOW_HIDDEN;
       break;
     case nsIScrollable::Scrollbar_Always:
       aValue = NS_STYLE_OVERFLOW_SCROLL;
       break;
   }
 }
 
-bool
-ScrollFrameHelper::IsScrollFrameWithSnapping() const
-{
-  nsPresContext* presContext = mOuter->PresContext();
-  if (!presContext->IsDynamic() &&
-      !(mIsRoot && presContext->HasPaginatedScrolling())) {
-    return false;
-  }
-
-  if (!mIsRoot) {
-    const nsStyleDisplay& display = *mOuter->StyleDisplay();
-    return display.mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE ||
-           display.mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE;
-  } else {
-    const ScrollbarStyles& display = presContext->GetViewportScrollbarStylesOverride();
-    return display.mScrollSnapTypeY != NS_STYLE_SCROLL_SNAP_TYPE_NONE ||
-           display.mScrollSnapTypeX != NS_STYLE_SCROLL_SNAP_TYPE_NONE;
-  }
-}
-
 ScrollbarStyles
 ScrollFrameHelper::GetScrollbarStylesFromFrame() const
 {
   nsPresContext* presContext = mOuter->PresContext();
   if (!presContext->IsDynamic() &&
       !(mIsRoot && presContext->HasPaginatedScrolling())) {
     return ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN);
   }
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -53,17 +53,16 @@ public:
   typedef mozilla::layers::Layer Layer;
 
   class AsyncScroll;
   class AsyncSmoothMSDScroll;
 
   ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot);
   ~ScrollFrameHelper();
 
-  bool IsScrollFrameWithSnapping() const;
   mozilla::ScrollbarStyles GetScrollbarStylesFromFrame() const;
 
   // If a child frame was added or removed on the scrollframe,
   // reload our child frame list.
   // We need this if a scrollbar frame is recreated.
   void ReloadChildFrames();
 
   nsresult CreateAnonymousContent(
@@ -747,19 +746,16 @@ public:
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override;
   virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements,
                                         uint32_t aFilter) override;
 
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const override {
     return mHelper.GetScrolledFrame();
   }
-  virtual bool IsScrollFrameWithSnapping() const override {
-    return mHelper.IsScrollFrameWithSnapping();
-  }
   virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override {
     return mHelper.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const override {
     return mHelper.GetScrollbarVisibility();
   }
   virtual nsMargin GetActualScrollbarSizes() const override {
     return mHelper.GetActualScrollbarSizes();
@@ -1163,19 +1159,16 @@ public:
 
   static void AdjustReflowStateForPrintPreview(nsBoxLayoutState& aState, bool& aSetBack);
   static void AdjustReflowStateBack(nsBoxLayoutState& aState, bool aSetBack);
 
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const override {
     return mHelper.GetScrolledFrame();
   }
-  virtual bool IsScrollFrameWithSnapping() const override {
-    return mHelper.IsScrollFrameWithSnapping();
-  }
   virtual mozilla::ScrollbarStyles GetScrollbarStyles() const override {
     return mHelper.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const override {
     return mHelper.GetScrollbarVisibility();
   }
   virtual nsMargin GetActualScrollbarSizes() const override {
     return mHelper.GetActualScrollbarSizes();
--- a/layout/generic/nsIScrollableFrame.h
+++ b/layout/generic/nsIScrollableFrame.h
@@ -60,18 +60,16 @@ public:
 
   /**
    * Get the styles (NS_STYLE_OVERFLOW_SCROLL, NS_STYLE_OVERFLOW_HIDDEN,
    * or NS_STYLE_OVERFLOW_AUTO) governing the horizontal and vertical
    * scrollbars for this frame.
    */
   virtual mozilla::ScrollbarStyles GetScrollbarStyles() const = 0;
 
-  virtual bool IsScrollFrameWithSnapping() const = 0;
-
   enum { HORIZONTAL = 0x01, VERTICAL = 0x02 };
   /**
    * Return the scrollbars which are visible. It's OK to call this during reflow
    * of the scrolled contents, in which case it will reflect the current
    * assumptions about scrollbar visibility.
    */
   virtual uint32_t GetScrollbarVisibility() const = 0;
   /**
--- a/media/libstagefright/binding/MP4Metadata.cpp
+++ b/media/libstagefright/binding/MP4Metadata.cpp
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "include/MPEG4Extractor.h"
 #include "media/stagefright/DataSource.h"
 #include "media/stagefright/MediaDefs.h"
 #include "media/stagefright/MediaSource.h"
 #include "media/stagefright/MetaData.h"
 #include "mozilla/Logging.h"
-#include "mozilla/SSE.h"
 #include "mozilla/Telemetry.h"
 #include "mp4_demuxer/MoofParser.h"
 #include "mp4_demuxer/MP4Metadata.h"
 
 #include <limits>
 #include <stdint.h>
 #include <vector>
 
@@ -118,30 +117,20 @@ private:
   RefPtr<Stream> mSource;
   mozilla::UniquePtr<mp4parse_state, FreeMP4ParseState> mRustState;
 };
 #endif
 
 MP4Metadata::MP4Metadata(Stream* aSource)
  : mStagefright(MakeUnique<MP4MetadataStagefright>(aSource))
 #ifdef MOZ_RUST_MP4PARSE
+ , mRust(MakeUnique<MP4MetadataRust>(aSource))
  , mReportedTelemetry(false)
 #endif
 {
-  // Rust's i686-pc-windows-msvc target assumes sse2 support.
-  // While we can pass -C target-feature=-sse2 to disable this
-  // in our own code, there's still the problem of the standard
-  // library. To work around this for the small number of users
-  // without SSE2 hardware, avoid calling into rust code.
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=1253202
-#if defined(MOZ_RUST_MP4PARSE)
-  if (mozilla::supports_sse2()) {
-    mRust = MakeUnique<MP4MetadataRust>(aSource);
-  }
-#endif
 }
 
 MP4Metadata::~MP4Metadata()
 {
 }
 
 /*static*/ bool
 MP4Metadata::HasCompleteMetadata(Stream* aSource)
--- a/media/mtransport/build/moz.build
+++ b/media/mtransport/build/moz.build
@@ -11,17 +11,17 @@ EXPORTS.mtransport += [
     '../m_cpp_utils.h',
     '../nricectx.h',
     '../nricemediastream.h',
     '../nriceresolverfake.h',
     '../rlogringbuffer.h',
     '../runnable_utils.h',
     '../sigslot.h',
     '../simpletokenbucket.h',
-    '../stun_udp_socket_filter.h',
+    '../stun_socket_filter.h',
     '../transportflow.h',
     '../transportlayer.h',
     '../transportlayerdtls.h',
     '../transportlayerice.h',
     '../transportlayerlog.h',
     '../transportlayerloopback.h',
     '../transportlayerprsock.h',
 ]
--- a/media/mtransport/common.build
+++ b/media/mtransport/common.build
@@ -10,17 +10,17 @@ mtransport_lcppsrcs = [
     'nr_timer.cpp',
     'nricectx.cpp',
     'nricemediastream.cpp',
     'nriceresolver.cpp',
     'nriceresolverfake.cpp',
     'nrinterfaceprioritizer.cpp',
     'rlogringbuffer.cpp',
     'simpletokenbucket.cpp',
-    'stun_udp_socket_filter.cpp',
+    'stun_socket_filter.cpp',
     'test_nr_socket.cpp',
     'transportflow.cpp',
     'transportlayer.cpp',
     'transportlayerdtls.cpp',
     'transportlayerice.cpp',
     'transportlayerlog.cpp',
     'transportlayerloopback.cpp',
     'transportlayerprsock.cpp',
--- a/media/mtransport/nr_socket_prsock.cpp
+++ b/media/mtransport/nr_socket_prsock.cpp
@@ -108,16 +108,17 @@ nrappkit copyright:
 #include "nsXULAppAPI.h"
 #include "runnable_utils.h"
 #include "mozilla/SyncRunnable.h"
 #include "nsTArray.h"
 #include "mozilla/dom/TCPSocketBinding.h"
 #include "nsITCPSocketCallback.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
+#include "nsISocketFilter.h"
 
 #ifdef XP_WIN
 #include "mozilla/WindowsVersion.h"
 #endif
 
 #if defined(MOZILLA_INTERNAL_API)
 // csi_platform.h deep in nrappkit defines LOG_INFO and LOG_WARNING
 #ifdef LOG_INFO
@@ -1491,17 +1492,17 @@ void NrUdpSocketIpc::create_i(const nsAC
   }
 
   // This can spin the event loop; don't do that with the monitor held
   socketChild->SetBackgroundSpinsEvents();
 
   ReentrantMonitorAutoEnter mon(monitor_);
   if (!socket_child_) {
     socket_child_ = socketChild;
-    socket_child_->SetFilterName(nsCString("stun"));
+    socket_child_->SetFilterName(nsCString(NS_NETWORK_SOCKET_FILTER_HANDLER_STUN_SUFFIX));
   } else {
     socketChild = nullptr;
   }
 
   RefPtr<NrUdpSocketIpcProxy> proxy(new NrUdpSocketIpcProxy);
   rv = proxy->Init(this);
   if (NS_FAILED(rv)) {
     err_ = true;
@@ -1922,16 +1923,18 @@ void NrTcpSocketIpc::connect_i(const nsA
                                const nsACString &local_addr,
                                uint16_t local_port) {
   ASSERT_ON_THREAD(io_thread_);
   mirror_state_ = NR_CONNECTING;
 
   dom::TCPSocketChild* child = new dom::TCPSocketChild(NS_ConvertUTF8toUTF16(remote_addr), remote_port);
   socket_child_ = child;
 
+  socket_child_->SetFilterName(nsCString(NS_NETWORK_SOCKET_FILTER_HANDLER_STUN_SUFFIX));
+
   // XXX remove remote!
   socket_child_->SendWindowlessOpenBind(this,
                                         remote_addr, remote_port,
                                         local_addr, local_port,
                                         /* use ssl */ false);
 }
 
 void NrTcpSocketIpc::write_i(nsAutoPtr<InfallibleTArray<uint8_t>> arr,
rename from media/mtransport/stun_udp_socket_filter.cpp
rename to media/mtransport/stun_socket_filter.cpp
--- a/media/mtransport/stun_udp_socket_filter.cpp
+++ b/media/mtransport/stun_socket_filter.cpp
@@ -7,17 +7,17 @@
 extern "C" {
 #include "nr_api.h"
 #include "transport_addr.h"
 #include "stun.h"
 }
 
 #include "mozilla/Attributes.h"
 #include "mozilla/net/DNS.h"
-#include "stun_udp_socket_filter.h"
+#include "stun_socket_filter.h"
 #include "nr_socket_prsock.h"
 
 namespace {
 
 class NetAddrCompare {
  public:
    bool operator()(const mozilla::net::NetAddr& lhs,
                    const mozilla::net::NetAddr& rhs) const {
@@ -80,25 +80,25 @@ class PendingSTUNRequest {
   }
 
  private:
   const UINT12 id_;
   const mozilla::net::NetAddr net_addr_;
   const bool is_id_set_;
 };
 
-class STUNUDPSocketFilter : public nsIUDPSocketFilter {
+class STUNUDPSocketFilter : public nsISocketFilter {
  public:
   STUNUDPSocketFilter()
     : white_list_(),
       pending_requests_() {}
 
   // Allocated/freed and used on the PBackground IPC thread
   NS_DECL_ISUPPORTS
-  NS_DECL_NSIUDPSOCKETFILTER
+  NS_DECL_NSISOCKETFILTER
 
  private:
   virtual ~STUNUDPSocketFilter() {}
 
   bool filter_incoming_packet(const mozilla::net::NetAddr *remote_addr,
                               const uint8_t *data,
                               uint32_t len);
 
@@ -106,29 +106,29 @@ class STUNUDPSocketFilter : public nsIUD
                               const uint8_t *data,
                               uint32_t len);
 
   std::set<mozilla::net::NetAddr, NetAddrCompare> white_list_;
   std::set<PendingSTUNRequest> pending_requests_;
   std::set<PendingSTUNRequest> response_allowed_;
 };
 
-NS_IMPL_ISUPPORTS(STUNUDPSocketFilter, nsIUDPSocketFilter)
+NS_IMPL_ISUPPORTS(STUNUDPSocketFilter, nsISocketFilter)
 
 NS_IMETHODIMP
 STUNUDPSocketFilter::FilterPacket(const mozilla::net::NetAddr *remote_addr,
                                   const uint8_t *data,
                                   uint32_t len,
                                   int32_t direction,
                                   bool *result) {
   switch (direction) {
-    case nsIUDPSocketFilter::SF_INCOMING:
+    case nsISocketFilter::SF_INCOMING:
       *result = filter_incoming_packet(remote_addr, data, len);
       break;
-    case nsIUDPSocketFilter::SF_OUTGOING:
+    case nsISocketFilter::SF_OUTGOING:
       *result = filter_outgoing_packet(remote_addr, data, len);
       break;
     default:
       MOZ_CRASH("Unknown packet direction");
   }
   return NS_OK;
 }
 
@@ -192,21 +192,168 @@ bool STUNUDPSocketFilter::filter_outgoin
     if (it != response_allowed_.end()) {
       return true;
     }
   }
 
   return false;
 }
 
+class PendingSTUNId {
+ public:
+  explicit PendingSTUNId(const UINT12 &id)
+    : id_(id) {}
+
+  bool operator<(const PendingSTUNId& rhs) const {
+    return memcmp(id_.octet, rhs.id_.octet, sizeof(id_.octet)) < 0;
+  }
+ private:
+  const UINT12 id_;
+};
+
+class STUNTCPSocketFilter : public nsISocketFilter {
+ public:
+  STUNTCPSocketFilter()
+    : white_listed_(false),
+      pending_request_ids_(),
+      response_allowed_ids_() {}
+
+  // Allocated/freed and used on the PBackground IPC thread
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSISOCKETFILTER
+
+ private:
+  virtual ~STUNTCPSocketFilter() {}
+
+  bool filter_incoming_packet(const uint8_t *data,
+                              uint32_t len);
+
+  bool filter_outgoing_packet(const uint8_t *data,
+                              uint32_t len);
+
+  bool white_listed_;
+  std::set<PendingSTUNId> pending_request_ids_;
+  std::set<PendingSTUNId> response_allowed_ids_;
+};
+
+NS_IMPL_ISUPPORTS(STUNTCPSocketFilter, nsISocketFilter)
+
+NS_IMETHODIMP
+STUNTCPSocketFilter::FilterPacket(const mozilla::net::NetAddr *remote_addr,
+                                  const uint8_t *data,
+                                  uint32_t len,
+                                  int32_t direction,
+                                  bool *result) {
+  switch (direction) {
+    case nsISocketFilter::SF_INCOMING:
+      *result = filter_incoming_packet(data, len);
+      break;
+    case nsISocketFilter::SF_OUTGOING:
+      *result = filter_outgoing_packet(data, len);
+      break;
+    default:
+      MOZ_CRASH("Unknown packet direction");
+  }
+  return NS_OK;
+}
+
+bool STUNTCPSocketFilter::filter_incoming_packet(const uint8_t *data, uint32_t len) {
+  // check if white listed already
+  if (white_listed_) {
+    return true;
+  }
+
+  UCHAR* stun = const_cast<uint8_t*>(data);
+  uint32_t length = len;
+  if (!nr_is_stun_message(stun, length)) {
+    stun += 2;
+    length -= 2;
+    if (!nr_is_stun_message(stun, length)) {
+      // Note: the UDP filter lets incoming packets pass, because order of
+      // packets is not guaranteed and the next packet is likely an important
+      // packet for DTLS (which is costly in terms of timing to wait for a
+      // retransmit). This does not apply to TCP with its guaranteed order. But
+      // we still let it pass, because otherwise we would have to buffer bytes
+      // here until the minimum STUN request size of bytes has been received.
+      return true;
+    }
+  }
+
+  const nr_stun_message_header *msg = reinterpret_cast<const nr_stun_message_header*>(stun);
+
+  // If it is a STUN response message and we can match its id with one of the
+  // pending requests, we can add this address into whitelist.
+  if (nr_is_stun_response_message(stun, length)) {
+    std::set<PendingSTUNId>::iterator it =
+      pending_request_ids_.find(PendingSTUNId(msg->id));
+    if (it != pending_request_ids_.end()) {
+      pending_request_ids_.erase(it);
+      white_listed_ = true;
+    }
+  } else {
+    // If it is a STUN message, but not a response message, we add it into
+    // response allowed list and allow outgoing filter to send a response back.
+    response_allowed_ids_.insert(PendingSTUNId(msg->id));
+  }
+
+  return true;
+}
+
+bool STUNTCPSocketFilter::filter_outgoing_packet(const uint8_t *data, uint32_t len) {
+  // check if white listed already
+  if (white_listed_) {
+    return true;
+  }
+
+  UCHAR* stun = const_cast<uint8_t*>(data);
+  uint32_t length = len;
+  if (!nr_is_stun_message(stun, length)) {
+    stun += 2;
+    length -= 2;
+    if (!nr_is_stun_message(stun, length)) {
+      return false;
+    }
+  }
+
+  const nr_stun_message_header *msg = reinterpret_cast<const nr_stun_message_header*>(stun);
+
+  // Check if it is a stun request. If yes, we put it into a pending list and wait for
+  // response packet.
+  if (nr_is_stun_request_message(stun, length)) {
+    pending_request_ids_.insert(PendingSTUNId(msg->id));
+    return true;
+  }
+
+  // If it is a stun response packet, and we had received the request before, we can
+  // allow it packet to pass filter.
+  if (nr_is_stun_response_message(stun, length)) {
+    std::set<PendingSTUNId>::iterator it =
+      response_allowed_ids_.find(PendingSTUNId(msg->id));
+    if (it != response_allowed_ids_.end()) {
+      response_allowed_ids_.erase(it);
+      white_listed_ = true;
+      return true;
+    }
+  }
+
+  return false;
+}
+
 } // anonymous namespace
 
-NS_IMPL_ISUPPORTS(nsStunUDPSocketFilterHandler, nsIUDPSocketFilterHandler)
+NS_IMPL_ISUPPORTS(nsStunUDPSocketFilterHandler, nsISocketFilterHandler)
 
-NS_IMETHODIMP nsStunUDPSocketFilterHandler::NewFilter(nsIUDPSocketFilter **result)
+NS_IMETHODIMP nsStunUDPSocketFilterHandler::NewFilter(nsISocketFilter **result)
 {
-  nsIUDPSocketFilter *ret = new STUNUDPSocketFilter();
-  if (!ret) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsISocketFilter *ret = new STUNUDPSocketFilter();
   NS_ADDREF(*result = ret);
   return NS_OK;
 }
+
+NS_IMPL_ISUPPORTS(nsStunTCPSocketFilterHandler, nsISocketFilterHandler)
+
+NS_IMETHODIMP nsStunTCPSocketFilterHandler::NewFilter(nsISocketFilter **result)
+{
+  nsISocketFilter *ret = new STUNTCPSocketFilter();
+  NS_ADDREF(*result = ret);
+  return NS_OK;
+}
+
rename from media/mtransport/stun_udp_socket_filter.h
rename to media/mtransport/stun_socket_filter.h
--- a/media/mtransport/stun_udp_socket_filter.h
+++ b/media/mtransport/stun_socket_filter.h
@@ -1,24 +1,36 @@
 /* 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 stun_udp_socket_filter_h__
-#define stun_udp_socket_filter_h__
+#ifndef stun_socket_filter_h__
+#define stun_socket_filter_h__
 
-#include "nsIUDPSocketFilter.h"
+#include "nsISocketFilter.h"
 
-#define NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID NS_NETWORK_UDP_SOCKET_FILTER_HANDLER_PREFIX "stun"
 #define NS_STUN_UDP_SOCKET_FILTER_HANDLER_CID { 0x3e43ee93, 0x829e, 0x4ea6, \
       { 0xa3, 0x4e, 0x62, 0xd9, 0xe4, 0xc9, 0xf9, 0x93 } };
 
-class nsStunUDPSocketFilterHandler : public nsIUDPSocketFilterHandler {
+class nsStunUDPSocketFilterHandler : public nsISocketFilterHandler {
 public:
   // Threadsafe because we create off-main-thread, but destroy on MainThread
   // via FreeFactoryEntries()
   NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSIUDPSOCKETFILTERHANDLER
+  NS_DECL_NSISOCKETFILTERHANDLER
 private:
   virtual ~nsStunUDPSocketFilterHandler() {}
 };
 
+#define NS_STUN_TCP_SOCKET_FILTER_HANDLER_CID { 0x9fea635a, 0x2fc2, 0x4d08, \
+  { 0x97, 0x21, 0xd2, 0x38, 0xd3, 0xf5, 0x2f, 0x92 } };
 
-#endif // stun_udp_socket_filter_h__
+class nsStunTCPSocketFilterHandler : public nsISocketFilterHandler {
+public:
+  // Threadsafe because we create off-main-thread, but destroy on MainThread