merge fx-team to m-c
authorWes Kocher <wkocher@mozilla.com>
Fri, 02 May 2014 22:53:59 -0700
changeset 181836 bdf3bcd18660b30a2d486680315904c5d2e492f9
parent 181830 01bcda055d36d4ae6ee75e2c5fd92ace027b6eab (diff)
parent 181835 62ead59d3f19b1ccceda9e1c41cb918f4e3fd836 (current diff)
child 181837 8d591a3f6feadb1723a5e864361ad2ca6e71e6ee
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
milestone32.0a1
merge fx-team to m-c
browser/themes/linux/devtools/alerticon-warning.png
browser/themes/linux/devtools/arrow-e.png
browser/themes/linux/devtools/background-noise-toolbar.png
browser/themes/linux/devtools/command-console.png
browser/themes/linux/devtools/commandline-icon.png
browser/themes/linux/devtools/commandline.png
browser/themes/linux/devtools/dropmarker.png
browser/themes/linux/devtools/editor-breakpoint.png
browser/themes/linux/devtools/editor-debug-location.png
browser/themes/linux/devtools/editor-error.png
browser/themes/linux/devtools/noise.png
browser/themes/linux/devtools/option-icon.png
browser/themes/linux/devtools/profiler-stopwatch.png
browser/themes/linux/devtools/responsive-background.png
browser/themes/linux/devtools/responsive-horizontal-resizer.png
browser/themes/linux/devtools/responsive-se-resizer.png
browser/themes/linux/devtools/responsive-vertical-resizer.png
browser/themes/linux/devtools/toggle-tools.png
browser/themes/linux/devtools/tracer-icon.png
browser/themes/linux/devtools/tracer-icon@2x.png
browser/themes/linux/devtools/webconsole.png
browser/themes/osx/devtools/alerticon-warning.png
browser/themes/osx/devtools/arrow-e.png
browser/themes/osx/devtools/background-noise-toolbar.png
browser/themes/osx/devtools/command-console.png
browser/themes/osx/devtools/commandline-icon.png
browser/themes/osx/devtools/commandline.png
browser/themes/osx/devtools/dropmarker.png
browser/themes/osx/devtools/editor-breakpoint.png
browser/themes/osx/devtools/editor-debug-location.png
browser/themes/osx/devtools/editor-error.png
browser/themes/osx/devtools/noise.png
browser/themes/osx/devtools/option-icon.png
browser/themes/osx/devtools/profiler-stopwatch.png
browser/themes/osx/devtools/responsive-background.png
browser/themes/osx/devtools/responsive-horizontal-resizer.png
browser/themes/osx/devtools/responsive-se-resizer.png
browser/themes/osx/devtools/responsive-vertical-resizer.png
browser/themes/osx/devtools/toggle-tools.png
browser/themes/osx/devtools/tracer-icon.png
browser/themes/osx/devtools/tracer-icon@2x.png
browser/themes/osx/devtools/webconsole.png
browser/themes/windows/devtools/alerticon-warning.png
browser/themes/windows/devtools/arrow-e.png
browser/themes/windows/devtools/background-noise-toolbar.png
browser/themes/windows/devtools/command-console.png
browser/themes/windows/devtools/commandline-icon.png
browser/themes/windows/devtools/commandline.png
browser/themes/windows/devtools/dropmarker.png
browser/themes/windows/devtools/editor-breakpoint.png
browser/themes/windows/devtools/editor-debug-location.png
browser/themes/windows/devtools/editor-error.png
browser/themes/windows/devtools/noise.png
browser/themes/windows/devtools/option-icon.png
browser/themes/windows/devtools/profiler-stopwatch.png
browser/themes/windows/devtools/responsive-background.png
browser/themes/windows/devtools/responsive-horizontal-resizer.png
browser/themes/windows/devtools/responsive-se-resizer.png
browser/themes/windows/devtools/responsive-vertical-resizer.png
browser/themes/windows/devtools/toggle-tools.png
browser/themes/windows/devtools/tracer-icon.png
browser/themes/windows/devtools/tracer-icon@2x.png
browser/themes/windows/devtools/webconsole.png
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d5800c36b2d5822fc3fe1899b9280401de466e1e"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e6383e6e785cc3ea237e902beb1092f9aa88e29d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,24 +10,24 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="d5800c36b2d5822fc3fe1899b9280401de466e1e"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -13,20 +13,20 @@
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e6383e6e785cc3ea237e902beb1092f9aa88e29d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "a328570f9becbe7f3f56057cdece95e508bbed1f", 
+    "revision": "557d2a3432f051075e8abf16adb649ad6c08ce00", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -14,22 +14,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="575fdbf046e966a5915b1f1e800e5d6ad0ea14c0"/>
   <project name="platform/development" path="development" revision="b1025ec93beeb480caaf3049d171283c3846461d"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="e6383e6e785cc3ea237e902beb1092f9aa88e29d">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="2a165bebfa19b11b697837409f9550dd2917c46c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="f603a1ed83fa9f17ea91795d6bc7a49cfa7b4aef"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="bd97f1cfe543964baa2bb1ea0ddafa32a9c53c23"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="a054c7385854b0e71b8d3071a465b9bc21581ee0"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="6ed3174842e9f7490478cd38502dcfa0b39158c5"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1536,8 +1536,12 @@ pref("browser.translation.detectLanguage
 // Telemetry experiments settings.
 pref("experiments.enabled", true);
 pref("experiments.manifest.fetchIntervalSeconds", 86400);
 pref("experiments.manifest.uri", "https://telemetry-experiment.cdn.mozilla.net/manifest/v1/firefox/%VERSION%/%CHANNEL%");
 pref("experiments.manifest.certs.1.commonName", "*.cdn.mozilla.net");
 pref("experiments.manifest.certs.1.issuerName", "CN=Cybertrust Public SureServer SV CA,O=Cybertrust Inc");
 // Whether experiments are supported by the current application profile.
 pref("experiments.supported", true);
+
+
+// Temporarily turn the new http cache v2 on for Desktop Firefox only
+pref("browser.cache.use_new_backend_temp", true);
--- a/content/canvas/public/DocumentRendererParent.h
+++ b/content/canvas/public/DocumentRendererParent.h
@@ -21,18 +21,20 @@ public:
     DocumentRendererParent();
     virtual ~DocumentRendererParent();
 
     void SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas,
 			  gfxContext* ctx);
     void DrawToCanvas(const nsIntSize& renderedSize,
 		      const nsCString& aData);
 
+    virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
     virtual bool Recv__delete__(const nsIntSize& renderedSize,
-                                const nsCString& data);
+                                const nsCString& data) MOZ_OVERRIDE;
 
 private:
     nsCOMPtr<nsICanvasRenderingContextInternal> mCanvas;
     nsRefPtr<gfxContext> mCanvasContext;
 
     DISALLOW_EVIL_CONSTRUCTORS(DocumentRendererParent);
 };
 
--- a/content/canvas/src/DocumentRendererParent.cpp
+++ b/content/canvas/src/DocumentRendererParent.cpp
@@ -43,15 +43,21 @@ void DocumentRendererParent::DrawToCanva
     // get rid of the pattern surface ref, because aData is very
     // likely to go away shortly
     mCanvasContext->SetColor(gfxRGBA(1,1,1,1));
 
     gfxRect damageRect = mCanvasContext->UserToDevice(rect);
     mCanvas->Redraw(damageRect);
 }
 
+void
+DocumentRendererParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005139
+}
+
 bool
 DocumentRendererParent::Recv__delete__(const nsIntSize& renderedSize,
                                        const nsCString& data)
 {
     DrawToCanvas(renderedSize, data);
     return true;
 }
--- a/content/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
+++ b/content/media/webspeech/synth/ipc/SpeechSynthesisParent.cpp
@@ -13,16 +13,22 @@ SpeechSynthesisParent::SpeechSynthesisPa
   MOZ_COUNT_CTOR(SpeechSynthesisParent);
 }
 
 SpeechSynthesisParent::~SpeechSynthesisParent()
 {
   MOZ_COUNT_DTOR(SpeechSynthesisParent);
 }
 
+void
+SpeechSynthesisParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005141
+}
+
 bool
 SpeechSynthesisParent::RecvReadVoiceList(InfallibleTArray<RemoteVoice>* aVoices,
                                          InfallibleTArray<nsString>* aDefaults)
 {
   nsSynthVoiceRegistry::GetInstance()->SendVoices(aVoices, aDefaults);
   return true;
 }
 
@@ -76,16 +82,22 @@ SpeechSynthesisRequestParent::~SpeechSyn
 {
   if (mTask && mTask->mActor) {
     mTask->mActor = nullptr;
   }
 
   MOZ_COUNT_DTOR(SpeechSynthesisRequestParent);
 }
 
+void
+SpeechSynthesisRequestParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005141
+}
+
 bool
 SpeechSynthesisRequestParent::RecvPause()
 {
   MOZ_ASSERT(mTask);
   mTask->Pause();
   return true;
 }
 
--- a/content/media/webspeech/synth/ipc/SpeechSynthesisParent.h
+++ b/content/media/webspeech/synth/ipc/SpeechSynthesisParent.h
@@ -17,16 +17,18 @@ class SpeechTaskParent;
 class SpeechSynthesisRequestParent;
 
 class SpeechSynthesisParent : public PSpeechSynthesisParent
 {
   friend class ContentParent;
   friend class SpeechSynthesisRequestParent;
 
 public:
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   bool RecvReadVoiceList(InfallibleTArray<RemoteVoice>* aVoices,
                          InfallibleTArray<nsString>* aDefaults) MOZ_OVERRIDE;
 
 protected:
   SpeechSynthesisParent();
   virtual ~SpeechSynthesisParent();
   PSpeechSynthesisRequestParent* AllocPSpeechSynthesisRequestParent(const nsString& aText,
                                                                     const nsString& aLang,
@@ -52,16 +54,18 @@ class SpeechSynthesisRequestParent : pub
 public:
   SpeechSynthesisRequestParent(SpeechTaskParent* aTask);
   virtual ~SpeechSynthesisRequestParent();
 
   nsRefPtr<SpeechTaskParent> mTask;
 
 protected:
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool RecvPause() MOZ_OVERRIDE;
 
   virtual bool RecvResume() MOZ_OVERRIDE;
 
   virtual bool RecvCancel() MOZ_OVERRIDE;
 };
 
 class SpeechTaskParent : public nsSpeechTask
--- a/dom/browser-element/BrowserElementPanning.js
+++ b/dom/browser-element/BrowserElementPanning.js
@@ -45,32 +45,32 @@ const ContentPanning = {
     addMessageListener("Gesture:DoubleTap", this._recvDoubleTap.bind(this));
     addEventListener("visibilitychange", this._handleVisibilityChange.bind(this));
     kObservedEvents.forEach((topic) => {
       Services.obs.addObserver(this, topic, false);
     });
   },
 
   _setupListenersForPanning: function cp_setupListenersForPanning() {
-    var events;
-    try {
-      content.document.createEvent('TouchEvent');
+    let events;
+
+    if (content.TouchEvent) {
       events = ['touchstart', 'touchend', 'touchmove'];
       this.watchedEventsType = 'touch';
 #ifdef MOZ_WIDGET_GONK
       // The gonk widget backend does not deliver mouse events per
       // spec.  Third-party content isn't exposed to this behavior,
       // but that behavior creates some extra work for us here.
       let appInfo = Cc["@mozilla.org/xre/app-info;1"];
       let isParentProcess =
         !appInfo || appInfo.getService(Ci.nsIXULRuntime)
                            .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
       this.hybridEvents = isParentProcess;
 #endif
-    } catch(e) {
+    } else {
       // Touch events aren't supported, so fall back on mouse.
       events = ['mousedown', 'mouseup', 'mousemove'];
       this.watchedEventsType = 'mouse';
     }
 
     let els = Cc["@mozilla.org/eventlistenerservice;1"]
                 .getService(Ci.nsIEventListenerService);
 
--- a/dom/fmradio/ipc/FMRadioParent.cpp
+++ b/dom/fmradio/ipc/FMRadioParent.cpp
@@ -20,16 +20,22 @@ FMRadioParent::FMRadioParent()
 
 FMRadioParent::~FMRadioParent()
 {
   MOZ_COUNT_DTOR(FMRadioParent);
 
   IFMRadioService::Singleton()->RemoveObserver(this);
 }
 
+void
+FMRadioParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005146
+}
+
 bool
 FMRadioParent::RecvGetStatusInfo(StatusInfo* aStatusInfo)
 {
   aStatusInfo->enabled() = IFMRadioService::Singleton()->IsEnabled();
   aStatusInfo->frequency() = IFMRadioService::Singleton()->GetFrequency();
   aStatusInfo->upperBound() =
     IFMRadioService::Singleton()->GetFrequencyUpperBound();
   aStatusInfo->lowerBound() =
--- a/dom/fmradio/ipc/FMRadioParent.h
+++ b/dom/fmradio/ipc/FMRadioParent.h
@@ -17,16 +17,19 @@ class PFMRadioRequestParent;
 
 class FMRadioParent MOZ_FINAL : public PFMRadioParent
                               , public FMRadioEventObserver
 {
 public:
   FMRadioParent();
   ~FMRadioParent();
 
+  virtual void
+  ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool
   RecvGetStatusInfo(StatusInfo* aStatusInfo) MOZ_OVERRIDE;
 
   virtual PFMRadioRequestParent*
   AllocPFMRadioRequestParent(const FMRadioRequestArgs& aArgs) MOZ_OVERRIDE;
 
   virtual bool
   DeallocPFMRadioRequestParent(PFMRadioRequestParent* aActor) MOZ_OVERRIDE;
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -2214,16 +2214,22 @@ IndexedDBDeleteDatabaseRequestParent::Ha
 
   if (!Send__delete__(this, mOpenRequest->GetErrorCode())) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
+void
+IndexedDBDeleteDatabaseRequestParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005149
+}
+
 nsresult
 IndexedDBDeleteDatabaseRequestParent::SetOpenRequest(
                                                  IDBOpenDBRequest* aOpenRequest)
 {
   MOZ_ASSERT(aOpenRequest);
   MOZ_ASSERT(!mOpenRequest);
 
   EventTarget* target = static_cast<EventTarget*>(aOpenRequest);
--- a/dom/indexedDB/ipc/IndexedDBParent.h
+++ b/dom/indexedDB/ipc/IndexedDBParent.h
@@ -858,16 +858,18 @@ class IndexedDBDeleteDatabaseRequestPare
 public:
   nsresult
   HandleEvent(nsIDOMEvent* aEvent);
 
 protected:
   IndexedDBDeleteDatabaseRequestParent(IDBFactory* aFactory);
   virtual ~IndexedDBDeleteDatabaseRequestParent();
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   nsresult
   SetOpenRequest(IDBOpenDBRequest* aOpenRequest);
 
   bool
   IsDisconnected() const
   {
     return static_cast<IndexedDBParent*>(Manager())->IsDisconnected();
   }
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -469,16 +469,19 @@ public:
     MOZ_ASSERT(aRemoteStream);
   }
 
   InputStreamParent()
   {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
+protected:
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
 private:
   // This method is only called by the IPDL message machinery.
   virtual bool
   Recv__delete__(const InputStreamParams& aParams,
                  const OptionalFileDescriptorSet& aFDs) MOZ_OVERRIDE;
 };
 
 nsDOMFileBase*
@@ -2155,16 +2158,22 @@ InputStreamChild::Recv__delete__(const I
   if (!stream) {
     return false;
   }
 
   mRemoteStream->SetStream(stream);
   return true;
 }
 
+void
+InputStreamParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005150
+}
+
 bool
 InputStreamParent::Recv__delete__(const InputStreamParams& aParams,
                                   const OptionalFileDescriptorSet& aFDs)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mRemoteStream);
 
   if (aFDs.type() != OptionalFileDescriptorSet::Tvoid_t) {
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -304,29 +304,37 @@ namespace dom {
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
 
 class MemoryReportRequestParent : public PMemoryReportRequestParent
 {
 public:
     MemoryReportRequestParent();
     virtual ~MemoryReportRequestParent();
 
+    virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
     virtual bool Recv__delete__(const uint32_t& generation, const InfallibleTArray<MemoryReport>& report);
 private:
     ContentParent* Owner()
     {
         return static_cast<ContentParent*>(Manager());
     }
 };
 
 MemoryReportRequestParent::MemoryReportRequestParent()
 {
     MOZ_COUNT_CTOR(MemoryReportRequestParent);
 }
 
+void
+MemoryReportRequestParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005154
+}
+
 bool
 MemoryReportRequestParent::Recv__delete__(const uint32_t& generation, const InfallibleTArray<MemoryReport>& childReports)
 {
     nsRefPtr<nsMemoryReporterManager> mgr =
         nsMemoryReporterManager::GetOrCreate();
     if (mgr) {
         mgr->HandleChildReports(generation, childReports);
     }
--- a/dom/ipc/CrashReporterParent.cpp
+++ b/dom/ipc/CrashReporterParent.cpp
@@ -21,16 +21,22 @@ void
 CrashReporterParent::AnnotateCrashReport(const nsCString& key,
                                          const nsCString& data)
 {
 #ifdef MOZ_CRASHREPORTER
     mNotes.Put(key, data);
 #endif
 }
 
+void
+CrashReporterParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005155
+}
+
 bool
 CrashReporterParent::RecvAppendAppNotes(const nsCString& data)
 {
     mAppNotes.Append(data);
     return true;
 }
 
 mozilla::ipc::IProtocol*
--- a/dom/ipc/CrashReporterParent.h
+++ b/dom/ipc/CrashReporterParent.h
@@ -72,16 +72,18 @@ public:
   const nsString& ChildDumpID() {
     return mChildDumpID;
   }
 
   void
   AnnotateCrashReport(const nsCString& key, const nsCString& data);
 
  protected:
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool
     RecvAnnotateCrashReport(const nsCString& key, const nsCString& data) MOZ_OVERRIDE {
     AnnotateCrashReport(key, data);
     return true;
   }
   virtual bool
     RecvAppendAppNotes(const nsCString& data) MOZ_OVERRIDE;
   virtual mozilla::ipc::IProtocol*
--- a/dom/ipc/FileDescriptorSetParent.cpp
+++ b/dom/ipc/FileDescriptorSetParent.cpp
@@ -22,16 +22,22 @@ FileDescriptorSetParent::~FileDescriptor
 void
 FileDescriptorSetParent::ForgetFileDescriptors(
                                      nsTArray<FileDescriptor>& aFileDescriptors)
 {
   aFileDescriptors.Clear();
   mFileDescriptors.SwapElements(aFileDescriptors);
 }
 
+void
+FileDescriptorSetParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005157
+}
+
 bool
 FileDescriptorSetParent::RecvAddFileDescriptor(
                                           const FileDescriptor& aFileDescriptor)
 {
   mFileDescriptors.AppendElement(aFileDescriptor);
   return true;
 }
 
--- a/dom/ipc/FileDescriptorSetParent.h
+++ b/dom/ipc/FileDescriptorSetParent.h
@@ -31,16 +31,18 @@ public:
 
   void
   ForgetFileDescriptors(nsTArray<FileDescriptor>& aFileDescriptors);
 
 private:
   FileDescriptorSetParent(const FileDescriptor& aFileDescriptor);
   ~FileDescriptorSetParent();
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool
   RecvAddFileDescriptor(const FileDescriptor& aFileDescriptor) MOZ_OVERRIDE;
 
   nsTArray<FileDescriptor> mFileDescriptors;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/plugins/ipc/BrowserStreamParent.cpp
+++ b/dom/plugins/ipc/BrowserStreamParent.cpp
@@ -25,16 +25,22 @@ BrowserStreamParent::BrowserStreamParent
 {
   mStream->pdata = static_cast<AStream*>(this);
 }
 
 BrowserStreamParent::~BrowserStreamParent()
 {
 }
 
+void
+BrowserStreamParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005159
+}
+
 bool
 BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges,
                                            NPError* result)
 {
   PLUGIN_LOG_DEBUG_FUNCTION;
 
   switch (mState) {
   case ALIVE:
--- a/dom/plugins/ipc/BrowserStreamParent.h
+++ b/dom/plugins/ipc/BrowserStreamParent.h
@@ -21,16 +21,18 @@ class BrowserStreamParent : public PBrow
 
 public:
   BrowserStreamParent(PluginInstanceParent* npp,
                       NPStream* stream);
   virtual ~BrowserStreamParent();
 
   virtual bool IsBrowserStream() MOZ_OVERRIDE { return true; }
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool AnswerNPN_RequestRead(const IPCByteRanges& ranges,
                                      NPError* result) MOZ_OVERRIDE;
 
   virtual bool RecvNPN_DestroyStream(const NPReason& reason) MOZ_OVERRIDE;
 
   virtual bool RecvStreamDestroyed() MOZ_OVERRIDE;
 
   int32_t WriteReady();
--- a/dom/plugins/ipc/PluginIdentifierParent.cpp
+++ b/dom/plugins/ipc/PluginIdentifierParent.cpp
@@ -12,16 +12,22 @@
 #include "nsCxPusher.h"
 #include "mozilla/unused.h"
 
 using namespace mozilla::plugins::parent;
 
 namespace mozilla {
 namespace plugins {
 
+void
+PluginIdentifierParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005161
+}
+
 bool
 PluginIdentifierParent::RecvRetain()
 {
   mTemporaryRefs = 0;
 
   // Intern the jsid if necessary.
   AutoSafeJSContext cx;
   JS::Rooted<jsid> id(cx, NPIdentifierToJSId(mIdentifier));
--- a/dom/plugins/ipc/PluginIdentifierParent.h
+++ b/dom/plugins/ipc/PluginIdentifierParent.h
@@ -59,16 +59,18 @@ protected:
     MOZ_COUNT_CTOR(PluginIdentifierParent);
   }
 
   virtual ~PluginIdentifierParent()
   {
     MOZ_COUNT_DTOR(PluginIdentifierParent);
   }
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool RecvRetain() MOZ_OVERRIDE;
 
   void AddTemporaryRef() {
     mTemporaryRefs++;
   }
 
   /**
    * @returns true if the last temporary reference was removed.
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -51,16 +51,22 @@ extern const wchar_t* kFlashFullscreenCl
 #elif defined(XP_MACOSX)
 #include <ApplicationServices/ApplicationServices.h>
 #endif // defined(XP_MACOSX)
 
 using namespace mozilla::plugins;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 
+void
+StreamNotifyParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005162
+}
+
 bool
 StreamNotifyParent::RecvRedirectNotifyResponse(const bool& allow)
 {
   PluginInstanceParent* instance = static_cast<PluginInstanceParent*>(Manager());
   instance->mNPNIface->urlredirectresponse(instance->mNPP, this, static_cast<NPBool>(allow));
   return true;
 }
 
--- a/dom/plugins/ipc/PluginScriptableObjectParent.cpp
+++ b/dom/plugins/ipc/PluginScriptableObjectParent.cpp
@@ -638,16 +638,22 @@ PluginScriptableObjectParent::DropNPObje
   NS_ASSERTION(instance, "Must have an instance!");
 
   instance->UnregisterNPObject(mObject);
   mObject = nullptr;
 
   unused << SendUnprotect();
 }
 
+void
+PluginScriptableObjectParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005163
+}
+
 bool
 PluginScriptableObjectParent::AnswerHasMethod(PPluginIdentifierParent* aId,
                                               bool* aHasMethod)
 {
   if (!mObject) {
     NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
     *aHasMethod = false;
     return true;
--- a/dom/plugins/ipc/PluginScriptableObjectParent.h
+++ b/dom/plugins/ipc/PluginScriptableObjectParent.h
@@ -40,16 +40,19 @@ public:
   virtual ~PluginScriptableObjectParent();
 
   void
   InitializeProxy();
 
   void
   InitializeLocal(NPObject* aObject);
 
+  virtual void
+  ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool
   AnswerHasMethod(PPluginIdentifierParent* aId,
                   bool* aHasMethod) MOZ_OVERRIDE;
 
   virtual bool
   AnswerInvoke(PPluginIdentifierParent* aId,
                const InfallibleTArray<Variant>& aArgs,
                Variant* aResult,
--- a/dom/plugins/ipc/PluginStreamParent.cpp
+++ b/dom/plugins/ipc/PluginStreamParent.cpp
@@ -21,16 +21,22 @@ PluginStreamParent::PluginStreamParent(P
                                             NullableStringGet(target),
                                             &mStream);
   if (*result == NPERR_NO_ERROR)
     mStream->pdata = static_cast<AStream*>(this);
   else
     mStream = nullptr;
 }
 
+void
+PluginStreamParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005166
+}
+
 bool
 PluginStreamParent::AnswerNPN_Write(const Buffer& data, int32_t* written)
 {
   if (mClosed) {
     *written = -1;
     return true;
   }
 
--- a/dom/plugins/ipc/PluginStreamParent.h
+++ b/dom/plugins/ipc/PluginStreamParent.h
@@ -21,16 +21,18 @@ class PluginStreamParent : public PPlugi
 
 public:
   PluginStreamParent(PluginInstanceParent* npp, const nsCString& mimeType,
                      const nsCString& target, NPError* result);
   virtual ~PluginStreamParent() { }
 
   virtual bool IsBrowserStream() MOZ_OVERRIDE { return false; }
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool AnswerNPN_Write(const Buffer& data, int32_t* written) MOZ_OVERRIDE;
 
   virtual bool Answer__delete__(const NPError& reason, const bool& artificial) MOZ_OVERRIDE;
 
 private:
   void NPN_DestroyStream(NPReason reason);
 
   PluginInstanceParent* mInstance;
--- a/dom/plugins/ipc/PluginSurfaceParent.cpp
+++ b/dom/plugins/ipc/PluginSurfaceParent.cpp
@@ -19,10 +19,16 @@ PluginSurfaceParent::PluginSurfaceParent
   if (dibsurf->Attach(handle, size.width, size.height, transparent))
     mSurface = dibsurf;
 }
 
 PluginSurfaceParent::~PluginSurfaceParent()
 {
 }
 
+void
+PluginSurfaceParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005167
+}
+
 }
 }
--- a/dom/plugins/ipc/PluginSurfaceParent.h
+++ b/dom/plugins/ipc/PluginSurfaceParent.h
@@ -22,16 +22,18 @@ namespace plugins {
 class PluginSurfaceParent : public PPluginSurfaceParent
 {
 public:
   PluginSurfaceParent(const WindowsSharedMemoryHandle& handle,
                       const gfxIntSize& size,
                       const bool transparent);
   ~PluginSurfaceParent();
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   gfxASurface* Surface() { return mSurface; }
 
 private:
   nsRefPtr<gfxASurface> mSurface;
 };
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/plugins/ipc/StreamNotifyParent.h
+++ b/dom/plugins/ipc/StreamNotifyParent.h
@@ -29,16 +29,18 @@ public:
   // so that we aren't destroyed again. see bug 536437.
   void SetDestructionFlag(bool* flag) {
     mDestructionFlag = flag;
   }
   void ClearDestructionFlag() {
     mDestructionFlag = nullptr;
   }
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
 private:
   bool RecvRedirectNotifyResponse(const bool& allow) MOZ_OVERRIDE;
 
   bool* mDestructionFlag;
 };
 
 } // namespace plugins
 } // namespace mozilla
--- a/dom/src/storage/DOMStorageIPC.cpp
+++ b/dom/src/storage/DOMStorageIPC.cpp
@@ -373,16 +373,22 @@ DOMStorageDBParent::CloneProtocol(Channe
 }
 
 DOMStorageDBParent::CacheParentBridge*
 DOMStorageDBParent::NewCache(const nsACString& aScope)
 {
   return new CacheParentBridge(this, aScope);
 }
 
+void
+DOMStorageDBParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005169
+}
+
 bool
 DOMStorageDBParent::RecvAsyncPreload(const nsCString& aScope, const bool& aPriority)
 {
   DOMStorageDBBridge* db = DOMStorageCache::StartDatabase();
   if (!db) {
     return false;
   }
 
--- a/dom/src/storage/DOMStorageIPC.h
+++ b/dom/src/storage/DOMStorageIPC.h
@@ -166,16 +166,17 @@ public:
 
   private:
     nsRefPtr<DOMStorageDBParent> mParent;
     nsCString mScope;
   };
 
 private:
   // IPC
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
   bool RecvAsyncPreload(const nsCString& aScope, const bool& aPriority);
   bool RecvPreload(const nsCString& aScope, const uint32_t& aAlreadyLoadedCount,
                    InfallibleTArray<nsString>* aKeys, InfallibleTArray<nsString>* aValues,
                    nsresult* aRv);
   bool RecvAsyncGetUsage(const nsCString& aScope);
   bool RecvAsyncAddItem(const nsCString& aScope, const nsString& aKey, const nsString& aValue);
   bool RecvAsyncUpdateItem(const nsCString& aScope, const nsString& aKey, const nsString& aValue);
   bool RecvAsyncRemoveItem(const nsCString& aScope, const nsString& aKey);
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -296,37 +296,37 @@ static void CopyDataSourceSurface(DataSo
 
     srcRow += srcRowHole;
     destRow += destRowHole;
     --rows;
   }
 }
 
 static int
-CalcStride(int width, int pixelSize, int alignment)
+CalcRowStride(int width, int pixelSize, int alignment)
 {
     MOZ_ASSERT(alignment);
 
-    int stride = width * pixelSize;
-    if (stride % alignment) { // Extra at the end of the line?
-        int alignmentCount = stride / alignment;
-        stride = (alignmentCount+1) * alignment;
+    int rowStride = width * pixelSize;
+    if (rowStride % alignment) { // Extra at the end of the line?
+        int alignmentCount = rowStride / alignment;
+        rowStride = (alignmentCount+1) * alignment;
     }
-    return stride;
+    return rowStride;
 }
 
 static int
-GuessAlignment(int width, int pixelSize, int stride)
+GuessAlignment(int width, int pixelSize, int rowStride)
 {
     int alignment = 8; // Max GLES allows.
-    while (CalcStride(width, pixelSize, alignment) != stride) {
+    while (CalcRowStride(width, pixelSize, alignment) != rowStride) {
         alignment /= 2;
         if (!alignment) {
-            MOZ_ASSERT(alignment);
-            return 1;
+            NS_WARNING("Bad alignment for GLES. Will use temp surf for readback.");
+            return 0;
         }
     }
     return alignment;
 }
 
 void
 ReadPixelsIntoImageSurface(GLContext* gl, gfxImageSurface* dest) {
     gl->MakeCurrent();
@@ -370,18 +370,28 @@ ReadPixelsIntoImageSurface(GLContext* gl
     GLenum readFormat = destFormat;
     GLenum readType = destType;
     bool needsTempSurf = !GetActualReadFormats(gl,
                                                destFormat, destType,
                                                readFormat, readType);
 
     nsAutoPtr<gfxImageSurface> tempSurf;
     gfxImageSurface* readSurf = nullptr;
-    int readAlignment = 0;
-    if (needsTempSurf) {
+
+    // Figure out alignment. We don't need to know why, we just need it
+    // to be valid.
+    int readAlignment = GuessAlignment(dest->Width(),
+                                       destPixelSize,
+                                       dest->Stride());
+    if (!readAlignment) // Couldn't calculate a valid alignment.
+        needsTempSurf = true;
+
+    if (!needsTempSurf) {
+        readSurf = dest;
+    } else {
         if (gl->DebugMode()) {
             NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!");
         }
         SurfaceFormat readFormatGFX;
 
         switch (readFormat) {
             case LOCAL_GL_RGBA:
             case LOCAL_GL_BGRA: {
@@ -420,23 +430,16 @@ ReadPixelsIntoImageSurface(GLContext* gl
                 MOZ_CRASH("Bad read type.");
             }
         }
 
         tempSurf = new gfxImageSurface(dest->GetSize(),
                                        SurfaceFormatToImageFormat(readFormatGFX),
                                        false);
         readSurf = tempSurf;
-    } else {
-        // Figure out alignment. We don't need to know why, we just need it
-        // to be valid.
-        readAlignment = GuessAlignment(dest->Width(),
-                                       destPixelSize,
-                                       dest->Stride());
-        readSurf = dest;
     }
     MOZ_ASSERT(readAlignment);
 
     GLint currentPackAlignment = 0;
     gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, &currentPackAlignment);
 
     if (currentPackAlignment != readAlignment)
         gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, readAlignment);
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -170,16 +170,22 @@ LayerTransactionParent::Destroy()
 
 LayersBackend
 LayerTransactionParent::GetCompositorBackendType() const
 {
   return mLayerManager->GetBackendType();
 }
 
 /* virtual */
+void
+LayerTransactionParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005171
+}
+
 bool
 LayerTransactionParent::RecvUpdateNoSwap(const InfallibleTArray<Edit>& cset,
                                          const TargetConfig& targetConfig,
                                          const bool& isFirstPaint,
                                          const bool& scheduleComposite)
 {
   return RecvUpdate(cset, targetConfig, isFirstPaint, scheduleComposite, nullptr);
 }
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -75,16 +75,18 @@ public:
     PLayerTransactionParent::DeallocShmem(aShmem);
   }
 
   virtual LayersBackend GetCompositorBackendType() const MOZ_OVERRIDE;
 
   virtual bool IsSameProcess() const MOZ_OVERRIDE;
 
 protected:
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual bool RecvUpdate(const EditArray& cset,
                           const TargetConfig& targetConfig,
                           const bool& isFirstPaint,
                           const bool& scheduleComposite,
                           EditReplyArray* reply) MOZ_OVERRIDE;
 
   virtual bool RecvUpdateNoSwap(const EditArray& cset,
                                 const TargetConfig& targetConfig,
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -2824,23 +2824,24 @@ class _GenerateProtocolActorCode(ipdl.as
             actortype = _cxxBareType(actor.asType(), actor.side)
             self.cls.addstmt(StmtDecl(MethodDecl(
                 _allocMethod(actor.ptype, actor.side).name,
                 params=[ Decl(Type('Transport', ptr=1), 'transport'),
                          Decl(Type('ProcessId'), 'otherProcess') ],
                 ret=actortype,
                 virtual=1, pure=1)))
 
-        # optional ActorDestroy() method; default is no-op
+        # ActorDestroy() method; default is no-op
         self.cls.addstmts([
             Whitespace.NL,
             MethodDefn(MethodDecl(
                 _destroyMethod().name,
                 params=[ Decl(_DestroyReason.Type(), 'why') ],
-                virtual=1)),
+                ret=Type.VOID,
+                virtual=1, pure=(self.side == 'parent'))),
             Whitespace.NL
         ])
 
         if ptype.isToplevel():
             # void ProcessingError(code); default to no-op
             processingerror = MethodDefn(
                 MethodDecl(p.processingErrorVar().name,
                            params=[ Param(_Result.Type(), 'code') ],
@@ -5454,16 +5455,17 @@ methodDefns."""
 
 def _splitMethodDefn(md, clsname):
     saveddecl = deepcopy(md.decl)
     md.decl.name = (clsname +'::'+ md.decl.name)
     md.decl.virtual = 0
     md.decl.static = 0
     md.decl.warn_unused = 0
     md.decl.never_inline = 0
+    md.decl.pure = 0
     md.decl.only_for_definition = True
     for param in md.decl.params:
         if isinstance(param, Param):
             param.default = None
     return saveddecl, md
 
 
 def _splitFuncDeclDefn(fun):
@@ -5510,17 +5512,17 @@ class _GenerateSkeletonImpl(Visitor):
             return
         decl = deepcopy(md)
         decl.pure = 0
         impl = MethodDefn(MethodDecl(self.implname(md.name),
                                              params=md.params,
                                              ret=md.ret))
         if md.ret.ptr:
             impl.addstmt(StmtReturn(ExprLiteral.ZERO))
-        else:
+        elif md.ret == Type.BOOL:
             impl.addstmt(StmtReturn(ExprVar('false')))
 
         self.cls.addstmts([ StmtDecl(decl), Whitespace.NL ])
         self.addmethodimpl(impl)
 
     def visitConstructorDecl(self, cd):
         self.cls.addstmt(StmtDecl(ConstructorDecl(self.name)))
         ctor = ConstructorDefn(ConstructorDecl(self.implname(self.name)))
--- a/ipc/testshell/TestShellParent.cpp
+++ b/ipc/testshell/TestShellParent.cpp
@@ -13,16 +13,22 @@
 #include "nsCxPusher.h"
 
 using namespace mozilla;
 using mozilla::ipc::TestShellParent;
 using mozilla::ipc::TestShellCommandParent;
 using mozilla::ipc::PTestShellCommandParent;
 using mozilla::dom::ContentParent;
 
+void
+TestShellParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005177
+}
+
 PTestShellCommandParent*
 TestShellParent::AllocPTestShellCommandParent(const nsString& aCommand)
 {
   return new TestShellCommandParent();
 }
 
 bool
 TestShellParent::DeallocPTestShellCommandParent(PTestShellCommandParent* aActor)
--- a/ipc/testshell/TestShellParent.h
+++ b/ipc/testshell/TestShellParent.h
@@ -19,16 +19,18 @@ namespace mozilla {
 
 namespace ipc {
 
 class TestShellCommandParent;
 
 class TestShellParent : public PTestShellParent
 {
 public:
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   PTestShellCommandParent*
   AllocPTestShellCommandParent(const nsString& aCommand);
 
   bool
   DeallocPTestShellCommandParent(PTestShellCommandParent* aActor);
 
   bool
   CommandDone(TestShellCommandParent* aActor, const nsString& aResponse);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug1004527.js
@@ -0,0 +1,8 @@
+if (!this.hasOwnProperty("TypedObject"))
+  quit();
+
+var { ArrayType, StructType, uint32 } = TypedObject;
+var L = 1024;
+var Matrix = uint32.array(L, 2);
+var matrix = new Matrix();
+evaluate("for (var i = 0; i < L; i++) matrix[i][0] = (function d() {});", { compileAndGo : true });
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1001378.js
@@ -0,0 +1,17 @@
+// Test that we don't incorrectly optimize out argument slots from resume
+// points.
+
+function boo() {
+  return foo.arguments[0];
+}
+function foo(a,b,c) {
+  if (a == 0) {
+    a ^= "";
+    return boo();
+  }
+}
+function inlined() {
+  return foo.apply({}, arguments);
+}
+assertEq(inlined(1,2,3), undefined);
+assertEq(inlined(0,2,3), 0);
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -49,17 +49,17 @@ jit::SplitCriticalEdges(MIRGraph &graph)
             block->replaceSuccessor(i, split);
             target->replacePredecessor(*block, split);
         }
     }
     return true;
 }
 
 // Operands to a resume point which are dead at the point of the resume can be
-// replaced with undefined values. This analysis supports limited detection of
+// replaced with a magic value. This analysis supports limited detection of
 // dead operands, pruning those which are defined in the resume point's basic
 // block and have no uses outside the block or at points later than the resume
 // point.
 //
 // This is intended to ensure that extra resume points within a basic block
 // will not artificially extend the lifetimes of any SSA values. This could
 // otherwise occur if the new resume point captured a value which is created
 // between the old and new resume point and is dead at the new resume point.
@@ -88,16 +88,24 @@ jit::EliminateDeadResumePointOperands(MI
             // Scanning uses does not give us sufficient information to tell
             // where instructions that are involved in box/unbox operations or
             // parameter passing might be live. Rewriting uses of these terms
             // in resume points may affect the interpreter's behavior. Rather
             // than doing a more sophisticated analysis, just ignore these.
             if (ins->isUnbox() || ins->isParameter() || ins->isTypeBarrier() || ins->isComputeThis())
                 continue;
 
+            // TypedObject intermediate values captured by resume points may
+            // be legitimately dead in Ion code, but are still needed if we
+            // bail out. They can recover on bailout.
+            if (ins->isNewDerivedTypedObject()) {
+                MOZ_ASSERT(ins->canRecoverOnBailout());
+                continue;
+            }
+
             // If the instruction's behavior has been constant folded into a
             // separate instruction, we can't determine precisely where the
             // instruction becomes dead and can't eliminate its uses.
             if (ins->isImplicitlyUsed())
                 continue;
 
             // Check if this instruction's result is only used within the
             // current block, and keep track of its last use in a definition
@@ -130,21 +138,33 @@ jit::EliminateDeadResumePointOperands(MI
                     !mrp->instruction() ||
                     mrp->instruction() == *ins ||
                     mrp->instruction()->id() <= maxDefinition)
                 {
                     uses++;
                     continue;
                 }
 
+                // Function.arguments can be used to access all arguments in
+                // non-strict scripts, so we can't optimize out any arguments.
+                CompileInfo &info = block->info();
+                if (!info.script()->strict()) {
+                    uint32_t slot = uses->index();
+                    uint32_t firstArgSlot = info.firstArgSlot();
+                    if (firstArgSlot <= slot && slot - firstArgSlot < info.nargs()) {
+                        uses++;
+                        continue;
+                    }
+                }
+
                 // Store an optimized out magic value in place of all dead
                 // resume point operands. Making any such substitution can in
                 // general alter the interpreter's behavior, even though the
                 // code is dead, as the interpreter will still execute opcodes
-                // whose effects cannot be observed. If the undefined value
+                // whose effects cannot be observed. If the magic value value
                 // were to flow to, say, a dead property access the
                 // interpreter could throw an exception; we avoid this problem
                 // by removing dead operands before removing dead code.
                 MConstant *constant = MConstant::New(graph.alloc(), MagicValue(JS_OPTIMIZED_OUT));
                 block->insertBefore(*(block->begin()), constant);
                 uses = mrp->replaceOperand(uses, constant);
             }
         }
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -4968,17 +4968,17 @@ IonBuilder::jsop_funcall(uint32_t argc)
 
 bool
 IonBuilder::jsop_funapply(uint32_t argc)
 {
     int calleeDepth = -((int)argc + 2);
 
     types::TemporaryTypeSet *calleeTypes = current->peek(calleeDepth)->resultTypeSet();
     JSFunction *native = getSingleCallTarget(calleeTypes);
-    if (argc != 2) {
+    if (argc != 2 || info().executionMode() == ArgumentsUsageAnalysis) {
         CallInfo callInfo(alloc(), false);
         if (!callInfo.init(current, argc))
             return false;
         return makeCall(native, callInfo, false);
     }
 
     // Disable compilation if the second argument to |apply| cannot be guaranteed
     // to be either definitely |arguments| or definitely not |arguments|.
@@ -4993,19 +4993,19 @@ IonBuilder::jsop_funapply(uint32_t argc)
     // Fallback to regular call if arg 2 is not definitely |arguments|.
     if (argument->type() != MIRType_MagicOptimizedArguments) {
         CallInfo callInfo(alloc(), false);
         if (!callInfo.init(current, argc))
             return false;
         return makeCall(native, callInfo, false);
     }
 
-    if (!native ||
-        !native->isNative() ||
-        native->native() != js_fun_apply)
+    if ((!native || !native->isNative() ||
+        native->native() != js_fun_apply) &&
+        info().executionMode() != DefinitePropertiesAnalysis)
     {
         return abort("fun.apply speculation failed");
     }
 
     current->peek(calleeDepth)->setImplicitlyUsedUnchecked();
 
     // Use funapply that definitely uses |arguments|
     return jsop_funapplyarguments(argc);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -1584,16 +1584,21 @@ class MNewDerivedTypedObject
 
     TypePolicy *typePolicy() {
         return this;
     }
 
     virtual AliasSet getAliasSet() const {
         return AliasSet::None();
     }
+
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return true;
+    }
 };
 
 // Abort parallel execution.
 class MAbortPar : public MAryControlInstruction<0, 0>
 {
     MAbortPar()
       : MAryControlInstruction<0, 0>()
     {
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -4,16 +4,18 @@
  * 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 "jit/Recover.h"
 
 #include "jscntxt.h"
 #include "jsmath.h"
 
+#include "builtin/TypedObject.h"
+
 #include "jit/IonSpewer.h"
 #include "jit/JitFrameIterator.h"
 #include "jit/MIR.h"
 #include "jit/MIRGraph.h"
 
 #include "vm/Interpreter.h"
 
 using namespace js;
@@ -162,8 +164,35 @@ RAdd::recover(JSContext *cx, SnapshotIte
     // MIRType_Float32 is a specialization embedding the fact that the result is
     // rounded to a Float32.
     if (isFloatOperation_ && !RoundFloat32(cx, result, &result))
         return false;
 
     iter.storeInstructionResult(result);
     return true;
 }
+
+bool
+MNewDerivedTypedObject::writeRecoverData(CompactBufferWriter &writer) const
+{
+    MOZ_ASSERT(canRecoverOnBailout());
+    writer.writeUnsigned(uint32_t(RInstruction::Recover_NewDerivedTypedObject));
+    return true;
+}
+
+RNewDerivedTypedObject::RNewDerivedTypedObject(CompactBufferReader &reader)
+{ }
+
+bool
+RNewDerivedTypedObject::recover(JSContext *cx, SnapshotIterator &iter) const
+{
+    Rooted<SizedTypeDescr *> descr(cx, &iter.read().toObject().as<SizedTypeDescr>());
+    Rooted<TypedObject *> owner(cx, &iter.read().toObject().as<TypedObject>());
+    int32_t offset = iter.read().toInt32();
+
+    JSObject *obj = TypedObject::createDerived(cx, descr, owner, offset);
+    if (!obj)
+        return false;
+
+    RootedValue result(cx, ObjectValue(*obj));
+    iter.storeInstructionResult(result);
+    return true;
+}
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -13,17 +13,18 @@
 
 class JSContext;
 
 namespace js {
 namespace jit {
 
 #define RECOVER_OPCODE_LIST(_)                  \
     _(ResumePoint)                              \
-    _(Add)
+    _(Add)                                      \
+    _(NewDerivedTypedObject)
 
 class RResumePoint;
 class SnapshotIterator;
 
 class RInstruction
 {
   public:
     enum Opcode
@@ -96,16 +97,28 @@ class RAdd MOZ_FINAL : public RInstructi
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     bool recover(JSContext *cx, SnapshotIterator &iter) const;
 };
 
+class RNewDerivedTypedObject MOZ_FINAL : public RInstruction
+{
+  public:
+    RINSTRUCTION_HEADER_(NewDerivedTypedObject)
+
+    virtual uint32_t numOperands() const {
+        return 3;
+    }
+
+    bool recover(JSContext *cx, SnapshotIterator &iter) const;
+};
+
 #undef RINSTRUCTION_HEADER_
 
 const RResumePoint *
 RInstruction::toResumePoint() const
 {
     MOZ_ASSERT(isResumePoint());
     return static_cast<const RResumePoint *>(this);
 }
--- a/netwerk/base/src/ChannelDiverterParent.cpp
+++ b/netwerk/base/src/ChannelDiverterParent.cpp
@@ -56,10 +56,16 @@ void
 ChannelDiverterParent::DivertTo(nsIStreamListener* newListener)
 {
   MOZ_ASSERT(newListener);
   MOZ_ASSERT(mDivertableChannelParent);
 
   mDivertableChannelParent->DivertTo(newListener);
 }
 
+void
+ChannelDiverterParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005179
+}
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/base/src/ChannelDiverterParent.h
+++ b/netwerk/base/src/ChannelDiverterParent.h
@@ -22,16 +22,19 @@ class ChannelDiverterParent :
 {
 public:
   ChannelDiverterParent();
   virtual ~ChannelDiverterParent();
 
   bool Init(const ChannelDiverterArgs& aChannel);
 
   void DivertTo(nsIStreamListener* newListener);
+
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
 private:
   nsRefPtr<ADivertableParentChannel> mDivertableChannelParent;
 };
 
 } // namespace net
 } // namespace mozilla
 
 #endif /* _channeldiverterparent_h_ */
--- a/netwerk/base/src/nsBufferedStreams.cpp
+++ b/netwerk/base/src/nsBufferedStreams.cpp
@@ -638,17 +638,17 @@ nsBufferedOutputStream::Flush()
         mFillPoint = mCursor = 0;
         return NS_OK;   // flushed everything
     }
 
     // slide the remainder down to the start of the buffer
     // |<-------------->|<---|----->|
     // b                a    c      s
     uint32_t rem = mFillPoint - amt;
-    memcpy(mBuffer, mBuffer + amt, rem);
+    memmove(mBuffer, mBuffer + amt, rem);
     mFillPoint = mCursor = rem;
     return NS_ERROR_FAILURE;        // didn't flush all
 }
 
 // nsISafeOutputStream
 NS_IMETHODIMP
 nsBufferedOutputStream::Finish()
 {
@@ -693,17 +693,17 @@ nsBufferedOutputStream::WriteSegments(ns
 {
     *_retval = 0;
     nsresult rv;
     while (count > 0) {
         uint32_t left = std::min(count, mBufferSize - mCursor);
         if (left == 0) {
             rv = Flush();
             if (NS_FAILED(rv))
-              return rv;
+                return (*_retval > 0) ? NS_OK : rv;
 
             continue;
         }
 
         uint32_t read = 0;
         rv = reader(this, closure, mBuffer + mCursor, *_retval, left, &read);
 
         if (NS_FAILED(rv)) // If we have written some data, return ok
--- a/netwerk/base/src/nsBufferedStreams.h
+++ b/netwerk/base/src/nsBufferedStreams.h
@@ -104,16 +104,16 @@ public:
     static nsresult
     Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
 
     nsIOutputStream* Sink() { 
         return (nsIOutputStream*)mStream;
     }
 
 protected:
-    NS_IMETHOD Fill() { return NS_OK; } // no-op for input streams
+    NS_IMETHOD Fill() { return NS_OK; } // no-op for output streams
 
     nsCOMPtr<nsISafeOutputStream> mSafeStream; // QI'd from mStream
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
 #endif // nsBufferedStreams_h__
--- a/netwerk/cache2/CacheFile.cpp
+++ b/netwerk/cache2/CacheFile.cpp
@@ -15,16 +15,17 @@
 #include "nsComponentManagerUtils.h"
 #include "nsProxyRelease.h"
 
 // When CACHE_CHUNKS is defined we always cache unused chunks in mCacheChunks.
 // When it is not defined, we always release the chunks ASAP, i.e. we cache
 // unused chunks only when:
 //  - CacheFile is memory-only
 //  - CacheFile is still waiting for the handle
+//  - the chunk is preloaded
 
 //#define CACHE_CHUNKS
 
 namespace mozilla {
 namespace net {
 
 class NotifyCacheFileListenerEvent : public nsRunnable {
 public:
@@ -176,16 +177,17 @@ CacheFile::CacheFile()
   : mLock("CacheFile.mLock")
   , mOpeningFile(false)
   , mReady(false)
   , mMemoryOnly(false)
   , mOpenAsMemoryOnly(false)
   , mDataAccessed(false)
   , mDataIsDirty(false)
   , mWritingMetadata(false)
+  , mPreloadWithoutInputStreams(true)
   , mStatus(NS_OK)
   , mDataSize(-1)
   , mOutput(nullptr)
 {
   LOG(("CacheFile::CacheFile() [this=%p]", this));
 }
 
 CacheFile::~CacheFile()
@@ -311,17 +313,17 @@ nsresult
 CacheFile::OnChunkRead(nsresult aResult, CacheFileChunk *aChunk)
 {
   CacheFileAutoLock lock(this);
 
   nsresult rv;
 
   uint32_t index = aChunk->Index();
 
-  LOG(("CacheFile::OnChunkRead() [this=%p, rv=0x%08x, chunk=%p, idx=%d]",
+  LOG(("CacheFile::OnChunkRead() [this=%p, rv=0x%08x, chunk=%p, idx=%u]",
        this, aResult, aChunk, index));
 
   if (NS_FAILED(aResult)) {
     SetError(aResult);
     CacheFileIOManager::DoomFile(mHandle, nullptr);
   }
 
   if (HaveChunkListeners(index)) {
@@ -334,17 +336,17 @@ CacheFile::OnChunkRead(nsresult aResult,
 
 nsresult
 CacheFile::OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk)
 {
   CacheFileAutoLock lock(this);
 
   nsresult rv;
 
-  LOG(("CacheFile::OnChunkWritten() [this=%p, rv=0x%08x, chunk=%p, idx=%d]",
+  LOG(("CacheFile::OnChunkWritten() [this=%p, rv=0x%08x, chunk=%p, idx=%u]",
        this, aResult, aChunk, aChunk->Index()));
 
   MOZ_ASSERT(!mMemoryOnly);
   MOZ_ASSERT(!mOpeningFile);
   MOZ_ASSERT(mHandle);
 
   if (NS_FAILED(aResult)) {
     SetError(aResult);
@@ -368,35 +370,27 @@ CacheFile::OnChunkWritten(nsresult aResu
 
   if (aChunk->mRefCnt != 2) {
     LOG(("CacheFile::OnChunkWritten() - Chunk is still used [this=%p, chunk=%p,"
          " refcnt=%d]", this, aChunk, aChunk->mRefCnt.get()));
 
     return NS_OK;
   }
 
-#ifdef CACHE_CHUNKS
+  bool keepChunk = false;
   if (NS_SUCCEEDED(aResult)) {
-    LOG(("CacheFile::OnChunkWritten() - Caching unused chunk [this=%p, "
-         "chunk=%p]", this, aChunk));
+    keepChunk = ShouldKeepChunk(aChunk->Index());
+    LOG(("CacheFile::OnChunkWritten() - %s unused chunk [this=%p, chunk=%p]",
+         keepChunk ? "Caching" : "Releasing", this, aChunk));
   } else {
-    LOG(("CacheFile::OnChunkWritten() - Removing failed chunk [this=%p, "
+    LOG(("CacheFile::OnChunkWritten() - Releasing failed chunk [this=%p, "
          "chunk=%p]", this, aChunk));
   }
-#else
-  LOG(("CacheFile::OnChunkWritten() - Releasing %s chunk [this=%p, chunk=%p]",
-       NS_SUCCEEDED(aResult) ? "unused" : "failed", this, aChunk));
-#endif
 
-  RemoveChunkInternal(aChunk,
-#ifdef CACHE_CHUNKS
-                      NS_SUCCEEDED(aResult));
-#else
-                      false);
-#endif
+  RemoveChunkInternal(aChunk, keepChunk);
 
   WriteMetadataIfNeededLocked();
 
   return NS_OK;
 }
 
 nsresult
 CacheFile::OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx,
@@ -575,16 +569,19 @@ CacheFile::OnMetadataRead(nsresult aResu
 
   bool isNew = false;
   if (NS_SUCCEEDED(aResult)) {
     mReady = true;
     mDataSize = mMetadata->Offset();
     if (mDataSize == 0 && mMetadata->ElementsSize() == 0) {
       isNew = true;
       mMetadata->MarkDirty();
+    } else {
+      CacheFileAutoLock lock(this);
+      PreloadChunks(0);
     }
 
     InitIndexEntry();
   }
 
   nsCOMPtr<CacheFileListener> listener;
   mListener.swap(listener);
   listener->OnFileReady(aResult, isNew);
@@ -666,16 +663,21 @@ CacheFile::OpenInputStream(nsIInputStrea
 
   if (!mReady) {
     LOG(("CacheFile::OpenInputStream() - CacheFile is not ready [this=%p]",
          this));
 
     return NS_ERROR_NOT_AVAILABLE;
   }
 
+  // Once we open input stream we no longer allow preloading of chunks without
+  // input stream, i.e. we will no longer keep first few chunks preloaded when
+  // the last input stream is closed.
+  mPreloadWithoutInputStreams = false;
+
   CacheFileInputStream *input = new CacheFileInputStream(this);
 
   LOG(("CacheFile::OpenInputStream() - Creating new input stream %p [this=%p]",
        input, this));
 
   mInputs.AppendElement(input);
   NS_ADDREF(input);
 
@@ -797,22 +799,17 @@ CacheFile::ThrowMemoryCachedData()
     // entries from being purged.
 
     LOG(("CacheFile::ThrowMemoryCachedData() - Ignoring request because the "
          "entry is still opening the file [this=%p]", this));
 
     return NS_ERROR_ABORT;
   }
 
-#ifdef CACHE_CHUNKS
   mCachedChunks.Clear();
-#else
-  // If we don't cache all chunks, mCachedChunks must be empty.
-  MOZ_ASSERT(mCachedChunks.Count() == 0);
-#endif
 
   return NS_OK;
 }
 
 nsresult
 CacheFile::GetElement(const char *aKey, char **_retval)
 {
   CacheFileAutoLock lock(this);
@@ -981,82 +978,97 @@ void
 CacheFile::ReleaseOutsideLock(nsISupports *aObject)
 {
   AssertOwnsLock();
 
   mObjsToRelease.AppendElement(aObject);
 }
 
 nsresult
-CacheFile::GetChunk(uint32_t aIndex, bool aWriter,
+CacheFile::GetChunk(uint32_t aIndex, ECallerType aCaller,
                     CacheFileChunkListener *aCallback, CacheFileChunk **_retval)
 {
   CacheFileAutoLock lock(this);
-  return GetChunkLocked(aIndex, aWriter, aCallback, _retval);
+  return GetChunkLocked(aIndex, aCaller, aCallback, _retval);
 }
 
 nsresult
-CacheFile::GetChunkLocked(uint32_t aIndex, bool aWriter,
+CacheFile::GetChunkLocked(uint32_t aIndex, ECallerType aCaller,
                           CacheFileChunkListener *aCallback,
                           CacheFileChunk **_retval)
 {
   AssertOwnsLock();
 
-  LOG(("CacheFile::GetChunkLocked() [this=%p, idx=%d, writer=%d, listener=%p]",
-       this, aIndex, aWriter, aCallback));
+  LOG(("CacheFile::GetChunkLocked() [this=%p, idx=%u, caller=%d, listener=%p]",
+       this, aIndex, aCaller, aCallback));
 
   MOZ_ASSERT(mReady);
   MOZ_ASSERT(mHandle || mMemoryOnly || mOpeningFile);
-  MOZ_ASSERT((aWriter && !aCallback) || (!aWriter && aCallback));
+  MOZ_ASSERT((aCaller == READER && aCallback) ||
+             (aCaller == WRITER && !aCallback) ||
+             (aCaller == PRELOADER && !aCallback));
+
+  // Preload chunks from disk when this is disk backed entry and the listener
+  // is reader.
+  bool preload = !mMemoryOnly && (aCaller == READER);
 
   nsresult rv;
 
   nsRefPtr<CacheFileChunk> chunk;
   if (mChunks.Get(aIndex, getter_AddRefs(chunk))) {
     LOG(("CacheFile::GetChunkLocked() - Found chunk %p in mChunks [this=%p]",
          chunk.get(), this));
 
+    // Preloader calls this method to preload only non-loaded chunks.
+    MOZ_ASSERT(aCaller != PRELOADER, "Unexpected!");
+
     // We might get failed chunk between releasing the lock in
     // CacheFileChunk::OnDataWritten/Read and CacheFile::OnChunkWritten/Read
     rv = chunk->GetStatus();
     if (NS_FAILED(rv)) {
       SetError(rv);
       LOG(("CacheFile::GetChunkLocked() - Found failed chunk in mChunks "
            "[this=%p]", this));
       return rv;
     }
 
-    if (chunk->IsReady() || aWriter) {
+    if (chunk->IsReady() || aCaller == WRITER) {
       chunk.swap(*_retval);
-    }
-    else {
+    } else {
       rv = QueueChunkListener(aIndex, aCallback);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
+    if (preload) {
+      PreloadChunks(aIndex + 1);
+    }
+
     return NS_OK;
   }
 
   if (mCachedChunks.Get(aIndex, getter_AddRefs(chunk))) {
-#ifndef CACHE_CHUNKS
-    // We don't cache all chunks, so we must not have handle and we must be
-    // either waiting for the handle, or this is memory-only entry.
-    MOZ_ASSERT(!mHandle && (mMemoryOnly || mOpeningFile));
-#endif
     LOG(("CacheFile::GetChunkLocked() - Reusing cached chunk %p [this=%p]",
          chunk.get(), this));
 
+    // Preloader calls this method to preload only non-loaded chunks.
+    MOZ_ASSERT(aCaller != PRELOADER, "Unexpected!");
+
     mChunks.Put(aIndex, chunk);
     mCachedChunks.Remove(aIndex);
     chunk->mFile = this;
     chunk->mRemovingChunk = false;
 
     MOZ_ASSERT(chunk->IsReady());
 
     chunk.swap(*_retval);
+
+    if (preload) {
+      PreloadChunks(aIndex + 1);
+    }
+
     return NS_OK;
   }
 
   int64_t off = aIndex * kChunkSize;
 
   if (off < mDataSize) {
     // We cannot be here if this is memory only entry since the chunk must exist
     MOZ_ASSERT(!mMemoryOnly);
@@ -1080,28 +1092,30 @@ CacheFile::GetChunkLocked(uint32_t aInde
     rv = chunk->Read(mHandle, std::min(static_cast<uint32_t>(mDataSize - off),
                      static_cast<uint32_t>(kChunkSize)),
                      mMetadata->GetHash(aIndex), this);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       RemoveChunkInternal(chunk, false);
       return rv;
     }
 
-    if (aWriter) {
+    if (aCaller == WRITER) {
       chunk.swap(*_retval);
-    }
-    else {
+    } else if (aCaller != PRELOADER) {
       rv = QueueChunkListener(aIndex, aCallback);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
+    if (preload) {
+      PreloadChunks(aIndex + 1);
+    }
+
     return NS_OK;
-  }
-  else if (off == mDataSize) {
-    if (aWriter) {
+  } else if (off == mDataSize) {
+    if (aCaller == WRITER) {
       // this listener is going to write to the chunk
       chunk = new CacheFileChunk(this, aIndex);
       mChunks.Put(aIndex, chunk);
 
       LOG(("CacheFile::GetChunkLocked() - Created new empty chunk %p [this=%p]",
            chunk.get(), this));
 
       chunk->InitNew(this);
@@ -1110,19 +1124,18 @@ CacheFile::GetChunkLocked(uint32_t aInde
       if (HaveChunkListeners(aIndex)) {
         rv = NotifyChunkListeners(aIndex, NS_OK, chunk);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
       chunk.swap(*_retval);
       return NS_OK;
     }
-  }
-  else {
-    if (aWriter) {
+  } else {
+    if (aCaller == WRITER) {
       // this chunk was requested by writer, but we need to fill the gap first
 
       // Fill with zero the last chunk if it is incomplete
       if (mDataSize % kChunkSize) {
         rv = PadChunkWithZeroes(mDataSize / kChunkSize);
         NS_ENSURE_SUCCESS(rv, rv);
 
         MOZ_ASSERT(!(mDataSize % kChunkSize));
@@ -1132,75 +1145,161 @@ CacheFile::GetChunkLocked(uint32_t aInde
 
       if (mMemoryOnly) {
         // We need to create all missing CacheFileChunks if this is memory-only
         // entry
         for (uint32_t i = startChunk ; i < aIndex ; i++) {
           rv = PadChunkWithZeroes(i);
           NS_ENSURE_SUCCESS(rv, rv);
         }
-      }
-      else {
+      } else {
         // We don't need to create CacheFileChunk for other empty chunks unless
         // there is some input stream waiting for this chunk.
 
         if (startChunk != aIndex) {
           // Make sure the file contains zeroes at the end of the file
           rv = CacheFileIOManager::TruncateSeekSetEOF(mHandle,
                                                       startChunk * kChunkSize,
                                                       aIndex * kChunkSize,
                                                       nullptr);
           NS_ENSURE_SUCCESS(rv, rv);
         }
 
         for (uint32_t i = startChunk ; i < aIndex ; i++) {
           if (HaveChunkListeners(i)) {
             rv = PadChunkWithZeroes(i);
             NS_ENSURE_SUCCESS(rv, rv);
-          }
-          else {
+          } else {
             mMetadata->SetHash(i, kEmptyChunkHash);
             mDataSize = (i + 1) * kChunkSize;
           }
         }
       }
 
       MOZ_ASSERT(mDataSize == off);
-      rv = GetChunkLocked(aIndex, true, nullptr, getter_AddRefs(chunk));
+      rv = GetChunkLocked(aIndex, WRITER, nullptr, getter_AddRefs(chunk));
       NS_ENSURE_SUCCESS(rv, rv);
 
       chunk.swap(*_retval);
       return NS_OK;
     }
   }
 
+  // We can be here only if the caller is reader since writer always create a
+  // new chunk above and preloader calls this method to preload only chunks that
+  // are not loaded but that do exist.
+  MOZ_ASSERT(aCaller == READER, "Unexpected!");
+
   if (mOutput) {
     // the chunk doesn't exist but mOutput may create it
     rv = QueueChunkListener(aIndex, aCallback);
     NS_ENSURE_SUCCESS(rv, rv);
-  }
-  else {
+  } else {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   return NS_OK;
 }
 
+void
+CacheFile::PreloadChunks(uint32_t aIndex)
+{
+  AssertOwnsLock();
+
+  uint32_t limit = aIndex + CacheObserver::PreloadChunkCount();
+
+  for (uint32_t i = aIndex; i < limit; ++i) {
+    int64_t off = i * kChunkSize;
+
+    if (off >= mDataSize) {
+      // This chunk is beyond EOF.
+      return;
+    }
+
+    if (mChunks.GetWeak(i) || mCachedChunks.GetWeak(i)) {
+      // This chunk is already in memory or is being read right now.
+      continue;
+    }
+
+    LOG(("CacheFile::PreloadChunks() - Preloading chunk [this=%p, idx=%u]",
+         this, i));
+
+    nsRefPtr<CacheFileChunk> chunk;
+    GetChunkLocked(i, PRELOADER, nullptr, getter_AddRefs(chunk));
+    // We've checked that we don't have this chunk, so no chunk must be
+    // returned.
+    MOZ_ASSERT(!chunk);
+  }
+}
+
+bool
+CacheFile::ShouldKeepChunk(uint32_t aIndex)
+{
+  AssertOwnsLock();
+
+#ifdef CACHE_CHUNKS
+  // We cache all chunks.
+  return true;
+#else
+  // Cache chunk when this is memory only entry or we don't have a handle yet.
+  if (mMemoryOnly || mOpeningFile) {
+    return true;
+  }
+
+  uint32_t preloadChunkCount = CacheObserver::PreloadChunkCount();
+
+  if (preloadChunkCount == 0) {
+    // Preloading of chunks is disabled
+    return false;
+  }
+
+  if (mPreloadWithoutInputStreams && aIndex < preloadChunkCount) {
+    // We don't have any input stream yet, but it is likely that some will be
+    // opened soon. Keep first preloadChunkCount chunks in memory.
+    return true;
+  }
+
+  // Check whether this chunk should be considered as preloaded chunk for any
+  // existing input stream.
+
+  // maxPos is the position of the last byte in the given chunk
+  int64_t maxPos = static_cast<int64_t>(aIndex + 1) * kChunkSize - 1;
+
+  // minPos is the position of the first byte in a chunk that precedes the given
+  // chunk by PreloadChunkCount chunks
+  int64_t minPos;
+  if (preloadChunkCount >= aIndex) {
+    minPos = 0;
+  } else {
+    minPos = static_cast<int64_t>(aIndex - preloadChunkCount) * kChunkSize;
+  }
+
+  for (uint32_t i = 0; i < mInputs.Length(); ++i) {
+    int64_t inputPos = mInputs[i]->GetPosition();
+    if (inputPos >= minPos && inputPos <= maxPos) {
+      return true;
+    }
+  }
+
+  return false;
+#endif
+}
+
 nsresult
 CacheFile::RemoveChunk(CacheFileChunk *aChunk)
 {
   nsresult rv;
 
   // Avoid lock reentrancy by increasing the RefCnt
   nsRefPtr<CacheFileChunk> chunk = aChunk;
 
   {
     CacheFileAutoLock lock(this);
 
-    LOG(("CacheFile::RemoveChunk() [this=%p, chunk=%p, idx=%d]",
+    LOG(("CacheFile::RemoveChunk() [this=%p, chunk=%p, idx=%u]",
          this, aChunk, aChunk->Index()));
 
     MOZ_ASSERT(mReady);
     MOZ_ASSERT((mHandle && !mMemoryOnly && !mOpeningFile) ||
                (!mHandle && mMemoryOnly && !mOpeningFile) ||
                (!mHandle && !mMemoryOnly && mOpeningFile));
 
     if (aChunk->mRefCnt != 2) {
@@ -1222,17 +1321,17 @@ CacheFile::RemoveChunk(CacheFileChunk *a
       ChunkListeners *listeners;
       mChunkListeners.Get(chunk->Index(), &listeners);
       MOZ_ASSERT(!listeners);
     }
 #endif
 
     if (NS_FAILED(mStatus)) {
       // Don't write any chunk to disk since this entry will be doomed
-      LOG(("CacheFile::RemoveChunk() - Removing chunk because of status "
+      LOG(("CacheFile::RemoveChunk() - Releasing chunk because of status "
            "[this=%p, chunk=%p, mStatus=0x%08x]", this, chunk.get(), mStatus));
 
       RemoveChunkInternal(chunk, false);
       return mStatus;
     }
 
     if (chunk->IsDirty() && !mMemoryOnly && !mOpeningFile) {
       LOG(("CacheFile::RemoveChunk() - Writing dirty chunk to the disk "
@@ -1257,37 +1356,21 @@ CacheFile::RemoveChunk(CacheFileChunk *a
 
         // chunk needs to be released under the lock to be able to rely on
         // CacheFileChunk::mRefCnt in CacheFile::OnChunkWritten()
         chunk = nullptr;
         return NS_OK;
       }
     }
 
-#ifdef CACHE_CHUNKS
-    LOG(("CacheFile::RemoveChunk() - Caching unused chunk [this=%p, chunk=%p]",
-         this, chunk.get()));
-#else
-    if (mMemoryOnly || mOpeningFile) {
-      LOG(("CacheFile::RemoveChunk() - Caching unused chunk [this=%p, chunk=%p,"
-           " reason=%s]", this, chunk.get(),
-           mMemoryOnly ? "memory-only" : "opening-file"));
-    } else {
-      LOG(("CacheFile::RemoveChunk() - Releasing unused chunk [this=%p, "
-           "chunk=%p]", this, chunk.get()));
-    }
-#endif
+    bool keepChunk = ShouldKeepChunk(aChunk->Index());
+    LOG(("CacheFile::RemoveChunk() - %s unused chunk [this=%p, chunk=%p]",
+         keepChunk ? "Caching" : "Releasing", this, chunk.get()));
 
-    RemoveChunkInternal(chunk,
-#ifdef CACHE_CHUNKS
-                        true);
-#else
-                        // Cache the chunk only when we have a reason to do so
-                        mMemoryOnly || mOpeningFile);
-#endif
+    RemoveChunkInternal(chunk, keepChunk);
 
     if (!mMemoryOnly)
       WriteMetadataIfNeededLocked();
   }
 
   return NS_OK;
 }
 
@@ -1316,16 +1399,20 @@ CacheFile::RemoveInput(CacheFileInputStr
   found = mInputs.RemoveElement(aInput);
   MOZ_ASSERT(found);
 
   ReleaseOutsideLock(static_cast<nsIInputStream*>(aInput));
 
   if (!mMemoryOnly)
     WriteMetadataIfNeededLocked();
 
+  // If the input didn't read all data, there might be left some preloaded
+  // chunks that won't be used anymore.
+  mCachedChunks.Enumerate(&CacheFile::CleanUpPreloadedChunks, this);
+
   return NS_OK;
 }
 
 nsresult
 CacheFile::RemoveOutput(CacheFileOutputStream *aOutput)
 {
   AssertOwnsLock();
 
@@ -1354,17 +1441,17 @@ CacheFile::RemoveOutput(CacheFileOutputS
 nsresult
 CacheFile::NotifyChunkListener(CacheFileChunkListener *aCallback,
                                nsIEventTarget *aTarget,
                                nsresult aResult,
                                uint32_t aChunkIdx,
                                CacheFileChunk *aChunk)
 {
   LOG(("CacheFile::NotifyChunkListener() [this=%p, listener=%p, target=%p, "
-       "rv=0x%08x, idx=%d, chunk=%p]", this, aCallback, aTarget, aResult,
+       "rv=0x%08x, idx=%u, chunk=%p]", this, aCallback, aTarget, aResult,
        aChunkIdx, aChunk));
 
   nsresult rv;
   nsRefPtr<NotifyChunkListenerEvent> ev;
   ev = new NotifyChunkListenerEvent(aCallback, aResult, aChunkIdx, aChunk);
   if (aTarget)
     rv = aTarget->Dispatch(ev, NS_DISPATCH_NORMAL);
   else
@@ -1373,17 +1460,17 @@ CacheFile::NotifyChunkListener(CacheFile
 
   return NS_OK;
 }
 
 nsresult
 CacheFile::QueueChunkListener(uint32_t aIndex,
                               CacheFileChunkListener *aCallback)
 {
-  LOG(("CacheFile::QueueChunkListener() [this=%p, idx=%d, listener=%p]",
+  LOG(("CacheFile::QueueChunkListener() [this=%p, idx=%u, listener=%p]",
        this, aIndex, aCallback));
 
   AssertOwnsLock();
 
   MOZ_ASSERT(aCallback);
 
   ChunkListenerItem *item = new ChunkListenerItem();
   item->mTarget = NS_GetCurrentThread();
@@ -1398,17 +1485,17 @@ CacheFile::QueueChunkListener(uint32_t a
   listeners->mItems.AppendElement(item);
   return NS_OK;
 }
 
 nsresult
 CacheFile::NotifyChunkListeners(uint32_t aIndex, nsresult aResult,
                                 CacheFileChunk *aChunk)
 {
-  LOG(("CacheFile::NotifyChunkListeners() [this=%p, idx=%d, rv=0x%08x, "
+  LOG(("CacheFile::NotifyChunkListeners() [this=%p, idx=%u, rv=0x%08x, "
        "chunk=%p]", this, aIndex, aResult, aChunk));
 
   AssertOwnsLock();
 
   nsresult rv, rv2;
 
   ChunkListeners *listeners;
   mChunkListeners.Get(aIndex, &listeners);
@@ -1563,17 +1650,17 @@ CacheFile::PostWriteTimer()
 
 PLDHashOperator
 CacheFile::WriteAllCachedChunks(const uint32_t& aIdx,
                                 nsRefPtr<CacheFileChunk>& aChunk,
                                 void* aClosure)
 {
   CacheFile *file = static_cast<CacheFile*>(aClosure);
 
-  LOG(("CacheFile::WriteAllCachedChunks() [this=%p, idx=%d, chunk=%p]",
+  LOG(("CacheFile::WriteAllCachedChunks() [this=%p, idx=%u, chunk=%p]",
        file, aIdx, aChunk.get()));
 
   file->mChunks.Put(aIdx, aChunk);
   aChunk->mFile = file;
   aChunk->mRemovingChunk = false;
 
   MOZ_ASSERT(aChunk->IsReady());
 
@@ -1586,17 +1673,17 @@ CacheFile::WriteAllCachedChunks(const ui
 PLDHashOperator
 CacheFile::FailListenersIfNonExistentChunk(
   const uint32_t& aIdx,
   nsAutoPtr<ChunkListeners>& aListeners,
   void* aClosure)
 {
   CacheFile *file = static_cast<CacheFile*>(aClosure);
 
-  LOG(("CacheFile::FailListenersIfNonExistentChunk() [this=%p, idx=%d]",
+  LOG(("CacheFile::FailListenersIfNonExistentChunk() [this=%p, idx=%u]",
        file, aIdx));
 
   nsRefPtr<CacheFileChunk> chunk;
   file->mChunks.Get(aIdx, getter_AddRefs(chunk));
   if (chunk) {
     MOZ_ASSERT(!chunk->IsReady());
     return PL_DHASH_NEXT;
   }
@@ -1616,38 +1703,57 @@ CacheFile::FailUpdateListeners(
   const uint32_t& aIdx,
   nsRefPtr<CacheFileChunk>& aChunk,
   void* aClosure)
 {
 #ifdef PR_LOGGING
   CacheFile *file = static_cast<CacheFile*>(aClosure);
 #endif
 
-  LOG(("CacheFile::FailUpdateListeners() [this=%p, idx=%d]",
+  LOG(("CacheFile::FailUpdateListeners() [this=%p, idx=%u]",
        file, aIdx));
 
   if (aChunk->IsReady()) {
     aChunk->NotifyUpdateListeners();
   }
 
   return PL_DHASH_NEXT;
 }
 
+PLDHashOperator
+CacheFile::CleanUpPreloadedChunks(const uint32_t& aIdx,
+                                  nsRefPtr<CacheFileChunk>& aChunk,
+                                  void* aClosure)
+{
+  CacheFile *file = static_cast<CacheFile*>(aClosure);
+
+  LOG(("CacheFile::CleanUpPreloadedChunks() [this=%p, idx=%u, chunk=%p]", file,
+       aIdx, aChunk.get()));
+
+  if (file->ShouldKeepChunk(aIdx)) {
+    LOG(("CacheFile::CleanUpPreloadedChunks() - Keeping chunk"));
+    return PL_DHASH_NEXT;
+  }
+
+  LOG(("CacheFile::CleanUpPreloadedChunks() - Removing chunk"));
+  return PL_DHASH_REMOVE;
+}
+
 nsresult
 CacheFile::PadChunkWithZeroes(uint32_t aChunkIdx)
 {
   AssertOwnsLock();
 
   // This method is used to pad last incomplete chunk with zeroes or create
   // a new chunk full of zeroes
   MOZ_ASSERT(mDataSize / kChunkSize == aChunkIdx);
 
   nsresult rv;
   nsRefPtr<CacheFileChunk> chunk;
-  rv = GetChunkLocked(aChunkIdx, true, nullptr, getter_AddRefs(chunk));
+  rv = GetChunkLocked(aChunkIdx, WRITER, nullptr, getter_AddRefs(chunk));
   NS_ENSURE_SUCCESS(rv, rv);
 
   LOG(("CacheFile::PadChunkWithZeroes() - Zeroing hole in chunk %d, range %d-%d"
        " [this=%p]", aChunkIdx, chunk->DataSize(), kChunkSize - 1, this));
 
   chunk->EnsureBufSize(kChunkSize);
   memset(chunk->BufForWriting() + chunk->DataSize(), 0, kChunkSize - chunk->DataSize());
 
--- a/netwerk/cache2/CacheFile.h
+++ b/netwerk/cache2/CacheFile.h
@@ -116,22 +116,32 @@ private:
 
   virtual ~CacheFile();
 
   void     Lock();
   void     Unlock();
   void     AssertOwnsLock() const;
   void     ReleaseOutsideLock(nsISupports *aObject);
 
-  nsresult GetChunk(uint32_t aIndex, bool aWriter,
+  enum ECallerType {
+    READER    = 0,
+    WRITER    = 1,
+    PRELOADER = 2
+  };
+
+  nsresult GetChunk(uint32_t aIndex, ECallerType aCaller,
                     CacheFileChunkListener *aCallback,
                     CacheFileChunk **_retval);
-  nsresult GetChunkLocked(uint32_t aIndex, bool aWriter,
+  nsresult GetChunkLocked(uint32_t aIndex, ECallerType aCaller,
                           CacheFileChunkListener *aCallback,
                           CacheFileChunk **_retval);
+
+  void     PreloadChunks(uint32_t aIndex);
+  bool     ShouldKeepChunk(uint32_t aIndex);
+
   nsresult RemoveChunk(CacheFileChunk *aChunk);
   void     RemoveChunkInternal(CacheFileChunk *aChunk, bool aCacheChunk);
 
   nsresult RemoveInput(CacheFileInputStream *aInput);
   nsresult RemoveOutput(CacheFileOutputStream *aOutput);
   nsresult NotifyChunkListener(CacheFileChunkListener *aCallback,
                                nsIEventTarget *aTarget,
                                nsresult aResult,
@@ -157,30 +167,36 @@ private:
                            const uint32_t& aIdx,
                            nsAutoPtr<mozilla::net::ChunkListeners>& aListeners,
                            void* aClosure);
 
   static PLDHashOperator FailUpdateListeners(const uint32_t& aIdx,
                                              nsRefPtr<CacheFileChunk>& aChunk,
                                              void* aClosure);
 
+  static PLDHashOperator CleanUpPreloadedChunks(
+                           const uint32_t& aIdx,
+                           nsRefPtr<CacheFileChunk>& aChunk,
+                           void* aClosure);
+
   nsresult PadChunkWithZeroes(uint32_t aChunkIdx);
 
   void SetError(nsresult aStatus);
 
   nsresult InitIndexEntry();
 
   mozilla::Mutex mLock;
   bool           mOpeningFile;
   bool           mReady;
   bool           mMemoryOnly;
   bool           mOpenAsMemoryOnly;
   bool           mDataAccessed;
   bool           mDataIsDirty;
   bool           mWritingMetadata;
+  bool           mPreloadWithoutInputStreams;
   nsresult       mStatus;
   int64_t        mDataSize;
   nsCString      mKey;
 
   nsRefPtr<CacheFileHandle>    mHandle;
   nsRefPtr<CacheFileMetadata>  mMetadata;
   nsCOMPtr<CacheFileListener>  mListener;
   nsCOMPtr<CacheFileIOListener>   mDoomAfterOpenListener;
--- a/netwerk/cache2/CacheFileInputStream.cpp
+++ b/netwerk/cache2/CacheFileInputStream.cpp
@@ -538,17 +538,18 @@ CacheFileInputStream::EnsureCorrectChunk
   if (mListeningForChunk == static_cast<int64_t>(chunkIdx)) {
     // We're already waiting for this chunk
     LOG(("CacheFileInputStream::EnsureCorrectChunk() - Already listening for "
          "chunk %lld [this=%p]", mListeningForChunk, this));
 
     return;
   }
 
-  rv = mFile->GetChunkLocked(chunkIdx, false, this, getter_AddRefs(mChunk));
+  rv = mFile->GetChunkLocked(chunkIdx, CacheFile::READER, this,
+                             getter_AddRefs(mChunk));
   if (NS_FAILED(rv)) {
     LOG(("CacheFileInputStream::EnsureCorrectChunk() - GetChunkLocked failed. "
          "[this=%p, idx=%d, rv=0x%08x]", this, chunkIdx, rv));
     if (rv != NS_ERROR_NOT_AVAILABLE) {
       // We store the error in mStatus, so we can propagate it later to consumer
       // in Read(), Available() etc. We need to handle NS_ERROR_NOT_AVAILABLE
       // differently since it is returned when the requested chunk is not
       // available and there is no writer that could create it, i.e. it means
--- a/netwerk/cache2/CacheFileInputStream.h
+++ b/netwerk/cache2/CacheFileInputStream.h
@@ -33,16 +33,18 @@ public:
   NS_IMETHOD OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk);
   NS_IMETHOD OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx,
                               CacheFileChunk *aChunk);
   NS_IMETHOD OnChunkUpdated(CacheFileChunk *aChunk);
 
   // Memory reporting
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
+  uint32_t GetPosition() const { return mPos; };
+
 private:
   virtual ~CacheFileInputStream();
 
   void ReleaseChunk();
   void EnsureCorrectChunk(bool aReleaseOnly);
   void CanRead(int64_t *aCanRead, const char **aBuf);
   void NotifyListener();
   void MaybeNotifyListener();
--- a/netwerk/cache2/CacheFileOutputStream.cpp
+++ b/netwerk/cache2/CacheFileOutputStream.cpp
@@ -340,17 +340,18 @@ CacheFileOutputStream::EnsureCorrectChun
       ReleaseChunk();
     }
   }
 
   if (aReleaseOnly)
     return;
 
   nsresult rv;
-  rv = mFile->GetChunkLocked(chunkIdx, true, nullptr, getter_AddRefs(mChunk));
+  rv = mFile->GetChunkLocked(chunkIdx, CacheFile::WRITER, nullptr,
+                             getter_AddRefs(mChunk));
   if (NS_FAILED(rv)) {
     LOG(("CacheFileOutputStream::EnsureCorrectChunk() - GetChunkLocked failed. "
          "[this=%p, idx=%d, rv=0x%08x]", this, chunkIdx, rv));
     mStatus = rv;
   }
 }
 
 void
--- a/netwerk/cache2/CacheIOThread.cpp
+++ b/netwerk/cache2/CacheIOThread.cpp
@@ -51,41 +51,50 @@ nsresult CacheIOThread::Init()
 
   return NS_OK;
 }
 
 nsresult CacheIOThread::Dispatch(nsIRunnable* aRunnable, uint32_t aLevel)
 {
   NS_ENSURE_ARG(aLevel < LAST_LEVEL);
 
+  // Runnable is always expected to be non-null, hard null-check bellow.
+  MOZ_ASSERT(aRunnable);
+
   MonitorAutoLock lock(mMonitor);
 
   if (mShutdown && (PR_GetCurrentThread() != mThread))
     return NS_ERROR_UNEXPECTED;
 
   return DispatchInternal(aRunnable, aLevel);
 }
 
 nsresult CacheIOThread::DispatchAfterPendingOpens(nsIRunnable* aRunnable)
 {
+  // Runnable is always expected to be non-null, hard null-check bellow.
+  MOZ_ASSERT(aRunnable);
+
   MonitorAutoLock lock(mMonitor);
 
   if (mShutdown && (PR_GetCurrentThread() != mThread))
     return NS_ERROR_UNEXPECTED;
 
   // Move everything from later executed OPEN level to the OPEN_PRIORITY level
   // where we post the (eviction) runnable.
   mEventQueue[OPEN_PRIORITY].AppendElements(mEventQueue[OPEN]);
   mEventQueue[OPEN].Clear();
 
   return DispatchInternal(aRunnable, OPEN_PRIORITY);
 }
 
 nsresult CacheIOThread::DispatchInternal(nsIRunnable* aRunnable, uint32_t aLevel)
 {
+  if (NS_WARN_IF(!aRunnable))
+    return NS_ERROR_NULL_POINTER;
+
   mMonitor.AssertCurrentThreadOwns();
 
   mEventQueue[aLevel].AppendElement(aRunnable);
   if (mLowestLevelWaiting > aLevel)
     mLowestLevelWaiting = aLevel;
 
   mMonitor.NotifyAll();
 
--- a/netwerk/cache2/CacheObserver.cpp
+++ b/netwerk/cache2/CacheObserver.cpp
@@ -51,16 +51,19 @@ int32_t CacheObserver::sMemoryCacheCapac
 int32_t CacheObserver::sAutoMemoryCacheCapacity = -1;
 
 static uint32_t const kDefaultDiskCacheCapacity = 250 * 1024; // 250 MB
 uint32_t CacheObserver::sDiskCacheCapacity = kDefaultDiskCacheCapacity;
 
 static bool const kDefaultSmartCacheSizeEnabled = false;
 bool CacheObserver::sSmartCacheSizeEnabled = kDefaultSmartCacheSizeEnabled;
 
+static uint32_t const kDefaultPreloadChunkCount = 4;
+uint32_t CacheObserver::sPreloadChunkCount = kDefaultPreloadChunkCount;
+
 static uint32_t const kDefaultMaxMemoryEntrySize = 4 * 1024; // 4 MB
 uint32_t CacheObserver::sMaxMemoryEntrySize = kDefaultMaxMemoryEntrySize;
 
 static uint32_t const kDefaultMaxDiskEntrySize = 50 * 1024; // 50 MB
 uint32_t CacheObserver::sMaxDiskEntrySize = kDefaultMaxDiskEntrySize;
 
 static uint32_t const kDefaultCompressionLevel = 1;
 uint32_t CacheObserver::sCompressionLevel = kDefaultCompressionLevel;
@@ -137,16 +140,19 @@ CacheObserver::AttachToPreferences()
   mozilla::Preferences::AddUintVarCache(
     &sDiskCacheCapacity, "browser.cache.disk.capacity", kDefaultDiskCacheCapacity);
   mozilla::Preferences::AddBoolVarCache(
     &sSmartCacheSizeEnabled, "browser.cache.disk.smart_size.enabled", kDefaultSmartCacheSizeEnabled);
   mozilla::Preferences::AddIntVarCache(
     &sMemoryCacheCapacity, "browser.cache.memory.capacity", kDefaultMemoryCacheCapacity);
 
   mozilla::Preferences::AddUintVarCache(
+    &sPreloadChunkCount, "browser.cache.disk.preload_chunk_count", kDefaultPreloadChunkCount);
+
+  mozilla::Preferences::AddUintVarCache(
     &sMaxDiskEntrySize, "browser.cache.disk.max_entry_size", kDefaultMaxDiskEntrySize);
   mozilla::Preferences::AddUintVarCache(
     &sMaxMemoryEntrySize, "browser.cache.memory.max_entry_size", kDefaultMaxMemoryEntrySize);
 
   // http://mxr.mozilla.org/mozilla-central/source/netwerk/cache/nsCacheEntryDescriptor.cpp#367
   mozilla::Preferences::AddUintVarCache(
     &sCompressionLevel, "browser.cache.compression_level", kDefaultCompressionLevel);
 
--- a/netwerk/cache2/CacheObserver.h
+++ b/netwerk/cache2/CacheObserver.h
@@ -35,16 +35,18 @@ class CacheObserver : public nsIObserver
   static uint32_t const MetadataMemoryLimit() // result in bytes.
     { return sMetadataMemoryLimit << 10; }
   static uint32_t const MemoryCacheCapacity(); // result in bytes.
   static uint32_t const DiskCacheCapacity() // result in bytes.
     { return sDiskCacheCapacity << 10; }
   static void SetDiskCacheCapacity(uint32_t); // parameter in bytes.
   static bool const SmartCacheSizeEnabled()
     { return sSmartCacheSizeEnabled; }
+  static uint32_t const PreloadChunkCount()
+    { return sPreloadChunkCount; }
   static uint32_t const MaxMemoryEntrySize() // result in bytes.
     { return sMaxMemoryEntrySize << 10; }
   static uint32_t const MaxDiskEntrySize() // result in bytes.
     { return sMaxDiskEntrySize << 10; }
   static uint32_t const CompressionLevel()
     { return sCompressionLevel; }
   static uint32_t const HalfLifeSeconds()
     { return sHalfLifeHours * 60 * 60; }
@@ -66,16 +68,17 @@ private:
   static uint32_t sUseNewCache;
   static bool sUseMemoryCache;
   static bool sUseDiskCache;
   static uint32_t sMetadataMemoryLimit;
   static int32_t sMemoryCacheCapacity;
   static int32_t sAutoMemoryCacheCapacity;
   static uint32_t sDiskCacheCapacity;
   static bool sSmartCacheSizeEnabled;
+  static uint32_t sPreloadChunkCount;
   static uint32_t sMaxMemoryEntrySize;
   static uint32_t sMaxDiskEntrySize;
   static uint32_t sCompressionLevel;
   static uint32_t sHalfLifeHours;
   static int32_t sHalfLifeExperiment;
   static bool sSanitizeOnShutdown;
   static bool sClearCacheOnShutdown;
 
--- a/netwerk/cookie/CookieServiceParent.cpp
+++ b/netwerk/cookie/CookieServiceParent.cpp
@@ -59,16 +59,22 @@ CookieServiceParent::CookieServiceParent
     already_AddRefed<nsCookieService>(nsCookieService::GetSingleton());
   NS_ASSERTION(mCookieService, "couldn't get nsICookieService");
 }
 
 CookieServiceParent::~CookieServiceParent()
 {
 }
 
+void
+CookieServiceParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005181
+}
+
 bool
 CookieServiceParent::RecvGetCookieString(const URIParams& aHost,
                                          const bool& aIsForeign,
                                          const bool& aFromHttp,
                                          const IPC::SerializedLoadContext&
                                                aLoadContext,
                                          nsCString* aResult)
 {
--- a/netwerk/cookie/CookieServiceParent.h
+++ b/netwerk/cookie/CookieServiceParent.h
@@ -23,17 +23,19 @@ public:
 
 protected:
   MOZ_WARN_UNUSED_RESULT bool
   GetAppInfoFromParams(const IPC::SerializedLoadContext &aLoadContext,
                        uint32_t& aAppId,
                        bool& aIsInBrowserElement,
                        bool& aIsPrivate);
 
-   virtual bool RecvGetCookieString(const URIParams& aHost,
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
+  virtual bool RecvGetCookieString(const URIParams& aHost,
                                    const bool& aIsForeign,
                                    const bool& aFromHttp,
                                    const IPC::SerializedLoadContext&
                                          loadContext,
                                    nsCString* aResult) MOZ_OVERRIDE;
 
   virtual bool RecvSetCookieString(const URIParams& aHost,
                                    const bool& aIsForeign,
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -173,16 +173,22 @@ NeckoParent::CreateChannelLoadContext(PB
   // the common case for most xpcshell tests.
   if (aSerialized.IsNotNull()) {
     aResult = new LoadContext(aSerialized, topFrameElement, appId, inBrowser);
   }
 
   return nullptr;
 }
 
+void
+NeckoParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005184
+}
+
 PHttpChannelParent*
 NeckoParent::AllocPHttpChannelParent(PBrowserParent* aBrowser,
                                      const SerializedLoadContext& aSerialized,
                                      const HttpChannelCreationArgs& aOpenArgs)
 {
   nsCOMPtr<nsILoadContext> loadContext;
   const char *error = CreateChannelLoadContext(aBrowser, Manager(),
                                                aSerialized, loadContext);
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -52,16 +52,18 @@ public:
    */
   MOZ_WARN_UNUSED_RESULT
   static const char*
   CreateChannelLoadContext(PBrowserParent* aBrowser,
                            PContentParent* aContent,
                            const SerializedLoadContext& aSerialized,
                            nsCOMPtr<nsILoadContext> &aResult);
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   virtual void
   CloneManagees(ProtocolBase* aSource,
               mozilla::ipc::ProtocolCloneContext* aCtx) MOZ_OVERRIDE;
   virtual PCookieServiceParent* AllocPCookieServiceParent() MOZ_OVERRIDE;
   virtual bool
   RecvPCookieServiceConstructor(PCookieServiceParent* aActor) MOZ_OVERRIDE
   {
     return PNeckoParent::RecvPCookieServiceConstructor(aActor);
--- a/netwerk/ipc/RemoteOpenFileParent.cpp
+++ b/netwerk/ipc/RemoteOpenFileParent.cpp
@@ -12,16 +12,22 @@
 #if !defined(XP_WIN) && !defined(MOZ_WIDGET_COCOA)
 #include <fcntl.h>
 #include <unistd.h>
 #endif
 
 namespace mozilla {
 namespace net {
 
+void
+RemoteOpenFileParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  // Implement me! Bug 1005186
+}
+
 bool
 RemoteOpenFileParent::OpenSendCloseDelete()
 {
 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
   MOZ_CRASH("OS X and Windows shouldn't be doing IPDL here");
 #else
 
   // TODO: make this async!
--- a/netwerk/ipc/RemoteOpenFileParent.h
+++ b/netwerk/ipc/RemoteOpenFileParent.h
@@ -17,16 +17,18 @@ namespace net {
 
 class RemoteOpenFileParent : public PRemoteOpenFileParent
 {
 public:
   RemoteOpenFileParent(nsIFileURL* aURI)
   : mURI(aURI)
   {}
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
+
   bool OpenSendCloseDelete();
 
 private:
   nsCOMPtr<nsIFileURL> mURI;
 };
 
 } // namespace net
 } // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_nsIBufferedOutputStream_writeFrom_block.js
@@ -0,0 +1,179 @@
+function run_test() { run_next_test(); }
+
+var CC = Components.Constructor;
+
+var Pipe = CC('@mozilla.org/pipe;1', Ci.nsIPipe, 'init');
+var BufferedOutputStream = CC('@mozilla.org/network/buffered-output-stream;1',
+                              Ci.nsIBufferedOutputStream, 'init');
+var ScriptableInputStream = CC('@mozilla.org/scriptableinputstream;1',
+                               Ci.nsIScriptableInputStream, 'init');
+
+// Verify that pipes behave as we expect. Subsequent tests assume
+// pipes behave as demonstrated here.
+add_test(function checkWouldBlockPipe() {
+  // Create a pipe with a one-byte buffer
+  var pipe = new Pipe(true, true, 1, 1);
+
+  // Writing two bytes should transfer only one byte, and
+  // return a partial count, not would-block.
+  do_check_eq(pipe.outputStream.write('xy', 2), 1);
+  do_check_eq(pipe.inputStream.available(), 1);
+
+  do_check_throws_nsIException(() => pipe.outputStream.write('y', 1),
+                               'NS_BASE_STREAM_WOULD_BLOCK');
+
+  // Check that nothing was written to the pipe.
+  do_check_eq(pipe.inputStream.available(), 1);
+  run_next_test();
+});
+
+// A writeFrom to a buffered stream should return
+// NS_BASE_STREAM_WOULD_BLOCK if no data was written.
+add_test(function writeFromBlocksImmediately() {
+  // Create a full pipe for our output stream. This will 'would-block' when
+  // written to.
+  var outPipe = new Pipe(true, true, 1, 1);
+  do_check_eq(outPipe.outputStream.write('x', 1), 1);
+
+  // Create a buffered stream, and fill its buffer, so the next write will
+  // try to flush.
+  var buffered = new BufferedOutputStream(outPipe.outputStream, 10);
+  do_check_eq(buffered.write('0123456789', 10), 10);
+
+  // Create a pipe with some data to be our input stream for the writeFrom
+  // call.
+  var inPipe = new Pipe(true, true, 1, 1);
+  do_check_eq(inPipe.outputStream.write('y', 1), 1);
+
+  do_check_eq(inPipe.inputStream.available(), 1);
+  do_check_throws_nsIException(() => buffered.writeFrom(inPipe.inputStream, 1),
+                               'NS_BASE_STREAM_WOULD_BLOCK');
+
+  // No data should have been consumed from the pipe.
+  do_check_eq(inPipe.inputStream.available(), 1);
+
+  run_next_test();
+});
+
+// A writeFrom to a buffered stream should return a partial count if any
+// data is written, when the last Flush call can only flush a portion of
+// the data.
+add_test(function writeFromReturnsPartialCountOnPartialFlush() {
+  // Create a pipe for our output stream. This will accept five bytes, and
+  // then 'would-block'.
+  var outPipe = new Pipe(true, true, 5, 1);
+
+  // Create a reference to the pipe's readable end that can be used
+  // from JavaScript.
+  var outPipeReadable = new ScriptableInputStream(outPipe.inputStream);
+
+  // Create a buffered stream whose buffer is too large to be flushed
+  // entirely to the output pipe.
+  var buffered = new BufferedOutputStream(outPipe.outputStream, 7);
+
+  // Create a pipe to be our input stream for the writeFrom call.
+  var inPipe = new Pipe(true, true, 15, 1);
+
+  // Write some data to our input pipe, for the rest of the test to consume.
+  do_check_eq(inPipe.outputStream.write('0123456789abcde', 15), 15);
+  do_check_eq(inPipe.inputStream.available(), 15);
+
+  // Write from the input pipe to the buffered stream. The buffered stream
+  // will fill its seven-byte buffer; and then the flush will only succeed
+  // in writing five bytes to the output pipe. The writeFrom call should
+  // return the number of bytes it consumed from inputStream.
+  do_check_eq(buffered.writeFrom(inPipe.inputStream, 11), 7);
+  do_check_eq(outPipe.inputStream.available(), 5);
+  do_check_eq(inPipe.inputStream.available(), 8);
+
+  // The partially-successful Flush should have created five bytes of
+  // available space in the buffered stream's buffer, so we should be able
+  // to write five bytes to it without blocking.
+  do_check_eq(buffered.writeFrom(inPipe.inputStream, 5), 5);
+  do_check_eq(outPipe.inputStream.available(), 5);
+  do_check_eq(inPipe.inputStream.available(), 3);
+
+  // Attempting to write any more data should would-block.
+  do_check_throws_nsIException(() => buffered.writeFrom(inPipe.inputStream, 1),
+                               'NS_BASE_STREAM_WOULD_BLOCK');
+
+  // No data should have been consumed from the pipe.
+  do_check_eq(inPipe.inputStream.available(), 3);
+
+  // Push the rest of the data through, checking that it all came through.
+  do_check_eq(outPipeReadable.available(), 5);
+  do_check_eq(outPipeReadable.read(5), '01234');
+  // Flush returns NS_ERROR_FAILURE if it can't transfer the full amount.
+  do_check_throws_nsIException(() => buffered.flush(), 'NS_ERROR_FAILURE');
+  do_check_eq(outPipeReadable.available(), 5);
+  do_check_eq(outPipeReadable.read(5), '56789');
+  buffered.flush();
+  do_check_eq(outPipeReadable.available(), 2);
+  do_check_eq(outPipeReadable.read(2), 'ab');
+  do_check_eq(buffered.writeFrom(inPipe.inputStream, 3), 3);
+  buffered.flush();
+  do_check_eq(outPipeReadable.available(), 3);
+  do_check_eq(outPipeReadable.read(3), 'cde');
+
+  run_next_test();
+});
+
+// A writeFrom to a buffered stream should return a partial count if any
+// data is written, when the last Flush call blocks.
+add_test(function writeFromReturnsPartialCountOnBlock() {
+  // Create a pipe for our output stream. This will accept five bytes, and
+  // then 'would-block'.
+  var outPipe = new Pipe(true, true, 5, 1);
+
+  // Create a reference to the pipe's readable end that can be used
+  // from JavaScript.
+  var outPipeReadable = new ScriptableInputStream(outPipe.inputStream);
+
+  // Create a buffered stream whose buffer is too large to be flushed
+  // entirely to the output pipe.
+  var buffered = new BufferedOutputStream(outPipe.outputStream, 7);
+
+  // Create a pipe to be our input stream for the writeFrom call.
+  var inPipe = new Pipe(true, true, 15, 1);
+
+  // Write some data to our input pipe, for the rest of the test to consume.
+  do_check_eq(inPipe.outputStream.write('0123456789abcde', 15), 15);
+  do_check_eq(inPipe.inputStream.available(), 15);
+
+  // Write enough from the input pipe to the buffered stream to fill the
+  // output pipe's buffer, and then flush it. Nothing should block or fail,
+  // but the output pipe should now be full.
+  do_check_eq(buffered.writeFrom(inPipe.inputStream, 5), 5);
+  buffered.flush();
+  do_check_eq(outPipe.inputStream.available(), 5);
+  do_check_eq(inPipe.inputStream.available(), 10);
+
+  // Now try to write more from the input pipe than the buffered stream's
+  // buffer can hold. It will attempt to flush, but the output pipe will
+  // would-block without accepting any data. writeFrom should return the
+  // correct partial count.
+  do_check_eq(buffered.writeFrom(inPipe.inputStream, 10), 7);
+  do_check_eq(outPipe.inputStream.available(), 5);
+  do_check_eq(inPipe.inputStream.available(), 3);
+
+  // Attempting to write any more data should would-block.
+  do_check_throws_nsIException(() => buffered.writeFrom(inPipe.inputStream, 3),
+                               'NS_BASE_STREAM_WOULD_BLOCK');
+
+  // No data should have been consumed from the pipe.
+  do_check_eq(inPipe.inputStream.available(), 3);
+
+  // Push the rest of the data through, checking that it all came through.
+  do_check_eq(outPipeReadable.available(), 5);
+  do_check_eq(outPipeReadable.read(5), '01234');
+  // Flush returns NS_ERROR_FAILURE if it can't transfer the full amount.
+  do_check_throws_nsIException(() => buffered.flush(), 'NS_ERROR_FAILURE');
+  do_check_eq(outPipeReadable.available(), 5);
+  do_check_eq(outPipeReadable.read(5), '56789');
+  do_check_eq(buffered.writeFrom(inPipe.inputStream, 3), 3);
+  buffered.flush();
+  do_check_eq(outPipeReadable.available(), 5);
+  do_check_eq(outPipeReadable.read(5), 'abcde');
+
+  run_next_test();
+});
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -13,16 +13,17 @@ support-files =
   data/test_readline6.txt
   data/test_readline7.txt
   data/test_readline8.txt
   data/signed_win.exe
   socks_client_subprocess.js
   test_link.desktop
   test_link.url
 
+[test_nsIBufferedOutputStream_writeFrom_block.js]
 [test_cache2-01-basic.js]
 [test_cache2-01a-basic-readonly.js]
 [test_cache2-01b-basic-datasize.js]
 [test_cache2-01c-basic-hasmeta-only.js]
 [test_cache2-01d-basic-not-wanted.js]
 [test_cache2-02-open-non-existing.js]
 [test_cache2-03-oncacheentryavail-throws.js]
 [test_cache2-04-oncacheentryavail-throws2x.js]
--- a/tools/profiler/tests/gtest/JSStreamWriterTest.cpp
+++ b/tools/profiler/tests/gtest/JSStreamWriterTest.cpp
@@ -174,10 +174,10 @@ TEST(JSStreamWriter, Complex2) {
                         b.Value("i");
                     b.EndObject();
                   b.EndArray();
               b.EndObject();
             b.EndArray();
         b.EndObject();
       b.EndArray();
   b.EndObject();
-  ASSERT_TRUE(ss.str().compare("{\"a\":[{\"b\":\"c\",\"d\":[{\"e\":[{\"f\":\"g\"},{\"h\":\"i\"}]}]}]}") 
+  ASSERT_TRUE(ss.str().compare("{\"a\":[{\"b\":\"c\",\"d\":[{\"e\":[{\"f\":\"g\"},{\"h\":\"i\"}]}]}]}") == 0);
 }
--- a/tools/profiler/tests/gtest/moz.build
+++ b/tools/profiler/tests/gtest/moz.build
@@ -13,12 +13,13 @@ if CONFIG['OS_TARGET'] in ('Android', 'L
 
 EXPORT_LIBRARY = True
 
 LOCAL_INCLUDES += [
     '/tools/profiler',
 ]
 
 UNIFIED_SOURCES += [
+    'JSStreamWriterTest.cpp',
     'ThreadProfileTest.cpp',
 ]
 
 FINAL_LIBRARY = 'xul-gtest'
--- a/xpcom/io/nsIOutputStream.idl
+++ b/xpcom/io/nsIOutputStream.idl
@@ -87,17 +87,18 @@ interface nsIOutputStream : nsISupports
      * Writes data into the stream from an input stream.
      *
      * @param aFromStream the stream containing the data to be written
      * @param aCount the maximum number of bytes to be written
      *
      * @return number of bytes written (may be less than aCount)
      *
      * @throws NS_BASE_STREAM_WOULD_BLOCK if writing to the output stream would
-     *    block the calling thread (non-blocking mode only)
+     *    block the calling thread (non-blocking mode only). This failure
+     *    means no bytes were transferred.
      * @throws <other-error> on failure
      *
      * NOTE: This method is defined by this interface in order to allow the
      * output stream to efficiently copy the data from the input stream into
      * its internal buffer (if any). If this method was provided as an external
      * facility, a separate char* buffer would need to be used in order to call
      * the output stream's other Write method.
      */
@@ -113,17 +114,18 @@ interface nsIOutputStream : nsISupports
      *
      * @param aReader the "provider" of the data to be written
      * @param aClosure opaque parameter passed to reader
      * @param aCount the maximum number of bytes to be written
      *
      * @return number of bytes written (may be less than aCount)
      *
      * @throws NS_BASE_STREAM_WOULD_BLOCK if writing to the output stream would
-     *    block the calling thread (non-blocking mode only)
+     *    block the calling thread (non-blocking mode only). This failure
+     *    means no bytes were transferred.
      * @throws NS_ERROR_NOT_IMPLEMENTED if the stream has no underlying buffer
      * @throws <other-error> on failure
      *
      * NOTE: this function may be unimplemented if a stream has no underlying
      * buffer (e.g., socket output stream).
      */
     [noscript] unsigned long writeSegments(in nsReadSegmentFun aReader,
                                            in voidPtr aClosure,