Merge m-c to fx-team.
authorRyan VanderMeulen <ryanvm@gmail.com>
Fri, 25 Apr 2014 16:33:22 -0400
changeset 180805 a9d318e1cc9df09b72a3e2e6dbfde4f65196e3ad
parent 180804 4ce5da6bd6d64165cc70567dda136e2e363f5406 (current diff)
parent 180680 0e91262606a631fbc4e0ea24c1447c0604787de1 (diff)
child 180806 49ec0d4753ddfea2b3fe3f2fce2e3c47dbbf064c
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
milestone31.0a1
Merge m-c to fx-team.
intl/uconv/tests/unit/test_bug718500.js
security/nss/cmd/libpkix/pkix/params/test_buildparams.c
security/nss/lib/libpkix/pkix/params/pkix_buildparams.c
security/nss/lib/libpkix/pkix/params/pkix_buildparams.h
security/nss/lib/softoken/ecdecode.c
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <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"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <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="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="0292e64ef8451df104dcf9ac3b2c6749b81684dd"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="85f9690323b235f4dcf2901ea2240d3c60fc22a0"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame/config.json
+++ b/b2g/config/flame/config.json
@@ -9,17 +9,17 @@
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml"
     ],
     "public_upload_files": [
         "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
         "{objdir}/dist/b2g-*.tar.gz",
         "{workdir}/sources.xml",
-        "{objdir}/dist/b2g-update/b2g-gecko-update.mar"
+        "{objdir}/dist/b2g-update/*.mar"
     ],
     "zip_files": [
         ["{workdir}/out/target/product/flame/*.img", "out/target/product/flame/"],
         ["{workdir}/boot.img", "out/target/product/flame/"],
         "{workdir}/flash.sh",
         "{workdir}/load-config.sh",
         "{workdir}/.config",
         "{workdir}/sources.xml"
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -13,17 +13,17 @@
   <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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <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"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "2fccee502f455ba2ca7178efa5cf247d90df8afb", 
+    "revision": "a0017eff21d39da46b6e8cf993f8fecf9ccb2af2", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,17 +12,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <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="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- 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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <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,17 +14,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <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="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -12,17 +12,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <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="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -12,17 +12,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <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"/>
new file mode 100644
--- /dev/null
+++ b/b2g/config/mozconfigs/linux32_gecko/debug
@@ -0,0 +1,36 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+. "$topsrcdir/build/unix/mozconfig.linux32"
+
+ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
+ac_add_options --enable-update-packaging
+ac_add_options --enable-signmar
+ac_add_options --enable-debug
+
+# Nightlies only since this has a cost in performance
+#ac_add_options --enable-js-diagnostics
+
+# This will overwrite the default of stripping everything and keep the symbol table.
+# This is useful for profiling and debugging and only increases the package size
+# by 2 MBs.
+STRIP_FLAGS="--strip-debug"
+
+# Needed to enable breakpad in application.ini
+export MOZILLA_OFFICIAL=1
+
+export MOZ_TELEMETRY_REPORTING=1
+
+# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
+# DISABLED WHILE NOT ON TRY ac_add_options --enable-warnings-as-errors
+
+# Use ccache
+. "$topsrcdir/build/mozconfig.cache"
+
+#B2G options
+ac_add_options --enable-application=b2g
+ENABLE_MARIONETTE=1
+ac_add_options --disable-elf-hack
+export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+GAIADIR=$topsrcdir/gaia
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
new file mode 100644
--- /dev/null
+++ b/b2g/config/mozconfigs/win32_gecko/debug
@@ -0,0 +1,31 @@
+. "$topsrcdir/b2g/config/mozconfigs/common"
+
+ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
+ac_add_options --enable-update-packaging
+ac_add_options --enable-jemalloc
+ac_add_options --enable-signmar
+ac_add_options --enable-debug
+
+# Nightlies only since this has a cost in performance
+ac_add_options --enable-js-diagnostics
+
+# Needed to enable breakpad in application.ini
+export MOZILLA_OFFICIAL=1
+
+export MOZ_TELEMETRY_REPORTING=1
+
+if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
+  . $topsrcdir/build/win32/mozconfig.vs2010-win64
+else
+  . $topsrcdir/build/win32/mozconfig.vs2010
+fi
+
+# B2G Options
+ac_add_options --enable-application=b2g
+ENABLE_MARIONETTE=1
+
+export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
+
+GAIADIR=$topsrcdir/gaia
+
+. "$topsrcdir/b2g/config/mozconfigs/common.override"
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,17 +12,17 @@
   <!--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="facd91d31db983a60c7f1035ca01b727c7a1de65"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="56f79456db5dc3ca010a56d09e1e8cc15a2408db"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="266bca6e60dad43e395f38b66edabe8bdc882334"/>
   <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="8d6c36d74ba9aefbc8c3618fc93dd4907a0dbf5e"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -10,17 +10,16 @@
 
 DEPRECATED_OPERATION(GetAttributeNode)
 DEPRECATED_OPERATION(SetAttributeNode)
 DEPRECATED_OPERATION(GetAttributeNodeNS)
 DEPRECATED_OPERATION(SetAttributeNodeNS)
 DEPRECATED_OPERATION(RemoveAttributeNode)
 DEPRECATED_OPERATION(CreateAttribute)
 DEPRECATED_OPERATION(CreateAttributeNS)
-DEPRECATED_OPERATION(Specified)
 DEPRECATED_OPERATION(OwnerElement)
 DEPRECATED_OPERATION(NodeValue)
 DEPRECATED_OPERATION(TextContent)
 DEPRECATED_OPERATION(EnablePrivilege)
 DEPRECATED_OPERATION(InputEncoding)
 DEPRECATED_OPERATION(MozBeforePaint)
 DEPRECATED_OPERATION(DOMExceptionCode)
 DEPRECATED_OPERATION(NoExposedProps)
--- a/content/base/src/Attr.cpp
+++ b/content/base/src/Attr.cpp
@@ -221,17 +221,16 @@ Attr::SetValue(const nsAString& aValue)
   ErrorResult rv;
   SetValue(aValue, rv);
   return rv.ErrorCode();
 }
 
 bool
 Attr::Specified() const
 {
-  OwnerDoc()->WarnOnceAbout(nsIDocument::eSpecified);
   return true;
 }
 
 NS_IMETHODIMP
 Attr::GetSpecified(bool* aSpecified)
 {
   NS_ENSURE_ARG_POINTER(aSpecified);
   *aSpecified = Specified();
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -1488,49 +1488,53 @@ nsFrameScriptExecutor::TryCacheLoadAndCo
   NS_NewChannel(getter_AddRefs(channel), uri);
   if (!channel) {
     return;
   }
 
   nsCOMPtr<nsIInputStream> input;
   channel->Open(getter_AddRefs(input));
   nsString dataString;
+  jschar* dataStringBuf = nullptr;
+  size_t dataStringLength = 0;
   uint64_t avail64 = 0;
   if (input && NS_SUCCEEDED(input->Available(&avail64)) && avail64) {
     if (avail64 > UINT32_MAX) {
       return;
     }
     nsCString buffer;
     uint32_t avail = (uint32_t)std::min(avail64, (uint64_t)UINT32_MAX);
     if (NS_FAILED(NS_ReadInputStreamToString(input, buffer, avail))) {
       return;
     }
     nsScriptLoader::ConvertToUTF16(channel, (uint8_t*)buffer.get(), avail,
-                                   EmptyString(), nullptr, dataString);
+                                   EmptyString(), nullptr,
+                                   dataStringBuf, dataStringLength);
   }
 
-  if (!dataString.IsEmpty()) {
+  JS::SourceBufferHolder srcBuf(dataStringBuf, dataStringLength,
+                                JS::SourceBufferHolder::GiveOwnership);
+
+  if (dataStringBuf && dataStringLength > 0) {
     AutoSafeJSContext cx;
     JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
     if (global) {
       JSAutoCompartment ac(cx, global);
       JS::CompileOptions options(cx);
       options.setFileAndLine(url.get(), 1);
       JS::Rooted<JSScript*> script(cx);
       JS::Rooted<JSObject*> funobj(cx);
       if (aRunInGlobalScope) {
         options.setNoScriptRval(true);
-        script = JS::Compile(cx, JS::NullPtr(), options, dataString.get(),
-                             dataString.Length());
+        script = JS::Compile(cx, JS::NullPtr(), options, srcBuf);
       } else {
         JS::Rooted<JSFunction *> fun(cx);
         fun = JS::CompileFunction(cx, JS::NullPtr(), options,
                                   nullptr, 0, nullptr, /* name, nargs, args */
-                                  dataString.get(),
-                                  dataString.Length());
+                                  srcBuf);
         if (!fun) {
           return;
         }
         funobj = JS_GetFunctionObject(fun);
       }
 
       if (!script && !funobj) {
         return;
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -1281,17 +1281,18 @@ nsINode::GetOwnerGlobal()
 }
 
 bool
 nsINode::UnoptimizableCCNode() const
 {
   const uintptr_t problematicFlags = (NODE_IS_ANONYMOUS_ROOT |
                                       NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE |
                                       NODE_IS_NATIVE_ANONYMOUS_ROOT |
-                                      NODE_MAY_BE_IN_BINDING_MNGR);
+                                      NODE_MAY_BE_IN_BINDING_MNGR |
+                                      NODE_IS_IN_SHADOW_TREE);
   return HasFlag(problematicFlags) ||
          NodeType() == nsIDOMNode::ATTRIBUTE_NODE ||
          // For strange cases like xbl:content/xbl:children
          (IsElement() &&
           AsElement()->IsInNamespace(kNameSpaceID_XBL));
 }
 
 /* static */
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -71,22 +71,31 @@ class nsScriptLoadRequest MOZ_FINAL : pu
 public:
   nsScriptLoadRequest(nsIScriptElement* aElement,
                       uint32_t aVersion,
                       CORSMode aCORSMode)
     : mElement(aElement),
       mLoading(true),
       mIsInline(true),
       mHasSourceMapURL(false),
+      mScriptTextBuf(nullptr),
+      mScriptTextLength(0),
       mJSVersion(aVersion),
       mLineNo(1),
       mCORSMode(aCORSMode)
   {
   }
 
+  ~nsScriptLoadRequest()
+  {
+    if (mScriptTextBuf) {
+      js_free(mScriptTextBuf);
+    }
+  }
+
   NS_DECL_THREADSAFE_ISUPPORTS
 
   void FireScriptAvailable(nsresult aResult)
   {
     mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
   }
   void FireScriptEvaluated(nsresult aResult)
   {
@@ -98,17 +107,18 @@ public:
     return mElement == nullptr;
   }
 
   nsCOMPtr<nsIScriptElement> mElement;
   bool mLoading;          // Are we still waiting for a load to complete?
   bool mIsInline;         // Is the script inline or loaded?
   bool mHasSourceMapURL;  // Does the HTTP header have a source map url?
   nsString mSourceMapURL; // Holds source map url for loaded scripts
-  nsString mScriptText;   // Holds script for text loaded scripts
+  jschar* mScriptTextBuf;   // Holds script text for non-inline scripts. Don't
+  size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
   uint32_t mJSVersion;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   nsAutoCString mURL;   // Keep the URI's filename alive during off thread parsing.
   int32_t mLineNo;
   const CORSMode mCORSMode;
 };
 
@@ -846,25 +856,25 @@ nsScriptLoader::AttemptAsyncScriptParse(
   }
 
   AutoPushJSContext cx(context->GetNativeContext());
   JS::Rooted<JSObject*> global(cx, globalObject->GetGlobalJSObject());
 
   JS::CompileOptions options(cx);
   FillCompileOptionsForRequest(aRequest, global, &options);
 
-  if (!JS::CanCompileOffThread(cx, options, aRequest->mScriptText.Length())) {
+  if (!JS::CanCompileOffThread(cx, options, aRequest->mScriptTextLength)) {
     return NS_ERROR_FAILURE;
   }
 
   nsRefPtr<NotifyOffThreadScriptLoadCompletedRunnable> runnable =
     new NotifyOffThreadScriptLoadCompletedRunnable(aRequest, this);
 
   if (!JS::CompileOffThread(cx, options,
-                            aRequest->mScriptText.get(), aRequest->mScriptText.Length(),
+                            aRequest->mScriptTextBuf, aRequest->mScriptTextLength,
                             OffThreadScriptLoaderCallback,
                             static_cast<void*>(runnable))) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   mDocument->BlockOnload();
 
   unused << runnable.forget();
@@ -879,37 +889,49 @@ nsScriptLoader::ProcessRequest(nsScriptL
 
   if (!aOffThreadToken) {
     nsresult rv = AttemptAsyncScriptParse(aRequest);
     if (rv != NS_ERROR_FAILURE)
       return rv;
   }
 
   NS_ENSURE_ARG(aRequest);
-  nsAFlatString* script;
   nsAutoString textData;
+  const jschar* scriptBuf = nullptr;
+  size_t scriptLength = 0;
+  JS::SourceBufferHolder::Ownership giveScriptOwnership =
+    JS::SourceBufferHolder::NoOwnership;
 
   nsCOMPtr<nsIDocument> doc;
 
   nsCOMPtr<nsINode> scriptElem = do_QueryInterface(aRequest->mElement);
 
   // If there's no script text, we try to get it from the element
   if (aRequest->mIsInline) {
     // XXX This is inefficient - GetText makes multiple
     // copies.
     aRequest->mElement->GetScriptText(textData);
 
-    script = &textData;
+    scriptBuf = textData.get();
+    scriptLength = textData.Length();
+    giveScriptOwnership = JS::SourceBufferHolder::NoOwnership;
   }
   else {
-    script = &aRequest->mScriptText;
+    scriptBuf = aRequest->mScriptTextBuf;
+    scriptLength = aRequest->mScriptTextLength;
+
+    giveScriptOwnership = JS::SourceBufferHolder::GiveOwnership;
+    aRequest->mScriptTextBuf = nullptr;
+    aRequest->mScriptTextLength = 0;
 
     doc = scriptElem->OwnerDoc();
   }
 
+  JS::SourceBufferHolder srcBuf(scriptBuf, scriptLength, giveScriptOwnership);
+
   nsCOMPtr<nsIScriptElement> oldParserInsertedScript;
   uint32_t parserCreated = aRequest->mElement->GetParserCreated();
   if (parserCreated) {
     oldParserInsertedScript = mCurrentParserInsertedScript;
     mCurrentParserInsertedScript = aRequest->mElement;
   }
 
   FireScriptAvailable(NS_OK, aRequest);
@@ -932,17 +954,17 @@ nsScriptLoader::ProcessRequest(nsScriptL
   }
 
   nsresult rv = NS_OK;
   if (runScript) {
     if (doc) {
       doc->BeginEvaluatingExternalScript();
     }
     aRequest->mElement->BeginEvaluating();
-    rv = EvaluateScript(aRequest, *script, aOffThreadToken);
+    rv = EvaluateScript(aRequest, srcBuf, aOffThreadToken);
     aRequest->mElement->EndEvaluating();
     if (doc) {
       doc->EndEvaluatingExternalScript();
     }
 
     nsContentUtils::DispatchTrustedEvent(scriptElem->OwnerDoc(),
                                          scriptElem,
                                          NS_LITERAL_STRING("afterscriptexecute"),
@@ -1039,17 +1061,17 @@ nsScriptLoader::FillCompileOptionsForReq
                                               /* aAllowWrapping = */ true))) {
     MOZ_ASSERT(elementVal.isObject());
     aOptions->setElement(&elementVal.toObject());
   }
 }
 
 nsresult
 nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
-                               const nsAFlatString& aScript,
+                               JS::SourceBufferHolder& aSrcBuf,
                                void** aOffThreadToken)
 {
   // We need a document to evaluate scripts.
   if (!mDocument) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIContent> scriptContent(do_QueryInterface(aRequest->mElement));
@@ -1090,17 +1112,17 @@ nsScriptLoader::EvaluateScript(nsScriptL
   context->SetProcessingScriptTag(true);
 
   // Update our current script.
   nsCOMPtr<nsIScriptElement> oldCurrent = mCurrentScript;
   mCurrentScript = aRequest->mElement;
 
   JS::CompileOptions options(entryScript.cx());
   FillCompileOptionsForRequest(aRequest, global, &options);
-  nsresult rv = nsJSUtils::EvaluateString(entryScript.cx(), aScript, global, options,
+  nsresult rv = nsJSUtils::EvaluateString(entryScript.cx(), aSrcBuf, global, options,
                                           aOffThreadToken);
 
   // Put the old script back in case it wants to do anything else.
   mCurrentScript = oldCurrent;
 
   context->SetProcessingScriptTag(oldProcessingScriptTag);
   return rv;
 }
@@ -1241,20 +1263,22 @@ DetectByteOrderMark(const unsigned char*
     break;
   }
   return !oCharset.IsEmpty();
 }
 
 /* static */ nsresult
 nsScriptLoader::ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
                                uint32_t aLength, const nsAString& aHintCharset,
-                               nsIDocument* aDocument, nsString& aString)
+                               nsIDocument* aDocument,
+                               jschar*& aBufOut, size_t& aLengthOut)
 {
   if (!aLength) {
-    aString.Truncate();
+    aBufOut = nullptr;
+    aLengthOut = 0;
     return NS_OK;
   }
 
   // The encoding info precedence is as follows from high to low:
   // The BOM
   // HTTP Content-Type (if name recognized)
   // charset attribute (if name recognized)
   // The encoding of the document
@@ -1297,27 +1321,33 @@ nsScriptLoader::ConvertToUTF16(nsIChanne
 
   int32_t unicodeLength = 0;
 
   nsresult rv =
     unicodeDecoder->GetMaxLength(reinterpret_cast<const char*>(aData),
                                  aLength, &unicodeLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!aString.SetLength(unicodeLength, fallible_t())) {
+  aBufOut = static_cast<jschar*>(js_malloc(unicodeLength * sizeof(jschar)));
+  if (!aBufOut) {
+    aLengthOut = 0;
     return NS_ERROR_OUT_OF_MEMORY;
   }
-
-  char16_t *ustr = aString.BeginWriting();
+  aLengthOut = unicodeLength;
 
   rv = unicodeDecoder->Convert(reinterpret_cast<const char*>(aData),
-                               (int32_t *) &aLength, ustr,
+                               (int32_t *) &aLength, aBufOut,
                                &unicodeLength);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
-  aString.SetLength(unicodeLength);
+  aLengthOut = unicodeLength;
+  if (NS_FAILED(rv)) {
+    js_free(aBufOut);
+    aBufOut = nullptr;
+    aLengthOut = 0;
+  }
   return rv;
 }
 
 NS_IMETHODIMP
 nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
                                  nsISupports* aContext,
                                  nsresult aStatus,
                                  uint32_t aStringLen,
@@ -1421,17 +1451,17 @@ nsScriptLoader::PrepareLoadedRequest(nsS
       aRequest->mElement->GetScriptCharset(hintCharset);
     } else {
       nsTArray<PreloadInfo>::index_type i =
         mPreloads.IndexOf(aRequest, 0, PreloadRequestComparator());
       NS_ASSERTION(i != mPreloads.NoIndex, "Incorrect preload bookkeeping");
       hintCharset = mPreloads[i].mCharset;
     }
     rv = ConvertToUTF16(channel, aString, aStringLen, hintCharset, mDocument,
-                        aRequest->mScriptText);
+                        aRequest->mScriptTextBuf, aRequest->mScriptTextLength);
 
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // This assertion could fire errorously if we ran out of memory when
   // inserting the request in the array. However it's an unlikely case
   // so if you see this assertion it is likely something else that is
   // wrong, especially if you see it more than once.
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -16,16 +16,20 @@
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsIDocument.h"
 #include "nsIStreamLoader.h"
 
 class nsScriptLoadRequest;
 class nsIURI;
 
+namespace JS {
+  class SourceBufferHolder;
+}
+
 //////////////////////////////////////////////////////////////
 // Script loader implementation
 //////////////////////////////////////////////////////////////
 
 class nsScriptLoader : public nsIStreamLoaderObserver
 {
   friend class nsScriptRequestProcessor;
 public:
@@ -135,22 +139,27 @@ public:
    * Convert the given buffer to a UTF-16 string.
    * @param aChannel     Channel corresponding to the data. May be null.
    * @param aData        The data to convert
    * @param aLength      Length of the data
    * @param aHintCharset Hint for the character set (e.g., from a charset
    *                     attribute). May be the empty string.
    * @param aDocument    Document which the data is loaded for. Must not be
    *                     null.
-   * @param aString      [out] Data as converted to unicode
+   * @param aBufOut      [out] jschar array allocated by ConvertToUTF16 and
+   *                     containing data converted to unicode.  Caller must
+   *                     js_free() this data when no longer needed.
+   * @param aLengthOut   [out] Length of array returned in aBufOut in number
+   *                     of jschars.
    */
   static nsresult ConvertToUTF16(nsIChannel* aChannel, const uint8_t* aData,
                                  uint32_t aLength,
                                  const nsAString& aHintCharset,
-                                 nsIDocument* aDocument, nsString& aString);
+                                 nsIDocument* aDocument,
+                                 jschar*& aBufOut, size_t& aLengthOut);
 
   /**
    * Processes any pending requests that are ready for processing.
    */
   void ProcessPendingRequests();
 
   /**
    * Check whether it's OK to load a script from aURI in
@@ -272,17 +281,17 @@ private:
   nsresult AttemptAsyncScriptParse(nsScriptLoadRequest* aRequest);
   nsresult ProcessRequest(nsScriptLoadRequest* aRequest,
                           void **aOffThreadToken = nullptr);
   void FireScriptAvailable(nsresult aResult,
                            nsScriptLoadRequest* aRequest);
   void FireScriptEvaluated(nsresult aResult,
                            nsScriptLoadRequest* aRequest);
   nsresult EvaluateScript(nsScriptLoadRequest* aRequest,
-                          const nsAFlatString& aScript,
+                          JS::SourceBufferHolder& aSrcBuf,
                           void **aOffThreadToken);
 
   already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject();
   void FillCompileOptionsForRequest(nsScriptLoadRequest *aRequest,
                                     JS::Handle<JSObject *> aScopeChain,
                                     JS::CompileOptions *aOptions);
 
   nsresult PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -844,17 +844,17 @@ MediaStreamGraphImpl::CreateOrDestroyAud
         audioOutputStream->mAudioPlaybackStartTime = aAudioOutputStartTime;
         audioOutputStream->mBlockedAudioTime = 0;
         audioOutputStream->mLastTickWritten = 0;
         audioOutputStream->mStream = new AudioStream();
         // XXX for now, allocate stereo output. But we need to fix this to
         // match the system's ideal channel configuration.
         // NOTE: we presume this is either fast or async-under-the-covers
         audioOutputStream->mStream->Init(2, mSampleRate,
-                                         AudioChannel::Normal,
+                                         aStream->mAudioChannelType,
                                          AudioStream::LowLatency);
         audioOutputStream->mTrackID = tracks->GetID();
 
         LogLatency(AsyncLatencyLogger::AudioStreamCreate,
                    reinterpret_cast<uint64_t>(aStream),
                    reinterpret_cast<int64_t>(audioOutputStream->mStream.get()));
       }
     }
@@ -1779,16 +1779,17 @@ MediaStream::MediaStream(DOMMediaStream*
   , mNotifiedBlocked(false)
   , mHasCurrentData(false)
   , mNotifiedHasCurrentData(false)
   , mWrapper(aWrapper)
   , mMainThreadCurrentTime(0)
   , mMainThreadFinished(false)
   , mMainThreadDestroyed(false)
   , mGraph(nullptr)
+  , mAudioChannelType(dom::AudioChannel::Normal)
 {
   MOZ_COUNT_CTOR(MediaStream);
   // aWrapper should not already be connected to a MediaStream! It needs
   // to be hooked up to this stream, and since this stream is only just
   // being created now, aWrapper must not be connected to anything.
   NS_ASSERTION(!aWrapper || !aWrapper->GetStream(),
                "Wrapper already has another media stream hooked up to it!");
 }
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -14,16 +14,17 @@
 #include "StreamBuffer.h"
 #include "TimeVarying.h"
 #include "VideoFrameContainer.h"
 #include "VideoSegment.h"
 #include "MainThreadUtils.h"
 #include "nsAutoRef.h"
 #include "speex/speex_resampler.h"
 #include "AudioMixer.h"
+#include "mozilla/dom/AudioChannelBinding.h"
 
 class nsIRunnable;
 
 template <>
 class nsAutoRefTraits<SpeexResamplerState> : public nsPointerRefTraits<SpeexResamplerState>
 {
   public:
   static void Release(SpeexResamplerState* aState) { speex_resampler_destroy(aState); }
@@ -519,16 +520,18 @@ public:
   virtual bool MainThreadNeedsUpdates() const
   {
     return true;
   }
 
   virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
   virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
 
+  void SetAudioChannelType(dom::AudioChannel aType) { mAudioChannelType = aType; }
+
 protected:
   virtual void AdvanceTimeVaryingValuesToCurrentTime(GraphTime aCurrentTime, GraphTime aBlockedTime)
   {
     mBufferStartTime += aBlockedTime;
     mGraphUpdateIndices.InsertTimeAtStart(aBlockedTime);
     mGraphUpdateIndices.AdvanceCurrentTime(aCurrentTime);
     mExplicitBlockerCount.AdvanceCurrentTime(aCurrentTime);
 
@@ -645,16 +648,18 @@ protected:
   DOMMediaStream* mWrapper;
   // Main-thread views of state
   StreamTime mMainThreadCurrentTime;
   bool mMainThreadFinished;
   bool mMainThreadDestroyed;
 
   // Our media stream graph
   MediaStreamGraphImpl* mGraph;
+
+  dom::AudioChannel mAudioChannelType;
 };
 
 /**
  * This is a stream into which a decoder can write audio and video.
  *
  * Audio and video can be written on any thread, but you probably want to
  * always write from the same thread to avoid unexpected interleavings.
  */
--- a/content/media/omx/OmxDecoder.cpp
+++ b/content/media/omx/OmxDecoder.cpp
@@ -419,28 +419,16 @@ bool OmxDecoder::TryLoad() {
   // read video metadata
   if (mVideoSource.get() && !SetVideoFormat()) {
     NS_WARNING("Couldn't set OMX video format");
     return false;
   }
 
   // read audio metadata
   if (mAudioSource.get()) {
-    // For RTSP, we don't read the audio source for now.
-    // The metadata of RTSP will be obtained through SDP at connection time.
-    if (mResource->GetRtspPointer()) {
-      sp<MetaData> meta = mAudioSource->getFormat();
-      if (!meta->findInt32(kKeyChannelCount, &mAudioChannels) ||
-          !meta->findInt32(kKeySampleRate, &mAudioSampleRate)) {
-        NS_WARNING("Couldn't get audio metadata from OMX decoder");
-        return false;
-      }
-      return true;
-    }
-
     // To reliably get the channel and sample rate data we need to read from the
     // audio source until we get a INFO_FORMAT_CHANGE status
     status_t err = mAudioSource->read(&mAudioBuffer);
     if (err != INFO_FORMAT_CHANGED) {
       if (err != OK) {
         NS_WARNING("Couldn't read audio buffer from OMX decoder");
         return false;
       }
--- a/content/media/omx/RtspOmxReader.cpp
+++ b/content/media/omx/RtspOmxReader.cpp
@@ -298,21 +298,21 @@ nsresult RtspOmxReader::Seek(int64_t aTi
   // the seek time to OMX a/v decoders.
   return MediaOmxReader::Seek(aTime, aStartTime, aEndTime, aCurrentTime);
 }
 
 nsresult
 RtspOmxReader::ReadMetadata(MediaInfo* aInfo,
                             MetadataTags** aTags)
 {
+  SetActive();
+
   nsresult rv = MediaOmxReader::ReadMetadata(aInfo, aTags);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  SetActive();
-
   return NS_OK;
 }
 
 void RtspOmxReader::SetIdle() {
   // Call parent class to set OMXCodec idle.
   MediaOmxReader::SetIdle();
 
   // Need to pause RTSP streaming OMXCodec decoding.
--- a/content/media/omx/RtspOmxReader.h
+++ b/content/media/omx/RtspOmxReader.h
@@ -60,25 +60,16 @@ public:
   // we returned are not useful for the MediaDecodeStateMachine. Unlike the
   // ChannelMediaResource, it has a "cache" that can store the whole streaming
   // data so the |GetBuffered| function can retrieve useful time ranges.
   virtual nsresult GetBuffered(mozilla::dom::TimeRanges* aBuffered,
                                int64_t aStartTime) MOZ_FINAL MOZ_OVERRIDE {
     return NS_OK;
   }
 
-  // Override FindStartTime() to return null pointer.
-  // For Rtsp, we don't have the first video frame in DECODING_METADATA state.
-  // It will be available until player request Play() and media decoder enters
-  // DECODING state.
-  virtual VideoData* FindStartTime(int64_t& aOutStartTime)
-    MOZ_FINAL MOZ_OVERRIDE {
-    return nullptr;
-  }
-
   virtual void SetIdle() MOZ_OVERRIDE;
   virtual void SetActive() MOZ_OVERRIDE;
 
 private:
   // A pointer to RtspMediaResource for calling the Rtsp specific function.
   // The lifetime of mRtspResource is controlled by MediaDecoder. MediaDecoder
   // holds the MediaDecoderStateMachine and RtspMediaResource.
   // And MediaDecoderStateMachine holds this RtspOmxReader.
--- a/content/media/test/mochitest.ini
+++ b/content/media/test/mochitest.ini
@@ -474,17 +474,17 @@ skip-if = appname == "seamonkey" # See b
 skip-if = toolkit == 'android' || os == "win" || (toolkit == 'gonk' && !debug) # See bug 832768 and 864682, b2g(assertion failures)
 [test_bug465498.html]
 skip-if = os == "win" || (toolkit == 'gonk' && !debug) # See bug 832768 and 864682
 [test_bug493187.html]
 skip-if = os == "win" || (buildapp=='b2g'&&debug) || (toolkit == 'gonk' && !debug) # See bug 707777, #b2g-emulator-debug - process crash
 [test_media_selection.html]
 skip-if = os == "win" || (toolkit == 'gonk' && !debug) # See bug 897843, b2g(timed out)
 [test_seek.html]
-skip-if = toolkit == 'android' || os == "win" || (toolkit == 'gonk' && !debug) # See bug 832678, 795271, and 857424 # android(bug 845162) androidx86(bug 845162)
+skip-if = toolkit == 'android' || (toolkit == 'gonk' && !debug) # See bug 832678, 795271, and 857424 # android(bug 845162) androidx86(bug 845162)
 
 # The tests below contain backend-specific tests. Write backend independent
 # tests rather than adding to this list.
 
 [test_can_play_type_webm.html]
 run-if = webm
 [test_can_play_type_no_webm.html]
 skip-if = webm
--- a/content/media/test/test_seek.html
+++ b/content/media/test/test_seek.html
@@ -18,16 +18,17 @@
   <script type="text/javascript" src="seek11.js"></script>
   <script type="text/javascript" src="seek12.js"></script>
   <script type="text/javascript" src="seek13.js"></script>
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
+SimpleTest.requestLongerTimeout(3);
 var manager = new MediaTestManager;
 
 // https://bugzilla.mozilla.org/show_bug.cgi?id=634747
 if (navigator.platform.startsWith("Win")) {
   SimpleTest.expectAssertions(0, 5);
 } else {
   // This is "###!!! ASSERTION: Page read cursor should be inside range: 'mPageOffset <= endOffset'"
   // https://bugzilla.mozilla.org/show_bug.cgi?id=846769
@@ -68,19 +69,18 @@ function startTest(test, token) {
   var name = test.name + " seek test " + test.number;
   var localIs = function(name) { return function(a, b, msg) {
     is(a, b, name + ": " + msg);
   }}(name);
   var localOk = function(name) { return function(a, msg) {
     ok(a, name + ": " + msg);
   }}(name);
   var localFinish = function(v, manager) { return function() {
-    if (v.parentNode) {
-      v.parentNode.removeChild(v);
-    }
+    v.onerror = null;
+    removeNodeAndSource(v);
     dump("SEEK-TEST: Finished " + name + "\n");
     manager.finished(v.token);
   }}(v, manager);
   dump("SEEK-TEST: Started " + name + "\n");
   window['test_seek' + test.number](v, test.duration/2, localIs, localOk, localFinish);
 }
 
 manager.runTests(createTestArray(), startTest);
--- a/content/media/webaudio/AudioContext.cpp
+++ b/content/media/webaudio/AudioContext.cpp
@@ -72,33 +72,34 @@ static float GetSampleRateForAudioContex
   } else {
     AudioStream::InitPreferredSampleRate();
     return static_cast<float>(AudioStream::PreferredSampleRate());
   }
 }
 
 AudioContext::AudioContext(nsPIDOMWindow* aWindow,
                            bool aIsOffline,
+                           AudioChannel aChannel,
                            uint32_t aNumberOfChannels,
                            uint32_t aLength,
                            float aSampleRate)
   : DOMEventTargetHelper(aWindow)
   , mSampleRate(GetSampleRateForAudioContext(aIsOffline, aSampleRate))
   , mNumberOfChannels(aNumberOfChannels)
   , mNodeCount(0)
   , mIsOffline(aIsOffline)
   , mIsStarted(!aIsOffline)
   , mIsShutDown(false)
 {
   aWindow->AddAudioContext(this);
 
   // Note: AudioDestinationNode needs an AudioContext that must already be
   // bound to the window.
-  mDestination = new AudioDestinationNode(this, aIsOffline, aNumberOfChannels,
-                                          aLength, aSampleRate);
+  mDestination = new AudioDestinationNode(this, aIsOffline, aChannel,
+                                          aNumberOfChannels, aLength, aSampleRate);
   // We skip calling SetIsOnlyNodeForContext during mDestination's constructor,
   // because we can only call SetIsOnlyNodeForContext after mDestination has
   // been set up.
   mDestination->SetIsOnlyNodeForContext(true);
 }
 
 AudioContext::~AudioContext()
 {
@@ -134,16 +135,34 @@ AudioContext::Constructor(const GlobalOb
 
   RegisterWeakMemoryReporter(object);
 
   return object.forget();
 }
 
 /* static */ already_AddRefed<AudioContext>
 AudioContext::Constructor(const GlobalObject& aGlobal,
+                          AudioChannel aChannel,
+                          ErrorResult& aRv)
+{
+  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
+  if (!window) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsRefPtr<AudioContext> object = new AudioContext(window, false, aChannel);
+
+  RegisterWeakMemoryReporter(object);
+
+  return object.forget();
+}
+
+/* static */ already_AddRefed<AudioContext>
+AudioContext::Constructor(const GlobalObject& aGlobal,
                           uint32_t aNumberOfChannels,
                           uint32_t aLength,
                           float aSampleRate,
                           ErrorResult& aRv)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
   if (!window) {
     aRv.Throw(NS_ERROR_FAILURE);
@@ -157,16 +176,17 @@ AudioContext::Constructor(const GlobalOb
       aSampleRate >= TRACK_RATE_MAX) {
     // The DOM binding protects us against infinity and NaN
     aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     return nullptr;
   }
 
   nsRefPtr<AudioContext> object = new AudioContext(window,
                                                    true,
+                                                   AudioChannel::Normal,
                                                    aNumberOfChannels,
                                                    aLength,
                                                    aSampleRate);
 
   RegisterWeakMemoryReporter(object);
 
   return object.forget();
 }
--- a/content/media/webaudio/AudioContext.h
+++ b/content/media/webaudio/AudioContext.h
@@ -62,16 +62,17 @@ class ScriptProcessorNode;
 class WaveShaperNode;
 class PeriodicWave;
 
 class AudioContext MOZ_FINAL : public DOMEventTargetHelper,
                                public nsIMemoryReporter
 {
   AudioContext(nsPIDOMWindow* aParentWindow,
                bool aIsOffline,
+               AudioChannel aChannel = AudioChannel::Normal,
                uint32_t aNumberOfChannels = 0,
                uint32_t aLength = 0,
                float aSampleRate = 0.0f);
   ~AudioContext();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioContext,
@@ -90,16 +91,22 @@ public:
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   using DOMEventTargetHelper::DispatchTrustedEvent;
 
   // Constructor for regular AudioContext
   static already_AddRefed<AudioContext>
   Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
 
+  // Constructor for regular AudioContext. A default audio channel is needed.
+  static already_AddRefed<AudioContext>
+  Constructor(const GlobalObject& aGlobal,
+              AudioChannel aChannel,
+              ErrorResult& aRv);
+
   // Constructor for offline AudioContext
   static already_AddRefed<AudioContext>
   Constructor(const GlobalObject& aGlobal,
               uint32_t aNumberOfChannels,
               uint32_t aLength,
               float aSampleRate,
               ErrorResult& aRv);
 
--- a/content/media/webaudio/AudioDestinationNode.cpp
+++ b/content/media/webaudio/AudioDestinationNode.cpp
@@ -223,16 +223,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
 NS_INTERFACE_MAP_END_INHERITING(AudioNode)
 
 NS_IMPL_ADDREF_INHERITED(AudioDestinationNode, AudioNode)
 NS_IMPL_RELEASE_INHERITED(AudioDestinationNode, AudioNode)
 
 AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
                                            bool aIsOffline,
+                                           AudioChannel aChannel,
                                            uint32_t aNumberOfChannels,
                                            uint32_t aLength,
                                            float aSampleRate)
   : AudioNode(aContext,
               aIsOffline ? aNumberOfChannels : 2,
               ChannelCountMode::Explicit,
               ChannelInterpretation::Speakers)
   , mFramesToProduce(aLength)
@@ -247,23 +248,23 @@ AudioDestinationNode::AudioDestinationNo
                             MediaStreamGraph::CreateNonRealtimeInstance(aSampleRate) :
                             MediaStreamGraph::GetInstance();
   AudioNodeEngine* engine = aIsOffline ?
                             new OfflineDestinationNodeEngine(this, aNumberOfChannels,
                                                              aLength, aSampleRate) :
                             static_cast<AudioNodeEngine*>(new DestinationNodeEngine(this));
 
   mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM);
+  mStream->SetAudioChannelType(aChannel);
   mStream->AddMainThreadListener(this);
   mStream->AddAudioOutput(&gWebAudioOutputKey);
 
-  AudioChannel channel = AudioChannelService::GetDefaultAudioChannel();
-  if (channel != AudioChannel::Normal) {
+  if (aChannel != AudioChannel::Normal) {
     ErrorResult rv;
-    SetMozAudioChannelType(channel, rv);
+    SetMozAudioChannelType(aChannel, rv);
   }
 
   if (!aIsOffline && UseAudioChannelService()) {
     nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetOwner());
     if (target) {
       target->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"), this,
                                      /* useCapture = */ true,
                                      /* wantsUntrusted = */ false);
--- a/content/media/webaudio/AudioDestinationNode.h
+++ b/content/media/webaudio/AudioDestinationNode.h
@@ -25,16 +25,17 @@ class AudioDestinationNode : public Audi
                            , public nsSupportsWeakReference
                            , public MainThreadMediaStreamListener
 {
 public:
   // This node type knows what MediaStreamGraph to use based on
   // whether it's in offline mode.
   AudioDestinationNode(AudioContext* aContext,
                        bool aIsOffline,
+                       AudioChannel aChannel = AudioChannel::Normal,
                        uint32_t aNumberOfChannels = 0,
                        uint32_t aLength = 0,
                        float aSampleRate = 0.0f);
 
   virtual void DestroyMediaStream() MOZ_OVERRIDE;
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(AudioDestinationNode, AudioNode)
--- a/content/media/webaudio/test/test_mozaudiochannel.html
+++ b/content/media/webaudio/test/test_mozaudiochannel.html
@@ -61,17 +61,17 @@ function test_permission(aChannel) {
 }
 
 function test_preferences(aChannel) {
   SpecialPowers.pushPrefEnv({"set": [["media.defaultAudioChannel", aChannel ]]},
     function() {
       SpecialPowers.pushPermissions(
         [{ "type": "audio-channel-" + aChannel, "allow": false, "context": document }],
         function() {
-          var ac = new AudioContext();
+          var ac = new AudioContext(aChannel);
           ok(ac, "AudioContext created");
           is(ac.mozAudioChannelType, aChannel, "Default ac channel == '" + aChannel + "'");
           runTest();
         }
       );
     }
   );
 }
--- a/content/media/webrtc/MediaEngineDefault.cpp
+++ b/content/media/webrtc/MediaEngineDefault.cpp
@@ -17,16 +17,18 @@
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #include "nsISupportsUtils.h"
 #endif
 
+#include "YuvStamper.h"
+
 #define VIDEO_RATE USECS_PER_S
 #define AUDIO_RATE 16000
 #define AUDIO_FRAME_LENGTH ((AUDIO_RATE * MediaEngine::DEFAULT_AUDIO_TIMER_MS) / 1000)
 namespace mozilla {
 
 using namespace mozilla::gfx;
 
 NS_IMPL_ISUPPORTS1(MediaEngineDefaultVideoSource, nsITimerCallback)
@@ -234,16 +236,23 @@ MediaEngineDefaultVideoSource::Notify(ns
   }
 
   // Allocate a single solid color image
   nsRefPtr<layers::Image> image = mImageContainer->CreateImage(ImageFormat::PLANAR_YCBCR);
   nsRefPtr<layers::PlanarYCbCrImage> ycbcr_image =
       static_cast<layers::PlanarYCbCrImage*>(image.get());
   layers::PlanarYCbCrData data;
   AllocateSolidColorFrame(data, mOpts.mWidth, mOpts.mHeight, 0x80, mCb, mCr);
+
+  uint64_t timestamp = PR_Now();
+  YuvStamper::Encode(mOpts.mWidth, mOpts.mHeight, mOpts.mWidth,
+		     data.mYChannel,
+		     reinterpret_cast<unsigned char*>(&timestamp), sizeof(timestamp),
+		     0, 0);
+
   ycbcr_image->SetData(data);
   // SetData copies data, so we can free the frame
   ReleaseFrame(data);
 
   MonitorAutoLock lock(mMonitor);
 
   // implicitly releases last image
   mImage = ycbcr_image.forget();
--- a/content/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -137,16 +137,17 @@ AudioOutputObserver::InsertFarEnd(const 
 
 #ifdef LOG_FAREND_INSERTION
     if (fp) {
       fwrite(&(mSaved->mData[mSamplesSaved * aChannels]), to_copy * aChannels, sizeof(int16_t), fp);
     }
 #endif
     aSamples -= to_copy;
     mSamplesSaved += to_copy;
+    aBuffer += to_copy * aChannels;
 
     if (mSamplesSaved >= mChunkSize) {
       int free_slots = mPlayoutFifo->capacity() - mPlayoutFifo->size();
       if (free_slots <= 0) {
         // XXX We should flag an overrun for the reader.  We can't drop data from it due to
         // thread safety issues.
         break;
       } else {
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -2614,18 +2614,17 @@ OffThreadScriptReceiverCallback(void *aT
     nsIOffThreadScriptReceiver* aReceiver = static_cast<nsIOffThreadScriptReceiver*>(aCallbackData);
     nsRefPtr<NotifyOffThreadScriptCompletedRunnable> notify =
         new NotifyOffThreadScriptCompletedRunnable(
             already_AddRefed<nsIOffThreadScriptReceiver>(aReceiver), aToken);
     NS_DispatchToMainThread(notify);
 }
 
 nsresult
-nsXULPrototypeScript::Compile(const char16_t* aText,
-                              int32_t aTextLength,
+nsXULPrototypeScript::Compile(JS::SourceBufferHolder& aSrcBuf,
                               nsIURI* aURI,
                               uint32_t aLineNo,
                               nsIDocument* aDocument,
                               nsXULPrototypeDocument* aProtoDoc,
                               nsIOffThreadScriptReceiver *aOffThreadReceiver /* = nullptr */)
 {
     // We'll compile the script in the compilation scope.
     MOZ_ASSERT(aProtoDoc);
@@ -2646,35 +2645,48 @@ nsXULPrototypeScript::Compile(const char
     // Function.prototype.toSource(). If it's out of line, we retrieve the
     // source from the files on demand.
     options.setSourceIsLazy(mOutOfLine);
     JS::Rooted<JSObject*> scope(cx, JS::CurrentGlobalOrNull(cx));
     if (scope) {
       JS::ExposeObjectToActiveJS(scope);
     }
 
-    if (aOffThreadReceiver && JS::CanCompileOffThread(cx, options, aTextLength)) {
+    if (aOffThreadReceiver && JS::CanCompileOffThread(cx, options, aSrcBuf.length())) {
         if (!JS::CompileOffThread(cx, options,
-                                  static_cast<const jschar*>(aText), aTextLength,
+                                  aSrcBuf.get(), aSrcBuf.length(),
                                   OffThreadScriptReceiverCallback,
                                   static_cast<void*>(aOffThreadReceiver))) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
         // This reference will be consumed by the NotifyOffThreadScriptCompletedRunnable.
         NS_ADDREF(aOffThreadReceiver);
     } else {
-        JSScript* script = JS::Compile(cx, scope, options,
-                                   static_cast<const jschar*>(aText), aTextLength);
+        JSScript* script = JS::Compile(cx, scope, options, aSrcBuf);
         if (!script)
             return NS_ERROR_OUT_OF_MEMORY;
         Set(script);
     }
     return NS_OK;
 }
 
+nsresult
+nsXULPrototypeScript::Compile(const char16_t* aText,
+                              int32_t aTextLength,
+                              nsIURI* aURI,
+                              uint32_t aLineNo,
+                              nsIDocument* aDocument,
+                              nsXULPrototypeDocument* aProtoDoc,
+                              nsIOffThreadScriptReceiver *aOffThreadReceiver /* = nullptr */)
+{
+  JS::SourceBufferHolder srcBuf(aText, aTextLength,
+                                JS::SourceBufferHolder::NoOwnership);
+  return Compile(srcBuf, aURI, aLineNo, aDocument, aProtoDoc, aOffThreadReceiver);
+}
+
 void
 nsXULPrototypeScript::UnlinkJSObjects()
 {
     if (mScriptObject) {
         mScriptObject = nullptr;
         mozilla::DropJSObjects(this);
     }
 }
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -51,16 +51,20 @@ typedef nsTArray<nsRefPtr<nsXULPrototype
 namespace mozilla {
 class EventChainPreVisitor;
 class EventListenerManager;
 namespace css {
 class StyleRule;
 }
 }
 
+namespace JS {
+class SourceBufferHolder;
+}
+
 ////////////////////////////////////////////////////////////////////////
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
 #define XUL_PROTOTYPE_ATTRIBUTE_METER(counter) (nsXULPrototypeAttribute::counter++)
 #else
 #define XUL_PROTOTYPE_ATTRIBUTE_METER(counter) ((void) 0)
 #endif
 
@@ -226,16 +230,22 @@ public:
                                 nsXULPrototypeDocument* aProtoDoc);
     virtual nsresult Deserialize(nsIObjectInputStream* aStream,
                                  nsXULPrototypeDocument* aProtoDoc,
                                  nsIURI* aDocumentURI,
                                  const nsCOMArray<nsINodeInfo> *aNodeInfos) MOZ_OVERRIDE;
     nsresult DeserializeOutOfLine(nsIObjectInputStream* aInput,
                                   nsXULPrototypeDocument* aProtoDoc);
 
+    nsresult Compile(JS::SourceBufferHolder& aSrcBuf,
+                     nsIURI* aURI, uint32_t aLineNo,
+                     nsIDocument* aDocument,
+                     nsXULPrototypeDocument* aProtoDoc,
+                     nsIOffThreadScriptReceiver *aOffThreadReceiver = nullptr);
+
     nsresult Compile(const char16_t* aText, int32_t aTextLength,
                      nsIURI* aURI, uint32_t aLineNo,
                      nsIDocument* aDocument,
                      nsXULPrototypeDocument* aProtoDoc,
                      nsIOffThreadScriptReceiver *aOffThreadReceiver = nullptr);
 
     void UnlinkJSObjects();
 
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -240,16 +240,20 @@ XULDocument::~XULDocument()
 
     if (--gRefCnt == 0) {
         NS_IF_RELEASE(gRDFService);
 
         NS_IF_RELEASE(kNC_persist);
         NS_IF_RELEASE(kNC_attribute);
         NS_IF_RELEASE(kNC_value);
     }
+
+    if (mOffThreadCompileStringBuf) {
+      js_free(mOffThreadCompileStringBuf);
+    }
 }
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult
 NS_NewXULDocument(nsIXULDocument** result)
 {
@@ -3521,36 +3525,53 @@ XULDocument::OnStreamComplete(nsIStreamL
         // from the FastLoad file, XULContentSinkImpl::OpenScript (over in
         // nsXULContentSink.cpp) would have already deserialized a non-null
         // script->mScriptObject, causing control flow at the top of LoadScript
         // not to reach here.
         nsCOMPtr<nsIURI> uri = mCurrentScriptProto->mSrcURI;
 
         // XXX should also check nsIHttpChannel::requestSucceeded
 
-        MOZ_ASSERT(!mOffThreadCompiling && mOffThreadCompileString.Length() == 0,
+        MOZ_ASSERT(!mOffThreadCompiling && (mOffThreadCompileStringLength == 0 &&
+                                            !mOffThreadCompileStringBuf),
                    "XULDocument can't load multiple scripts at once");
 
         rv = nsScriptLoader::ConvertToUTF16(channel, string, stringLen,
-                                            EmptyString(), this, mOffThreadCompileString);
+                                            EmptyString(), this,
+                                            mOffThreadCompileStringBuf,
+                                            mOffThreadCompileStringLength);
         if (NS_SUCCEEDED(rv)) {
-            rv = mCurrentScriptProto->Compile(mOffThreadCompileString.get(),
-                                              mOffThreadCompileString.Length(),
+            // Attempt to give ownership of the buffer to the JS engine.  If
+            // we hit offthread compilation, however, we will have to take it
+            // back below in order to keep the memory alive until compilation
+            // completes.
+            JS::SourceBufferHolder srcBuf(mOffThreadCompileStringBuf,
+                                          mOffThreadCompileStringLength,
+                                          JS::SourceBufferHolder::GiveOwnership);
+            mOffThreadCompileStringBuf = nullptr;
+            mOffThreadCompileStringLength = 0;
+
+            rv = mCurrentScriptProto->Compile(srcBuf,
                                               uri, 1, this,
                                               mCurrentPrototype,
                                               this);
             if (NS_SUCCEEDED(rv) && !mCurrentScriptProto->GetScriptObject()) {
                 // We will be notified via OnOffThreadCompileComplete when the
                 // compile finishes. Keep the contents of the compiled script
                 // alive until the compilation finishes.
                 mOffThreadCompiling = true;
+                // If the JS engine did not take the source buffer, then take
+                // it back here to ensure it remains alive.
+                mOffThreadCompileStringBuf = srcBuf.take();
+                if (mOffThreadCompileStringBuf) {
+                  mOffThreadCompileStringLength = srcBuf.length();
+                }
                 BlockOnload();
                 return NS_OK;
             }
-            mOffThreadCompileString.Truncate();
         }
     }
 
     return OnScriptCompileComplete(mCurrentScriptProto->GetScriptObject(), rv);
 }
 
 NS_IMETHODIMP
 XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus)
@@ -3562,17 +3583,21 @@ XULDocument::OnScriptCompileComplete(JSS
 
     // Allow load events to be fired once off thread compilation finishes.
     if (mOffThreadCompiling) {
         mOffThreadCompiling = false;
         UnblockOnload(false);
     }
 
     // After compilation finishes the script's characters are no longer needed.
-    mOffThreadCompileString.Truncate();
+    if (mOffThreadCompileStringBuf) {
+      js_free(mOffThreadCompileStringBuf);
+      mOffThreadCompileStringBuf = nullptr;
+      mOffThreadCompileStringLength = 0;
+    }
 
     // Clear mCurrentScriptProto now, but save it first for use below in
     // the execute code, and in the while loop that resumes walks of other
     // documents that raced to load this script.
     nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
     mCurrentScriptProto = nullptr;
 
     // Clear the prototype's loading flag before executing the script or
--- a/content/xul/document/src/XULDocument.h
+++ b/content/xul/document/src/XULDocument.h
@@ -455,17 +455,18 @@ protected:
      * The load event is blocked while this is in progress.
      */
     bool mOffThreadCompiling;
 
     /**
      * If the current transcluded script is being compiled off thread, the
      * source for that script.
      */
-    nsString mOffThreadCompileString;
+    jschar* mOffThreadCompileStringBuf;
+    size_t mOffThreadCompileStringLength;
 
     /**
      * Check if a XUL template builder has already been hooked up.
      */
     static nsresult
     CheckTemplateBuilderHookup(nsIContent* aElement, bool* aNeedsHookup);
 
     /**
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -82,18 +82,18 @@ AudioChannelService::Shutdown()
   if (gAudioChannelService) {
     gAudioChannelService = nullptr;
   }
 }
 
 NS_IMPL_ISUPPORTS2(AudioChannelService, nsIObserver, nsITimerCallback)
 
 AudioChannelService::AudioChannelService()
-: mCurrentHigherChannel(INT32_MAX)
-, mCurrentVisibleHigherChannel(INT32_MAX)
+: mCurrentHigherChannel(-1)
+, mCurrentVisibleHigherChannel(-1)
 , mPlayableHiddenContentChildID(CONTENT_PROCESS_ID_UNKNOWN)
 , mDisabled(false)
 , mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
 {
   if (XRE_GetProcessType() == GeckoProcessType_Default) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->AddObserver(this, "ipc:content-shutdown", false);
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/AudioChannelChromeScript.js
@@ -0,0 +1,18 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
+const { Services } = Cu.import('resource://gre/modules/Services.jsm');
+const { SystemAppProxy } = Cu.import('resource://gre/modules/SystemAppProxy.jsm');
+
+addMessageListener('init-chrome-event', function(message) {
+  // listen mozChromeEvent and forward to content process.
+  let type = message.type;
+
+  SystemAppProxy.addEventListener('mozChromeEvent', function(event) {
+    let details = event.detail;
+    if (details.type === type) {
+      sendAsyncMessage('chrome-event', details);
+    }
+  }, true);
+});
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/file_audio.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test audio-channel-changed & visible-audio-channel-changed mozChromeEvent</title>
+</head>
+<body>
+  <div id="content"></div>
+  <script>
+  var normalAudio;
+  var contentAudio;
+  var notificationAudio;
+  var alarmAudio;
+  var telephonyAudio;
+  var ringerAudio;
+  var publicnotificationAudio;
+
+  function playWithAudioType(audio, type) {
+    audio.mozAudioChannelType = type;
+    audio.src = "test.ogg";
+    audio.loop = true;
+
+    audio.play();
+  }
+
+  function runTest() {
+    // normal channel.
+    normalAudio = new Audio();
+    playWithAudioType(normalAudio, 'normal');
+
+    // content channel.
+    contentAudio = new Audio();
+    playWithAudioType(contentAudio, 'content');
+
+    // notification channel.
+    notificationAudio = new Audio();
+    playWithAudioType(notificationAudio, 'notification');
+
+    // alarm channel.
+    alarmAudio = new Audio();
+    playWithAudioType(alarmAudio, 'alarm');
+
+    // telephony channel.
+    telephonyAudio = new Audio();
+    playWithAudioType(telephonyAudio, 'telephony');
+
+    // ringer channel.
+    ringerAudio = new Audio();
+    playWithAudioType(ringerAudio, 'ringer');
+
+    // publicnotification channel.
+    publicnotificationAudio = new Audio();
+    playWithAudioType(publicnotificationAudio, 'publicnotification');
+
+    window.addEventListener('hashchange', function(event) {
+      if (location.hash == "#pauseAudio") {
+        publicnotificationAudio.pause();
+        ringerAudio.pause();
+        telephonyAudio.pause();
+      }
+
+      if (location.hash == "#pauseAudioFollowing") {
+        alarmAudio.pause();
+        notificationAudio.pause();
+        contentAudio.pause();
+        normalAudio.pause();
+      }
+    }, false);
+  }
+
+  function checkBackgroundStatus() {
+    if (location.hash == "#fg") {
+      runTest();
+      return;
+    }
+
+    if (document.hidden) {
+      runTest();
+      return;
+    }
+
+    document.addEventListener('visibilitychange', function visibilityChange() {
+      if (document.hidden) {
+        runTest();
+      }
+    });
+  }
+
+  SpecialPowers.pushPermissions(
+    [{ "type": "audio-channel-content", "allow": 1, "context": document },
+     { "type": "audio-channel-notification", "allow": 1, "context": document },
+     { "type": "audio-channel-alarm", "allow": 1, "context": document },
+     { "type": "audio-channel-telephony", "allow": 1, "context": document },
+     { "type": "audio-channel-ringer", "allow": 1, "context": document },
+     { "type": "audio-channel-publicnotification", "allow": 1, "context": document }],
+    checkBackgroundStatus);
+
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/mochitest.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+support-files =
+  file_audio.html
+  AudioChannelChromeScript.js
+
+[test_audioChannelChange.html]
+skip-if = (toolkit != 'gonk')
--- a/dom/audiochannel/tests/moz.build
+++ b/dom/audiochannel/tests/moz.build
@@ -6,10 +6,12 @@
 
 CPP_UNIT_TESTS += [
     'TestAudioChannelService.cpp',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT':
     DEFINES['NOMINMAX'] = True
 
+MOCHITEST_MANIFESTS += ['mochitest.ini']
+
 FAIL_ON_WARNINGS = True
 
new file mode 100644
--- /dev/null
+++ b/dom/audiochannel/tests/test_audioChannelChange.html
@@ -0,0 +1,209 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test audio-channel-changed & visible-audio-channel-changed mozChromeEvent</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  <div id="content"></div>
+  <script type="application/javascript;version=1.7">
+  var expectedAudioTypes;
+  var expectedVisibleAudioTypes;
+  var expectedVisibleAudioType;
+  var index;
+  var visibleIndex;
+  var iframe1;
+  var normalAudio;
+
+  function playWithAudioType(audio, type) {
+    audio.mozAudioChannelType = type;
+    audio.src = "test.ogg";
+    audio.loop = true;
+
+    audio.play();
+  }
+
+  function fgBgTestListener(message) {
+    var type = message.type;
+    var channel = message.channel;
+
+    if (type == 'audio-channel-changed') {
+      is(channel, expectedAudioTypes[index], channel + " is received and expected " + expectedAudioTypes[index]);
+      index++;
+    }
+
+    if (type == 'visible-audio-channel-changed') {
+      is(channel, expectedVisibleAudioType, channel + " is received and expected " + expectedVisibleAudioType);
+    }
+
+    // All audio types are playing now so ask to pause them.
+    // This call will stop audio from highest to telephony.
+    if ('cmd-pause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudio';
+      index++;
+    }
+
+    // According to there is a 1.5 second delay of releasing telephony,
+    // we need to wait for it then continue to pause others.
+    if ('cmd-secondPause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudioFollowing';
+      index++;
+    }
+
+    if (index == expectedAudioTypes.length) {
+      document.body.removeChild(iframe1);
+      script.removeMessageListener('chrome-event', fgBgTestListener);
+      normalAudio.pause();
+      SimpleTest.finish();
+    }
+  }
+
+  // Channel of visible-audio-channel-changed event should be always normal.
+  // Audios in background should not effect visible-audio-channel-changed.
+  function runFgBgTest() {
+    expectedAudioTypes = ["normal", "content", "notification",
+                          "alarm", "telephony", "ringer", "publicnotification", "cmd-pause",
+                          "ringer", "telephony", "alarm", "cmd-secondPause", "notification",
+                          "content", "normal"];
+    expectedVisibleAudioType = "normal";
+    index = 0;
+
+    script.addMessageListener('chrome-event', fgBgTestListener);
+
+    // To play a audio with normal channel in the foreground.
+    normalAudio = new Audio();
+    playWithAudioType(normalAudio, 'normal');
+
+    iframe1.src = 'file_audio.html#bg';
+    document.body.appendChild(iframe1);
+    iframe1.setVisible(false);
+  }
+
+  function bgTestListener(message) {
+    var type = message.type;
+    var channel = message.channel;
+
+    if (type == 'audio-channel-changed') {
+      is(channel, expectedAudioTypes[index], channel + " is received and expected " + expectedAudioTypes[index]);
+      index++;
+    }
+
+    if (type == 'visible-audio-channel-changed') {
+      is(channel, expectedVisibleAudioType, channel + " is received and expected " + expectedVisibleAudioType);
+    }
+
+    // All audio types are playing now so ask to pause them.
+    if ('cmd-pause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudio';
+      index++;
+    }
+
+    if ('cmd-secondPause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudioFollowing';
+      index++;
+    }
+
+    if (index == expectedAudioTypes.length) {
+      document.body.removeChild(iframe1);
+      script.removeMessageListener('chrome-event', bgTestListener);
+      runFgBgTest();
+    }
+  }
+
+  // 1. Channel of visible-audio-channel-changed event should be always none.
+  // 2. normal is not allowed to be played in the background.
+  function runBgTest() {
+    expectedAudioTypes = ["content", "notification",
+                          "alarm", "telephony", "ringer", "publicnotification", "cmd-pause",
+                         "ringer", "telephony", "alarm", "cmd-secondPause", "notification",
+                          "content", "none"];
+    expectedVisibleAudioType = "none";
+    index = 0;
+
+    script.addMessageListener('chrome-event', bgTestListener);
+
+    iframe1.src = 'file_audio.html#bg';
+    document.body.appendChild(iframe1);
+    iframe1.setVisible(false);
+  }
+
+  function fgTestListener(message) {
+    var type = message.type;
+    var channel = message.channel;
+
+    if (type == 'audio-channel-changed') {
+      is(channel, expectedAudioTypes[index], channel + " is received and expected " + expectedAudioTypes[index]);
+      index++;
+    }
+
+    if (type == 'visible-audio-channel-changed') {
+      is(channel, expectedAudioTypes[visibleIndex], channel + " is received and expected " + expectedAudioTypes[visibleIndex]);
+      visibleIndex++;
+    }
+
+    // All audio types are playing now so ask to pause them.
+    if ('cmd-pause' == expectedAudioTypes[visibleIndex] &&
+        'cmd-pause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudio';
+      visibleIndex++;
+      index++;
+    }
+
+    if ('cmd-secondPause' == expectedAudioTypes[visibleIndex] &&
+        'cmd-secondPause' == expectedAudioTypes[index]) {
+      iframe1.src = 'file_audio.html#pauseAudioFollowing';
+      visibleIndex++;
+      index++;
+    }
+
+    if (index == expectedAudioTypes.length && visibleIndex == expectedAudioTypes.length) {
+      document.body.removeChild(iframe1);
+      script.removeMessageListener('chrome-event', fgTestListener);
+      runBgTest();
+    }
+  }
+
+  // The foreground audio will effect both of audio-channel-changed and
+  // visible-audio-channel-changed.
+  function runFgTest() {
+    expectedAudioTypes = ["normal", "content", "notification",
+                          "alarm", "telephony", "ringer", "publicnotification",
+                          "cmd-pause", "ringer", "telephony", "alarm",
+                          "cmd-secondPause", "notification", "content",
+                          "normal", "none"];
+
+    index = 0;
+    visibleIndex = 0;
+
+    script.addMessageListener('chrome-event', fgTestListener);
+
+    iframe1 = document.createElement('iframe');
+    iframe1.setAttribute('mozbrowser', true);
+    iframe1.src = 'file_audio.html#fg';
+    document.body.appendChild(iframe1);
+  }
+
+  var url = SimpleTest.getTestFileURL("AudioChannelChromeScript.js")
+  var script = SpecialPowers.loadChromeScript(url);
+  script.sendAsyncMessage("init-chrome-event", {
+    type: 'audio-channel-changed'
+  });
+  script.sendAsyncMessage("init-chrome-event", {
+    type: 'visible-audio-channel-changed'
+  });
+
+  SimpleTest.waitForExplicitFinish();
+
+  SpecialPowers.pushPermissions(
+    [{ "type": "browser", "allow": 1, "context": document },
+     { "type": "embed-apps", "allow": 1, "context": document },
+     { "type": "webapps-manage", "allow": 1, "context": document }], function() {
+    SpecialPowers.pushPrefEnv({"set": [["dom.ipc.browser_frames.oop_by_default", true],
+                                       ["media.useAudioChannelService", true],
+                                       ["dom.mozBrowserFramesEnabled", true]]}, runFgTest);
+  });
+  </script>
+</body>
+</html>
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -175,22 +175,39 @@ nsresult
 nsJSUtils::EvaluateString(JSContext* aCx,
                           const nsAString& aScript,
                           JS::Handle<JSObject*> aScopeObject,
                           JS::CompileOptions& aCompileOptions,
                           const EvaluateOptions& aEvaluateOptions,
                           JS::MutableHandle<JS::Value> aRetValue,
                           void **aOffThreadToken)
 {
+  const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
+  JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
+                                JS::SourceBufferHolder::NoOwnership);
+  return EvaluateString(aCx, srcBuf, aScopeObject, aCompileOptions,
+                        aEvaluateOptions, aRetValue, aOffThreadToken);
+}
+
+nsresult
+nsJSUtils::EvaluateString(JSContext* aCx,
+                          JS::SourceBufferHolder& aSrcBuf,
+                          JS::Handle<JSObject*> aScopeObject,
+                          JS::CompileOptions& aCompileOptions,
+                          const EvaluateOptions& aEvaluateOptions,
+                          JS::MutableHandle<JS::Value> aRetValue,
+                          void **aOffThreadToken)
+{
   PROFILER_LABEL("JS", "EvaluateString");
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
   MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, aEvaluateOptions.needResult);
   MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, aEvaluateOptions.needResult);
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
+  MOZ_ASSERT(aSrcBuf.get());
 
   // Unfortunately, the JS engine actually compiles scripts with a return value
   // in a different, less efficient way.  Furthermore, it can't JIT them in many
   // cases.  So we need to be explicitly told whether the caller cares about the
   // return value.  Callers can do this by calling the other overload of
   // EvaluateString() which calls this function with aEvaluateOptions.needResult
   // set to false.
   aRetValue.setUndefined();
@@ -227,22 +244,20 @@ nsJSUtils::EvaluateString(JSContext* aCx
           ok = JS_ExecuteScript(aCx, rootedScope, script);
         }
       } else {
         ok = false;
       }
     } else {
       if (aEvaluateOptions.needResult) {
         ok = JS::Evaluate(aCx, rootedScope, aCompileOptions,
-                          PromiseFlatString(aScript).get(),
-                          aScript.Length(), aRetValue);
+                          aSrcBuf, aRetValue);
       } else {
         ok = JS::Evaluate(aCx, rootedScope, aCompileOptions,
-                          PromiseFlatString(aScript).get(),
-                          aScript.Length());
+                          aSrcBuf);
       }
     }
 
     if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) {
       JS::Rooted<JS::Value> value(aCx, aRetValue);
       JSString* str = JS::ToString(aCx, value);
       ok = !!str;
       aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue());
@@ -287,16 +302,30 @@ nsJSUtils::EvaluateString(JSContext* aCx
 {
   EvaluateOptions options;
   options.setNeedResult(false);
   JS::RootedValue unused(aCx);
   return EvaluateString(aCx, aScript, aScopeObject, aCompileOptions,
                         options, &unused, aOffThreadToken);
 }
 
+nsresult
+nsJSUtils::EvaluateString(JSContext* aCx,
+                          JS::SourceBufferHolder& aSrcBuf,
+                          JS::Handle<JSObject*> aScopeObject,
+                          JS::CompileOptions& aCompileOptions,
+                          void **aOffThreadToken)
+{
+  EvaluateOptions options;
+  options.setNeedResult(false);
+  JS::RootedValue unused(aCx);
+  return EvaluateString(aCx, aSrcBuf, aScopeObject, aCompileOptions,
+                        options, &unused, aOffThreadToken);
+}
+
 //
 // nsDOMJSUtils.h
 //
 
 JSObject* GetDefaultScopeFromJSContext(JSContext *cx)
 {
   // DOM JSContexts don't store their default compartment object on
   // the cx, so in those cases we need to fetch it via the scx
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -90,23 +90,37 @@ public:
   static nsresult EvaluateString(JSContext* aCx,
                                  const nsAString& aScript,
                                  JS::Handle<JSObject*> aScopeObject,
                                  JS::CompileOptions &aCompileOptions,
                                  const EvaluateOptions& aEvaluateOptions,
                                  JS::MutableHandle<JS::Value> aRetValue,
                                  void **aOffThreadToken = nullptr);
 
+  static nsresult EvaluateString(JSContext* aCx,
+                                 JS::SourceBufferHolder& aSrcBuf,
+                                 JS::Handle<JSObject*> aScopeObject,
+                                 JS::CompileOptions &aCompileOptions,
+                                 const EvaluateOptions& aEvaluateOptions,
+                                 JS::MutableHandle<JS::Value> aRetValue,
+                                 void **aOffThreadToken = nullptr);
+
 
   static nsresult EvaluateString(JSContext* aCx,
                                  const nsAString& aScript,
                                  JS::Handle<JSObject*> aScopeObject,
                                  JS::CompileOptions &aCompileOptions,
                                  void **aOffThreadToken = nullptr);
 
+  static nsresult EvaluateString(JSContext* aCx,
+                                 JS::SourceBufferHolder& aSrcBuf,
+                                 JS::Handle<JSObject*> aScopeObject,
+                                 JS::CompileOptions &aCompileOptions,
+                                 void **aOffThreadToken = nullptr);
+
 };
 
 class MOZ_STACK_CLASS AutoDontReportUncaught {
   JSContext* mContext;
   bool mWasSet;
 
 public:
   AutoDontReportUncaught(JSContext* aContext) : mContext(aContext) {
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -44,17 +44,16 @@ FormValidationStepMismatchOneValue=Pleas
 FormValidationBadInputNumber=Please enter a number.
 GetAttributeNodeWarning=Use of getAttributeNode() is deprecated. Use getAttribute() instead.
 SetAttributeNodeWarning=Use of setAttributeNode() is deprecated. Use setAttribute() instead.
 GetAttributeNodeNSWarning=Use of getAttributeNodeNS() is deprecated. Use getAttributeNS() instead.
 SetAttributeNodeNSWarning=Use of setAttributeNodeNS() is deprecated. Use setAttributeNS() instead.
 RemoveAttributeNodeWarning=Use of removeAttributeNode() is deprecated. Use removeAttribute() instead.
 CreateAttributeWarning=Use of document.createAttribute() is deprecated. Use element.setAttribute() instead.
 CreateAttributeNSWarning=Use of document.createAttributeNS() is deprecated. Use element.setAttributeNS() instead.
-SpecifiedWarning=Use of attributes' specified attribute is deprecated. It always returns true.
 OwnerElementWarning=Use of attributes' ownerElement attribute is deprecated.
 NodeValueWarning=Use of attributes' nodeValue attribute is deprecated. Use value instead.
 TextContentWarning=Use of attributes' textContent attribute is deprecated. Use value instead.
 EnablePrivilegeWarning=Use of enablePrivilege is deprecated.  Please use code that runs with the system principal (e.g. an extension) instead.
 nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated.  Please use JSON.parse instead.
 nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated.  Please use JSON.stringify instead.
 nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
 InputEncodingWarning=Use of inputEncoding is deprecated.
--- a/dom/system/gonk/Nfc.js
+++ b/dom/system/gonk/Nfc.js
@@ -76,19 +76,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
                                    "@mozilla.org/parentprocessmessagemanager;1",
                                    "nsIMessageBroadcaster");
 XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
                                    "@mozilla.org/system-message-internal;1",
                                    "nsISystemMessagesInternal");
 XPCOMUtils.defineLazyServiceGetter(this, "gSystemWorkerManager",
                                    "@mozilla.org/telephony/system-worker-manager;1",
                                    "nsISystemWorkerManager");
-XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
-                                   "@mozilla.org/settingsService;1",
-                                   "nsISettingsService");
 XPCOMUtils.defineLazyServiceGetter(this, "UUIDGenerator",
                                     "@mozilla.org/uuid-generator;1",
                                     "nsIUUIDGenerator");
 XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
   return {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
                                            Ci.nsIObserver]),
 
@@ -410,41 +407,37 @@ XPCOMUtils.defineLazyGetter(this, "gMess
 });
 
 function Nfc() {
   debug("Starting Worker");
   this.worker = new ChromeWorker("resource://gre/modules/nfc_worker.js");
   this.worker.onerror = this.onerror.bind(this);
   this.worker.onmessage = this.onmessage.bind(this);
 
-  Services.obs.addObserver(this, NFC.TOPIC_MOZSETTINGS_CHANGED, false);
+  gMessageManager.init(this);
 
-  gMessageManager.init(this);
-  let lock = gSettingsService.createLock();
-  lock.get(NFC.SETTING_NFC_ENABLED, this);
   // Maps sessionId (that are generated from nfcd) with a unique guid : 'SessionToken'
   this.sessionTokenMap = {};
   this.targetsByRequestId = {};
 
   gSystemWorkerManager.registerNfcWorker(this.worker);
 }
 
 Nfc.prototype = {
 
   classID:   NFC_CID,
   classInfo: XPCOMUtils.generateCI({classID: NFC_CID,
                                     classDescription: "Nfc",
                                     interfaces: [Ci.nsIWorkerHolder]}),
 
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder,
-                                         Ci.nsIObserver,
-                                         Ci.nsISettingsServiceCallback]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWorkerHolder]),
 
   _currentSessionId: null,
-  _enabled: false,
+
+  powerLevel: NFC.NFC_POWER_LEVEL_UNKNOWN,
 
   onerror: function onerror(event) {
     debug("Got an error: " + event.filename + ":" +
           event.lineno + ": " + event.message + "\n");
     event.preventDefault();
   },
 
   /**
@@ -521,16 +514,20 @@ Nfc.prototype = {
      case "ConfigResponse":
         let target = this.targetsByRequestId[message.requestId];
         if (!target) {
           debug("No target for requestId: " + message.requestId);
           return;
         }
         delete this.targetsByRequestId[message.requestId];
 
+        if (message.status == NFC.GECKO_NFC_ERROR_SUCCESS) {
+          this.powerLevel = message.powerLevel;
+        }
+
         target.sendAsyncMessage("NFC:ConfigResponse", message);
         break;
       case "ConnectResponse": // Fall through.
       case "CloseResponse":
       case "GetDetailsNDEFResponse":
       case "ReadNDEFResponse":
       case "MakeReadOnlyNDEFResponse":
       case "WriteNDEFResponse":
@@ -570,18 +567,18 @@ Nfc.prototype = {
       return null;
     } else if (message.name == "NFC:PowerOff") {
       this.targetsByRequestId[message.json.requestId] = message.target;
       this.setConfig({powerLevel: NFC.NFC_POWER_LEVEL_DISABLED,
                       requestId: message.json.requestId});
       return null;
     }
 
-    if (!this._enabled) {
-      debug("NFC is not enabled.");
+    if (this.powerLevel != NFC.NFC_POWER_LEVEL_ENABLED) {
+      debug("NFC is not enabled. current powerLevel:" + this.powerLevel);
       this.sendNfcErrorResponse(message);
       return null;
     }
 
     // Sanity check on sessionId
     if (message.json.sessionToken !== this.sessionTokenMap[this._currentSessionId]) {
       debug("Invalid Session Token: " + message.json.sessionToken +
             " Expected Session Token: " + this.sessionTokenMap[this._currentSessionId]);
@@ -625,45 +622,16 @@ Nfc.prototype = {
       default:
         debug("UnSupported : Message Name " + message.name);
         return null;
     }
 
     return null;
   },
 
-  /**
-   * nsISettingsServiceCallback
-   */
-
-  handle: function handle(aName, aResult) {
-    switch(aName) {
-      case NFC.SETTING_NFC_ENABLED:
-        debug("'nfc.enabled' is now " + aResult);
-        this._enabled = aResult;
-        break;
-    }
-  },
-
-  /**
-   * nsIObserver
-   */
-
-  observe: function observe(subject, topic, data) {
-    switch (topic) {
-      case NFC.TOPIC_MOZSETTINGS_CHANGED:
-        let setting = JSON.parse(data);
-        if (setting) {
-          let setting = JSON.parse(data);
-          this.handle(setting.key, setting.value);
-        }
-        break;
-    }
-  },
-
   setConfig: function setConfig(prop) {
     this.sendToWorker("config", prop);
   }
 };
 
 if (NFC_ENABLED) {
   this.NSGetFactory = XPCOMUtils.generateNSGetFactory([Nfc]);
 }
--- a/dom/system/gonk/nfc_consts.js
+++ b/dom/system/gonk/nfc_consts.js
@@ -61,17 +61,15 @@ this.GECKO_NFC_ERROR_SUCCESS            
 this.GECKO_NFC_ERROR_GENERIC_FAILURE     = 1;
 
 // NFC powerlevels must match config PDUs.
 this.NFC_POWER_LEVEL_UNKNOWN        = -1;
 this.NFC_POWER_LEVEL_DISABLED       = 0;
 this.NFC_POWER_LEVEL_LOW            = 1;
 this.NFC_POWER_LEVEL_ENABLED        = 2;
 
-this.TOPIC_MOZSETTINGS_CHANGED      = "mozsettings-changed";
 this.TOPIC_XPCOM_SHUTDOWN           = "xpcom-shutdown";
-this.SETTING_NFC_ENABLED            = "nfc.enabled";
 
 this.NFC_PEER_EVENT_READY = 0x01;
 this.NFC_PEER_EVENT_LOST  = 0x02;
 
 // Allow this file to be imported via Components.utils.import().
 this.EXPORTED_SYMBOLS = Object.keys(this);
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1493,16 +1493,21 @@ RilObject.prototype = {
       options.featureStr = options.number;
       this.sendCdmaFlashCommand(options);
     } else {
       this.sendDialRequest(options);
     }
   },
 
   sendDialRequest: function(options) {
+    // Always succeed.
+    options.success = true;
+    this.sendChromeMessage(options);
+    this._createPendingOutgoingCall(options);
+
     let Buf = this.context.Buf;
     Buf.newParcel(options.request, options);
     Buf.writeString(options.number);
     Buf.writeInt32(options.clirMode || 0);
     Buf.writeInt32(options.uusInfo || 0);
     // TODO Why do we need this extra 0? It was put it in to make this
     // match the format of the binary message.
     Buf.writeInt32(0);
@@ -1536,16 +1541,17 @@ RilObject.prototype = {
   hangUp: function(options) {
     let call = this.currentCalls[options.callIndex];
     if (!call) {
       return;
     }
 
     let callIndex = call.callIndex;
     if (callIndex === OUTGOING_PLACEHOLDER_CALL_INDEX) {
+      if (DEBUG) this.context.debug("Hang up pending outgoing call.");
       this._removeVoiceCall(call, GECKO_CALL_ERROR_NORMAL_CALL_CLEARING);
       return;
     }
 
     if (call.state === CALL_STATE_HOLDING) {
       this.sendHangUpBackgroundRequest(callIndex);
     } else {
       this.sendHangUpRequest(callIndex);
@@ -3841,37 +3847,37 @@ RilObject.prototype = {
         this.currentConference.cache[currentCall.callIndex] = newCall;
         currentCall.state = newCall.state;
         currentCall.isMpty = newCall.isMpty;
         conferenceChanged = true;
       }
     }
 
     if (pendingOutgoingCall) {
-      // We don't get a successful call for pendingOutgoingCall.
       if (!newCalls || Object.keys(newCalls).length === 0) {
-        if (DEBUG) this.context.debug("No result for pending outgoing call.");
-        pendingOutgoingCall.failCause = GECKO_CALL_ERROR_UNSPECIFIED;
-        this._handleDisconnectedCall(pendingOutgoingCall);
-      }
-
-      delete this.currentCalls[OUTGOING_PLACEHOLDER_CALL_INDEX];
+        // We don't get a successful call for pendingOutgoingCall.
+        this._removePendingOutgoingCall(GECKO_CALL_ERROR_UNSPECIFIED);
+      } else {
+        // Only remove it from currentCalls map. Will use the new call to
+        // replace the placeholder.
+        delete this.currentCalls[OUTGOING_PLACEHOLDER_CALL_INDEX];
+      }
     }
 
     // Go through any remaining calls that are new to us.
     for each (let newCall in newCalls) {
       if (newCall.isVoice) {
         if (newCall.isMpty) {
           conferenceChanged = true;
         }
         if (!pendingOutgoingCall &&
             (newCall.state === CALL_STATE_DIALING ||
              newCall.state === CALL_STATE_ALERTING)) {
           // Receive a new outgoing call which is already hung up by user.
-          if (DEBUG) this.context.debug("Hang up pending outgoing call");
+          if (DEBUG) this.context.debug("Pending outgoing call is hung up by user.");
           this.sendHangUpRequest(newCall.callIndex);
         } else {
           this._addNewVoiceCall(newCall);
         }
       }
     }
 
     if (clearConferenceRequest) {
@@ -3928,16 +3934,35 @@ RilObject.prototype = {
         this.getFailCauseCode((function(call, failCause) {
           call.failCause = failCause;
           this._handleDisconnectedCall(call);
         }).bind(this, removedCall));
       }
     }
   },
 
+  _createPendingOutgoingCall: function(options) {
+    if (DEBUG) this.context.debug("Create a pending outgoing call.");
+    this._addNewVoiceCall({
+      number: options.number,
+      state: CALL_STATE_DIALING,
+      callIndex: OUTGOING_PLACEHOLDER_CALL_INDEX
+    });
+  },
+
+  _removePendingOutgoingCall: function(failCause) {
+    let call = this.currentCalls[OUTGOING_PLACEHOLDER_CALL_INDEX];
+    if (!call) {
+      return;
+    }
+
+    if (DEBUG) this.context.debug("Remove pending outgoing call.");
+    this._removeVoiceCall(pendingOutgoingCall, failCause);
+  },
+
   _ensureConference: function() {
     let oldState = this.currentConference.state;
     let remaining = Object.keys(this.currentConference.participants);
 
     if (remaining.length == 1) {
       // Remove that if only does one remain in a conference call.
       let call = this.currentCalls[remaining[0]];
       call.isConference = false;
@@ -5324,34 +5349,24 @@ RilObject.prototype[REQUEST_GET_CURRENT_
       };
     }
 
     calls[call.callIndex] = call;
   }
   this._processCalls(calls);
 };
 RilObject.prototype[REQUEST_DIAL] = function REQUEST_DIAL(length, options) {
-  options.success = (options.rilRequestError === 0);
-  if (options.success) {
-    this.sendChromeMessage(options);
-
-    // Create a pending outgoing call.
-    if (DEBUG) this.context.debug("Create a pending outgoing call.");
-    this._addNewVoiceCall({
-      number: options.number,
-      state: CALL_STATE_DIALING,
-      callIndex: OUTGOING_PLACEHOLDER_CALL_INDEX
-    });
-  } else {
-    this.getFailCauseCode((function(options, failCause) {
-      options.errorMsg = failCause;
-      this.sendChromeMessage(options);
-    }).bind(this, options));
-  }
-};
+  // We already return a successful response before. Don't respond it again!
+  if (options.rilRequestError) {
+    this.getFailCauseCode((function(failCause) {
+      this._removePendingOutgoingCall(failCause);
+    }).bind(this));
+  }
+};
+RilObject.prototype[REQUEST_DIAL_EMERGENCY_CALL] = RilObject.prototype[REQUEST_DIAL];
 RilObject.prototype[REQUEST_GET_IMSI] = function REQUEST_GET_IMSI(length, options) {
   if (options.rilRequestError) {
     return;
   }
 
   this.iccInfoPrivate.imsi = this.context.Buf.readString();
   if (DEBUG) {
     this.context.debug("IMSI: " + this.iccInfoPrivate.imsi);
--- a/dom/tests/browser/browser_focus_steal_from_chrome.js
+++ b/dom/tests/browser/browser_focus_steal_from_chrome.js
@@ -3,17 +3,18 @@ function test() {
 
   let secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
                          .getService(Components.interfaces
                                                .nsIScriptSecurityManager);
 
   let fm = Components.classes["@mozilla.org/focus-manager;1"]
                      .getService(Components.interfaces.nsIFocusManager);
 
-  let tabs = [ gBrowser.selectedTab, gBrowser.addTab() ];
+  let tabs = [ gBrowser.addTab(), gBrowser.addTab() ];
+  gBrowser.selectedTab = tabs[0];
 
   let testingList = [
     { uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><input id='target'></body>",
       tagName: "INPUT", methodName: "focus" },
     { uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').select(); }, 10);\"><input id='target'></body>",
       tagName: "INPUT", methodName: "select" },
     { uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><a href='about:blank' id='target'>anchor</a></body>",
       tagName: "A", methodName: "focus" },
@@ -56,17 +57,16 @@ function test() {
   let canRetry;
   let callback;
   let loadedCount;
   let setFocusToChrome;
 
   function runNextTest() {
     if (++testingIndex >= testingList.length) {
       // cleaning-up...
-      gBrowser.addTab();
       for (let i = 0; i < tabs.length; i++) {
         gBrowser.removeTab(tabs[i]);
       }
       finish();
       return;
     }
     callback = doTest1;
     loadTestPage(false);
--- a/dom/tests/browser/browser_focus_steal_from_chrome_during_mousedown.js
+++ b/dom/tests/browser/browser_focus_steal_from_chrome_during_mousedown.js
@@ -8,17 +8,18 @@ function test() {
     "    document.getElementById('willBeFocused').focus();" +
     "    aEvent.preventDefault();" +
     "  }" +
     "</script>" +
     "<body id=\"body\">" +
     "<button id=\"eventTarget\" onmousedown=\"onMouseDown(event);\">click here</button>" +
     "<input id=\"willBeFocused\"></body>";
 
-  let tab = gBrowser.selectedTab;
+  let tab = gBrowser.addTab();
+  gBrowser.selectedTab = tab;
 
   // Set the focus to the contents.
   tab.linkedBrowser.focus();
   // Load on the tab
   tab.linkedBrowser.addEventListener("load", onLoadTab, true);
   tab.linkedBrowser.loadURI(kTestURI);
 
   function onLoadTab() {
@@ -47,13 +48,12 @@ function test() {
       is(e.id, "willBeFocused",
          "The input element isn't active element: button=" + button);
 
       is(fm.focusedElement, e,
          "The active element isn't focused element in App level: button=" +
          button);
     }
 
-    gBrowser.addTab();
     gBrowser.removeTab(tab);
     finish();
   }
 }
--- a/dom/webidl/Attr.webidl
+++ b/dom/webidl/Attr.webidl
@@ -13,19 +13,18 @@
 interface Attr : Node {
   readonly attribute DOMString localName;
            [SetterThrows]
            attribute DOMString value;
 
   readonly attribute DOMString name;
   readonly attribute DOMString? namespaceURI;
   readonly attribute DOMString? prefix;
+
+  readonly attribute boolean specified;
 };
 
 // Mozilla extensions
 
 partial interface Attr {
-  readonly attribute boolean specified;
-
-
            [GetterThrows]
   readonly attribute Element? ownerElement;
 };
--- a/dom/webidl/AudioContext.webidl
+++ b/dom/webidl/AudioContext.webidl
@@ -8,32 +8,33 @@
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 callback DecodeSuccessCallback = void (AudioBuffer decodedData);
 callback DecodeErrorCallback = void ();
 
-[Constructor]
+[Constructor,
+ Constructor(AudioChannel audioChannelType)]
 interface AudioContext : EventTarget {
 
     readonly attribute AudioDestinationNode destination;
     readonly attribute float sampleRate;
     readonly attribute double currentTime;
     readonly attribute AudioListener listener;
 
     [NewObject, Throws]
     AudioBuffer createBuffer(unsigned long numberOfChannels, unsigned long length, float sampleRate);
 
     void decodeAudioData(ArrayBuffer audioData,
                          DecodeSuccessCallback successCallback,
                          optional DecodeErrorCallback errorCallback);
 
-    // AudioNode creation 
+    // AudioNode creation
     [NewObject]
     AudioBufferSourceNode createBufferSource();
 
     [NewObject, Throws]
     MediaStreamAudioDestinationNode createMediaStreamDestination();
 
     [NewObject, Throws]
     ScriptProcessorNode createScriptProcessor(optional unsigned long bufferSize = 0,
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -553,16 +553,17 @@ var WifiManager = (function() {
   // try to connect to the supplicant
   var connectTries = 0;
   var retryTimer = null;
   function connectCallback(ok) {
     if (ok === 0) {
       // Tell the event worker to start waiting for events.
       retryTimer = null;
       connectTries = 0;
+      recvErrors = 0;
       manager.connectToSupplicant = true;
       didConnectSupplicant(function(){});
       return;
     }
     if (connectTries++ < 5) {
       // Try again in 1 seconds.
       if (!retryTimer)
         retryTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
@@ -730,18 +731,18 @@ var WifiManager = (function() {
       var handlerName = driverEventMap[eventData];
       if (handlerName)
         notify(handlerName);
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-TERMINATING") === 0) {
       // As long the monitor socket is not closed and we haven't seen too many
       // recv errors yet, we will keep going for a bit longer.
-      if (eventData.indexOf("connection closed") === -1 &&
-          eventData.indexOf("recv error") !== -1 && ++recvErrors < 10)
+      if (event.indexOf("connection closed") === -1 &&
+          event.indexOf("recv error") !== -1 && ++recvErrors < 10)
         return true;
 
       notifyStateChange({ state: "DISCONNECTED", BSSID: null, id: -1 });
 
       // If the supplicant is terminated as commanded, the supplicant lost
       // notification will be sent after driver unloaded. In such case, the
       // manager state will be "DISABLING" or "UNINITIALIZED".
       // So if supplicant terminated with incorrect manager state, implying
--- a/dom/workers/ScriptLoader.cpp
+++ b/dom/workers/ScriptLoader.cpp
@@ -130,29 +130,39 @@ ChannelFromScriptURL(nsIPrincipal* princ
 
   channel.forget(aChannel);
   return rv;
 }
 
 struct ScriptLoadInfo
 {
   ScriptLoadInfo()
-  : mLoadResult(NS_ERROR_NOT_INITIALIZED), mExecutionScheduled(false),
-    mExecutionResult(false)
+  : mScriptTextBuf(nullptr)
+  , mScriptTextLength(0)
+  , mLoadResult(NS_ERROR_NOT_INITIALIZED), mExecutionScheduled(false)
+  , mExecutionResult(false)
   { }
 
+  ~ScriptLoadInfo()
+  {
+    if (mScriptTextBuf) {
+      js_free(mScriptTextBuf);
+    }
+  }
+
   bool
   ReadyToExecute()
   {
     return !mChannel && NS_SUCCEEDED(mLoadResult) && !mExecutionScheduled;
   }
 
   nsString mURL;
   nsCOMPtr<nsIChannel> mChannel;
-  nsString mScriptText;
+  jschar* mScriptTextBuf;
+  size_t mScriptTextLength;
 
   nsresult mLoadResult;
   bool mExecutionScheduled;
   bool mExecutionResult;
 };
 
 class ScriptLoaderRunnable;
 
@@ -443,22 +453,23 @@ private:
     nsIDocument* parentDoc = mWorkerPrivate->GetDocument();
 
     // Use the regular nsScriptLoader for this grunt work! Should be just fine
     // because we're running on the main thread.
     // Unlike <script> tags, Worker scripts are always decoded as UTF-8,
     // per spec. So we explicitly pass in the charset hint.
     rv = nsScriptLoader::ConvertToUTF16(aLoadInfo.mChannel, aString, aStringLen,
                                         NS_LITERAL_STRING("UTF-8"), parentDoc,
-                                        aLoadInfo.mScriptText);
+                                        aLoadInfo.mScriptTextBuf,
+                                        aLoadInfo.mScriptTextLength);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    if (aLoadInfo.mScriptText.IsEmpty()) {
+    if (!aLoadInfo.mScriptTextBuf || !aLoadInfo.mScriptTextLength) {
       return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
     NS_ASSERTION(channel, "This should never fail!");
 
     // Figure out what we actually loaded.
     nsCOMPtr<nsIURI> finalURI;
@@ -725,18 +736,24 @@ ScriptExecutorRunnable::WorkerRun(JSCont
                                     false);
       return true;
     }
 
     NS_ConvertUTF16toUTF8 filename(loadInfo.mURL);
 
     JS::CompileOptions options(aCx);
     options.setFileAndLine(filename.get(), 1);
-    if (!JS::Evaluate(aCx, global, options, loadInfo.mScriptText.get(),
-                      loadInfo.mScriptText.Length())) {
+
+    JS::SourceBufferHolder srcBuf(loadInfo.mScriptTextBuf,
+                                  loadInfo.mScriptTextLength,
+                                  JS::SourceBufferHolder::GiveOwnership);
+    loadInfo.mScriptTextBuf = nullptr;
+    loadInfo.mScriptTextLength = 0;
+
+    if (!JS::Evaluate(aCx, global, options, srcBuf)) {
       return true;
     }
 
     loadInfo.mExecutionResult = true;
   }
 
   return true;
 }
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -102,28 +102,43 @@ Compositor::DrawDiagnostics(DiagnosticFl
 
   DrawDiagnosticsInternal(aFlags, aVisibleRect, aClipRect, aTransform,
                           aFlashCounter);
 }
 
 gfx::Rect
 Compositor::ClipRectInLayersCoordinates(gfx::Rect aClip) const {
   gfx::Rect result;
+  aClip = aClip + GetCurrentRenderTarget()->GetOrigin();
+  gfx::IntSize destSize = GetWidgetSize();
+
   switch (mScreenRotation) {
-    case ROTATION_90:
-    case ROTATION_270:
-      result = gfx::Rect(aClip.y, aClip.x, aClip.height, aClip.width);
-      break;
     case ROTATION_0:
-    case ROTATION_180:
-    default:
       result = aClip;
       break;
+    case ROTATION_90:
+      result = gfx::Rect(aClip.y,
+                         destSize.width - aClip.x - aClip.width,
+                         aClip.height, aClip.width);
+      break;
+    case ROTATION_270:
+      result = gfx::Rect(destSize.height - aClip.y - aClip.height,
+                         aClip.x,
+                         aClip.height, aClip.width);
+      break;
+    case ROTATION_180:
+      result = gfx::Rect(destSize.width - aClip.x - aClip.width,
+                         destSize.height - aClip.y - aClip.height,
+                         aClip.width, aClip.height);
+      break;
+      // ScreenRotation has a sentinel value, need to catch it in the switch
+      // statement otherwise the build fails (-WError)
+    default: {}
   }
-  return result + GetCurrentRenderTarget()->GetOrigin();
+  return result;
 }
 
 void
 Compositor::DrawDiagnosticsInternal(DiagnosticFlags aFlags,
                                     const gfx::Rect& aVisibleRect,
                                     const gfx::Rect& aClipRect,
                                     const gfx::Matrix4x4& aTransform,
                                     uint32_t aFlashCounter)
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -495,16 +495,17 @@ public:
   // On b2g the clip rect is in the coordinate space of the physical screen
   // independently of its rotation, while the coordinate space of the layers,
   // on the other hand, depends on the screen orientation.
   // This only applies to b2g as with other platforms, orientation is handled
   // at the OS level rather than in Gecko.
   // In addition, the clip rect needs to be offset by the rendering origin.
   // This becomes important if intermediate surfaces are used.
   gfx::Rect ClipRectInLayersCoordinates(gfx::Rect aClip) const;
+
 protected:
   void DrawDiagnosticsInternal(DiagnosticFlags aFlags,
                                const gfx::Rect& aVisibleRect,
                                const gfx::Rect& aClipRect,
                                const gfx::Matrix4x4& transform,
                                uint32_t aFlashCounter);
 
   bool ShouldDrawDiagnostics(DiagnosticFlags);
@@ -523,16 +524,18 @@ protected:
    * current frame. This value is an approximation and is not accurate,
    * especially in the presence of transforms.
    */
   size_t mPixelsPerFrame;
   size_t mPixelsFilled;
 
   ScreenRotation mScreenRotation;
 
+  virtual gfx::IntSize GetWidgetSize() const = 0;
+
 private:
   static LayersBackend sBackend;
 
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -373,16 +373,17 @@ BasicCompositor::BeginFrame(const nsIntR
                             const gfx::Rect *aClipRectIn,
                             const gfx::Matrix& aTransform,
                             const gfx::Rect& aRenderBounds,
                             gfx::Rect *aClipRectOut /* = nullptr */,
                             gfx::Rect *aRenderBoundsOut /* = nullptr */)
 {
   nsIntRect intRect;
   mWidget->GetClientBounds(intRect);
+  mWidgetSize = gfx::ToIntSize(intRect.Size());
 
   // The result of GetClientBounds is shifted over by the size of the window
   // manager styling. We want to ignore that.
   intRect.MoveTo(0, 0);
   Rect rect = Rect(0, 0, intRect.width, intRect.height);
 
   // Sometimes the invalid region is larger than we want to draw.
   nsIntRegion invalidRegionSafe;
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -120,19 +120,22 @@ public:
     return LayersBackend::LAYERS_BASIC;
   }
 
   virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
 
   gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; }
 
 private:
+
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE { return mWidgetSize; }
+
   // Widget associated with this compositor
   nsIWidget *mWidget;
-  nsIntSize mWidgetSize;
+  gfx::IntSize mWidgetSize;
 
   // The final destination surface
   RefPtr<gfx::DrawTarget> mDrawTarget;
   // The current render target for drawing
   RefPtr<BasicCompositingRenderTarget> mRenderTarget;
   // An optional destination target to copy the results
   // to after drawing is completed.
   RefPtr<gfx::DrawTarget> mCopyTarget;
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -480,17 +480,24 @@ TileClient::DiscardFrontBuffer()
   }
 }
 
 void
 TileClient::DiscardBackBuffer()
 {
   if (mBackBuffer) {
     MOZ_ASSERT(mBackLock);
-    mManager->GetTexturePool(mBackBuffer->GetFormat())->ReturnTextureClient(mBackBuffer);
+    if (!mBackBuffer->ImplementsLocking() && mBackLock->GetReadCount() > 1) {
+      // Our current back-buffer is still locked by the compositor. This can occur
+      // when the client is producing faster than the compositor can consume. In
+      // this case we just want to drop it and not return it to the pool.
+      mManager->GetTexturePool(mBackBuffer->GetFormat())->ReportClientLost();
+    } else {
+      mManager->GetTexturePool(mBackBuffer->GetFormat())->ReturnTextureClient(mBackBuffer);
+    }
     mBackLock->ReadUnlock();
     mBackBuffer = nullptr;
     mBackLock = nullptr;
   }
 }
 
 TextureClient*
 TileClient::GetBackBuffer(const nsIntRegion& aDirtyRegion, TextureClientPool *aPool, bool *aCreatedTextureClient, bool aCanRerasterizeValidRegion)
--- a/gfx/layers/composite/CompositableHost.cpp
+++ b/gfx/layers/composite/CompositableHost.cpp
@@ -17,18 +17,59 @@
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "gfxPlatform.h"                // for gfxPlatform
 
 namespace mozilla {
 namespace layers {
 
 class Compositor;
 
+/**
+ * IPDL actor used by CompositableHost to match with its corresponding
+ * CompositableClient on the content side.
+ *
+ * CompositableParent is owned by the IPDL system. It's deletion is triggered
+ * by either the CompositableChild's deletion, or by the IPDL communication
+ * goind down.
+ */
+class CompositableParent : public PCompositableParent
+{
+public:
+  CompositableParent(CompositableParentManager* aMgr,
+                     const TextureInfo& aTextureInfo,
+                     uint64_t aID = 0)
+  {
+    MOZ_COUNT_CTOR(CompositableParent);
+    mHost = CompositableHost::Create(aTextureInfo);
+    mHost->SetAsyncID(aID);
+    if (aID) {
+      CompositableMap::Set(aID, this);
+    }
+  }
+
+  ~CompositableParent()
+  {
+    MOZ_COUNT_DTOR(CompositableParent);
+    CompositableMap::Erase(mHost->GetAsyncID());
+  }
+
+  virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE
+  {
+    if (mHost) {
+      mHost->Detach(nullptr, CompositableHost::FORCE_DETACH);
+    }
+  }
+
+  RefPtr<CompositableHost> mHost;
+};
+
 CompositableHost::CompositableHost(const TextureInfo& aTextureInfo)
   : mTextureInfo(aTextureInfo)
+  , mAsyncID(0)
+  , mCompositorID(0)
   , mCompositor(nullptr)
   , mLayer(nullptr)
   , mFlashCounter(0)
   , mAttached(false)
   , mKeepAttached(false)
 {
   MOZ_COUNT_CTOR(CompositableHost);
 }
@@ -36,16 +77,38 @@ CompositableHost::CompositableHost(const
 CompositableHost::~CompositableHost()
 {
   MOZ_COUNT_DTOR(CompositableHost);
   if (mBackendData) {
     mBackendData->ClearData();
   }
 }
 
+PCompositableParent*
+CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr,
+                                  const TextureInfo& aTextureInfo,
+                                  uint64_t aID)
+{
+  return new CompositableParent(aMgr, aTextureInfo, aID);
+}
+
+bool
+CompositableHost::DestroyIPDLActor(PCompositableParent* aActor)
+{
+  delete aActor;
+  return true;
+}
+
+CompositableHost*
+CompositableHost::FromIPDLActor(PCompositableParent* aActor)
+{
+  MOZ_ASSERT(aActor);
+  return static_cast<CompositableParent*>(aActor)->mHost;
+}
+
 void
 CompositableHost::UseTextureHost(TextureHost* aTexture)
 {
   if (!aTexture) {
     return;
   }
   aTexture->SetCompositor(GetCompositor());
   aTexture->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData());
@@ -166,64 +229,35 @@ CompositableHost::DumpTextureHost(FILE* 
   nsRefPtr<gfxASurface> surf = platform->GetThebesSurfaceForDrawTarget(dt);
   if (!surf) {
     return;
   }
   surf->DumpAsDataURL(aFile ? aFile : stderr);
 }
 #endif
 
-void
-CompositableParent::ActorDestroy(ActorDestroyReason why)
-{
-  if (mHost) {
-    mHost->Detach(nullptr, CompositableHost::FORCE_DETACH);
-  }
-}
-
-CompositableParent::CompositableParent(CompositableParentManager* aMgr,
-                                       const TextureInfo& aTextureInfo,
-                                       uint64_t aID)
-: mManager(aMgr)
-, mType(aTextureInfo.mCompositableType)
-, mID(aID)
-, mCompositorID(0)
-{
-  MOZ_COUNT_CTOR(CompositableParent);
-  mHost = CompositableHost::Create(aTextureInfo);
-  if (aID) {
-    CompositableMap::Set(aID, this);
-  }
-}
-
-CompositableParent::~CompositableParent()
-{
-  MOZ_COUNT_DTOR(CompositableParent);
-  CompositableMap::Erase(mID);
-}
-
 namespace CompositableMap {
 
-typedef std::map<uint64_t, CompositableParent*> CompositableMap_t;
+typedef std::map<uint64_t, PCompositableParent*> CompositableMap_t;
 static CompositableMap_t* sCompositableMap = nullptr;
 bool IsCreated() {
   return sCompositableMap != nullptr;
 }
-CompositableParent* Get(uint64_t aID)
+PCompositableParent* Get(uint64_t aID)
 {
   if (!IsCreated() || aID == 0) {
     return nullptr;
   }
   CompositableMap_t::iterator it = sCompositableMap->find(aID);
   if (it == sCompositableMap->end()) {
     return nullptr;
   }
   return it->second;
 }
-void Set(uint64_t aID, CompositableParent* aParent)
+void Set(uint64_t aID, PCompositableParent* aParent)
 {
   if (!IsCreated() || aID == 0) {
     return;
   }
   (*sCompositableMap)[aID] = aParent;
 }
 void Erase(uint64_t aID)
 {
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -46,16 +46,17 @@ struct TiledLayerProperties
 };
 
 class Layer;
 class SurfaceDescriptor;
 class Compositor;
 class ISurfaceAllocator;
 class ThebesBufferData;
 class TiledLayerComposer;
+class CompositableParentManager;
 struct EffectChain;
 
 /**
  * A base class for doing CompositableHost and platform dependent task on TextureHost.
  */
 class CompositableBackendSpecificData
 {
 protected:
@@ -302,85 +303,46 @@ public:
 
   virtual void RemoveTextureHost(TextureHost* aTexture);
 
   // Called every time this is composited
   void BumpFlashCounter() {
     mFlashCounter = mFlashCounter >= DIAGNOSTIC_FLASH_COUNTER_MAX
                   ? DIAGNOSTIC_FLASH_COUNTER_MAX : mFlashCounter + 1;
   }
+
+  static PCompositableParent*
+  CreateIPDLActor(CompositableParentManager* mgr,
+                  const TextureInfo& textureInfo,
+                  uint64_t asyncID);
+
+  static bool DestroyIPDLActor(PCompositableParent* actor);
+
+  static CompositableHost* FromIPDLActor(PCompositableParent* actor);
+
+  uint64_t GetCompositorID() const { return mCompositorID; }
+
+  uint64_t GetAsyncID() const { return mAsyncID; }
+
+  void SetCompositorID(uint64_t aID) { mCompositorID = aID; }
+
+  void SetAsyncID(uint64_t aID) { mAsyncID = aID; }
+
 protected:
   TextureInfo mTextureInfo;
+  uint64_t mAsyncID;
+  uint64_t mCompositorID;
   Compositor* mCompositor;
   Layer* mLayer;
   RefPtr<CompositableBackendSpecificData> mBackendData;
   uint32_t mFlashCounter; // used when the pref "layers.flash-borders" is true.
   bool mAttached;
   bool mKeepAttached;
 };
 
-class CompositableParentManager;
-
-/**
- * IPDL actor used by CompositableHost to match with its corresponding
- * CompositableClient on the content side.
- *
- * CompositableParent is owned by the IPDL system. It's deletion is triggered
- * by either the CompositableChild's deletion, or by the IPDL communication
- * goind down.
- */
-class CompositableParent : public PCompositableParent
-{
-public:
-  CompositableParent(CompositableParentManager* aMgr,
-                     const TextureInfo& aTextureInfo,
-                     uint64_t aID = 0);
-  ~CompositableParent();
-
-  virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
-
-  CompositableHost* GetCompositableHost() const
-  {
-    return mHost;
-  }
-
-  void SetCompositableHost(CompositableHost* aHost)
-  {
-    mHost = aHost;
-  }
-
-  CompositableType GetType() const
-  {
-    return mType;
-  }
-
-  CompositableParentManager* GetCompositableManager() const
-  {
-    return mManager;
-  }
-
-  void SetCompositorID(uint64_t aCompositorID)
-  {
-    mCompositorID = aCompositorID;
-  }
-
-  uint64_t GetCompositorID() const
-  {
-    return mCompositorID;
-  }
-
-private:
-  RefPtr<CompositableHost> mHost;
-  CompositableParentManager* mManager;
-  CompositableType mType;
-  uint64_t mID;
-  uint64_t mCompositorID;
-};
-
-
 /**
  * Global CompositableMap, to use in the compositor thread only.
  *
  * PCompositable and PLayer can, in the case of async textures, be managed by
  * different top level protocols. In this case they don't share the same
  * communication channel and we can't send an OpAttachCompositable (PCompositable,
  * PLayer) message.
  *
@@ -401,18 +363,18 @@ private:
  * ImageBridge is used by all the existing compositors that have a video, so
  * there isn't an instance or "something" that lives outside the boudaries of a
  * given layer manager on the compositor thread except the image bridge and the
  * thread itself.
  */
 namespace CompositableMap {
   void Create();
   void Destroy();
-  CompositableParent* Get(uint64_t aID);
-  void Set(uint64_t aID, CompositableParent* aParent);
+  PCompositableParent* Get(uint64_t aID);
+  void Set(uint64_t aID, PCompositableParent* aParent);
   void Erase(uint64_t aID);
   void Clear();
 } // CompositableMap
 
 
 } // namespace
 } // namespace
 
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_COMPOSITORD3D11_H
 #define MOZILLA_GFX_COMPOSITORD3D11_H
 
 #include "mozilla/gfx/2D.h"
+#include "gfx2DGlue.h"
 #include "mozilla/layers/Compositor.h"
 #include "TextureD3D11.h"
 #include <d3d11.h>
 
 class nsWidget;
 
 namespace mozilla {
 namespace layers {
@@ -152,16 +153,18 @@ private:
   void VerifyBufferSize();
   void UpdateRenderTarget();
   bool CreateShaders();
   void UpdateConstantBuffers();
   void SetSamplerForFilter(gfx::Filter aFilter);
   void SetPSForEffect(Effect *aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat);
   void PaintToTarget();
 
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE { return gfx::ToIntSize(mSize); }
+
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
 
   DeviceAttachmentsD3D11* mAttachments;
 
--- a/gfx/layers/d3d9/CompositorD3D9.h
+++ b/gfx/layers/d3d9/CompositorD3D9.h
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_COMPOSITORD3D9_H
 #define MOZILLA_GFX_COMPOSITORD3D9_H
 
 #include "mozilla/gfx/2D.h"
+#include "gfx2DGlue.h"
 #include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/TextureD3D9.h"
 #include "DeviceManagerD3D9.h"
 
 class nsWidget;
 
 namespace mozilla {
 namespace layers {
@@ -148,16 +149,21 @@ private:
    * everything and render it all. This method checks the reset counts
    * match and if not invalidates everything (a long comment on that in
    * the cpp file).
    */
   void CheckResetCount();
 
   void ReportFailure(const nsACString &aMsg, HRESULT aCode);
 
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE
+  {
+    return gfx::ToIntSize(mSize);
+  }
+
   /* Device manager instance for this compositor */
   nsRefPtr<DeviceManagerD3D9> mDeviceManager;
 
   /* Swap chain associated with this compositor */
   nsRefPtr<SwapChainD3D9> mSwapChain;
 
   /* Widget associated with this layer manager */
   nsIWidget *mWidget;
--- a/gfx/layers/ipc/CompositableTransactionParent.cpp
+++ b/gfx/layers/ipc/CompositableTransactionParent.cpp
@@ -27,78 +27,73 @@
 #include "nsRegion.h"                   // for nsIntRegion
 
 namespace mozilla {
 namespace layers {
 
 class ClientTiledLayerBuffer;
 class Compositor;
 
-template<typename T>
-CompositableHost* AsCompositable(const T& op)
+template<typename Op>
+CompositableHost* AsCompositable(const Op& op)
 {
-  return static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost();
+  return CompositableHost::FromIPDLActor(op.compositableParent());
 }
 
 // This function can in some cases fail and return false without it being a bug.
 // This can theoretically happen if the ImageBridge sends frames before
 // we created the layer tree. Since we can't enforce that the layer
 // tree is already created before ImageBridge operates, there isn't much
 // we can do about it, but in practice it is very rare.
 // Typically when a tab with a video is dragged from a window to another,
 // there can be a short time when the video is still sending frames
 // asynchonously while the layer tree is not reconstructed. It's not a
 // big deal.
 // Note that Layers transactions do not need to call this because they always
 // schedule the composition, in LayerManagerComposite::EndTransaction.
 template<typename T>
 bool ScheduleComposition(const T& op)
 {
-  CompositableParent* comp = static_cast<CompositableParent*>(op.compositableParent());
-  if (!comp || !comp->GetCompositorID()) {
+  CompositableHost* comp = AsCompositable(op);
+  uint64_t id = comp->GetCompositorID();
+  if (!comp || !id) {
     return false;
   }
-  CompositorParent* cp
-    = CompositorParent::GetCompositor(comp->GetCompositorID());
+  CompositorParent* cp = CompositorParent::GetCompositor(id);
   if (!cp) {
     return false;
   }
   cp->ScheduleComposition();
   return true;
 }
 
 bool
 CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation& aEdit,
                                                      EditReplyVector& replyv)
 {
   switch (aEdit.type()) {
     case CompositableOperation::TOpCreatedIncrementalTexture: {
       MOZ_LAYERS_LOG(("[ParentSide] Created texture"));
       const OpCreatedIncrementalTexture& op = aEdit.get_OpCreatedIncrementalTexture();
-
-      CompositableParent* compositableParent =
-        static_cast<CompositableParent*>(op.compositableParent());
-      CompositableHost* compositable = compositableParent->GetCompositableHost();
+      CompositableHost* compositable = AsCompositable(op);
 
       bool success =
-        compositable->CreatedIncrementalTexture(compositableParent->GetCompositableManager(),
+        compositable->CreatedIncrementalTexture(this,
                                                 op.textureInfo(),
                                                 op.bufferRect());
       if (!success) {
         return false;
       }
       break;
     }
     case CompositableOperation::TOpPaintTextureRegion: {
       MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));
 
       const OpPaintTextureRegion& op = aEdit.get_OpPaintTextureRegion();
-      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
-      CompositableHost* compositable =
-        compositableParent->GetCompositableHost();
+      CompositableHost* compositable = AsCompositable(op);
       Layer* layer = compositable->GetLayer();
       if (!layer || layer->GetType() != Layer::TYPE_THEBES) {
         return false;
       }
       ThebesLayerComposite* thebes = static_cast<ThebesLayerComposite*>(layer);
 
       const ThebesBufferData& bufferData = op.bufferData();
 
@@ -108,55 +103,50 @@ CompositableParentManager::ReceiveCompos
       if (!compositable->UpdateThebes(bufferData,
                                       op.updatedRegion(),
                                       thebes->GetValidRegion(),
                                       &frontUpdatedRegion))
       {
         return false;
       }
       replyv.push_back(
-        OpContentBufferSwap(compositableParent, nullptr, frontUpdatedRegion));
+        OpContentBufferSwap(op.compositableParent(), nullptr, frontUpdatedRegion));
 
       RenderTraceInvalidateEnd(thebes, "FF00FF");
       // return texure data to client if necessary
       ReturnTextureDataIfNecessary(compositable, replyv, op.compositableParent());
       break;
     }
     case CompositableOperation::TOpPaintTextureIncremental: {
       MOZ_LAYERS_LOG(("[ParentSide] Paint ThebesLayer"));
 
       const OpPaintTextureIncremental& op = aEdit.get_OpPaintTextureIncremental();
 
-      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
-      CompositableHost* compositable =
-        compositableParent->GetCompositableHost();
+      CompositableHost* compositable = AsCompositable(op);
 
       SurfaceDescriptor desc = op.image();
 
       compositable->UpdateIncremental(op.textureId(),
                                       desc,
                                       op.updatedRegion(),
                                       op.bufferRect(),
                                       op.bufferRotation());
       break;
     }
     case CompositableOperation::TOpUpdatePictureRect: {
       const OpUpdatePictureRect& op = aEdit.get_OpUpdatePictureRect();
-      CompositableHost* compositable
-       = static_cast<CompositableParent*>(op.compositableParent())->GetCompositableHost();
+      CompositableHost* compositable = AsCompositable(op);
       MOZ_ASSERT(compositable);
       compositable->SetPictureRect(op.picture());
       break;
     }
     case CompositableOperation::TOpUseTiledLayerBuffer: {
       MOZ_LAYERS_LOG(("[ParentSide] Paint TiledLayerBuffer"));
       const OpUseTiledLayerBuffer& op = aEdit.get_OpUseTiledLayerBuffer();
-      CompositableParent* compositableParent = static_cast<CompositableParent*>(op.compositableParent());
-      CompositableHost* compositable =
-        compositableParent->GetCompositableHost();
+      CompositableHost* compositable = AsCompositable(op);
 
       TiledLayerComposer* tileComposer = compositable->AsTiledLayerComposer();
       NS_ASSERTION(tileComposer, "compositable is not a tile composer");
 
       const SurfaceDescriptorTiles& tileDesc = op.tileLayerDescriptor();
       tileComposer->UseTiledLayerBuffer(this, tileDesc);
       break;
     }
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -188,23 +188,22 @@ ImageBridgeParent::DeallocPGrallocBuffer
 }
 
 PCompositableParent*
 ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
                                             uint64_t* aID)
 {
   uint64_t id = GenImageContainerID();
   *aID = id;
-  return new CompositableParent(this, aInfo, id);
+  return CompositableHost::CreateIPDLActor(this, aInfo, id);
 }
 
 bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
 {
-  delete aActor;
-  return true;
+  return CompositableHost::DestroyIPDLActor(aActor);
 }
 
 PTextureParent*
 ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                        const TextureFlags& aFlags)
 {
   return TextureHost::CreateIPDLActor(this, aSharedData, aFlags);
 }
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -55,23 +55,16 @@ class PGrallocBufferParent;
 // Convenience accessors
 static ShadowLayerParent*
 cast(const PLayerParent* in)
 {
   return const_cast<ShadowLayerParent*>(
     static_cast<const ShadowLayerParent*>(in));
 }
 
-static CompositableParent*
-cast(const PCompositableParent* in)
-{
-  return const_cast<CompositableParent*>(
-    static_cast<const CompositableParent*>(in));
-}
-
 template<class OpCreateT>
 static ShadowLayerParent*
 AsLayerComposite(const OpCreateT& op)
 {
   return cast(op.layerParent());
 }
 
 static ShadowLayerParent*
@@ -503,34 +496,36 @@ LayerTransactionParent::RecvUpdate(const
       if (!ReceiveCompositableUpdate(edit.get_CompositableOperation(),
                                 replyv)) {
         return false;
       }
       break;
     }
     case Edit::TOpAttachCompositable: {
       const OpAttachCompositable& op = edit.get_OpAttachCompositable();
-      if (!Attach(cast(op.layerParent()), cast(op.compositableParent()), false)) {
+      CompositableHost* host = CompositableHost::FromIPDLActor(op.compositableParent());
+      if (!Attach(cast(op.layerParent()), host, false)) {
         return false;
       }
-      cast(op.compositableParent())->SetCompositorID(
-        mLayerManager->GetCompositor()->GetCompositorID());
+      host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
       break;
     }
     case Edit::TOpAttachAsyncCompositable: {
       const OpAttachAsyncCompositable& op = edit.get_OpAttachAsyncCompositable();
-      CompositableParent* compositableParent = CompositableMap::Get(op.containerID());
+      PCompositableParent* compositableParent = CompositableMap::Get(op.containerID());
       if (!compositableParent) {
         NS_ERROR("CompositableParent not found in the map");
         return false;
       }
-      if (!Attach(cast(op.layerParent()), compositableParent, true)) {
+      CompositableHost* host = CompositableHost::FromIPDLActor(compositableParent);
+      if (!Attach(cast(op.layerParent()), host, true)) {
         return false;
       }
-      compositableParent->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
+
+      host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
       break;
     }
     default:
       NS_RUNTIMEABORT("not reached");
     }
   }
 
   {
@@ -689,46 +684,45 @@ LayerTransactionParent::RecvSetAsyncScro
     return false;
   }
   controller->SetTestAsyncScrollOffset(CSSPoint(aX, aY));
   return true;
 }
 
 bool
 LayerTransactionParent::Attach(ShadowLayerParent* aLayerParent,
-                               CompositableParent* aCompositable,
-                               bool aIsAsyncVideo)
+                               CompositableHost* aCompositable,
+                               bool aIsAsync)
 {
+  if (!aCompositable) {
+    return false;
+  }
+
   Layer* baselayer = aLayerParent->AsLayer();
   if (!baselayer) {
     return false;
   }
   LayerComposite* layer = baselayer->AsLayerComposite();
   if (!layer) {
     return false;
   }
 
   Compositor* compositor
     = static_cast<LayerManagerComposite*>(aLayerParent->AsLayer()->Manager())->GetCompositor();
 
-  CompositableHost* compositable = aCompositable->GetCompositableHost();
-  if (!compositable) {
-    return false;
-  }
-  if (!layer->SetCompositableHost(compositable)) {
+  if (!layer->SetCompositableHost(aCompositable)) {
     // not all layer types accept a compositable, see bug 967824
     return false;
   }
-  compositable->Attach(aLayerParent->AsLayer(),
-                       compositor,
-                       aIsAsyncVideo
-                         ? CompositableHost::ALLOW_REATTACH
-                           | CompositableHost::KEEP_ATTACHED
-                         : CompositableHost::NO_FLAGS);
-
+  aCompositable->Attach(aLayerParent->AsLayer(),
+                        compositor,
+                        aIsAsync
+                          ? CompositableHost::ALLOW_REATTACH
+                            | CompositableHost::KEEP_ATTACHED
+                          : CompositableHost::NO_FLAGS);
   return true;
 }
 
 bool
 LayerTransactionParent::RecvClearCachedResources()
 {
   if (mRoot) {
     // NB: |mRoot| here is the *child* context's root.  In this parent
@@ -784,24 +778,23 @@ LayerTransactionParent::DeallocPLayerPar
 {
   delete actor;
   return true;
 }
 
 PCompositableParent*
 LayerTransactionParent::AllocPCompositableParent(const TextureInfo& aInfo)
 {
-  return new CompositableParent(this, aInfo);
+  return CompositableHost::CreateIPDLActor(this, aInfo, 0);
 }
 
 bool
-LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* actor)
+LayerTransactionParent::DeallocPCompositableParent(PCompositableParent* aActor)
 {
-  delete actor;
-  return true;
+  return CompositableHost::DestroyIPDLActor(aActor);
 }
 
 PTextureParent*
 LayerTransactionParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                             const TextureFlags& aFlags)
 {
   return TextureHost::CreateIPDLActor(this, aSharedData, aFlags);
 }
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -116,17 +116,17 @@ protected:
   virtual PCompositableParent* AllocPCompositableParent(const TextureInfo& aInfo) MOZ_OVERRIDE;
   virtual bool DeallocPCompositableParent(PCompositableParent* actor) MOZ_OVERRIDE;
 
   virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                               const TextureFlags& aFlags) MOZ_OVERRIDE;
   virtual bool DeallocPTextureParent(PTextureParent* actor) MOZ_OVERRIDE;
 
   bool Attach(ShadowLayerParent* aLayerParent,
-              CompositableParent* aCompositable,
+              CompositableHost* aCompositable,
               bool aIsAsyncVideo);
 
   void AddIPDLReference() {
     MOZ_ASSERT(mIPCOpen == false);
     mIPCOpen = true;
     AddRef();
   }
   void ReleaseIPDLReference() {
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_COMPOSITOROGL_H
 #define MOZILLA_GFX_COMPOSITOROGL_H
 
+#include "gfx2DGlue.h"
 #include "GLContextTypes.h"             // for GLContext, etc
 #include "GLDefs.h"                     // for GLuint, LOCAL_GL_TEXTURE_2D, etc
 #include "OGLShaderProgram.h"           // for ShaderProgramOGL, etc
 #include "Units.h"                      // for ScreenPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Attributes.h"         // for MOZ_OVERRIDE, MOZ_FINAL
 #include "mozilla/RefPtr.h"             // for TemporaryRef, RefPtr
 #include "mozilla/gfx/2D.h"             // for DrawTarget
@@ -280,16 +281,21 @@ public:
 private:
   virtual void DrawQuadInternal(const gfx::Rect& aRect,
                                 const gfx::Rect& aClipRect,
                                 const EffectChain &aEffectChain,
                                 gfx::Float aOpacity,
                                 const gfx::Matrix4x4 &aTransformi,
                                 GLuint aDrawMode);
 
+  virtual gfx::IntSize GetWidgetSize() const MOZ_OVERRIDE
+  {
+    return gfx::ToIntSize(mWidgetSize);
+  }
+
   /**
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
 
   /** Widget associated with this compositor */
   nsIWidget *mWidget;
   nsIntSize mWidgetSize;
deleted file mode 100644
--- a/intl/uconv/tests/unit/test_bug718500.js
+++ /dev/null
@@ -1,208 +0,0 @@
-var detectList = [
-  "chardet.universal_charset_detector",
-  "chardet.ja_parallel_state_machine",
-  "chardet.ko_parallel_state_machine",
-  "chardet.zhtw_parallel_state_machine",
-  "chardet.zhcn_parallel_state_machine",
-  "chardet.zh_parallel_state_machine",
-  "chardet.cjk_parallel_state_machine",
-  "chardet.off",
-  "chardet.ruprob",
-  "chardet.ukprob",
-];
-
-var encoderList = [
-  "ISO-8859-1",
-  "windows-1252",
-  "macintosh",
-  "UTF-8",
-  "us-ascii",
-  "ISO-8859-2",
-  "ISO-8859-3",
-  "ISO-8859-4",
-  "ISO-8859-5",
-  "ISO-8859-6",
-  "ISO-8859-6-I",
-  "ISO-8859-6-E",
-  "ISO-8859-7",
-  "ISO-8859-8",
-  "ISO-8859-8-I",
-  "ISO-8859-8-E",
-  "ISO-8859-9",
-  "ISO-8859-10",
-  "ISO-8859-13",
-  "ISO-8859-14",
-  "ISO-8859-15",
-  "ISO-8859-16",
-  "ISO-IR-111",
-  "windows-1250",
-  "windows-1251",
-  "windows-1253",
-  "windows-1254",
-  "windows-1255",
-  "windows-1256",
-  "windows-1257",
-  "windows-1258",
-  "TIS-620",
-  "windows-874",
-  "ISO-8859-11",
-  "KOI8-R",
-  "KOI8-U",
-  "x-mac-ce",
-  "x-mac-greek",
-  "x-mac-turkish",
-  "x-mac-croatian",
-  "x-mac-romanian",
-  "x-mac-cyrillic",
-  "x-mac-icelandic",
-  "armscii-8",
-  "x-viet-tcvn5712",
-  "VISCII",
-  "x-viet-vps",
-  "UTF-16",
-  "UTF-16BE",
-  "UTF-16LE",
-  "T.61-8bit",
-  "x-user-defined",
-  "x-mac-arabic",
-  "x-mac-devanagari",
-  "x-mac-farsi",
-  "x-mac-gurmukhi",
-  "x-mac-gujarati",
-  "x-mac-hebrew",
-
-  "IBM850",
-  "IBM852",
-  "IBM855",
-  "IBM857",
-  "IBM862",
-  "IBM864",
-  "IBM866",
-  "Shift_JIS",
-  "ISO-2022-JP",
-  "EUC-JP",
-  "jis_0201",
-  "x-euc-tw",
-  "Big5",
-  "Big5-HKSCS",
-  "hkscs-1",
-  "EUC-KR",
-  "x-johab",
-  "GB2312",
-  "gbk",
-  "HZ-GB-2312",
-  "gb18030",
-  "replacement",
-];
-
-var decoderList = [
-  "ISO-8859-1",
-  "windows-1252",
-  "macintosh",
-  "UTF-8",
-  "us-ascii",
-  "ISO-8859-2",
-  "ISO-8859-3",
-  "ISO-8859-4",
-  "ISO-8859-5",
-  "ISO-8859-6",
-  "ISO-8859-6-I",
-  "ISO-8859-6-E",
-  "ISO-8859-7",
-  "ISO-8859-8",
-  "ISO-8859-8-I",
-  "ISO-8859-8-E",
-  "ISO-8859-9",
-  "ISO-8859-10",
-  "ISO-8859-13",
-  "ISO-8859-14",
-  "ISO-8859-15",
-  "ISO-8859-16",
-  "ISO-IR-111",
-  "windows-1250",
-  "windows-1251",
-  "windows-1253",
-  "windows-1254",
-  "windows-1255",
-  "windows-1256",
-  "windows-1257",
-  "windows-1258",
-  "TIS-620",
-  "windows-874",
-  "ISO-8859-11",
-  "KOI8-R",
-  "KOI8-U",
-  "x-mac-ce",
-  "x-mac-greek",
-  "x-mac-turkish",
-  "x-mac-croatian",
-  "x-mac-romanian",
-  "x-mac-cyrillic",
-  "x-mac-icelandic",
-  "armscii-8",
-  "x-viet-tcvn5712",
-  "VISCII",
-  "x-viet-vps",
-  "UTF-16",
-  "UTF-16BE",
-  "UTF-16LE",
-  "T.61-8bit",
-  "x-user-defined",
-  "x-mac-arabic",
-  "x-mac-devanagari",
-  "x-mac-farsi",
-  "x-mac-gurmukhi",
-  "x-mac-gujarati",
-  "x-mac-hebrew",
-  "IBM850",
-  "IBM852",
-  "IBM855",
-  "IBM857",
-  "IBM862",
-  "IBM864",
-  "IBM866",
-  "Shift_JIS",
-  "ISO-2022-JP",
-  "EUC-JP",
-  "x-euc-tw",
-  "Big5",
-  "Big5-HKSCS",
-  "EUC-KR",
-  "x-johab",
-  "GB2312",
-  "gbk",
-  "HZ-GB-2312",
-  "gb18030",
-  "ISO-2022-KR",
-  "ISO-2022-CN",
-  "replacement",
-];
-
-function verifyList(aEnumerator, aList)
-{
-  var count = 0;
-
-  while (aEnumerator.hasMore()) {
-    var result = aEnumerator.getNext();
-    for (var i = 0; i < aList.length; i++) {
-      if (result == aList[i]) {
-        count++;
-        break;
-      }
-    }
-    if (i == aList.length) {
-      do_throw("Unknown chardet: " + result);
-    }
-  }
-  do_check_eq(count, aList.length);
-}
-
-function run_test()
-{
-  var cm = Components.classes["@mozilla.org/charset-converter-manager;1"]
-           .getService(Components.interfaces.nsICharsetConverterManager);
-
-  verifyList(cm.GetCharsetDetectorList(), detectList);
-  verifyList(cm.getEncoderList(), encoderList);
-  verifyList(cm.getDecoderList(), decoderList);
-}
--- a/intl/uconv/tests/unit/xpcshell.ini
+++ b/intl/uconv/tests/unit/xpcshell.ini
@@ -34,17 +34,16 @@ support-files =
 [test_bug563618.js]
 [test_bug601429.js]
 [test_bug699673.js]
 [test_bug90411.js]
 [test_bug713519.js]
 [test_bug715319.euc_jp.js]
 [test_bug715319.gb2312.js]
 [test_bug715319.dbcs.js]
-[test_bug718500.js]
 [test_charset_conversion.js]
 [test_decode_8859-1.js]
 [test_decode_8859-10.js]
 [test_decode_8859-11.js]
 [test_decode_8859-13.js]
 [test_decode_8859-14.js]
 [test_decode_8859-15.js]
 [test_decode_8859-2.js]
--- a/js/src/NamespaceImports.h
+++ b/js/src/NamespaceImports.h
@@ -32,16 +32,18 @@ class AutoValueVector;
 
 class AutoIdArray;
 
 class AutoGCRooter;
 template <typename T> class AutoVectorRooter;
 template<typename K, typename V> class AutoHashMapRooter;
 template<typename T> class AutoHashSetRooter;
 
+class SourceBufferHolder;
+
 class HandleValueArray;
 
 }
 
 // Do the importing.
 namespace js {
 
 using JS::Value;
@@ -82,16 +84,17 @@ using JS::AutoVectorRooter;
 using JS::CallArgs;
 using JS::CallNonGenericMethod;
 using JS::CallReceiver;
 using JS::CompileOptions;
 using JS::IsAcceptableThis;
 using JS::NativeImpl;
 using JS::OwningCompileOptions;
 using JS::ReadOnlyCompileOptions;
+using JS::SourceBufferHolder;
 
 using JS::Rooted;
 using JS::RootedFunction;
 using JS::RootedId;
 using JS::RootedObject;
 using JS::RootedScript;
 using JS::RootedString;
 using JS::RootedValue;
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -315,19 +315,20 @@ EvalKernel(JSContext *cx, const CallArgs
 
         CompileOptions options(cx);
         options.setFileAndLine(filename, 1)
                .setCompileAndGo(true)
                .setForEval(true)
                .setNoScriptRval(false)
                .setOriginPrincipals(originPrincipals)
                .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
+        SourceBufferHolder srcBuf(chars.get(), length, SourceBufferHolder::NoOwnership);
         JSScript *compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                      scopeobj, callerScript, options,
-                                                     chars.get(), length, flatStr, staticLevel);
+                                                     srcBuf, flatStr, staticLevel);
         if (!compiled)
             return false;
 
         MarkFunctionsWithinEvalScript(compiled);
 
         esg.setNewScript(compiled);
     }
 
@@ -383,19 +384,20 @@ js::DirectEvalStringFromIon(JSContext *c
 
         CompileOptions options(cx);
         options.setFileAndLine(filename, 1)
                .setCompileAndGo(true)
                .setForEval(true)
                .setNoScriptRval(false)
                .setOriginPrincipals(originPrincipals)
                .setIntroductionInfo(introducerFilename, "eval", lineno, maybeScript, pcOffset);
+        SourceBufferHolder srcBuf(chars.get(), length, SourceBufferHolder::NoOwnership);
         JSScript *compiled = frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                      scopeobj, callerScript, options,
-                                                     chars.get(), length, flatStr, staticLevel);
+                                                     srcBuf, flatStr, staticLevel);
         if (!compiled)
             return false;
 
         MarkFunctionsWithinEvalScript(compiled);
 
         esg.setNewScript(compiled);
     }
 
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -22,22 +22,22 @@
 
 #include "frontend/Parser-inl.h"
 
 using namespace js;
 using namespace js::frontend;
 using mozilla::Maybe;
 
 static bool
-CheckLength(ExclusiveContext *cx, size_t length)
+CheckLength(ExclusiveContext *cx, SourceBufferHolder &srcBuf)
 {
     // Note this limit is simply so we can store sourceStart and sourceEnd in
     // JSScript as 32-bits. It could be lifted fairly easily, since the compiler
     // is using size_t internally already.
-    if (length > UINT32_MAX) {
+    if (srcBuf.length() > UINT32_MAX) {
         if (cx->isJSContext())
             JS_ReportErrorNumber(cx->asJSContext(), js_GetErrorMessage, nullptr,
                                  JSMSG_SOURCE_TOO_LONG);
         return false;
     }
     return true;
 }
 
@@ -149,24 +149,24 @@ CanLazilyParse(ExclusiveContext *cx, con
         !cx->compartment()->options().discardSource() &&
         !options.sourceIsLazy &&
         !(cx->compartment()->debugMode() &&
           cx->compartment()->runtimeFromAnyThread()->debugHooks.newScriptHook);
 }
 
 void
 frontend::MaybeCallSourceHandler(JSContext *cx, const ReadOnlyCompileOptions &options,
-                                 const jschar *chars, size_t length)
+                                 SourceBufferHolder &srcBuf)
 {
     JSSourceHandler listener = cx->runtime()->debugHooks.sourceHandler;
     void *listenerData = cx->runtime()->debugHooks.sourceHandlerData;
 
     if (listener) {
         void *listenerTSData;
-        listener(options.filename(), options.lineno, chars, length,
+        listener(options.filename(), options.lineno, srcBuf.get(), srcBuf.length(),
                  &listenerTSData, listenerData);
     }
 }
 
 ScriptSourceObject *
 frontend::CreateScriptSourceObject(ExclusiveContext *cx, const ReadOnlyCompileOptions &options)
 {
     ScriptSource *ss = cx->new_<ScriptSource>();
@@ -179,84 +179,89 @@ frontend::CreateScriptSourceObject(Exclu
 
     return ScriptSourceObject::create(cx, ss, options);
 }
 
 JSScript *
 frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject scopeChain,
                         HandleScript evalCaller,
                         const ReadOnlyCompileOptions &options,
-                        const jschar *chars, size_t length,
+                        SourceBufferHolder &srcBuf,
                         JSString *source_ /* = nullptr */,
                         unsigned staticLevel /* = 0 */,
                         SourceCompressionTask *extraSct /* = nullptr */)
 {
+    JS_ASSERT(srcBuf.get());
+
     RootedString source(cx, source_);
 
     js::TraceLogger *logger = nullptr;
     if (cx->isJSContext())
         logger = TraceLoggerForMainThread(cx->asJSContext()->runtime());
     else
         logger = TraceLoggerForCurrentThread();
     uint32_t logId = js::TraceLogCreateTextId(logger, options);
     js::AutoTraceLog scriptLogger(logger, logId);
     js::AutoTraceLog typeLogger(logger, TraceLogger::ParserCompileScript);
 
     if (cx->isJSContext())
-        MaybeCallSourceHandler(cx->asJSContext(), options, chars, length);
+        MaybeCallSourceHandler(cx->asJSContext(), options, srcBuf);
 
     /*
      * The scripted callerFrame can only be given for compile-and-go scripts
      * and non-zero static level requires callerFrame.
      */
     JS_ASSERT_IF(evalCaller, options.compileAndGo);
     JS_ASSERT_IF(evalCaller, options.forEval);
     JS_ASSERT_IF(staticLevel != 0, evalCaller);
 
-    if (!CheckLength(cx, length))
+    if (!CheckLength(cx, srcBuf))
         return nullptr;
     JS_ASSERT_IF(staticLevel != 0, !options.sourceIsLazy);
 
     RootedScriptSource sourceObject(cx, CreateScriptSourceObject(cx, options));
     if (!sourceObject)
         return nullptr;
 
     ScriptSource *ss = sourceObject->source();
 
     SourceCompressionTask mysct(cx);
     SourceCompressionTask *sct = extraSct ? extraSct : &mysct;
 
     if (!cx->compartment()->options().discardSource()) {
         if (options.sourceIsLazy)
             ss->setSourceRetrievable();
-        else if (!ss->setSourceCopy(cx, chars, length, false, sct))
+        else if (!ss->setSourceCopy(cx, srcBuf, false, sct))
             return nullptr;
     }
 
     bool canLazilyParse = CanLazilyParse(cx, options);
 
     Maybe<Parser<SyntaxParseHandler> > syntaxParser;
     if (canLazilyParse) {
-        syntaxParser.construct(cx, alloc, options, chars, length, /* foldConstants = */ false,
+        syntaxParser.construct(cx, alloc, options, srcBuf.get(), srcBuf.length(),
+                               /* foldConstants = */ false,
                                (Parser<SyntaxParseHandler> *) nullptr,
                                (LazyScript *) nullptr);
     }
 
-    Parser<FullParseHandler> parser(cx, alloc, options, chars, length, /* foldConstants = */ true,
+    Parser<FullParseHandler> parser(cx, alloc, options, srcBuf.get(), srcBuf.length(),
+                                    /* foldConstants = */ true,
                                     canLazilyParse ? &syntaxParser.ref() : nullptr, nullptr);
     parser.sct = sct;
     parser.ss = ss;
 
     Directives directives(options.strictOption);
     GlobalSharedContext globalsc(cx, scopeChain, directives, options.extraWarningsOption);
 
     bool savedCallerFun = options.compileAndGo &&
                           evalCaller && evalCaller->functionOrCallerFunction();
     Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), savedCallerFun,
-                                                  options, staticLevel, sourceObject, 0, length));
+                                                  options, staticLevel, sourceObject, 0,
+                                                  srcBuf.length()));
     if (!script)
         return nullptr;
 
     // We can specialize a bit for the given scope chain if that scope chain is the global object.
     JSObject *globalScope =
         scopeChain && scopeChain == &scopeChain->global() ? (JSObject*) scopeChain : nullptr;
     JS_ASSERT_IF(globalScope, globalScope->isNative());
     JS_ASSERT_IF(globalScope, JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(globalScope->getClass()));
@@ -486,58 +491,60 @@ frontend::CompileLazyFunction(JSContext 
 
     return EmitFunctionScript(cx, &bce, pn->pn_body);
 }
 
 // Compile a JS function body, which might appear as the value of an event
 // handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
 static bool
 CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, const ReadOnlyCompileOptions &options,
-                    const AutoNameVector &formals, const jschar *chars, size_t length,
+                    const AutoNameVector &formals, SourceBufferHolder &srcBuf,
                     GeneratorKind generatorKind)
 {
     js::TraceLogger *logger = js::TraceLoggerForMainThread(cx->runtime());
     uint32_t logId = js::TraceLogCreateTextId(logger, options);
     js::AutoTraceLog scriptLogger(logger, logId);
     js::AutoTraceLog typeLogger(logger, TraceLogger::ParserCompileFunction);
 
     // FIXME: make Function pass in two strings and parse them as arguments and
     // ProgramElements respectively.
 
-    MaybeCallSourceHandler(cx, options, chars, length);
+    MaybeCallSourceHandler(cx, options, srcBuf);
 
-    if (!CheckLength(cx, length))
+    if (!CheckLength(cx, srcBuf))
         return false;
 
     RootedScriptSource sourceObject(cx, CreateScriptSourceObject(cx, options));
     if (!sourceObject)
         return nullptr;
     ScriptSource *ss = sourceObject->source();
 
     SourceCompressionTask sct(cx);
     JS_ASSERT(!options.sourceIsLazy);
     if (!cx->compartment()->options().discardSource()) {
-        if (!ss->setSourceCopy(cx, chars, length, true, &sct))
+        if (!ss->setSourceCopy(cx, srcBuf, true, &sct))
             return false;
     }
 
     bool canLazilyParse = CanLazilyParse(cx, options);
 
     Maybe<Parser<SyntaxParseHandler> > syntaxParser;
     if (canLazilyParse) {
         syntaxParser.construct(cx, &cx->tempLifoAlloc(),
-                               options, chars, length, /* foldConstants = */ false,
+                               options, srcBuf.get(), srcBuf.length(),
+                               /* foldConstants = */ false,
                                (Parser<SyntaxParseHandler> *) nullptr,
                                (LazyScript *) nullptr);
     }
 
     JS_ASSERT(!options.forEval);
 
     Parser<FullParseHandler> parser(cx, &cx->tempLifoAlloc(),
-                                    options, chars, length, /* foldConstants = */ true,
+                                    options, srcBuf.get(), srcBuf.length(),
+                                    /* foldConstants = */ true,
                                     canLazilyParse ? &syntaxParser.ref() : nullptr, nullptr);
     parser.sct = &sct;
     parser.ss = ss;
 
     JS_ASSERT(fun);
     JS_ASSERT(fun->isTenured());
 
     fun->setArgCount(formals.length());
@@ -579,17 +586,17 @@ CompileFunctionBody(JSContext *cx, Mutab
     if (!NameFunctions(cx, fn))
         return false;
 
     if (fn->pn_funbox->function()->isInterpreted()) {
         JS_ASSERT(fun == fn->pn_funbox->function());
 
         Rooted<JSScript*> script(cx, JSScript::Create(cx, js::NullPtr(), false, options,
                                                       /* staticLevel = */ 0, sourceObject,
-                                                      /* sourceStart = */ 0, length));
+                                                      /* sourceStart = */ 0, srcBuf.length()));
         if (!script)
             return false;
 
         script->bindings = fn->pn_funbox->bindings;
 
         /*
          * The reason for checking fun->environment() below is that certain
          * consumers of JS::CompileFunction, namely
@@ -621,20 +628,20 @@ CompileFunctionBody(JSContext *cx, Mutab
         return false;
 
     return true;
 }
 
 bool
 frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun,
                               const ReadOnlyCompileOptions &options,
-                              const AutoNameVector &formals, const jschar *chars, size_t length)
+                              const AutoNameVector &formals, JS::SourceBufferHolder &srcBuf)
 {
-    return CompileFunctionBody(cx, fun, options, formals, chars, length, NotGenerator);
+    return CompileFunctionBody(cx, fun, options, formals, srcBuf, NotGenerator);
 }
 
 bool
 frontend::CompileStarGeneratorBody(JSContext *cx, MutableHandleFunction fun,
                                    const ReadOnlyCompileOptions &options, const AutoNameVector &formals,
-                                   const jschar *chars, size_t length)
+                                   JS::SourceBufferHolder &srcBuf)
 {
-    return CompileFunctionBody(cx, fun, options, formals, chars, length, StarGenerator);
+    return CompileFunctionBody(cx, fun, options, formals, srcBuf, StarGenerator);
 }
--- a/js/src/frontend/BytecodeCompiler.h
+++ b/js/src/frontend/BytecodeCompiler.h
@@ -18,42 +18,42 @@ class LazyScript;
 class LifoAlloc;
 struct SourceCompressionTask;
 
 namespace frontend {
 
 JSScript *
 CompileScript(ExclusiveContext *cx, LifoAlloc *alloc,
               HandleObject scopeChain, HandleScript evalCaller,
-              const ReadOnlyCompileOptions &options, const jschar *chars, size_t length,
+              const ReadOnlyCompileOptions &options, SourceBufferHolder &srcBuf,
               JSString *source_ = nullptr, unsigned staticLevel = 0,
               SourceCompressionTask *extraSct = nullptr);
 
 bool
 CompileLazyFunction(JSContext *cx, Handle<LazyScript*> lazy, const jschar *chars, size_t length);
 
 bool
 CompileFunctionBody(JSContext *cx, MutableHandleFunction fun,
                     const ReadOnlyCompileOptions &options,
-                    const AutoNameVector &formals, const jschar *chars, size_t length);
+                    const AutoNameVector &formals, JS::SourceBufferHolder &srcBuf);
 bool
 CompileStarGeneratorBody(JSContext *cx, MutableHandleFunction fun,
                          const ReadOnlyCompileOptions &options,
-                         const AutoNameVector &formals, const jschar *chars, size_t length);
+                         const AutoNameVector &formals, JS::SourceBufferHolder &srcBuf);
 
 ScriptSourceObject *
 CreateScriptSourceObject(ExclusiveContext *cx, const ReadOnlyCompileOptions &options);
 
 /*
  * This should be called while still on the main thread if compilation will
  * occur on a worker thread.
  */
 void
 MaybeCallSourceHandler(JSContext *cx, const ReadOnlyCompileOptions &options,
-                       const jschar *chars, size_t length);
+                       JS::SourceBufferHolder &srcBuf);
 
 /*
  * True if str consists of an IdentifierStart character, followed by one or
  * more IdentifierPart characters, i.e. it matches the IdentifierName production
  * in the language spec.
  *
  * This returns true even if str is a keyword like "if".
  *
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -562,25 +562,54 @@ js::Nursery::moveObjectToTenured(JSObjec
     if (src->is<ArrayObject>())
         srcSize = sizeof(ObjectImpl);
 
     js_memcpy(dst, src, srcSize);
     tenuredSize += moveSlotsToTenured(dst, src, dstKind);
     tenuredSize += moveElementsToTenured(dst, src, dstKind);
 
     if (src->is<TypedArrayObject>())
-        dst->setPrivate(dst->fixedData(TypedArrayObject::FIXED_DATA_START));
+        forwardTypedArrayPointers(dst, src);
 
     /* The shape's list head may point into the old object. */
     if (&src->shape_ == dst->shape_->listp)
         dst->shape_->listp = &dst->shape_;
 
     return tenuredSize;
 }
 
+void
+js::Nursery::forwardTypedArrayPointers(JSObject *dst, JSObject *src)
+{
+    /*
+     * Typed array data may be stored inline inside the object's fixed slots. If
+     * so, we need update the private pointer and leave a forwarding pointer at
+     * the start of the data.
+     */
+    TypedArrayObject &typedArray = src->as<TypedArrayObject>();
+    JS_ASSERT_IF(typedArray.buffer(), !isInside(src->getPrivate()));
+    if (typedArray.buffer())
+        return;
+
+    void *srcData = src->fixedData(TypedArrayObject::FIXED_DATA_START);
+    void *dstData = dst->fixedData(TypedArrayObject::FIXED_DATA_START);
+    JS_ASSERT(src->getPrivate() == srcData);
+    dst->setPrivate(dstData);
+
+    /*
+     * We don't know the number of slots here, but
+     * TypedArrayObject::AllocKindForLazyBuffer ensures that it's always at
+     * least one.
+     */
+    size_t nslots = 1;
+    setSlotsForwardingPointer(reinterpret_cast<HeapSlot*>(srcData),
+                              reinterpret_cast<HeapSlot*>(dstData),
+                              nslots);
+}
+
 size_t
 js::Nursery::moveSlotsToTenured(JSObject *dst, JSObject *src, AllocKind dstKind)
 {
     /* Fixed slots have already been copied over. */
     if (!src->hasDynamicSlots())
         return 0;
 
     if (!isInside(src->slots)) {
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -266,16 +266,17 @@ class Nursery
     MOZ_ALWAYS_INLINE void traceObject(gc::MinorCollectionTracer *trc, JSObject *src);
     MOZ_ALWAYS_INLINE void markSlots(gc::MinorCollectionTracer *trc, HeapSlot *vp, uint32_t nslots);
     MOZ_ALWAYS_INLINE void markSlots(gc::MinorCollectionTracer *trc, HeapSlot *vp, HeapSlot *end);
     MOZ_ALWAYS_INLINE void markSlot(gc::MinorCollectionTracer *trc, HeapSlot *slotp);
     void *moveToTenured(gc::MinorCollectionTracer *trc, JSObject *src);
     size_t moveObjectToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
     size_t moveElementsToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
     size_t moveSlotsToTenured(JSObject *dst, JSObject *src, gc::AllocKind dstKind);
+    void forwardTypedArrayPointers(JSObject *dst, JSObject *src);
 
     /* Handle relocation of slots/elements pointers stored in Ion frames. */
     void setSlotsForwardingPointer(HeapSlot *oldSlots, HeapSlot *newSlots, uint32_t nslots);
     void setElementsForwardingPointer(ObjectElements *oldHeader, ObjectElements *newHeader,
                                       uint32_t nelems);
 
     /* Free malloced pointers owned by freed things in the nursery. */
     void freeHugeSlots(JSRuntime *rt);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-993768.js
@@ -0,0 +1,13 @@
+var SECTION = "";
+gcPreserveCode()
+gczeal(9, 1000);
+function test() {
+    var f32 = new Float32Array(10);
+    f32[0] = 5;
+    var i = 0;
+    for (var j = 0; j < 10000; ++j) {
+        f32[i + 1] = f32[i] - 1;
+        SECTION += 1;
+    }
+} 
+test();
--- a/js/src/jit/AsmJSLink.cpp
+++ b/js/src/jit/AsmJSLink.cpp
@@ -573,17 +573,18 @@ HandleDynamicLinkFailure(JSContext *cx, 
     if (module.bufferArgumentName())
         formals.infallibleAppend(module.bufferArgumentName());
 
     CompileOptions options(cx);
     options.setOriginPrincipals(module.scriptSource()->originPrincipals())
            .setCompileAndGo(false)
            .setNoScriptRval(false);
 
-    if (!frontend::CompileFunctionBody(cx, &fun, options, formals, src->chars(), end - begin))
+    SourceBufferHolder srcBuf(src->chars(), end - begin, SourceBufferHolder::NoOwnership);
+    if (!frontend::CompileFunctionBody(cx, &fun, options, formals, srcBuf))
         return false;
 
     // Call the function we just recompiled.
     args.setCallee(ObjectValue(*fun));
     return Invoke(cx, args);
 }
 
 #ifdef MOZ_VTUNE
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4520,25 +4520,33 @@ JS::CompileOptions::wrap(JSContext *cx, 
             introductionScriptRoot = nullptr;
     }
 
     return true;
 }
 
 JSScript *
 JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
-            const jschar *chars, size_t length)
+            SourceBufferHolder &srcBuf)
 {
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     AutoLastFrameCheck lfc(cx);
 
-    return frontend::CompileScript(cx, &cx->tempLifoAlloc(), obj, NullPtr(), options, chars, length);
+    return frontend::CompileScript(cx, &cx->tempLifoAlloc(), obj, NullPtr(), options, srcBuf);
+}
+
+JSScript *
+JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
+            const jschar *chars, size_t length)
+{
+    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
+    return Compile(cx, obj, options, srcBuf);
 }
 
 JSScript *
 JS::Compile(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
             const char *bytes, size_t length)
 {
     jschar *chars;
     if (options.utf8)
@@ -4684,17 +4692,17 @@ JS_GetGlobalFromScript(JSScript *script)
 {
     JS_ASSERT(!script->isCachedEval());
     return &script->global();
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
-                    const jschar *chars, size_t length)
+                    SourceBufferHolder &srcBuf)
 {
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
     AutoLastFrameCheck lfc(cx);
 
     RootedAtom funAtom(cx);
@@ -4711,32 +4719,41 @@ JS::CompileFunction(JSContext *cx, Handl
             return nullptr;
     }
 
     RootedFunction fun(cx, NewFunction(cx, NullPtr(), nullptr, 0, JSFunction::INTERPRETED, obj,
                                        funAtom, JSFunction::FinalizeKind, TenuredObject));
     if (!fun)
         return nullptr;
 
-    if (!frontend::CompileFunctionBody(cx, &fun, options, formals, chars, length))
+    if (!frontend::CompileFunctionBody(cx, &fun, options, formals, srcBuf))
         return nullptr;
 
     if (obj && funAtom && options.defineOnScope) {
         Rooted<jsid> id(cx, AtomToId(funAtom));
         RootedValue value(cx, ObjectValue(*fun));
         if (!JSObject::defineGeneric(cx, obj, id, value, nullptr, nullptr, JSPROP_ENUMERATE))
             return nullptr;
     }
 
     return fun;
 }
 
 JS_PUBLIC_API(JSFunction *)
 JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
                     const char *name, unsigned nargs, const char *const *argnames,
+                    const jschar *chars, size_t length)
+{
+  SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
+  return JS::CompileFunction(cx, obj, options, name, nargs, argnames, srcBuf);
+}
+
+JS_PUBLIC_API(JSFunction *)
+JS::CompileFunction(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
+                    const char *name, unsigned nargs, const char *const *argnames,
                     const char *bytes, size_t length)
 {
     jschar *chars;
     if (options.utf8)
         chars = UTF8CharsToNewTwoByteCharsZ(cx, UTF8Chars(bytes, length), &length).get();
     else
         chars = InflateString(cx, bytes, &length);
     if (!chars)
@@ -4853,32 +4870,32 @@ JS_ExecuteScriptVersion(JSContext *cx, H
 {
     return ExecuteScript(cx, obj, script, nullptr);
 }
 
 static const unsigned LARGE_SCRIPT_LENGTH = 500*1024;
 
 static bool
 Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
-         const jschar *chars, size_t length, JS::Value *rval)
+         SourceBufferHolder &srcBuf, JS::Value *rval)
 {
     CompileOptions options(cx, optionsArg);
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     AutoLastFrameCheck lfc(cx);
 
     options.setCompileAndGo(obj->is<GlobalObject>());
     options.setNoScriptRval(!rval);
     SourceCompressionTask sct(cx);
     RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                     obj, NullPtr(), options,
-                                                    chars, length, nullptr, 0, &sct));
+                                                    srcBuf, nullptr, 0, &sct));
     if (!script)
         return false;
 
     JS_ASSERT(script->getVersion() == options.version);
 
     bool result = Execute(cx, script, *obj, rval);
     if (!sct.complete())
         result = false;
@@ -4893,29 +4910,37 @@ Evaluate(JSContext *cx, HandleObject obj
         PrepareZoneForGC(cx->zone());
         GC(cx->runtime(), GC_NORMAL, JS::gcreason::FINISH_LARGE_EVALUTE);
     }
 
     return result;
 }
 
 static bool
+Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+         const jschar *chars, size_t length, JS::Value *rval)
+{
+  SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
+  return ::Evaluate(cx, obj, optionsArg, srcBuf, rval);
+}
+
+static bool
 Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *bytes, size_t length, JS::Value *rval)
 {
     jschar *chars;
     if (options.utf8)
         chars = UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(bytes, length), &length).get();
     else
         chars = InflateString(cx, bytes, &length);
     if (!chars)
         return false;
 
-    bool ok = ::Evaluate(cx, obj, options, chars, length, rval);
-    js_free(chars);
+    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::GiveOwnership);
+    bool ok = ::Evaluate(cx, obj, options, srcBuf, rval);
     return ok;
 }
 
 static bool
 Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
          const char *filename, JS::Value *rval)
 {
     FileContents buffer(cx);
@@ -4927,16 +4952,23 @@ Evaluate(JSContext *cx, HandleObject obj
 
     CompileOptions options(cx, optionsArg);
     options.setFileAndLine(filename, 1);
     return Evaluate(cx, obj, options, buffer.begin(), buffer.length(), rval);
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+             SourceBufferHolder &srcBuf, MutableHandleValue rval)
+{
+    return ::Evaluate(cx, obj, optionsArg, srcBuf, rval.address());
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
              const jschar *chars, size_t length, MutableHandleValue rval)
 {
     return ::Evaluate(cx, obj, optionsArg, chars, length, rval.address());
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
              const char *bytes, size_t length, MutableHandleValue rval)
@@ -4948,16 +4980,23 @@ extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
              const char *filename, MutableHandleValue rval)
 {
     return ::Evaluate(cx, obj, optionsArg, filename, rval.address());
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
+             SourceBufferHolder &srcBuf)
+{
+    return ::Evaluate(cx, obj, optionsArg, srcBuf, nullptr);
+}
+
+extern JS_PUBLIC_API(bool)
+JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsArg,
              const jschar *chars, size_t length)
 {
     return ::Evaluate(cx, obj, optionsArg, chars, length, nullptr);
 }
 
 extern JS_PUBLIC_API(bool)
 JS::Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &options,
              const char *bytes, size_t length)
@@ -4978,16 +5017,26 @@ JS_EvaluateUCScript(JSContext *cx, Handl
 {
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
 
     return ::Evaluate(cx, obj, options, chars, length, rval.address());
 }
 
 JS_PUBLIC_API(bool)
+JS_EvaluateUCScript(JSContext *cx, HandleObject obj, SourceBufferHolder &srcBuf,
+                    const char *filename, unsigned lineno, MutableHandleValue rval)
+{
+    CompileOptions options(cx);
+    options.setFileAndLine(filename, lineno);
+
+    return ::Evaluate(cx, obj, options, srcBuf, rval.address());
+}
+
+JS_PUBLIC_API(bool)
 JS_EvaluateScript(JSContext *cx, HandleObject obj, const char *bytes, unsigned nbytes,
                   const char *filename, unsigned lineno, MutableHandleValue rval)
 {
     CompileOptions options(cx);
     options.setFileAndLine(filename, lineno);
 
     return ::Evaluate(cx, obj, options, bytes, nbytes, rval.address());
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -872,16 +872,101 @@ class AutoIdRooter : private AutoGCRoote
 
     friend void AutoGCRooter::trace(JSTracer *trc);
 
   private:
     jsid id_;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
+// Container class for passing in script source buffers to the JS engine.  This
+// not only groups the buffer and length values, it also provides a way to
+// optionally pass ownership of the buffer to the JS engine without copying.
+// Rules for use:
+//
+//  1) The data array must be allocated with js_malloc() or js_realloc() if
+//     ownership is being granted to the SourceBufferHolder.
+//  2) If ownership is not given to the SourceBufferHolder, then the memory
+//     must be kept alive until the JS compilation is complete.
+//  3) Any code calling SourceBufferHolder::take() must guarantee to keep the
+//     memory alive until JS compilation completes.  Normally only the JS
+//     engine should be calling take().
+//
+// Example use:
+//
+//    size_t length = 512;
+//    jschar* chars = static_cast<jschar*>(js_malloc(sizeof(jschar) * length));
+//    JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
+//    JS::Compile(cx, obj, options, srcBuf);
+//
+class MOZ_STACK_CLASS SourceBufferHolder MOZ_FINAL
+{
+  public:
+    enum Ownership {
+      NoOwnership,
+      GiveOwnership
+    };
+
+    SourceBufferHolder(const jschar *data, size_t dataLength, Ownership ownership)
+      : data_(data),
+        length_(dataLength),
+        ownsChars_(ownership == GiveOwnership)
+    {
+        // Ensure that null buffers properly return an unowned, empty,
+        // null-terminated string.
+        static const jschar NullChar_ = 0;
+        if (!get()) {
+            data_ = &NullChar_;
+            length_ = 0;
+            ownsChars_ = false;
+        }
+    }
+
+    ~SourceBufferHolder() {
+        if (ownsChars_)
+            js_free(const_cast<jschar *>(data_));
+    }
+
+    // Access the underlying source buffer without affecting ownership.
+    const jschar *get() const { return data_; }
+
+    // Length of the source buffer in jschars (not bytes)
+    size_t length() const { return length_; }
+
+    // Returns true if the SourceBufferHolder owns the buffer and will free
+    // it upon destruction.  If true, it is legal to call take().
+    bool ownsChars() const { return ownsChars_; }
+
+    // Retrieve and take ownership of the underlying data buffer.  The caller
+    // is now responsible for calling js_free() on the returned value, *but only
+    // after JS script compilation has completed*.
+    //
+    // After the buffer has been taken the SourceBufferHolder functions as if
+    // it had been constructed on an unowned buffer;  get() and length() still
+    // work.  In order for this to be safe the taken buffer must be kept alive
+    // until after JS script compilation completes as noted above.
+    //
+    // Note, it's the caller's responsibility to check ownsChars() before taking
+    // the buffer.  Taking and then free'ing an unowned buffer will have dire
+    // consequences.
+    jschar *take() {
+        JS_ASSERT(ownsChars_);
+        ownsChars_ = false;
+        return const_cast<jschar *>(data_);
+    }
+
+  private:
+    SourceBufferHolder(SourceBufferHolder &) MOZ_DELETE;
+    SourceBufferHolder &operator=(SourceBufferHolder &) MOZ_DELETE;
+
+    const jschar *data_;
+    size_t length_;
+    bool ownsChars_;
+};
+
 } /* namespace JS */
 
 /************************************************************************/
 
 /* Property attributes, set in JSPropertySpec and passed to API functions. */
 #define JSPROP_ENUMERATE        0x01    /* property is visible to for/in loop */
 #define JSPROP_READONLY         0x02    /* not settable: assignment is no-op.
                                            This flag is only valid when neither
@@ -3644,16 +3729,20 @@ extern JS_PUBLIC_API(JSScript *)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
         const char *bytes, size_t length);
 
 extern JS_PUBLIC_API(JSScript *)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
         const jschar *chars, size_t length);
 
 extern JS_PUBLIC_API(JSScript *)
+Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+        SourceBufferHolder &srcBuf);
+
+extern JS_PUBLIC_API(JSScript *)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, FILE *file);
 
 extern JS_PUBLIC_API(JSScript *)
 Compile(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options, const char *filename);
 
 extern JS_PUBLIC_API(bool)
 CanCompileOffThread(JSContext *cx, const ReadOnlyCompileOptions &options, size_t length);
 
@@ -3686,16 +3775,21 @@ CompileFunction(JSContext *cx, JS::Handl
                 const char *name, unsigned nargs, const char *const *argnames,
                 const char *bytes, size_t length);
 
 extern JS_PUBLIC_API(JSFunction *)
 CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
                 const char *name, unsigned nargs, const char *const *argnames,
                 const jschar *chars, size_t length);
 
+extern JS_PUBLIC_API(JSFunction *)
+CompileFunction(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+                const char *name, unsigned nargs, const char *const *argnames,
+                SourceBufferHolder &srcBuf);
+
 } /* namespace JS */
 
 extern JS_PUBLIC_API(JSString *)
 JS_DecompileScript(JSContext *cx, JS::Handle<JSScript*> script, const char *name, unsigned indent);
 
 /*
  * API extension: OR this into indent to avoid pretty-printing the decompiled
  * source resulting from JS_DecompileFunction{,Body}.
@@ -3782,28 +3876,36 @@ JS_EvaluateUCScript(JSContext *cx, JS::H
                     const jschar *chars, unsigned length,
                     const char *filename, unsigned lineno,
                     JS::MutableHandle<JS::Value> rval);
 
 namespace JS {
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+         SourceBufferHolder &srcBuf, JS::MutableHandleValue rval);
+
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const jschar *chars, size_t length, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *bytes, size_t length, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *filename, JS::MutableHandleValue rval);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
+         SourceBufferHolder &srcBuf);
+
+extern JS_PUBLIC_API(bool)
+Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const jschar *chars, size_t length);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
          const char *bytes, size_t length);
 
 extern JS_PUBLIC_API(bool)
 Evaluate(JSContext *cx, JS::HandleObject obj, const ReadOnlyCompileOptions &options,
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -1612,20 +1612,21 @@ FunctionConstructor(JSContext *cx, unsig
 
     if (!JSFunction::setTypeForScriptedFunction(cx, fun))
         return false;
 
     if (hasRest)
         fun->setHasRest();
 
     bool ok;
+    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
     if (isStarGenerator)
-        ok = frontend::CompileStarGeneratorBody(cx, &fun, options, formals, chars, length);
+        ok = frontend::CompileStarGeneratorBody(cx, &fun, options, formals, srcBuf);
     else
-        ok = frontend::CompileFunctionBody(cx, &fun, options, formals, chars, length);
+        ok = frontend::CompileFunctionBody(cx, &fun, options, formals, srcBuf);
     args.rval().setObject(*fun);
     return ok;
 }
 
 bool
 js::Function(JSContext *cx, unsigned argc, Value *vp)
 {
     return FunctionConstructor(cx, argc, vp, NotGenerator);
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3848,17 +3848,17 @@ ExclusiveContext::getNewType(const Class
 
     if (!newTypeObjects.initialized() && !newTypeObjects.init())
         return nullptr;
 
     // Canonicalize new functions to use the original one associated with its script.
     if (fun) {
         if (fun->hasScript())
             fun = fun->nonLazyScript()->functionNonDelazifying();
-        else if (fun->isInterpretedLazy())
+        else if (fun->isInterpretedLazy() && !fun->isSelfHostedBuiltin())
             fun = fun->lazyScript()->functionNonDelazifying();
         else
             fun = nullptr;
     }
 
     TypeObjectWithNewScriptSet::AddPtr p =
         newTypeObjects.lookupForAdd(TypeObjectWithNewScriptSet::Lookup(clasp, proto, fun));
     if (p) {
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1562,21 +1562,21 @@ ScriptSource::substring(JSContext *cx, u
     SourceDataCache::AutoHoldEntry holder;
     const jschar *chars = this->chars(cx, holder);
     if (!chars)
         return nullptr;
     return js_NewStringCopyN<CanGC>(cx, chars + start, stop - start);
 }
 
 bool
-ScriptSource::setSourceCopy(ExclusiveContext *cx, const jschar *src, uint32_t length,
+ScriptSource::setSourceCopy(ExclusiveContext *cx, SourceBufferHolder &srcBuf,
                             bool argumentsNotIncluded, SourceCompressionTask *task)
 {
     JS_ASSERT(!hasSourceData());
-    length_ = length;
+    length_ = srcBuf.length();
     argumentsNotIncluded_ = argumentsNotIncluded;
 
     // There are several cases where source compression is not a good idea:
     //  - If the script is tiny, then compression will save little or no space.
     //  - If the script is enormous, then decompression can take seconds. With
     //    lazy parsing, decompression is not uncommon, so this can significantly
     //    increase latency.
     //  - If there is only one core, then compression will contend with JS
@@ -1599,26 +1599,28 @@ ScriptSource::setSourceCopy(ExclusiveCon
     bool canCompressOffThread =
         WorkerThreadState().cpuCount > 1 &&
         WorkerThreadState().threadCount >= 2;
 #else
     bool canCompressOffThread = false;
 #endif
     const size_t TINY_SCRIPT = 256;
     const size_t HUGE_SCRIPT = 5 * 1024 * 1024;
-    if (TINY_SCRIPT <= length && length < HUGE_SCRIPT && canCompressOffThread) {
+    if (TINY_SCRIPT <= srcBuf.length() && srcBuf.length() < HUGE_SCRIPT && canCompressOffThread) {
         task->ss = this;
-        task->chars = src;
+        task->chars = srcBuf.get();
         ready_ = false;
         if (!StartOffThreadCompression(cx, task))
             return false;
+    } else if (srcBuf.ownsChars()) {
+        data.source = srcBuf.take();
     } else {
-        if (!adjustDataSize(sizeof(jschar) * length))
+        if (!adjustDataSize(sizeof(jschar) * srcBuf.length()))
             return false;
-        PodCopy(data.source, src, length_);
+        PodCopy(data.source, srcBuf.get(), length_);
     }
 
     return true;
 }
 
 void
 ScriptSource::setSource(const jschar *src, size_t length)
 {
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -475,18 +475,17 @@ class ScriptSource
     void incref() { refs++; }
     void decref() {
         JS_ASSERT(refs != 0);
         if (--refs == 0)
             destroy();
     }
     bool initFromOptions(ExclusiveContext *cx, const ReadOnlyCompileOptions &options);
     bool setSourceCopy(ExclusiveContext *cx,
-                       const jschar *src,
-                       uint32_t length,
+                       JS::SourceBufferHolder &srcBuf,
                        bool argumentsNotIncluded,
                        SourceCompressionTask *tok);
     void setSource(const jschar *src, size_t length);
     bool ready() const { return ready_; }
     void setSourceRetrievable() { sourceRetrievable_ = true; }
     bool sourceRetrievable() const { return sourceRetrievable_; }
     bool hasSourceData() const { return !ready() || !!data.source; }
     uint32_t length() const {
--- a/js/src/jsworkers.cpp
+++ b/js/src/jsworkers.cpp
@@ -294,17 +294,18 @@ bool
 js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &options,
                               const jschar *chars, size_t length,
                               JS::OffThreadCompileCallback callback, void *callbackData)
 {
     // Suppress GC so that calls below do not trigger a new incremental GC
     // which could require barriers on the atoms compartment.
     gc::AutoSuppressGC suppress(cx);
 
-    frontend::MaybeCallSourceHandler(cx, options, chars, length);
+    SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
+    frontend::MaybeCallSourceHandler(cx, options, srcBuf);
 
     EnsureWorkerThreadsInitialized(cx);
 
     JS::CompartmentOptions compartmentOptions(cx->compartment()->options());
     compartmentOptions.setZone(JS::FreshZone);
     compartmentOptions.setInvisibleToDebugger(true);
     compartmentOptions.setMergeable(true);
 
@@ -855,20 +856,22 @@ WorkerThread::handleParseWorkload()
 
     parseTask = WorkerThreadState().parseWorklist().popCopy();
     parseTask->cx->setWorkerThread(this);
 
     {
         AutoUnlockWorkerThreadState unlock;
         PerThreadData::AutoEnterRuntime enter(threadData.addr(),
                                               parseTask->exclusiveContextGlobal->runtimeFromAnyThread());
+        SourceBufferHolder srcBuf(parseTask->chars, parseTask->length,
+                                  SourceBufferHolder::NoOwnership);
         parseTask->script = frontend::CompileScript(parseTask->cx, &parseTask->alloc,
                                                     NullPtr(), NullPtr(),
                                                     parseTask->options,
-                                                    parseTask->chars, parseTask->length);
+                                                    srcBuf);
     }
 
     // The callback is invoked while we are still off the main thread.
     parseTask->callback(parseTask, parseTask->callbackData);
 
     // FinishOffThreadScript will need to be called on the script to
     // migrate it into the correct compartment.
     WorkerThreadState().parseFinishedList().append(parseTask);
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -339,19 +339,19 @@ ArrayBufferObject::neuter(JSContext *cx,
     for (ArrayBufferViewObject *view = buffer->viewList(); view; view = view->nextView()) {
         view->neuter(newData);
 
         // Notify compiled jit code that the base pointer has moved.
         MarkObjectStateChange(cx, view);
     }
 
     if (buffer->isMappedArrayBuffer())
-        buffer->changeContents(cx, nullptr);
+        buffer->setNewOwnedData(cx->runtime()->defaultFreeOp(), nullptr);
     else if (newData != buffer->dataPointer())
-        buffer->changeContents(cx, newData);
+        buffer->setNewOwnedData(cx->runtime()->defaultFreeOp(), newData);
 
     buffer->setByteLength(0);
     buffer->setViewList(nullptr);
     buffer->setIsNeutered();
 
     // If this is happening during an incremental GC, remove the buffer from
     // the list of live buffers with multiple views if necessary.
     if (buffer->inLiveList()) {
@@ -366,43 +366,54 @@ ArrayBufferObject::neuter(JSContext *cx,
             }
         }
         JS_ASSERT(found);
         buffer->setInLiveList(false);
     }
 }
 
 void
-ArrayBufferObject::changeContents(JSContext *cx, void *newData)
+ArrayBufferObject::setNewOwnedData(FreeOp* fop, void *newData)
 {
     JS_ASSERT(!isAsmJSArrayBuffer());
     JS_ASSERT(!isSharedArrayBuffer());
     JS_ASSERT_IF(isMappedArrayBuffer(), !newData);
 
+    if (ownsData()) {
+        JS_ASSERT(newData != dataPointer());
+        releaseData(fop);
+    }
+
+    setDataPointer(static_cast<uint8_t *>(newData), OwnsData);
+}
+
+void
+ArrayBufferObject::changeContents(JSContext *cx, void *newData)
+{
+    // Change buffer contents.
+    uint8_t* oldDataPointer = dataPointer();
+    setNewOwnedData(cx->runtime()->defaultFreeOp(), newData);
+
     // Update all views.
     ArrayBufferViewObject *viewListHead = viewList();
     for (ArrayBufferViewObject *view = viewListHead; view; view = view->nextView()) {
         // Watch out for NULL data pointers in views. This means that the view
         // is not fully initialized (in which case it'll be initialized later
         // with the correct pointer).
         uint8_t *viewDataPointer = view->dataPointer();
         if (viewDataPointer) {
             JS_ASSERT(newData);
-            viewDataPointer += static_cast<uint8_t *>(newData) - dataPointer();
+            ptrdiff_t offset = viewDataPointer - oldDataPointer;
+            viewDataPointer = static_cast<uint8_t *>(newData) + offset;
             view->setPrivate(viewDataPointer);
         }
 
         // Notify compiled jit code that the base pointer has moved.
         MarkObjectStateChange(cx, view);
     }
-
-    if (ownsData())
-        releaseData(cx->runtime()->defaultFreeOp());
-
-    setDataPointer(static_cast<uint8_t *>(newData), OwnsData);
 }
 
 #if defined(JS_CPU_X64)
 // Refer to comment above AsmJSMappedSize in AsmJS.h.
 JS_STATIC_ASSERT(AsmJSAllocationGranularity == AsmJSPageSize);
 #endif
 
 #if defined(JS_ION) && defined(JS_CPU_X64)
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -119,16 +119,17 @@ class ArrayBufferObject : public JSObjec
         return !isNeutered();
     }
 
     static void addSizeOfExcludingThis(JSObject *obj, mozilla::MallocSizeOf mallocSizeOf,
                                        JS::ObjectsExtraSizes *sizes);
 
     void addView(ArrayBufferViewObject *view);
 
+    void setNewOwnedData(FreeOp* fop, void *newData);
     void changeContents(JSContext *cx, void *newData);
 
     /*
      * Ensure data is not stored inline in the object. Used when handing back a
      * GC-safe pointer.
      */
     static bool ensureNonInline(JSContext *cx, Handle<ArrayBufferObject*> buffer);
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -4653,18 +4653,19 @@ js::EvaluateInEnv(JSContext *cx, Handle<
     CompileOptions options(cx);
     options.setCompileAndGo(true)
            .setForEval(true)
            .setNoScriptRval(false)
            .setFileAndLine(filename, lineno)
            .setCanLazilyParse(false)
            .setIntroductionType("debugger eval");
     RootedScript callerScript(cx, frame ? frame.script() : nullptr);
+    SourceBufferHolder srcBuf(chars.get(), length, SourceBufferHolder::NoOwnership);
     RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(), env, callerScript,
-                                                    options, chars.get(), length,
+                                                    options, srcBuf,
                                                     /* source = */ nullptr,
                                                     /* staticLevel = */ frame ? 1 : 0));
     if (!script)
         return false;
 
     script->setActiveEval();
     ExecuteType type = !frame ? EXECUTE_DEBUG_GLOBAL : EXECUTE_DEBUG;
     return ExecuteKernel(cx, script, *env, thisv, type, frame, rval.address());
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -46,18 +46,19 @@ class TypedArrayObject : public ArrayBuf
     // object is created lazily.
     static const uint32_t INLINE_BUFFER_LIMIT =
         (JSObject::MAX_FIXED_SLOTS - FIXED_DATA_START) * sizeof(Value);
 
     static gc::AllocKind
     AllocKindForLazyBuffer(size_t nbytes)
     {
         JS_ASSERT(nbytes <= INLINE_BUFFER_LIMIT);
-        int dataSlots = (nbytes - 1) / sizeof(Value) + 1;
-        JS_ASSERT(int(nbytes) <= dataSlots * int(sizeof(Value)));
+        /* For GGC we need at least one slot in which to store a forwarding pointer. */
+        size_t dataSlots = Max(size_t(1), AlignBytes(nbytes, sizeof(Value)) / sizeof(Value));
+        JS_ASSERT(nbytes <= dataSlots * sizeof(Value));
         return gc::GetGCObjectKind(FIXED_DATA_START + dataSlots);
     }
 
     static Value bufferValue(TypedArrayObject *tarr) {
         return tarr->getFixedSlot(BUFFER_SLOT);
     }
     static Value byteOffsetValue(TypedArrayObject *tarr) {
         return tarr->getFixedSlot(BYTEOFFSET_SLOT);
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -140,33 +140,35 @@ mozJSSubScriptLoader::ReadScript(nsIURI 
 
     /* set our own error reporter so we can report any bad things as catchable
      * exceptions, including the source/line number */
     JSErrorReporter er = JS_SetErrorReporter(cx, xpc::SystemErrorReporter);
 
     JS::CompileOptions options(cx);
     options.setFileAndLine(uriStr, 1);
     if (!charset.IsVoid()) {
-        nsString script;
+        jschar *scriptBuf = nullptr;
+        size_t scriptLength = 0;
+
         rv = nsScriptLoader::ConvertToUTF16(nullptr, reinterpret_cast<const uint8_t*>(buf.get()), len,
-                                            charset, nullptr, script);
+                                            charset, nullptr, scriptBuf, scriptLength);
+
+        JS::SourceBufferHolder srcBuf(scriptBuf, scriptLength,
+                                      JS::SourceBufferHolder::GiveOwnership);
 
         if (NS_FAILED(rv)) {
             return ReportError(cx, LOAD_ERROR_BADCHARSET);
         }
 
         if (!reuseGlobal) {
-            *scriptp = JS::Compile(cx, target_obj, options,
-                                   script.get(),
-                                   script.Length());
+            *scriptp = JS::Compile(cx, target_obj, options, srcBuf);
         } else {
             *functionp = JS::CompileFunction(cx, target_obj, options,
                                              nullptr, 0, nullptr,
-                                             script.get(),
-                                             script.Length());
+                                             srcBuf);
         }
     } else {
         // We only use lazy source when no special encoding is specified because
         // the lazy source loader doesn't know the encoding.
         if (!reuseGlobal) {
             options.setSourceIsLazy(true);
             *scriptp = JS::Compile(cx, target_obj, options, buf.get(), len);
         } else {
@@ -381,31 +383,38 @@ public:
     NS_DECL_NSISTREAMLOADEROBSERVER
 
     ScriptPrecompiler(nsIObserver* aObserver,
                       nsIPrincipal* aPrincipal,
                       nsIChannel* aChannel)
         : mObserver(aObserver)
         , mPrincipal(aPrincipal)
         , mChannel(aChannel)
+        , mScriptBuf(nullptr)
+        , mScriptLength(0)
     {}
 
     virtual ~ScriptPrecompiler()
-    {}
+    {
+      if (mScriptBuf) {
+        js_free(mScriptBuf);
+      }
+    }
 
     static void OffThreadCallback(void *aToken, void *aData);
 
     /* Sends the "done" notification back. Main thread only. */
     void SendObserverNotification();
 
 private:
     nsRefPtr<nsIObserver> mObserver;
     nsRefPtr<nsIPrincipal> mPrincipal;
     nsRefPtr<nsIChannel> mChannel;
-    nsString mScript;
+    jschar* mScriptBuf;
+    size_t mScriptLength;
 };
 
 NS_IMPL_ISUPPORTS1(ScriptPrecompiler, nsIStreamLoaderObserver);
 
 class NotifyPrecompilationCompleteRunnable : public nsRunnable
 {
 public:
     NS_DECL_NSIRUNNABLE
@@ -474,17 +483,18 @@ ScriptPrecompiler::OnStreamComplete(nsIS
 
     // Just notify that we are done with this load.
     NS_ENSURE_SUCCESS(aStatus, NS_OK);
 
     // Convert data to jschar* and prepare to call CompileOffThread.
     nsAutoString hintCharset;
     nsresult rv =
         nsScriptLoader::ConvertToUTF16(mChannel, aString, aLength,
-                                       hintCharset, nullptr, mScript);
+                                       hintCharset, nullptr,
+                                       mScriptBuf, mScriptLength);
 
     NS_ENSURE_SUCCESS(rv, NS_OK);
 
     // Our goal is to cache persistently the compiled script and to avoid quota
     // checks. Since the caching mechanism decide the persistence type based on
     // the principal, we create a new global with the app's principal.
     // We then enter its compartment to compile with its principal.
     AutoSafeJSContext cx;
@@ -504,26 +514,26 @@ ScriptPrecompiler::OnStreamComplete(nsIS
     options.installedFile = true;
 
     nsCOMPtr<nsIURI> uri;
     mChannel->GetURI(getter_AddRefs(uri));
     nsAutoCString spec;
     uri->GetSpec(spec);
     options.setFile(spec.get());
 
-    if (!JS::CanCompileOffThread(cx, options, mScript.Length())) {
+    if (!JS::CanCompileOffThread(cx, options, mScriptLength)) {
         NS_WARNING("Can't compile script off thread!");
         return NS_OK;
     }
 
     nsRefPtr<NotifyPrecompilationCompleteRunnable> runnable =
         new NotifyPrecompilationCompleteRunnable(this);
 
     if (!JS::CompileOffThread(cx, options,
-                              mScript.get(), mScript.Length(),
+                              mScriptBuf, mScriptLength,
                               OffThreadCallback,
                               static_cast<void*>(runnable))) {
         NS_WARNING("Failed to compile script off thread!");
         return NS_OK;
     }
 
     unused << runnable.forget();
     notifier.Disarm();
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -2981,27 +2981,27 @@ ReadSourceFromFilename(JSContext *cx, co
         uint32_t bytesRead;
         rv = scriptStream->Read(reinterpret_cast<char *>(ptr), end - ptr, &bytesRead);
         if (NS_FAILED(rv))
             return rv;
         MOZ_ASSERT(bytesRead > 0, "stream promised more bytes before EOF");
         ptr += bytesRead;
     }
 
-    nsString decoded;
     rv = nsScriptLoader::ConvertToUTF16(scriptChannel, buf, rawLen, EmptyString(),
-                                        nullptr, decoded);
+                                        nullptr, *src, *len);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    // Copy to JS engine.
-    *len = decoded.Length();
-    *src = static_cast<jschar *>(JS_malloc(cx, decoded.Length()*sizeof(jschar)));
     if (!*src)
         return NS_ERROR_FAILURE;
-    memcpy(*src, decoded.get(), decoded.Length()*sizeof(jschar));
+
+    // Historically this method used JS_malloc() which updates the GC memory
+    // accounting.  Since ConvertToUTF16() now uses js_malloc() instead we
+    // update the accounting manually after the fact.
+    JS_updateMallocCounter(cx, *len);
 
     return NS_OK;
 }
 
 // The JS engine calls this object's 'load' member function when it needs
 // the source for a chrome JS function. See the comment in the XPCJSRuntime
 // constructor.
 class XPCJSSourceHook: public js::SourceHook {
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -480,16 +480,33 @@ MakeContinuationFluid(nsIFrame* aFrame, 
                 "next-in-flow is not next continuation!");
   aFrame->SetNextInFlow(aNext);
 
   NS_ASSERTION (!aNext->GetPrevInFlow() || aNext->GetPrevInFlow() == aFrame,
                 "prev-in-flow is not prev continuation!");
   aNext->SetPrevInFlow(aFrame);
 }
 
+static void
+MakeContinuationsNonFluidUpParentChain(nsIFrame* aFrame, nsIFrame* aNext)
+{
+  nsIFrame* frame;
+  nsIFrame* next;
+
+  for (frame = aFrame, next = aNext;
+       frame && next &&
+         next != frame && next == frame->GetNextInFlow() &&
+         IsBidiSplittable(frame);
+       frame = frame->GetParent(), next = next->GetParent()) {
+
+    frame->SetNextContinuation(next);
+    next->SetPrevContinuation(frame);
+  }
+}
+
 // If aFrame is the last child of its parent, convert bidi continuations to
 // fluid continuations for all of its inline ancestors.
 // If it isn't the last child, make sure that its continuation is fluid.
 static void
 JoinInlineAncestors(nsIFrame* aFrame)
 {
   nsIFrame* frame = aFrame;
   do {
@@ -836,30 +853,17 @@ nsBidiPresUtils::ResolveParagraph(nsBloc
             /*
              * If the directional run ends at the end of the frame, make sure
              * that any continuation is non-fluid, and do the same up the
              * parent chain
              */
             nsIFrame* next = frame->GetNextInFlow();
             if (next) {
               currentLine->MarkDirty();
-              nsIFrame* parent = frame;
-              nsIFrame* nextParent = next;
-              while (parent && nextParent) {
-                if (parent == nextParent ||
-                    nextParent != parent->GetNextInFlow() ||
-                    !IsBidiSplittable(parent)) {
-                  break;
-                }
-                parent->SetNextContinuation(nextParent);
-                nextParent->SetPrevContinuation(parent);
-
-                parent = parent->GetParent();
-                nextParent = nextParent->GetParent();
-              }
+              MakeContinuationsNonFluidUpParentChain(frame, next);
             }
           }
           frame->AdjustOffsetsForBidi(contentOffset, contentOffset + fragmentLength);
         }
       } // isTextFrame
       else {
         ++lineOffset;
       }
@@ -1655,21 +1659,17 @@ nsBidiPresUtils::RemoveBidiContinuation(
       }
     }
   }
 
   // Make sure that the last continuation we made fluid does not itself have a
   // fluid continuation (this can happen when re-resolving after dynamic changes
   // to content)
   nsIFrame* lastFrame = aBpd->FrameAt(aLastIndex);
-  nsIFrame* next = lastFrame->GetNextInFlow();
-  if (next && IsBidiSplittable(lastFrame)) {
-    lastFrame->SetNextContinuation(next);
-    next->SetPrevContinuation(lastFrame);
-  }
+  MakeContinuationsNonFluidUpParentChain(lastFrame, lastFrame->GetNextInFlow());
 }
 
 nsresult
 nsBidiPresUtils::FormatUnicodeText(nsPresContext*  aPresContext,
                                    char16_t*       aText,
                                    int32_t&         aTextLength,
                                    nsCharType       aCharType,
                                    bool             aIsOddLevel)
--- a/media/webrtc/moz.build
+++ b/media/webrtc/moz.build
@@ -209,8 +209,9 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk
         GYP_DIRS += ['signalingtest']
         GYP_DIRS['signalingtest'].input = 'signaling/signaling.gyp'
         GYP_DIRS['signalingtest'].variables = gyp_vars.copy()
         GYP_DIRS['signalingtest'].variables.update(
             build_for_test=1
         )
         GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources
         GYP_DIRS['signalingtest'].non_unified_sources += signaling_non_unified_sources_2
+
--- a/media/webrtc/signaling/signaling.gyp
+++ b/media/webrtc/signaling/signaling.gyp
@@ -61,16 +61,17 @@
         '../trunk/webrtc/video_engine/include',
         '../trunk/webrtc/voice_engine/include',
         '../trunk/webrtc/modules/interface',
         '../trunk/webrtc/peerconnection',
         '../../libyuv/include',
         '../../../netwerk/srtp/src/include',
         '../../../netwerk/srtp/src/crypto/include',
         '../../../ipc/chromium/src',
+        '../../mtransport/third_party/nrappkit/src/util/libekr',
       ],
 
       #
       # DEPENDENCIES
       #
       'dependencies': [
       ],
 
@@ -88,16 +89,17 @@
         './src/media-conduit/VideoConduit.h',
         './src/media-conduit/VideoConduit.cpp',
         # Common
         './src/common/CommonTypes.h',
         './src/common/csf_common.h',
         './src/common/NullDeleter.h',
         './src/common/Wrapper.h',
         './src/common/NullTransport.h',
+        './src/common/YuvStamper.cpp',
         # Browser Logging
         './src/common/browser_logging/CSFLog.cpp',
         './src/common/browser_logging/CSFLog.h',
         # Browser Logging
         './src/common/time_profiling/timecard.c',
         './src/common/time_profiling/timecard.h',
         # Call Control
         './src/callcontrol/CC_CallTypes.cpp',
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/src/common/YuvStamper.cpp
@@ -0,0 +1,459 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#elif defined XP_WIN
+#include <winsock2.h>
+#endif
+#include <string.h>
+
+#include "nspr.h"
+#include "YuvStamper.h"
+
+typedef uint32_t UINT4; //Needed for r_crc32() call
+extern "C" {
+#include "r_crc32.h"
+}
+
+namespace mozilla {
+
+#define ON_5 0x20
+#define ON_4 0x10
+#define ON_3 0x08
+#define ON_2 0x04
+#define ON_1 0x02
+#define ON_0 0x01
+
+/*
+  0, 0, 1, 1, 0, 0,
+  0, 1, 0, 0, 1, 0,
+  1, 0, 0, 0, 0, 1,
+  1, 0, 0, 0, 0, 1,
+  1, 0, 0, 0, 0, 1,
+  0, 1, 0, 0, 1, 0,
+  0, 0, 1, 1, 0, 0
+*/
+static unsigned char DIGIT_0 [] =
+  { ON_3 | ON_2,
+    ON_4 | ON_1,
+    ON_5 | ON_0,
+    ON_5 | ON_0,
+    ON_5 | ON_0,
+    ON_4 | ON_1,
+    ON_3 | ON_2
+  };
+    
+/*
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 0, 1, 0, 0,
+*/
+static unsigned char DIGIT_1 [] =
+  { ON_2,
+    ON_2,
+    ON_2,
+    ON_2,
+    ON_2,
+    ON_2,
+    ON_2
+  };
+
+/*
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 1,
+*/
+static unsigned char DIGIT_2 [] =
+  { ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+    ON_0,
+    ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1,
+    ON_5,
+    ON_5,
+    ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+  };
+
+/*
+  1, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1,
+  1, 1, 1, 1, 1, 0,
+*/
+static unsigned char DIGIT_3 [] =
+  { ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+    ON_0,
+    ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_0,
+    ON_0,
+    ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+  };
+
+/*
+  0, 1, 0, 0, 0, 1,
+  0, 1, 0, 0, 0, 1,
+  0, 1, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1
+*/
+static unsigned char DIGIT_4 [] =
+  { ON_4 | ON_0,
+    ON_4 | ON_0,
+    ON_4 | ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_0,
+    ON_0,
+    ON_0,
+  };
+
+/*
+  0, 1, 1, 1, 1, 1,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  0, 1, 1, 1, 1, 0,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1,
+  1, 1, 1, 1, 1, 0,
+*/
+static unsigned char DIGIT_5 [] =
+  { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_5,
+    ON_5,
+    ON_4 | ON_3 | ON_2 | ON_1,
+    ON_0,
+    ON_0,
+    ON_5 | ON_4 | ON_3 | ON_2 | ON_1,
+  };
+
+/*
+  0, 1, 1, 1, 1, 1,
+  1, 0, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0,
+  1, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 1,
+  1, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 0,
+*/
+static unsigned char DIGIT_6 [] =
+  { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_5,
+    ON_5,
+    ON_4 | ON_3 | ON_2 | ON_1,
+    ON_5 | ON_0,
+    ON_5 | ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1,
+  };
+
+/*
+  1, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 1, 0,
+  0, 0, 0, 1, 0, 0,
+  0, 0, 1, 0, 0, 0,
+  0, 1, 0, 0, 0, 0,
+  1, 0, 0, 0, 0, 0
+*/
+static unsigned char DIGIT_7 [] =
+  { ON_5 | ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_0,
+    ON_1,
+    ON_2,
+    ON_3,
+    ON_4,
+    ON_5
+  };
+
+/*
+  0, 1, 1, 1, 1, 1,
+  1, 0, 0, 0, 0, 1,
+  1, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 0,
+  1, 0, 0, 0, 0, 1,
+  1, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 0
+*/
+static unsigned char DIGIT_8 [] =
+  { ON_4 | ON_3 | ON_2 | ON_1,
+    ON_5 | ON_0,
+    ON_5 | ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1,
+    ON_5 | ON_0,
+    ON_5 | ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1,
+  };
+
+/*
+  0, 1, 1, 1, 1, 1,
+  1, 0, 0, 0, 0, 1,
+  1, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 0, 0, 0, 0, 1,
+  0, 1, 1, 1, 1, 0
+*/
+static unsigned char DIGIT_9 [] =
+  { ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_5 | ON_0,
+    ON_5 | ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1 | ON_0,
+    ON_0,
+    ON_0,
+    ON_4 | ON_3 | ON_2 | ON_1,
+  };
+
+static unsigned char *DIGITS[] = {
+    DIGIT_0,
+    DIGIT_1,
+    DIGIT_2,
+    DIGIT_3,
+    DIGIT_4,
+    DIGIT_5,
+    DIGIT_6,
+    DIGIT_7,
+    DIGIT_8,
+    DIGIT_9
+};
+
+  YuvStamper::YuvStamper(unsigned char* pYData,
+			 uint32_t width,
+			 uint32_t height,
+			 uint32_t stride,
+			 uint32_t x,
+			 uint32_t y,
+			 unsigned char symbol_width,
+			 unsigned char symbol_height):
+    pYData(pYData), mStride(stride),
+    mWidth(width), mHeight(height),
+    mSymbolWidth(symbol_width), mSymbolHeight(symbol_height),
+    mCursor(x, y) {}
+
+  bool YuvStamper::Encode(uint32_t width, uint32_t height, uint32_t stride,
+			  unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+			  uint32_t x, uint32_t y)
+  {
+    YuvStamper stamper(pYData, width, height, stride,
+		       x, y, sBitSize, sBitSize);
+
+    // Reserve space for a checksum.
+    if (stamper.Capacity() < 8 * (msg_len + sizeof(uint32_t)))
+    {
+      return false;
+    }
+
+    bool ok = false;
+    uint32_t crc;
+    unsigned char* pCrc = reinterpret_cast<unsigned char*>(&crc);
+    r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &crc);
+    crc = htonl(crc);
+
+    while (msg_len-- > 0) {
+      if (!stamper.Write8(*pMsg++)) {
+	return false;
+      }
+    }
+
+    // Add checksum after the message.
+    ok = stamper.Write8(*pCrc++) &&
+         stamper.Write8(*pCrc++) &&
+         stamper.Write8(*pCrc++) &&
+         stamper.Write8(*pCrc++);
+
+    return ok;
+  }
+
+  bool YuvStamper::Decode(uint32_t width, uint32_t height, uint32_t stride,
+			  unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+			  uint32_t x, uint32_t y)
+  {
+    YuvStamper stamper(pYData, width, height, stride,
+		       x, y, sBitSize, sBitSize);
+
+    unsigned char* ptr = pMsg;
+    size_t len = msg_len;
+    uint32_t crc, msg_crc;
+    unsigned char* pCrc = reinterpret_cast<unsigned char*>(&crc);
+
+    // Account for space reserved for the checksum
+    if (stamper.Capacity() < 8 * (len + sizeof(uint32_t))) {
+      return false;
+    }
+
+    while (len-- > 0) {
+      if(!stamper.Read8(*ptr++)) {
+	return false;
+      }
+    }
+
+    if (!(stamper.Read8(*pCrc++) &&
+          stamper.Read8(*pCrc++) &&
+          stamper.Read8(*pCrc++) &&
+          stamper.Read8(*pCrc++))) {
+      return false;
+    }
+
+    r_crc32(reinterpret_cast<char*>(pMsg), (int)msg_len, &msg_crc);
+    return crc == htonl(msg_crc);
+  }
+
+  inline uint32_t YuvStamper::Capacity()
+  {
+    // Enforce at least a symbol width and height offset from outer edges.
+    if (mCursor.y + mSymbolHeight > mHeight) {
+      return 0;
+    }
+
+    if (mCursor.x + mSymbolWidth > mWidth && !AdvanceCursor()) {
+      return 0;
+    }
+
+    // Normalize frame integral to mSymbolWidth x mSymbolHeight
+    uint32_t width = mWidth / mSymbolWidth;
+    uint32_t height = mHeight / mSymbolHeight;
+    uint32_t x = mCursor.x / mSymbolWidth;
+    uint32_t y = mCursor.y / mSymbolHeight;
+
+    return (width * height - width * y)- x;
+  }
+
+  bool YuvStamper::Write8(unsigned char value)
+  {
+    // Encode MSB to LSB.
+    unsigned char mask = 0x80;
+    while (mask) {
+      if (!WriteBit(!!(value & mask))) {
+	return false;
+      }
+      mask >>= 1;
+    }
+    return true;
+  }
+
+  bool YuvStamper::WriteBit(bool one)
+  {
+    // A bit is mapped to a mSymbolWidth x mSymbolHeight square of luma data points.
+    unsigned char value = one ? sYOn : sYOff;
+    for (uint32_t y = 0; y < mSymbolHeight; y++) {
+      for (uint32_t x = 0; x < mSymbolWidth; x++) {
+	*(pYData + (mCursor.x + x) + ((mCursor.y + y) * mStride)) = value;
+      }
+    }
+
+    return AdvanceCursor();
+  }
+
+  bool YuvStamper::AdvanceCursor()
+  {
+    mCursor.x += mSymbolWidth;
+    if (mCursor.x + mSymbolWidth > mWidth) {
+      // move to the start of the next row if possible.
+      mCursor.y += mSymbolHeight;
+      if (mCursor.y + mSymbolHeight > mHeight) {
+	// end of frame, do not advance
+	mCursor.y -= mSymbolHeight;
+	mCursor.x -= mSymbolWidth;
+	return false;
+      } else {
+	mCursor.x = 0;
+      }
+    }
+
+    return true;
+  }
+
+  bool YuvStamper::Read8(unsigned char &value)
+  {
+    unsigned char octet = 0;
+    unsigned char bit = 0;
+
+    for (int i = 8; i > 0; --i) {
+      if (!ReadBit(bit)) {
+	return false;
+      }
+      octet <<= 1;
+      octet |= bit;
+    }
+
+    value = octet;
+    return true;
+  }
+
+  bool YuvStamper::ReadBit(unsigned char &bit)
+  {
+    uint32_t sum = 0;
+    for (uint32_t y = 0; y < mSymbolHeight; y++) {
+      for (uint32_t x = 0; x < mSymbolWidth; x++) {
+	sum += *(pYData + mStride * (mCursor.y + y) + mCursor.x + x);
+      }
+    }
+
+    // apply threshold to collected bit square
+    bit = (sum > (sBitThreshold * mSymbolWidth * mSymbolHeight)) ? 1 : 0;
+    return AdvanceCursor();
+  }
+
+  bool YuvStamper::WriteDigits(uint32_t value)
+  {
+    char buf[20];
+    PR_snprintf(buf, sizeof(buf), "%.5u", value);
+    size_t size = strlen(buf);
+
+    if (Capacity() < size) {
+      return false;
+    }
+
+    for (size_t i=0; i < size; ++i) {
+      if (!WriteDigit(buf[i] - '0'))
+	return false;
+      if (!AdvanceCursor()) {
+	return false;
+      }
+    }
+
+    return true;
+  }
+
+  bool YuvStamper::WriteDigit(unsigned char digit) {
+    if (digit > sizeof(DIGITS)/sizeof(DIGITS[0]))
+      return false;
+
+    unsigned char *dig = DIGITS[digit];
+    for (uint32_t row = 0; row < sDigitHeight; ++row) {
+      unsigned char mask = 0x01 << (sDigitWidth - 1);
+      for (uint32_t col = 0; col < sDigitWidth; ++col, mask >>= 1) {
+	if (dig[row] & mask) {
+	  for (uint32_t xx=0; xx < sPixelSize; ++xx) {
+	    for (uint32_t yy=0; yy < sPixelSize; ++yy) {
+	      WritePixel(pYData,
+			 mCursor.x + (col * sPixelSize) + xx,
+			 mCursor.y + (row * sPixelSize) + yy);
+	    }
+	  }
+	}
+      }
+    }
+
+    return true;
+  }
+
+  void YuvStamper::WritePixel(unsigned char *data, uint32_t x, uint32_t y) {
+    unsigned char *ptr = &data[y * mStride + x];
+    *ptr = (*ptr > sLumaThreshold) ? sLumaMin : sLumaMax;
+    return;
+   }
+
+}  // Namespace mozilla.
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/src/common/YuvStamper.h
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef YUV_STAMPER_H_
+#define YUV_STAMPER_H_
+
+#include "nptypes.h"
+
+namespace mozilla {
+
+class
+YuvStamper {
+public:
+  bool WriteDigits(uint32_t value);
+
+  template<typename T>
+  static bool Write(uint32_t width, uint32_t height, uint32_t stride,
+                    unsigned char *pYData, const T& value,
+                    uint32_t x=0, uint32_t y=0)
+  {
+    YuvStamper stamper(pYData, width, height, stride,
+		       x, y,
+		       (sDigitWidth + sInterDigit) * sPixelSize,
+		       (sDigitHeight + sInterLine) * sPixelSize);
+    return stamper.WriteDigits(value);
+  }
+
+  static bool Encode(uint32_t width, uint32_t height, uint32_t stride,
+		     unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+		     uint32_t x = 0, uint32_t y = 0);
+
+  static bool Decode(uint32_t width, uint32_t height, uint32_t stride,
+		     unsigned char* pYData, unsigned char* pMsg, size_t msg_len,
+		     uint32_t x = 0, uint32_t y = 0);
+
+ private:
+  YuvStamper(unsigned char* pYData,
+	     uint32_t width, uint32_t height, uint32_t stride,
+	     uint32_t x, uint32_t y,
+	     unsigned char symbol_width, unsigned char symbol_height);
+
+  bool WriteDigit(unsigned char digit);
+  void WritePixel(unsigned char* data, uint32_t x, uint32_t y);
+  uint32_t Capacity();
+  bool AdvanceCursor();
+  bool WriteBit(bool one);
+  bool Write8(unsigned char value);
+  bool ReadBit(unsigned char &value);
+  bool Read8(unsigned char &bit);
+
+  const static unsigned char sPixelSize = 3;
+  const static unsigned char sDigitWidth = 6;
+  const static unsigned char sDigitHeight = 7;
+  const static unsigned char sInterDigit = 1;
+  const static unsigned char sInterLine = 1;
+  const static uint32_t sBitSize = 4;
+  const static uint32_t sBitThreshold = 60;
+  const static unsigned char sYOn = 0x80;
+  const static unsigned char sYOff = 0;
+  const static unsigned char sLumaThreshold = 96;
+  const static unsigned char sLumaMin = 16;
+  const static unsigned char sLumaMax = 235;
+
+  unsigned char* pYData;
+  uint32_t mStride;
+  uint32_t mWidth;
+  uint32_t mHeight;
+  unsigned char mSymbolWidth;
+  unsigned char mSymbolHeight;
+
+  struct Cursor {
+    Cursor(uint32_t x, uint32_t y):
+      x(x), y(y) {}
+    uint32_t x;
+    uint32_t y;
+  } mCursor;
+};
+
+}
+
+#endif
+
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -6,18 +6,21 @@
 #include "nspr.h"
 
 // For rtcp-fb constants
 #include "ccsdp.h"
 
 #include "VideoConduit.h"
 #include "AudioConduit.h"
 #include "nsThreadUtils.h"
-
 #include "LoadManager.h"
+#include "YuvStamper.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
 
 #include "webrtc/common_video/interface/native_handle.h"
 #include "webrtc/video_engine/include/vie_errors.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidJNIWrapper.h"
 #endif
 
@@ -728,19 +731,34 @@ WebrtcVideoConduit::ConfigureRecvMediaCo
   mUsingNackBasic = use_nack_basic;
 
   //Start Receive on the video engine
   if(mPtrViEBase->StartReceive(mChannel) == -1)
   {
     error = mPtrViEBase->LastError();
     CSFLogError(logTag, "%s Start Receive Error %d ", __FUNCTION__, error);
 
+
     return kMediaConduitUnknownError;
   }
 
+#ifdef MOZILLA_INTERNAL_API
+  if (NS_IsMainThread()) {
+    nsresult rv;
+    nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
+    if (NS_SUCCEEDED(rv)) {
+      nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
+
+      if (branch) {
+	branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable);
+      }
+    }
+  }
+#endif
+
   // by now we should be successfully started the reception
   mPtrRTP->SetRembStatus(mChannel, false, true);
   mEngineReceiving = true;
   DumpCodecDB();
   return kMediaConduitNoError;
 }
 
 // XXX we need to figure out how to feed back changes in preferred capture
@@ -1045,16 +1063,20 @@ int WebrtcVideoConduit::SendRTCPPacket(i
 // WebRTC::ExternalMedia Implementation
 int
 WebrtcVideoConduit::FrameSizeChange(unsigned int width,
                                     unsigned int height,
                                     unsigned int numStreams)
 {
   CSFLogDebug(logTag,  "%s ", __FUNCTION__);
 
+
+  mReceivingWidth = width;
+  mReceivingHeight = height;
+
   if(mRenderer)
   {
     mRenderer->FrameSizeChange(width, height, numStreams);
     return 0;
   }
 
   CSFLogError(logTag,  "%s Renderer is NULL ", __FUNCTION__);
   return -1;
@@ -1074,16 +1096,28 @@ WebrtcVideoConduit::DeliverFrame(unsigne
     layers::Image* img = nullptr;
     // |handle| should be a webrtc::NativeHandle if available.
     if (handle) {
       webrtc::NativeHandle* native_h = static_cast<webrtc::NativeHandle*>(handle);
       // In the handle, there should be a layers::Image.
       img = static_cast<layers::Image*>(native_h->GetHandle());
     }
 
+    if (mVideoLatencyTestEnable && mReceivingWidth && mReceivingHeight) {
+      uint64_t now = PR_Now();
+      uint64_t timestamp = 0;
+      bool ok = YuvStamper::Decode(mReceivingWidth, mReceivingHeight, mReceivingWidth,
+				   buffer,
+				   reinterpret_cast<unsigned char*>(&timestamp),
+				   sizeof(timestamp), 0, 0);
+      if (ok) {
+	VideoLatencyUpdate(now - timestamp);
+      }
+    }
+
     const ImageHandle img_h(img);
     mRenderer->RenderVideoFrame(buffer, buffer_size, time_stamp, render_time,
                                 img_h);
     return 0;
   }
 
   CSFLogError(logTag,  "%s Renderer is NULL  ", __FUNCTION__);
   return -1;
@@ -1202,9 +1236,21 @@ WebrtcVideoConduit::DumpCodecDB() const
   {
     CSFLogDebug(logTag,"Payload Name: %s", mRecvCodecList[i]->mName.c_str());
     CSFLogDebug(logTag,"Payload Type: %d", mRecvCodecList[i]->mType);
     CSFLogDebug(logTag,"Payload Max Frame Size: %d", mRecvCodecList[i]->mMaxFrameSize);
     CSFLogDebug(logTag,"Payload Max Frame Rate: %d", mRecvCodecList[i]->mMaxFrameRate);
   }
 }
 
+void
+WebrtcVideoConduit::VideoLatencyUpdate(uint64_t newSample)
+{
+  mVideoLatencyAvg = (sRoundingPadding * newSample + sAlphaNum * mVideoLatencyAvg) / sAlphaDen;
+}
+
+uint64_t
+WebrtcVideoConduit::MozVideoLatencyAvg()
+{
+  return mVideoLatencyAvg / sRoundingPadding;
+}
+
 }// end namespace
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -223,17 +223,21 @@ public:
                       mRenderer(nullptr),
                       mPtrExtCapture(nullptr),
                       mEngineTransmitting(false),
                       mEngineReceiving(false),
                       mChannel(-1),
                       mCapId(-1),
                       mCurSendCodecConfig(nullptr),
                       mSendingWidth(0),
-                      mSendingHeight(0)
+		      mSendingHeight(0),
+		      mReceivingWidth(640),
+		      mReceivingHeight(480),
+		      mVideoLatencyTestEnable(false),
+		      mVideoLatencyAvg(0)
   {
   }
 
   virtual ~WebrtcVideoConduit() ;
 
   MediaConduitErrorCode Init(WebrtcVideoConduit *other);
 
   int GetChannel() { return mChannel; }
@@ -248,16 +252,17 @@ public:
                              uint32_t* jitterMs,
                              uint32_t* packetsReceived,
                              uint64_t* bytesReceived,
                              uint32_t* cumulativeLost,
                              int32_t* rttMs);
   bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
                            unsigned int* packetsSent,
                            uint64_t* bytesSent);
+  uint64_t MozVideoLatencyAvg();
 
 private:
 
   WebrtcVideoConduit(const WebrtcVideoConduit& other) MOZ_DELETE;
   void operator=(const WebrtcVideoConduit& other) MOZ_DELETE;
 
   //Local database of currently applied receive codecs
   typedef std::vector<VideoCodecConfig* > RecvCodecList;
@@ -276,16 +281,19 @@ private:
                            const VideoCodecConfig* codecInfo) const;
 
   //Checks the codec to be applied
   MediaConduitErrorCode ValidateCodecConfig(const VideoCodecConfig* codecInfo, bool send) const;
 
   //Utility function to dump recv codec database
   void DumpCodecDB() const;
 
+  // Video Latency Test averaging filter
+  void VideoLatencyUpdate(uint64_t new_sample);
+
   // The two sides of a send/receive pair of conduits each keep a pointer to the other.
   // They also share a single VideoEngine and mChannel.  Shutdown must be coordinated
   // carefully to avoid double-freeing or accessing after one frees.
   WebrtcVideoConduit*  mOtherDirection;
   // The other side has shut down our mChannel and related items already
   bool mShutDown;
 
   // A few of these are shared by both directions.  They're released by the last
@@ -309,15 +317,23 @@ private:
   bool mEngineReceiving;    // if true ==> Receive Sus-sysmtem up and running
 
   int mChannel; // Video Channel for this conduit
   int mCapId;   // Capturer for this conduit
   RecvCodecList    mRecvCodecList;
   VideoCodecConfig* mCurSendCodecConfig;
   unsigned short mSendingWidth;
   unsigned short mSendingHeight;
+  unsigned short mReceivingWidth;
+  unsigned short mReceivingHeight;
+  bool mVideoLatencyTestEnable;
+  uint64_t mVideoLatencyAvg;
+
+  static const unsigned int sAlphaNum = 7;
+  static const unsigned int sAlphaDen = 8;
+  static const unsigned int sRoundingPadding = 1024;
 
   mozilla::RefPtr<WebrtcAudioConduit> mSyncedTo;
 };
 
 } // end namespace
 
 #endif
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1523,17 +1523,17 @@ pref("intl.hyphenation-alias.bs-*", "sh"
 
 // Norwegian has two forms, Bokmål and Nynorsk, with "no" as a macrolanguage encompassing both.
 // For "no", we'll alias to "nb" (Bokmål) as that is the more widely used written form.
 pref("intl.hyphenation-alias.no", "nb");
 pref("intl.hyphenation-alias.no-*", "nb");
 pref("intl.hyphenation-alias.nb-*", "nb");
 pref("intl.hyphenation-alias.nn-*", "nn");
 
-pref("font.mathfont-family", "MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXGeneral, Asana Math, Standard Symbols L, DejaVu Sans, Cambria Math");
+pref("font.mathfont-family", "Latin Modern Math, XITS Math, STIX Math, Cambria Math, Asana Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Termes Math, Neo Euler, Lucida Bright Math, MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXGeneral, Standard Symbols L, DejaVu Sans");
 
 // Some CJK fonts have bad underline offset, their CJK character glyphs are overlapped (or adjoined)  to its underline.
 // These fonts are ignored the underline offset, instead of it, the underline is lowered to bottom of its em descent.
 pref("font.blacklist.underline_offset", "FangSong,Gulim,GulimChe,MingLiU,MingLiU-ExtB,MingLiU_HKSCS,MingLiU-HKSCS-ExtB,MS Gothic,MS Mincho,MS PGothic,MS PMincho,MS UI Gothic,PMingLiU,PMingLiU-ExtB,SimHei,SimSun,SimSun-ExtB,Hei,Kai,Apple LiGothic,Apple LiSung,Osaka");
 
 #ifdef MOZ_WIDGET_GONK
 // Whitelist of fonts that ship with B2G that do not include space lookups in
 // default features. This allows us to skip analyzing the GSUB/GPOS tables
@@ -3081,17 +3081,17 @@ pref("font.default.zh-TW", "sans-serif")
 pref("font.size.variable.zh-TW", 15);
 pref("font.size.fixed.zh-TW", 16);
 
 pref("font.default.zh-HK", "sans-serif");
 pref("font.size.variable.zh-HK", 15);
 pref("font.size.fixed.zh-HK", 16);
 
 // Apple's Symbol is Unicode so use it
-pref("font.mathfont-family", "MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXGeneral, Asana Math, Symbol, DejaVu Sans, Cambria Math");
+pref("font.mathfont-family", "Latin Modern Math, XITS Math, STIX Math, Cambria Math, Asana Math, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Termes Math, Neo Euler, Lucida Bright Math, MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXGeneral, Symbol, DejaVu Sans");
 
 // individual font faces to be treated as independent families
 // names are Postscript names of each face
 pref("font.single-face-list", "Osaka-Mono");
 
 // optimization hint for fonts with localized names to be read in at startup, otherwise read in at lookup miss
 // names are canonical family names (typically English names)
 pref("font.preload-names-list", "Hiragino Kaku Gothic ProN,Hiragino Mincho ProN,STSong");
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -3050,30 +3050,58 @@ nsCacheService::CloseAllStreams()
 bool
 nsCacheService::GetClearingEntries()
 {
     AssertOwnsLock();
     return gService->mClearingEntries;
 }
 
 // static
-void nsCacheService::GetDiskCacheDirectory(nsIFile ** result) {
+void nsCacheService::GetCacheBaseDirectoty(nsIFile ** result)
+{
     *result = nullptr;
-    if (gService && gService->mObserver) {
-        nsCOMPtr<nsIFile> directory =
-            gService->mObserver->DiskCacheParentDirectory();
-        if (!directory)
-            return;
-
-        nsresult rv = directory->AppendNative(NS_LITERAL_CSTRING("Cache"));
-        if (NS_FAILED(rv))
-            return;
-
-        directory.forget(result);
-    }
+    if (!gService || !gService->mObserver)
+        return;
+
+    nsCOMPtr<nsIFile> directory =
+        gService->mObserver->DiskCacheParentDirectory();
+    if (!directory)
+        return;
+
+    directory->Clone(result);
+}
+
+// static
+void nsCacheService::GetDiskCacheDirectory(nsIFile ** result)
+{
+    nsCOMPtr<nsIFile> directory;
+    GetCacheBaseDirectoty(getter_AddRefs(directory));
+    if (!directory)
+        return;
+
+    nsresult rv = directory->AppendNative(NS_LITERAL_CSTRING("Cache"));
+    if (NS_FAILED(rv))
+        return;
+
+    directory.forget(result);
+}
+
+// static
+void nsCacheService::GetAppCacheDirectory(nsIFile ** result)
+{
+    nsCOMPtr<nsIFile> directory;
+    GetCacheBaseDirectoty(getter_AddRefs(directory));
+    if (!directory)
+        return;
+
+    nsresult rv = directory->AppendNative(NS_LITERAL_CSTRING("OfflineCache"));
+    if (NS_FAILED(rv))
+        return;
+
+    directory.forget(result);
 }
 
 
 #if defined(PR_LOGGING)
 void
 nsCacheService::LogCacheStatistics()
 {
     uint32_t hitPercentage = (uint32_t)((((double)mCacheHits) /
--- a/netwerk/cache/nsCacheService.h
+++ b/netwerk/cache/nsCacheService.h
@@ -122,17 +122,19 @@ public:
     static nsresult  SetCacheElement(nsCacheEntry * entry, nsISupports * element);
 
     static nsresult  ValidateEntry(nsCacheEntry * entry);
 
     static int32_t   CacheCompressionLevel();
 
     static bool      GetClearingEntries();
 
+    static void      GetCacheBaseDirectoty(nsIFile ** result);
     static void      GetDiskCacheDirectory(nsIFile ** result);
+    static void      GetAppCacheDirectory(nsIFile ** result);
 
     /**
      * Methods called by any cache classes
      */
 
     static
     nsCacheService * GlobalInstance()   { return gService; }
 
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_16_1_BETA1
+NSS_3_16_1_BETA2
--- a/security/nss/cmd/bltest/blapitest.c
+++ b/security/nss/cmd/bltest/blapitest.c
@@ -2933,102 +2933,113 @@ get_params(PLArenaPool *arena, bltestPar
 	break;
     }
 }
 
 SECStatus
 verify_self_test(bltestIO *result, bltestIO *cmp, bltestCipherMode mode,
 		 PRBool forward, SECStatus sigstatus)
 {
-    int res;
+    PRBool equal;
     char *modestr = mode_strings[mode];
-    res = SECITEM_CompareItem(&result->pBuf, &cmp->buf);
+    equal = SECITEM_ItemsAreEqual(&result->pBuf, &cmp->buf);
     if (is_sigCipher(mode)) {
 	if (forward) {
-	    if (res == 0) {
+	    if (equal) {
 		printf("Signature self-test for %s passed.\n", modestr);
 	    } else {
 		printf("Signature self-test for %s failed!\n", modestr);
 	    }
+	    return equal ? SECSuccess : SECFailure;
 	} else {
 	    if (sigstatus == SECSuccess) {
 		printf("Verification self-test for %s passed.\n", modestr);
 	    } else {
 		printf("Verification self-test for %s failed!\n", modestr);
 	    }
+	    return sigstatus;
 	}
-	return sigstatus;
     } else if (is_hashCipher(mode)) {
-	if (res == 0) {
+	if (equal) {
 	    printf("Hash self-test for %s passed.\n", modestr);
 	} else {
 	    printf("Hash self-test for %s failed!\n", modestr);
 	}
     } else {
 	if (forward) {
-	    if (res == 0) {
+	    if (equal) {
 		printf("Encryption self-test for %s passed.\n", modestr);
 	    } else {
 		printf("Encryption self-test for %s failed!\n", modestr);
 	    }
 	} else {
-	    if (res == 0) {
+	    if (equal) {
 		printf("Decryption self-test for %s passed.\n", modestr);
 	    } else {
 		printf("Decryption self-test for %s failed!\n", modestr);
 	    }
 	}
     }
-    return (res != 0);
+    return equal ? SECSuccess : SECFailure;
+}
+
+static SECStatus
+ReadFileToItem(SECItem *dst, const char *filename)
+{
+    PRFileDesc *file;
+    SECStatus rv;
+
+    file = PR_Open(filename, PR_RDONLY, 00660);
+    if (!file) {
+	return SECFailure;
+    }
+    rv = SECU_FileToItem(dst, file);
+    PR_Close(file);
+    return rv;
 }
 
 static SECStatus
 blapi_selftest(bltestCipherMode *modes, int numModes, int inoff, int outoff,
                PRBool encrypt, PRBool decrypt)
 {
     bltestCipherInfo cipherInfo;
     bltestIO pt, ct;
     bltestCipherMode mode;
     bltestParams *params;
     int i, j, nummodes, numtests;
     char *modestr;
     char filename[256];
-    PRFileDesc *file;
     PLArenaPool *arena;
     SECItem item;
-    PRBool finished;
     SECStatus rv = SECSuccess, srv;
 
     PORT_Memset(&cipherInfo, 0, sizeof(cipherInfo));
     arena = PORT_NewArena(BLTEST_DEFAULT_CHUNKSIZE);
     cipherInfo.arena = arena;
 
-    finished = PR_FALSE;
     nummodes = (numModes == 0) ? NUMMODES : numModes;
-    for (i=0; i < nummodes && !finished; i++) {
+    for (i=0; i < nummodes; i++) {
 	if (numModes > 0)
 	    mode = modes[i];
 	else
 	    mode = i;
 	if (mode == bltestINVALID) {
 	    fprintf(stderr, "%s: Skipping invalid mode.\n",progName);
 	    continue;
 	}
 	modestr = mode_strings[mode];
 	cipherInfo.mode = mode;
 	params = &cipherInfo.params;
 	/* get the number of tests in the directory */
 	sprintf(filename, "%s/tests/%s/%s", testdir, modestr, "numtests");
-	file = PR_Open(filename, PR_RDONLY, 00660);
-	if (!file) {
-	    fprintf(stderr, "%s: File %s does not exist.\n", progName,filename);
-	    return SECFailure;
+	if (ReadFileToItem(&item, filename) != SECSuccess) {
+	    fprintf(stderr, "%s: Cannot read file %s.\n", progName, filename);
+	    rv = SECFailure;
+	    continue;
 	}
-	rv = SECU_FileToItem(&item, file);
-	PR_Close(file);
 	/* loop over the tests in the directory */
 	numtests = 0;
 	for (j=0; j<item.len; j++) {
 	    if (!isdigit(item.data[j])) {
 		break;
 	    }
 	    numtests *= 10;
 	    numtests += (int) (item.data[j] - '0');
@@ -3043,49 +3054,44 @@ blapi_selftest(bltestCipherMode *modes, 
 	            "ciphertext", j);
 	    load_file_data(arena, &ct, filename, bltestBase64Encoded);
 
 	    get_params(arena, params, mode, j);
 	    /* Forward Operation (Encrypt/Sign/Hash)
 	    ** Align the input buffer (plaintext) according to request
 	    ** then perform operation and compare to ciphertext
 	    */
-	    /* XXX for now */
-	    rv = SECSuccess;
 	    if (encrypt) {
 		bltestCopyIO(arena, &cipherInfo.input, &pt);
 		misalignBuffer(arena, &cipherInfo.input, inoff);
 		memset(&cipherInfo.output.buf, 0, sizeof cipherInfo.output.buf);
 		rv |= cipherInit(&cipherInfo, PR_TRUE);
 		misalignBuffer(arena, &cipherInfo.output, outoff);
 		rv |= cipherDoOp(&cipherInfo);
 		rv |= cipherFinish(&cipherInfo);
 		rv |= verify_self_test(&cipherInfo.output, 
-		                       &ct, mode, PR_TRUE, 0);
+		                       &ct, mode, PR_TRUE, SECSuccess);
 		/* If testing hash, only one op to test */
 		if (is_hashCipher(mode))
 		    continue;
-		/*if (rv) return rv;*/
 		if (is_sigCipher(mode)) {
 		    /* Verify operations support detached signature files. For
 		    ** consistency between tests that run Sign/Verify back to
 		    ** back (eg: self-tests) and tests that are only running
 		    ** verify operations, copy the output into the sig buf,
 		    ** and then copy the sig buf back out when verifying. For
 		    ** self-tests, this is unnecessary copying, but for
 		    ** verify-only operations, this ensures that the output
 		    ** buffer is properly configured
 		    */
 		    bltestCopyIO(arena, &params->asymk.sig, &cipherInfo.output);
 		}
 	    }
 	    if (!decrypt)
 		continue;
-	    /* XXX for now */
-	    rv = SECSuccess;
 	    /* Reverse Operation (Decrypt/Verify)
 	    ** Align the input buffer (ciphertext) according to request
 	    ** then perform operation and compare to plaintext
 	    */
 	    if (is_sigCipher(mode)) {
 		bltestCopyIO(arena, &cipherInfo.input, &pt);
 		bltestCopyIO(arena, &cipherInfo.output, &params->asymk.sig);
 	    } else {
@@ -3095,17 +3101,16 @@ blapi_selftest(bltestCipherMode *modes, 
 	    misalignBuffer(arena, &cipherInfo.input, inoff);
 	    rv |= cipherInit(&cipherInfo, PR_FALSE);
 	    misalignBuffer(arena, &cipherInfo.output, outoff);
 	    srv = SECSuccess;
 	    srv |= cipherDoOp(&cipherInfo);
 	    rv |= cipherFinish(&cipherInfo);
 	    rv |= verify_self_test(&cipherInfo.output, 
 	                           &pt, mode, PR_FALSE, srv);
-	    /*if (rv) return rv;*/
 	}
     }
     return rv;
 }
 
 SECStatus
 dump_file(bltestCipherMode mode, char *filename)
 {
@@ -3600,17 +3605,17 @@ int main(int argc, char **argv)
 	    !bltest.commands[cmd_Encrypt].activated)
 	    encrypt = PR_FALSE;
 	if (bltest.commands[cmd_Encrypt].activated &&
 	    !bltest.commands[cmd_Decrypt].activated)
 	    decrypt = PR_FALSE;
 	rv = blapi_selftest(modesToTest, numModesToTest, inoff, outoff,
 	                    encrypt, decrypt);
 	PORT_Free(cipherInfo);
-	return rv;
+	return rv == SECSuccess ? 0 : 1;
     }
 
     /* Do FIPS self-test */
     if (bltest.commands[cmd_FIPS].activated) {
 	CK_RV ckrv = sftk_fipsPowerUpSelfTest();
 	fprintf(stdout, "CK_RV: %ld.\n", ckrv);
         PORT_Free(cipherInfo);
         if (ckrv == CKR_OK)
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext1
@@ -0,0 +1,1 @@
+AzZ2PpZtkllaVnzJzlN/Xg==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext10
@@ -0,0 +1,3 @@
+eykx9YVfcXFF4A8VKp9HlDWbH/yz5V9ZTjMJi1HCOmx0oGwdlP3tf9KuQsfbesrv
+WETLM67dxoUlhe0AIKZpnSy1OAnO/RaRSM5CKSr6sGNEOXgwbFgsGLnODaPQhM5N
+PEgs/Y/PGoUITon7iLQKCE1elyRm0HZmEm+3YfhAePI=
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext11
@@ -0,0 +1,3 @@
+sJUS8+/57Q2FiQmDpz2tu3w2eNUlgb5kqKj8WG9JDyUhKXpHigWYBA69D1UJ+vsJ
+afnZ5gDq7zOxuT7tmWh7Fn+JpQZarEOc5G87jSLTCGXmTkXvjNMLaYQ1OoRKEcjN
+YNug6IZrPuMNJLP6imQ7MoNT4GAQ+oJzyP1U7woraTDlUgquXNWQL5uGozWSykNl
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext12
@@ -0,0 +1,4 @@
+a+ihKABFWjIFOIU+DLoxvS2A6gyFFkpMXCYa5IVBfZPv/i68DQoLUdbqGGM9IQz2
+PAxN28J2B/LoHtkRMZHvhtVvO5m+bEFaQVApn7hGznFgtAtjuvEXnRknWi6DaYN2
+0ouSVIxo4G5tmU4sFQHtKXAU5wLN7+4vZWRHcGAJYU2AHeHKr3P4t/pWzxupS2MZ
+M7vld2JDgIUPEXQ1oDVbKw==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext13
@@ -0,0 +1,1 @@
+UdRHefkNQKgASCdsA1y0nKKke8ubnPcnC5FEeTeH1T8=
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext14
@@ -0,0 +1,2 @@
+1fVYl2C/nHYiKP3iNt4fot0trUSNs/qb4MQZbv1Go1yE3RrHfZ21jJWRjLMXpkMK
+CNL7ao6LDxybcsejRNw0nw==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext15
@@ -0,0 +1,2 @@
+dTlZdL0ys2ZWVKbI45a4iuNLEjV1hyp6tofY52tG35EailkM0B0vXDML46Zibp3T
+ql4Q7RTo/4KYEbb+1Q8/UzykOFocvKePXEdE5Q8vg1kWXCSF0TJOdsPq52oMysYp
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext16
@@ -0,0 +1,3 @@
+gVjiFCDyW1nWrpQ/ocvyHwLpefQZ2rASanIbfu9Vvumtl/XM/30jkFe7wZqMN4FC
+92cvHV5+F9e+vLAHDoNVys5mYBcaU7YYFq6CSm72nORwtv/TtbtLQ4h02R0nhU07
+byWGDTholY3jMH1isTOb3duKMYwM4PM8F8rw6fYECCA=
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext17
@@ -0,0 +1,3 @@
+km2ySMwbog8MV2MafIrvCU95GTe5BZSeNGAkDov6b6SDEVobMQtuQ2nK68UmKIg3
+ex3apYAOpJaivf8PmhAx5xKcmiDjViHn8Li6yg2HAw8q58qFk8hZlnegb9SyYAnq
+0I/srCTKqc8srTtHDIInQVp7Hg8uqz+tltcKIJyLsmxidnfiUxuUNcpuPERNGVtf
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext18
@@ -0,0 +1,4 @@
+yCzyxHbeqMtqbmB6QNLwORvoLqnshKU3poIPmvuZe3Y5fQBUJPqmp03E6MeqSokA
+aQ+JS20dyoBnU5PSJDrax2LxWTAeNX6YtyR2IxDNWnuv4cKgMNukb9k6n9uJzBMs
+qcF9xyAx7Ggi7lqdmdvKZseEwBsIhcu2LinZeAGSfsQVpdIVFY0yX57miUN60bdo
+StM8DZJzlFGsh/Of+MMbhA==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext19
@@ -0,0 +1,1 @@
+L6Dfciqf07ZMsY+ys9tV/yJnQidXKJQT+PZXUHQSpkw=
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext2
@@ -0,0 +1,1 @@
+qaFjG/SZaVTrwJOVeyNFiQ==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext20
@@ -0,0 +1,2 @@
+BdXHdylCGwi3N+QRGfpEONH1cMx3Kk1sPff/7aA4TvhCiM43/ExMfRElpJmwUTZM
+OJ/WOb3aZH2qO9rasutVlA==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext21
@@ -0,0 +1,2 @@
+rD1tuv4uD3QGMv2eggv2BEzVsVUcu5zAPAslw5zLfzO4Oqz8pAoyZfK7/4eRU0SK
+ysuI/Ps7t7EP5GOmjAEJ8Cg4Lj5VexrfAu1kira7iV3wIF0m67+ppf2M69jkvuPc
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext22
@@ -0,0 +1,3 @@
+kLe5YwojePU/UBq3vv8DkVUAgHG8hDjniZMs/T6xKZGVRl5mM4SUY/20Q3Unji/b
+ExCCHmSSz4D/Fct3JQn7Qm867uJ71JOIgv0q5rW9nZH6SkOxe7Q5675ZwEIxAWOo
+Kl/lOIeW7uNaGBoScfAL4puFLY+nWbrQH/RnjwEFlM0=
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext23
@@ -0,0 +1,3 @@
+AlSyNGO8q+xaOV63TI+w6xN6B7xvXp9h7AsFfeMFcU+PopQiHJGhWcMVk5uB4wDu
+kCGS7F8VJUQo2HcveTJOxDKYyiHACzcCc+5eXtkOQ++h4FpdFxIJ/jT58pI326Km
+cmZQ/TsTIXR9EgiGPGw8az4th5q18leC8Iuo8qu+Y+C+20oifoGvs2u2ZFUINW00
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext24
@@ -0,0 +1,4 @@
+/Fhz5Q3o+vTGuEunB7CFTp25qy6ffXB/u6M4xoQ6GPxvrOuvZj0mKW+zKbTSbxhJ
+THngnneWR/m6+odIljDXn0MBYQwjAMGdvzFIt8rIxPSUQQJ1TzMukrb3xedbxhee
+uHegeNRxkAkCF0TBTxP9KlWiucRNGAAGhahFpPYyx8VqdzBu+maiTQXQiNzXwT/i
+T8RHJ1ll255NN/vJMERIzQ==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext3
@@ -0,0 +1,1 @@
+J1z8BBPYzLcFE8OFmx0Pcg==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext4
@@ -0,0 +1,1 @@
+ybgTX/G1rcQT39BTshvZbQ==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext5
@@ -0,0 +1,1 @@
+XJ2ETtRvmIUIXl1qT5TH1w==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext6
@@ -0,0 +1,1 @@
+qf91vXz2YT03Mcd8O20MBA==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext7
@@ -0,0 +1,1 @@
+xNxh2XJZZ6MCAQSpc48jhoUnzoOaqxdS/YvblagsTQA=
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext8
@@ -0,0 +1,2 @@
+Gblgl3LGPzOGCL9utSyhC+ZQl/icHgkFxCQB/Ud5GuLFRAstRzEWyni9n/L7YBXP
+0xZSTq59y5Wuc46+roSkZw==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/ciphertext9
@@ -0,0 +1,2 @@
+O4YRv8SXPFzY6YKwc7MxhM0mEQFZFy5EmI61/1ZhoeFvrWclj8v+5VRpJnoS3DdI
+k7TjUz029WNMMJVYNZbxNaqM0RONyJi8VlHuNakuv4mrautTZmU7xgpw4AdPwR7+
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv10
@@ -0,0 +1,1 @@
+4n\ЮXS,
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv11
@@ -0,0 +1,1 @@
+$_&[v
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv12
@@ -0,0 +1,1 @@
+/H$J
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv13
@@ -0,0 +1,1 @@
+f~My`P[
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv14
@@ -0,0 +1,1 @@
+Y R9<8
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv15
@@ -0,0 +1,1 @@
+6긃lÏc(F
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv16
@@ -0,0 +1,1 @@
+țЗëOHm
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv17
@@ -0,0 +1,1 @@
+(3E
<
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv18
@@ -0,0 +1,1 @@
+$@8,{cU
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv19
@@ -0,0 +1,1 @@
+47EquW
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv20
@@ -0,0 +1,1 @@
++̻lIH*V
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv21
@@ -0,0 +1,2 @@

+SE
;
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv22
@@ -0,0 +1,1 @@
+LYcY`&u>I
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..99b22495ccacd11ae5c41ccdd2a241b9470d3a3b
GIT binary patch
literal 16
Yc$^D7Ci&;XCVQSr)h`UoPMyvL07fVXQ~&?~
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv24
@@ -0,0 +1,1 @@
+ՁӶ꡵?~
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv7
@@ -0,0 +1,1 @@
+X<e/40e
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv8
@@ -0,0 +1,1 @@
+	]`i|J
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/iv9
@@ -0,0 +1,1 @@
+e60ָBz
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key10
@@ -0,0 +1,1 @@
+đ1E)%Ux
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key11
@@ -0,0 +1,1 @@
+}qMnjhjq
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key12
@@ -0,0 +1,1 @@
+,A7Q'0W6xk
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key13
@@ -0,0 +1,1 @@
+곱XsQ.k!
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key14
@@ -0,0 +1,1 @@
+{{Mi~ϖuy|5
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key15
@@ -0,0 +1,1 @@
+uZ	Ӊ<ɸTT
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..71afcb384f652847a5a15141d4bec356a5376dc6
GIT binary patch
literal 24
gc%1vqd43+l?H|n<bJ^!iVkkerZe!TV9lC2P0F>1W1poj5
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key17
@@ -0,0 +1,1 @@
+<g)NfOE(3
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key18
@@ -0,0 +1,1 @@
+*JUWk,jMK^
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key19
@@ -0,0 +1,1 @@
+lkL(eNlC3ۛ_w`gԝ
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key20
@@ -0,0 +1,1 @@
+cqj[Z=Kѯszޞc
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key21
@@ -0,0 +1,2 @@
+s3\i
+YMH҂*
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key22
@@ -0,0 +1,1 @@
+Eg!- 9 eX-"8R&
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key23
@@ -0,0 +1,1 @@
+A-]s+d)WG;ʋp

\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key24
@@ -0,0 +1,1 @@
+HY~c,w#$Z]
;vS+
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
Kc${NkzzzTa7ytnP
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
Kc${NkzzzTa7ytnP
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
Kc${Nkzz+ZbAOHaX
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
Kc${Nkzz+ZbAOHaX
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c1e46cee5edf8442a908610bfa0210df55912925
GIT binary patch
literal 16
Xc${NrxW>HjsK}G-#EH9{xvY2qGus8}
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key8
@@ -0,0 +1,1 @@
+Wn
>+9
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/key9
@@ -0,0 +1,1 @@
+緺O|4F^
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/mktst.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
+do
+    file="test$i.txt"
+    grep "KEY = " $file | sed -e 's;KEY = ;;' | hex > key$i
+    grep "IV = "  $file | sed -e 's;IV = ;;' | hex > iv$i
+    grep "PLAINTEXT = "  $file | sed -e 's;PLAINTEXT = ;;' | hex  > plaintext$i
+    grep "CIPHERTEXT = "  $file | sed -e 's;CIPHERTEXT = ;;' | hex > ciphertext$i.bin
+    btoa < ciphertext$i.bin > ciphertext$i
+    rm ciphertext$i.bin
+done
--- a/security/nss/cmd/bltest/tests/aes_cbc/numtests
+++ b/security/nss/cmd/bltest/tests/aes_cbc/numtests
@@ -1,1 +1,1 @@
-7
+25
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext1
@@ -0,0 +1,1 @@
+D<']s
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext10
@@ -0,0 +1,2 @@
+jx~
Ve3l@QRd.My^{ҧL.TS
+ykǚMvъGflMPfTG6³$k{mE_ٿ켦5ΛE˝
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext11
@@ -0,0 +1,1 @@
++<s
rmiUZ;D_&;цnMmt {̞Gʺ8#QٍnkKԫϞߡϖ; g}wmn~?tHDP6S6\?ۄO)
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext12
@@ -0,0 +1,1 @@
+@0S4فo??jWuESi:aIi֦>ͼL`"W	2mM甎TR#D0~7y-@%_B@Ct8>'s;Uw/`?{,b6+q]?
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext13
@@ -0,0 +1,1 @@
+NLh#!mi9:-Yt@
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext14
@@ -0,0 +1,1 @@
+78wT"/L-+
y[A0#FhŎIyҖyO
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext15
@@ -0,0 +1,1 @@
+/_:X :kd1:4~8W#;wS.Qp<IVC.NBjؽl*Ǚo;`gA=JReJ3M
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext16
@@ -0,0 +1,1 @@
+v(g,$ѝDYm&ǚ/qz2j$2c|s%5eE<"bAؙjpKWԆ#"?)vF _?'7\y'
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext17
@@ -0,0 +1,2 @@
+[1ؾm6JXcJCkUҞArqqm;.PkE 搃J0A%N@}B7y/בMufBu/k=2j饷
+VWFM99 ?~ߎ~d1@p藴k+@EP3w5B
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4858130f6624513fd3967636d0a94fa32080b18c
GIT binary patch
literal 160
zc$@*C0AK&UioXDm6JwZqg3Nc&?2&1EqlJH-PlUaBKx`9@0%?x`GIr2Jks!YGSB-f7
z%D#>V4iRw+KME&Ay;4I?#{d<GOc)-${ZYmQryNq`z~K<QK#bI4vPh^4ii*H%xl*hh
zf3DF)fPWfu8-MG{_k&kr-u{y8&&R2hP8@J7|K_}gb3W4{LNOr-TEH#%mMhD_lW>ym
OzYdV7vJO4i!bGmGT}_$*
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0d6ad5e8c8ce9227c5d865f9611d744f34fa2470
GIT binary patch
literal 32
oc$^D(`R?JGpa#wtr_Y*ZmUhTbEehFaKk@ppG+hBhg`n3A03N;%bN~PV
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext2
@@ -0,0 +1,1 @@
+du"}Nr
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext20
@@ -0,0 +1,1 @@
+7%k1sXIC{4ɿOւ5&zan%JV}֎L8V;c
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext21
@@ -0,0 +1,1 @@
+:ަnBAw^7$^OdH2[`4[xe"n<v-]g'?zo<IpWa?F@Pz߰
\ No newline at end of file
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a36a7f9da083ee25e73838e070e3de67a1b2cd7f
GIT binary patch
literal 128
zc$@)%0Du1_Z`VBITI1@RCEY5NR7pOT*keEDGqquM+~{~*<=eZ2+w#bw?y>1>QHhoX
z<ncSa5xG0|^P4njz7&OvTXGFbQY|+A?Rqktn;wNMl7Pg0xC5LQ#F7<ppnVu*5`!?{
ioG^{vp=nN)$VCA0rXFEIm*{FR?81%qOv^maR5z+EaY7;h
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5201604a5f4b52d856f9f60dffe7a2dcfb10df1a
GIT binary patch
literal 144
zc$@){0B`>SU<Sme8W;?jDS}O%30se<sBgsjCG4zW*kAVElHaIsCWyc)C@dR_^hB2j
z@-21g8Ib{9vLkfKUym7GTd=R|0|XEFmR=4MIoqXWJ{M1lrJ=K*<E(?6;|HYVOHYp*
y0Au$!>=>-u|1Q7abA#tJRfi+zLGYo2ZLi;*=pqoQB#Xflv%$QJP9-d$8`uK{W<=Ql
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..42c59ead887f692e13b6e5bbfe82c26331c34b2e
GIT binary patch
literal 160
zc$@*C0AK$MW7HGVhDC7a3$|g4_@ud5RfcGcGP|Iq?7=oKt*1)bGQ}#-(W-Prx>kEm
zeX8vD%p9_jg0B`z<s&NqC}?R`HCdPksi*LI9}|9;vEj+uyot7@<gcmQSXJ$+S5Q`{
z^!Owq79=aM!d5X2oidmvtTjDxU!$LZ&cQ_1LPc2l_Y0WGAPH^{EQMWJNQIyVC5R54
O`*T5K&d&EN@G!VcN=~-`
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext3
@@ -0,0 +1,1 @@
+zj)xmu9
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext4
@@ -0,0 +1,1 @@
+-BWdӚ#
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext5
@@ -0,0 +1,2 @@
+G0
+%&T}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext6
@@ -0,0 +1,1 @@
+$6<f_(%״t
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext7
@@ -0,0 +1,1 @@
+%ǿ& 092y
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext8
@@ -0,0 +1,1 @@
+TT"`7?6$n.yZniAr+ڼ,FW 
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/plaintext9
@@ -0,0 +1,2 @@
+*,CVtGFT4m&ݼ@yK⩠
+QQ@'5H
CN`Sv7%(sQ:ŴDdg_x
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test1.txt
@@ -0,0 +1,5 @@
+COUNT = 0
+KEY = 00000000000000000000000000000000
+IV = 00000000000000000000000000000000
+PLAINTEXT = f34481ec3cc627bacd5dc3fb08f273e6
+CIPHERTEXT = 0336763e966d92595a567cc9ce537f5e
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test10.txt
@@ -0,0 +1,5 @@
+COUNT = 7
+KEY = c491ca31f91708458e29a925ec558d78
+IV = 9ef934946e5cd0ae97bd58532cb49381
+PLAINTEXT = cb6a787e0dec56f9a165957f81af336ca6b40785d9e94093c6190e5152649f882e874d79ac5e167bd2a74ce5ae088d2ee854f6539e0a94796b1e1bd4c9fcdbc79acbef4d01eeb89776d18af71ae2a4fc47dd66df6c4dbe1d1850e466549a47b636bcc7c2b3a62495b56bb67b6d455f1eebd9bfefecbca6c7f335cfce9b45cb9d
+CIPHERTEXT = 7b2931f5855f717145e00f152a9f4794359b1ffcb3e55f594e33098b51c23a6c74a06c1d94fded7fd2ae42c7db7acaef5844cb33aeddc6852585ed0020a6699d2cb53809cefd169148ce42292afab063443978306c582c18b9ce0da3d084ce4d3c482cfd8fcf1a85084e89fb88b40a084d5e972466d07666126fb761f84078f2
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test11.txt
@@ -0,0 +1,5 @@
+COUNT = 8
+KEY = f6e87d71b0104d6eb06a68dc6a71f498
+IV = 1c245f26195b76ebebc2edcac412a2f8
+PLAINTEXT = f82bef3c73a6f7f80db285726d691db6bf55eec25a859d3ba0e0445f26b9bb3b16a3161ed1866e4dd8f2e5f8ecb4e46d74a7a78c20cdfc7bcc9e479ba7a0caba9438238ad0c01651d5d98de37f03ddce6e6b4bd4ab03cf9e8ed818aedfa1cf963b932067b97d776dce1087196e7e913f7448e38244509f0caf36bd8217e15336d35c149fd4e41707893fdb84014f8729
+CIPHERTEXT = b09512f3eff9ed0d85890983a73dadbb7c3678d52581be64a8a8fc586f490f2521297a478a0598040ebd0f5509fafb0969f9d9e600eaef33b1b93eed99687b167f89a5065aac439ce46f3b8d22d30865e64e45ef8cd30b6984353a844a11c8cd60dba0e8866b3ee30d24b3fa8a643b328353e06010fa8273c8fd54ef0a2b6930e5520aae5cd5902f9b86a33592ca4365
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test12.txt
@@ -0,0 +1,5 @@
+COUNT = 9
+KEY = 2c14413751c31e2730570ba3361c786b
+IV = 1dbbeb2f19abb448af849796244a19d7
+PLAINTEXT = 40d930f9a05334d9816fe204999c3f82a03f6a0457a8c475c94553d1d116693adc618049f0a769a2eed6a6cb14c0143ec5cccdbc8dec4ce560cfd206225709326d4de7948e54d603d01b12d7fed752fb23f1aa4494fbb00130e9ded4e77e37c079042d828040c325b1a5efd15fc842e44014ca4374bf38f3c3fc3ee327733b0c8aee1abcd055772f18dc04603f7b2c1ea69ff662361f2be0a171bbdcea1e5d3f
+CIPHERTEXT = 6be8a12800455a320538853e0cba31bd2d80ea0c85164a4c5c261ae485417d93effe2ebc0d0a0b51d6ea18633d210cf63c0c4ddbc27607f2e81ed9113191ef86d56f3b99be6c415a4150299fb846ce7160b40b63baf1179d19275a2e83698376d28b92548c68e06e6d994e2c1501ed297014e702cdefee2f656447706009614d801de1caaf73f8b7fa56cf1ba94b631933bbe577624380850f117435a0355b2b
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test13.txt
@@ -0,0 +1,5 @@
+COUNT = 1
+KEY = eab3b19c581aa873e1981c83ab8d83bbf8025111fb2e6b21
+IV = f3d6667e8d4d791e60f7505ba383eb05
+PLAINTEXT = 9d4e4cccd1682321856df069e3f1c6fa391a083a9fb02d59db74c14081b3acc4
+CIPHERTEXT = 51d44779f90d40a80048276c035cb49ca2a47bcb9b9cf7270b9144793787d53f
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test14.txt
@@ -0,0 +1,5 @@
+COUNT = 3
+KEY = 067bb17b4df785697eaccf961f98e212cb75e6797ce935cb
+IV = 8b59c9209c529ca8391c9fc0ce033c38
+PLAINTEXT = db3785a889b4bd387754da222f0e4c2d2bfe0d79e05bc910fba941beea30f1239eacf0068f4619ec01c368e986fca6b7c58e490579d29611bd10087986eff54f
+CIPHERTEXT = d5f5589760bf9c762228fde236de1fa2dd2dad448db3fa9be0c4196efd46a35c84dd1ac77d9db58c95918cb317a6430a08d2fb6a8e8b0f1c9b72c7a344dc349f
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test15.txt
@@ -0,0 +1,5 @@
+COUNT = 5
+KEY = e3fecc75f0075a09b383dfd389a3d33cc9b854b3b254c0f4
+IV = 36eab883afef936cc38f63284619cd19
+PLAINTEXT = 931b2f5f3a5820d53a6beaaa6431083a3488f4eb03b0f5b57ef838e1579623103bd6e6800377538b2e51ef708f3c4956432e8a8ee6a34e190642b26ad8bdae6c2af9a6c7996f3b6004d2671e41f1c9f40ee03d1c4a52b0a0654a331f15f34dce
+CIPHERTEXT = 75395974bd32b3665654a6c8e396b88ae34b123575872a7ab687d8e76b46df911a8a590cd01d2f5c330be3a6626e9dd3aa5e10ed14e8ff829811b6fed50f3f533ca4385a1cbca78f5c4744e50f2f8359165c2485d1324e76c3eae76a0ccac629
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test16.txt
@@ -0,0 +1,5 @@
+COUNT = 7
+KEY = fb09cf9e00dbf883689d079c920077c0073c31890b55bab5
+IV = e3c89bd097c3abddf64f4881db6dbfe2
+PLAINTEXT = c1a37683fb289467dd1b2c89efba16bbd2ee24cf18d19d44596ded2682c79a2f711c7a32bf6a24badd32a4ee637c73b7a41da6258635650f91fb9ffa45bdfc3cb122136241b3deced8996aa51ea8d3e81c9d70e006a44bc0571ed48623a0d622a93fa9da290baaedf5d9e876c94620945ff8ecc83f27379ed55cf490c5790f27
+CIPHERTEXT = 8158e21420f25b59d6ae943fa1cbf21f02e979f419dab0126a721b7eef55bee9ad97f5ccff7d239057bbc19a8c378142f7672f1d5e7e17d7bebcb0070e8355cace6660171a53b61816ae824a6ef69ce470b6ffd3b5bb4b438874d91d27854d3b6f25860d3868958de3307d62b1339bdddb8a318c0ce0f33c17caf0e9f6040820
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test17.txt
@@ -0,0 +1,5 @@
+COUNT = 8
+KEY = bca6fa3c67fd294e958f66fe8bd64f45f428f5bc8e9733a7
+IV = 92a47f2833f1450d1da41717bdc6e83c
+PLAINTEXT = 5becbc31d8bead6d36ae014a5863d14a431e6b55d29ea6baaa417271716db3a33b2e506b452086dfe690834ac2de30bc41254ec5401ec47d064237c7792fdcd7914d8af20eb114756642d519021a8c75a92f6bc53d326ae9a5b7e1b10a9756574692934d9939fc399e0c203f7edf8e7e6482eadd31a0400770e897b48c6bca2b404593045080e93377358c42a0f4dede
+CIPHERTEXT = 926db248cc1ba20f0c57631a7c8aef094f791937b905949e3460240e8bfa6fa483115a1b310b6e4369caebc5262888377b1ddaa5800ea496a2bdff0f9a1031e7129c9a20e35621e7f0b8baca0d87030f2ae7ca8593c8599677a06fd4b26009ead08fecac24caa9cf2cad3b470c8227415a7b1e0f2eab3fad96d70a209c8bb26c627677e2531b9435ca6e3c444d195b5f
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test18.txt
@@ -0,0 +1,5 @@
+COUNT = 9
+KEY = 162ad50ee64a0702aa551f571dedc16b2c1b6a1e4d4b5eee
+IV = 24408038161a2ccae07b029bb66355c1
+PLAINTEXT = be8abf00901363987a82cc77d0ec91697ba3857f9e4f84bd79406c138d02698f003276d0449120bef4578d78fecabe8e070e11710b3f0a2744bd52434ec70015884c181ebdfd51c604a71c52e4c0e110bc408cd462b248a80b8a8ac06bb952ac1d7faed144807f1a731b7febcaf7835762defe92eccfc7a9944e1c702cffe6bc86733ed321423121085ac02df8962bcbc1937092eebf0e90a8b20e3dd8c244ae
+CIPHERTEXT = c82cf2c476dea8cb6a6e607a40d2f0391be82ea9ec84a537a6820f9afb997b76397d005424faa6a74dc4e8c7aa4a8900690f894b6d1dca80675393d2243adac762f159301e357e98b724762310cd5a7bafe1c2a030dba46fd93a9fdb89cc132ca9c17dc72031ec6822ee5a9d99dbca66c784c01b0885cbb62e29d97801927ec415a5d215158d325f9ee689437ad1b7684ad33c0d92739451ac87f39ff8c31b84
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test19.txt
@@ -0,0 +1,5 @@
+COUNT = 1
+KEY = dce26c6b4cfb286510da4eecd2cffe6cdf430f33db9b5f77b460679bd49d13ae
+IV = fdeaa134c8d7379d457175fd1a57d3fc
+PLAINTEXT = 50e9eee1ac528009e8cbcd356975881f957254b13f91d7c6662d10312052eb00
+CIPHERTEXT = 2fa0df722a9fd3b64cb18fb2b3db55ff2267422757289413f8f657507412a64c
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test2.txt
@@ -0,0 +1,5 @@
+COUNT = 1
+KEY = 00000000000000000000000000000000
+IV = 00000000000000000000000000000000
+PLAINTEXT = 9798c4640bad75c7c3227db910174e72
+CIPHERTEXT = a9a1631bf4996954ebc093957b234589
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test20.txt
@@ -0,0 +1,5 @@
+COUNT = 3
+KEY = 0493ff637108af6a5b8e90ac1fdf035a3d4bafd1afb573be7ade9e8682e663e5
+IV = c0cd2bebccbb6c49920bd5482ac756e8
+PLAINTEXT = 8b37f9148df4bb25956be6310c73c8dc58ea9714ff49b643107b34c9bff096a94fedd6823526abc27a8e0b16616eee254ab4567dd68e8ccd4c38ac563b13639c
+CIPHERTEXT = 05d5c77729421b08b737e41119fa4438d1f570cc772a4d6c3df7ffeda0384ef84288ce37fc4c4c7d1125a499b051364c389fd639bdda647daa3bdadab2eb5594
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test21.txt
@@ -0,0 +1,5 @@
+COUNT = 5
+KEY = 73b8faf00b3302ac99855cf6f9e9e48518690a5906a4869d4dcf48d282faae2a
+IV = b3cb97a80a539912b8c21f450d3b9395
+PLAINTEXT = 3adea6e06e42c4f041021491f2775ef6378cb08824165edc4f6448e232175b60d0345b9f9c78df6596ec9d22b7b9e76e8f3c76b32d5d67273f1d83fe7a6fc3dd3c49139170fa5701b3beac61b490f0a9e13f844640c4500f9ad3087adfb0ae10
+CIPHERTEXT = ac3d6dbafe2e0f740632fd9e820bf6044cd5b1551cbb9cc03c0b25c39ccb7f33b83aacfca40a3265f2bbff879153448acacb88fcfb3bb7b10fe463a68c0109f028382e3e557b1adf02ed648ab6bb895df0205d26ebbfa9a5fd8cebd8e4bee3dc
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test22.txt
@@ -0,0 +1,5 @@
+COUNT = 7
+KEY = 458b67bf212d20f3a57fce392065582dcefbf381aa22949f8338ab9052260e1d
+IV = 4c12effc5963d40459602675153e9649
+PLAINTEXT = 256fd73ce35ae3ea9c25dd2a9454493e96d8633fe633b56176dce8785ce5dbbb84dbf2c8a2eeb1e96b51899605e4f13bbc11b93bf6f39b3469be14858b5b720d4a522d36feed7a329c9b1e852c9280c47db8039c17c4921571a07d1864128330e09c308ddea1694e95c84500f1a61e614197e86a30ecc28df64ccb3ccf5437aa
+CIPHERTEXT = 90b7b9630a2378f53f501ab7beff039155008071bc8438e789932cfd3eb1299195465e6633849463fdb44375278e2fdb1310821e6492cf80ff15cb772509fb426f3aeee27bd4938882fd2ae6b5bd9d91fa4a43b17bb439ebbe59c042310163a82a5fe5388796eee35a181a1271f00be29b852d8fa759bad01ff4678f010594cd
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test23.txt
@@ -0,0 +1,5 @@
+COUNT = 8
+KEY = d2412db0845d84e5732b8bbd642957473b81fb99ca8bff70e7920d16c1dbec89
+IV = 51c619fcf0b23f0c7925f400a6cacb6d
+PLAINTEXT = 026006c4a71a180c9929824d9d095b8faaa86fc4fa25ecac61d85ff6de92dfa8702688c02a282c1b8af4449707f22d75e91991015db22374c95f8f195d5bb0afeb03040ff8965e0e1339dba5653e174f8aa5a1b39fe3ac839ce307a4e44b4f8f1b0063f738ec18acdbff2ebfe07383e734558723e741f0a1836dafdf9de82210a9248bc113b3c1bc8b4e252ca01bd803
+CIPHERTEXT = 0254b23463bcabec5a395eb74c8fb0eb137a07bc6f5e9f61ec0b057de305714f8fa294221c91a159c315939b81e300ee902192ec5f15254428d8772f79324ec43298ca21c00b370273ee5e5ed90e43efa1e05a5d171209fe34f9f29237dba2a6726650fd3b1321747d1208863c6c3c6b3e2d879ab5f25782f08ba8f2abbe63e0bedb4a227e81afb36bb6645508356d34
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test24.txt
@@ -0,0 +1,5 @@
+COUNT = 9
+KEY = 48be597e632c16772324c8d3fa1d9c5a9ecd010f14ec5d110d3bfec376c5532b
+IV = d6d581b8cf04ebd3b6eaa1b53f047ee1
+PLAINTEXT = 0c63d413d3864570e70bb6618bf8a4b9585586688c32bba0a5ecc1362fada74ada32c52acfd1aa7444ba567b4e7daaecf7cc1cb29182af164ae5232b002868695635599807a9a7f07a1f137e97b1e1c9dabc89b6a5e4afa9db5855edaa575056a8f4f8242216242bb0c256310d9d329826ac353d715fa39f80cec144d6424558f9f70b98c920096e0f2c855d594885a00625880e9dfb734163cecef72cf030b8
+CIPHERTEXT = fc5873e50de8faf4c6b84ba707b0854e9db9ab2e9f7d707fbba338c6843a18fc6facebaf663d26296fb329b4d26f18494c79e09e779647f9bafa87489630d79f4301610c2300c19dbf3148b7cac8c4f4944102754f332e92b6f7c5e75bc6179eb877a078d4719009021744c14f13fd2a55a2b9c44d18000685a845a4f632c7c56a77306efa66a24d05d088dcd7c13fe24fc447275965db9e4d37fbc9304448cd
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test3.txt
@@ -0,0 +1,5 @@
+COUNT = 0
+KEY = 000000000000000000000000000000000000000000000000
+IV = 00000000000000000000000000000000
+PLAINTEXT = 1b077a6af4b7f98229de786d7516b639
+CIPHERTEXT = 275cfc0413d8ccb70513c3859b1d0f72
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test4.txt
@@ -0,0 +1,5 @@
+COUNT = 1
+KEY = 000000000000000000000000000000000000000000000000
+IV = 00000000000000000000000000000000
+PLAINTEXT = 9c2d8842e5f48f57648205d39a239af1
+CIPHERTEXT = c9b8135ff1b5adc413dfd053b21bd96d
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test5.txt
@@ -0,0 +1,5 @@
+COUNT = 0
+KEY = 0000000000000000000000000000000000000000000000000000000000000000
+IV = 00000000000000000000000000000000
+PLAINTEXT = 014730f80ac625fe84f026c60bfd547d
+CIPHERTEXT = 5c9d844ed46f9885085e5d6a4f94c7d7
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test6.txt
@@ -0,0 +1,5 @@
+COUNT = 1
+KEY = 0000000000000000000000000000000000000000000000000000000000000000
+IV = 00000000000000000000000000000000
+PLAINTEXT = 0b24af36193ce4665f2825d7b4749c98
+CIPHERTEXT = a9ff75bd7cf6613d3731c77c3b6d0c04
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test7.txt
@@ -0,0 +1,5 @@
+COUNT = 1
+KEY = 0700d603a1c514e46b6191ba430a3a0c
+IV = aad1583cd91365e3bb2f0c3430d065bb
+PLAINTEXT = 068b25c7bfb1f8bdd4cfc908f69dffc5ddc726a197f0e5f720f730393279be91
+CIPHERTEXT = c4dc61d9725967a3020104a9738f23868527ce839aab1752fd8bdb95a82c4d00
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test8.txt
@@ -0,0 +1,5 @@
+COUNT = 3
+KEY = b7f3c9576e12dd0db63e8f8fac2b9a39
+IV = c80f095d8bb1a060699f7c19974a1aa0
+PLAINTEXT = 9ac19954ce1319b354d3220460f71c1e373f1cd336240881160cfde46ebfed2e791e8d5a1a136ebd1dc469dec00c4187722b841cdabcb22c1be8a14657da200e
+CIPHERTEXT = 19b9609772c63f338608bf6eb52ca10be65097f89c1e0905c42401fd47791ae2c5440b2d473116ca78bd9ff2fb6015cfd316524eae7dcb95ae738ebeae84a467
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_cbc/test9.txt
@@ -0,0 +1,5 @@
+COUNT = 5
+KEY = bbe7b7ba07124ff1ae7c3416fe8b465e
+IV = 7f65b5ee3630bed6b84202d97fb97a1e
+PLAINTEXT = 2aad0c2c4306568bad7447460fd3dac054346d26feddbc9abd9110914011b4794be2a9a00a519a51a5b5124014f4ed2735480db21b434e99a911bb0b60fe0253763725b628d5739a5117b7ee3aefafc5b4c1bf446467e7bf5f78f31ff7caf187
+CIPHERTEXT = 3b8611bfc4973c5cd8e982b073b33184cd26110159172e44988eb5ff5661a1e16fad67258fcbfee55469267a12dc374893b4e3533d36f5634c3095583596f135aa8cd1138dc898bc5651ee35a92ebf89ab6aeb5366653bc60a70e0074fc11efe
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/ciphertext1
@@ -0,0 +1,1 @@
+AzZ2PpZtkllaVnzJzlN/Xg==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/ciphertext2
@@ -0,0 +1,1 @@
+qaFjG/SZaVTrwJOVeyNFiQ==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/ciphertext3
@@ -0,0 +1,1 @@
+J1z8BBPYzLcFE8OFmx0Pcg==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/ciphertext4
@@ -0,0 +1,1 @@
+ybgTX/G1rcQT39BTshvZbQ==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/ciphertext5
@@ -0,0 +1,1 @@
+XJ2ETtRvmIUIXl1qT5TH1w==
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/ciphertext6
@@ -0,0 +1,1 @@
+qf91vXz2YT03Mcd8O20MBA==
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..01d633b27e8ea9b17084fc911d0c8cc43a4170a9
GIT binary patch
literal 16
Kc${NkKm`B*5C8!H
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
Kc${NkzzzTa7ytnP
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4ac5fc6cf890b46738523c4d4d9d964e312f368f
GIT binary patch
literal 24
Kc${NkzzzTa7ytnP
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
Kc${Nkzz+ZbAOHaX
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4e4e4935707a596987ec1cc32e3d0d587dbe4f04
GIT binary patch
literal 32
Kc${Nkzz+ZbAOHaX
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/mktst.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+for i in 1 2 3 4 5 6
+do
+    file="test$i.txt"
+    grep "KEY = " $file | sed -e 's;KEY = ;;' | hex > key$i
+    grep "PLAINTEXT = "  $file | sed -e 's;PLAINTEXT = ;;' | hex  > plaintext$i
+    grep "CIPHERTEXT = "  $file | sed -e 's;CIPHERTEXT = ;;' | hex > ciphertext$i.bin
+    btoa < ciphertext$i.bin > ciphertext$i
+    rm ciphertext$i.bin
+done
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/plaintext1
@@ -0,0 +1,1 @@
+D<']s
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/plaintext2
@@ -0,0 +1,1 @@
+du"}Nr
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/plaintext3
@@ -0,0 +1,1 @@
+zj)xmu9
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/plaintext4
@@ -0,0 +1,1 @@
+-BWdӚ#
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/plaintext5
@@ -0,0 +1,2 @@
+G0
+%&T}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/plaintext6
@@ -0,0 +1,1 @@
+$6<f_(%״t
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/test1.txt
@@ -0,0 +1,4 @@
+COUNT = 0
+KEY = 00000000000000000000000000000000
+PLAINTEXT = f34481ec3cc627bacd5dc3fb08f273e6
+CIPHERTEXT = 0336763e966d92595a567cc9ce537f5e
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/test2.txt
@@ -0,0 +1,4 @@
+COUNT = 1
+KEY = 00000000000000000000000000000000
+PLAINTEXT = 9798c4640bad75c7c3227db910174e72
+CIPHERTEXT = a9a1631bf4996954ebc093957b234589
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/test3.txt
@@ -0,0 +1,4 @@
+COUNT = 0
+KEY = 000000000000000000000000000000000000000000000000
+PLAINTEXT = 1b077a6af4b7f98229de786d7516b639
+CIPHERTEXT = 275cfc0413d8ccb70513c3859b1d0f72
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/test4.txt
@@ -0,0 +1,4 @@
+COUNT = 1
+KEY = 000000000000000000000000000000000000000000000000
+PLAINTEXT = 9c2d8842e5f48f57648205d39a239af1
+CIPHERTEXT = c9b8135ff1b5adc413dfd053b21bd96d
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/test5.txt
@@ -0,0 +1,4 @@
+COUNT = 0
+KEY = 0000000000000000000000000000000000000000000000000000000000000000
+PLAINTEXT = 014730f80ac625fe84f026c60bfd547d
+CIPHERTEXT = 5c9d844ed46f9885085e5d6a4f94c7d7
new file mode 100644
--- /dev/null
+++ b/security/nss/cmd/bltest/tests/aes_ecb/test6.txt
@@ -0,0 +1,4 @@
+COUNT = 1
+KEY = 0000000000000000000000000000000000000000000000000000000000000000
+PLAINTEXT = 0b24af36193ce4665f2825d7b4749c98
+CIPHERTEXT = a9ff75bd7cf6613d3731c77c3b6d0c04
deleted file mode 100644
--- a/security/nss/cmd/libpkix/pkix/params/test_buildparams.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/*
- * test_buildparams.c
- *
- * Test BuildParams Type
- *
- */
-
-#include "testutil.h"
-#include "testutil_nss.h"
-
-static void *plContext = NULL;
-
-static void
-testDestroy(void *goodObject, void *equalObject, void *diffObject)
-{
-        PKIX_TEST_STD_VARS();
-
-        subTest("PKIX_BuildParams_Destroy");
-
-        PKIX_TEST_DECREF_BC(goodObject);
-        PKIX_TEST_DECREF_BC(equalObject);
-        PKIX_TEST_DECREF_BC(diffObject);
-
-cleanup:
-
-        PKIX_TEST_RETURN();
-
-}
-
-static
-void testGetProcParams(
-        PKIX_BuildParams *goodObject,
-        PKIX_BuildParams *equalObject){
-
-        PKIX_ProcessingParams *goodProcParams = NULL;
-        PKIX_ProcessingParams *equalProcParams = NULL;
-
-        PKIX_TEST_STD_VARS();
-        subTest("PKIX_BuildParams_GetProcessingParams");
-
-        PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildParams_GetProcessingParams
-                (goodObject, &goodProcParams, NULL));
-
-        PKIX_TEST_EXPECT_NO_ERROR(PKIX_BuildParams_GetProcessingParams
-                (equalObject, &equalProcParams, NULL));
-
-        testEqualsHelper
-                ((PKIX_PL_Object *)goodProcParams,
-                (PKIX_PL_Object *)equalProcParams,
-                PKIX_TRUE,
-                plContext);
-
-cleanup:
-
-        PKIX_TEST_DECREF_AC(goodProcParams);
-        PKIX_TEST_DECREF_AC(equalProcParams);
-
-        PKIX_TEST_RETURN();
-}
-
-static
-void printUsage(char *pName){
-        printf("\nUSAGE: %s <central-data-dir>\n\n", pName);
-}
-
-int test_buildparams(int argc, char *argv[]) {
-
-        PKIX_BuildParams *goodObject = NULL;
-        PKIX_BuildParams *equalObject = NULL;
-        PKIX_BuildParams *diffObject = NULL;
-        PKIX_UInt32 actualMinorVersion;
-        PKIX_UInt32 j = 0;
-
-        char *dataCentralDir = NULL;
-        char *goodInput = "yassir2yassir";
-        char *diffInput = "yassir2bcn";
-
-        char *expectedAscii =
-                "[\n"
-                "\tProcessing Params: \n"
-                "\t********BEGIN PROCESSING PARAMS********\n"
-                "\t\t"
-                "[\n"
-                "\tTrust Anchors: \n"
-                "\t********BEGIN LIST OF TRUST ANCHORS********\n"
-                "\t\t"
-"([\n"
-                "\tTrusted CA Name:         "
-                "CN=yassir,OU=bcn,OU=east,O=sun,C=us\n"
-                "\tTrusted CA PublicKey:    ANSI X9.57 DSA Signature\n"
-                "\tInitial Name Constraints:(null)\n"
-                "]\n"
-                ", [\n"
-                "\tTrusted CA Name:         OU=bcn,OU=east,O=sun,C=us\n"
-                "\tTrusted CA PublicKey:    ANSI X9.57 DSA Signature\n"
-                "\tInitial Name Constraints:(null)\n"
-                "]\n"
-                ")\n"
-                "\t********END LIST OF TRUST ANCHORS********\n"
-                "\tDate:    \t\t(null)\n"
-                "\tTarget Constraints:    (null)\n"
-                "\tInitial Policies:      (null)\n"
-                "\tQualifiers Rejected:   FALSE\n"
-                "\tCert Stores:           (EMPTY)\n"
-                "\tResource Limits:       (null)\n"
-                "\tCRL Checking Enabled:  0\n"
-                "]\n"
-                "\n"
-                "\t********END PROCESSING PARAMS********\n"
-                "]\n";
-
-        PKIX_TEST_STD_VARS();
-
-        startTests("BuildParams");
-
-        PKIX_TEST_EXPECT_NO_ERROR(
-            PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
-
-        if (argc < 2){
-                printUsage(argv[0]);
-                return (0);
-        }
-
-        dataCentralDir = argv[j+1];
-
-        subTest("PKIX_BuildParams_Create");
-
-        goodObject = createBuildParams
-                (dataCentralDir,
-                goodInput,
-                diffInput,
-                NULL,
-                NULL,
-                PKIX_FALSE,
-                plContext);
-
-        equalObject = createBuildParams
-                (dataCentralDir,
-                goodInput,
-                diffInput,
-                NULL,
-                NULL,
-                PKIX_FALSE,
-                plContext);
-
-        diffObject = createBuildParams
-                (dataCentralDir,
-                diffInput,
-                goodInput,
-                NULL,
-                NULL,
-                PKIX_FALSE,
-                plContext);
-
-        testGetProcParams(goodObject, equalObject);
-
-        PKIX_TEST_EQ_HASH_TOSTR_DUP
-                (goodObject,
-                equalObject,
-                diffObject,
-                expectedAscii,
-                BuildParams,
-                PKIX_FALSE);
-
-        testDestroy(goodObject, equalObject, diffObject);
-
-cleanup:
-
-        PKIX_Shutdown(plContext);
-
-        PKIX_TEST_RETURN();
-
-        endTests("BuildParams");
-
-        return (0);
-}
--- a/security/nss/cmd/libpkix/pkixutil/pkixutil.c
+++ b/security/nss/cmd/libpkix/pkixutil/pkixutil.c
@@ -21,18 +21,16 @@ typedef int (*mainTestFn)(int argc, char
 extern int libpkix_buildthreads(int argc, char *argv[]);
 extern int nss_threads(int argc, char *argv[]);
 extern int test_certselector(int argc, char *argv[]);
 extern int test_comcertselparams(int argc, char *argv[]);
 extern int test_certchainchecker(int argc, char *argv[]);
 extern int test_comcrlselparams(int argc, char *argv[]);
 extern int test_crlselector(int argc, char *argv[]);
 
-/* This test fails to build. Need to fix                */
-/* extern int test_buildparams(int argc, char *argv[]); */
 extern int test_procparams(int argc, char *argv[]);
 extern int test_resourcelimits(int argc, char *argv[]);
 extern int test_trustanchor(int argc, char *argv[]);
 extern int test_valparams(int argc, char *argv[]);
 extern int test_buildresult(int argc, char *argv[]);
 extern int test_policynode(int argc, char *argv[]);
 extern int test_valresult(int argc, char *argv[]);
 extern int test_verifynode(int argc, char *argv[]);
@@ -99,17 +97,16 @@ typedef struct {
 testFunctionRef testFnRefTable[] = {
     {"libpkix_buildthreads",           libpkix_buildthreads},
     {"nss_threads",                    nss_threads},
     {"test_certselector",              test_certselector},
     {"test_comcertselparams",          test_comcertselparams},
     {"test_certchainchecker",          test_certchainchecker},
     {"test_comcrlselparams",           test_comcrlselparams},
     {"test_crlselector",               test_crlselector},
-/*  {"test_buildparams",               test_buildparams}*/
     {"test_procparams",                test_procparams},
     {"test_resourcelimits",            test_resourcelimits},
     {"test_trustanchor",               test_trustanchor},
     {"test_valparams",                 test_valparams},
     {"test_buildresult",               test_buildresult},
     {"test_policynode",                test_policynode},
     {"test_valresult",                 test_valresult},
     {"test_verifynode",                test_verifynode},
--- a/security/nss/cmd/modutil/modutil.c
+++ b/security/nss/cmd/modutil/modutil.c
@@ -827,16 +827,21 @@ main(int argc, char *argv[])
 		goto loser;
 	}
 
 	errcode = init_crypto(createdb, readOnly);
 	if( errcode != SUCCESS) {
 		goto loser;
 	}
 
+	errcode = LoadMechanismList();
+	if (errcode != SUCCESS) {
+		goto loser;
+	}
+
 	/* Execute the command */
 	switch(command) {
 	case ADD_COMMAND:
 		errcode = AddModule(moduleName, libFile, ciphers, mechanisms, secmodString);
 		break;
 	case CHANGEPW_COMMAND:
 		errcode = ChangePW(tokenName, pwFile, newpwFile);
 		break;
--- a/security/nss/cmd/modutil/modutil.h
+++ b/security/nss/cmd/modutil/modutil.h
@@ -15,16 +15,17 @@
 #include <seccomon.h>
 #include <secmod.h>
 #include <secutil.h>
 
 #include <prlock.h>
 
 #include "error.h"
 
+Error LoadMechanismList(void);
 Error FipsMode(char *arg);
 Error ChkFipsMode(char *arg);
 Error AddModule(char *moduleName, char *libFile, char *ciphers,
       char *mechanisms, char* modparms);
 Error DeleteModule(char *moduleName);
 Error ListModule(char *moduleName);
 Error ListModules();
 Error ChangePW(char *tokenName, char *pwFile, char *newpwFile);
--- a/security/nss/cmd/modutil/pk11.c
+++ b/security/nss/cmd/modutil/pk11.c
@@ -1,23 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* To edit this file, set TABSTOPS to 4 spaces. 
- * This is not the normal NSS convention. 
+/* To edit this file, set TABSTOPS to 4 spaces.
+ * This is not the normal NSS convention.
  */
 
 #include "modutil.h"
-/* #include "secmodti.h"  */
 #include "pk11func.h"
 
-static PK11DefaultArrayEntry *pk11_DefaultArray = NULL;
-static int pk11_DefaultArraySize = 0;
-
 /*************************************************************************
  *
  * F i p s M o d e
  * If arg=="true", enable FIPS mode on the internal module.  If arg=="false",
  * disable FIPS mode on the internal module.
  */
 Error
 FipsMode(char *arg)
@@ -105,53 +101,88 @@ ChkFipsMode(char *arg)
 }
 
 /************************************************************************
  * Cipher and Mechanism name-bitmask translation tables
  */
 
 typedef struct {
     const char *name;
-    const unsigned long mask;
+    unsigned long mask;
 } MaskString;
 
-static const MaskString mechanismStrings[] = {
-    {"RSA", PUBLIC_MECH_RSA_FLAG},
-    {"DSA", PUBLIC_MECH_DSA_FLAG},
-    {"RC2", PUBLIC_MECH_RC2_FLAG},
-    {"RC4", PUBLIC_MECH_RC4_FLAG},
-    {"RC5", PUBLIC_MECH_RC5_FLAG},
-    {"DES", PUBLIC_MECH_DES_FLAG},
-    {"DH", PUBLIC_MECH_DH_FLAG},
-    {"FORTEZZA", PUBLIC_MECH_FORTEZZA_FLAG},
-    {"SHA1", PUBLIC_MECH_SHA1_FLAG},
-    {"MD5", PUBLIC_MECH_MD5_FLAG},
-    {"MD2", PUBLIC_MECH_MD2_FLAG},
-    {"SSL", PUBLIC_MECH_SSL_FLAG},
-    {"TLS", PUBLIC_MECH_TLS_FLAG},
-    {"AES", PUBLIC_MECH_AES_FLAG},
-    {"CAMELLIA", PUBLIC_MECH_CAMELLIA_FLAG},
-    {"SHA256", PUBLIC_MECH_SHA256_FLAG},
-    {"SHA512", PUBLIC_MECH_SHA512_FLAG},
-    {"RANDOM", PUBLIC_MECH_RANDOM_FLAG},
-    {"FRIENDLY", PUBLIC_MECH_FRIENDLY_FLAG}
-};
-static const int numMechanismStrings =
-    sizeof(mechanismStrings) / sizeof(mechanismStrings[0]);
 
 static const MaskString cipherStrings[] = {
     {"FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG}
 };
 static const int numCipherStrings =
     sizeof(cipherStrings) / sizeof(cipherStrings[0]);
 
-/* Maximum length of a colon-separated list of all the strings in an 
+/* Initialized by LoadMechanismList */
+static MaskString *mechanismStrings =  NULL;
+static int numMechanismStrings = 0;
+const static PK11DefaultArrayEntry *pk11_DefaultArray = NULL;
+static int pk11_DefaultArraySize = 0;
+
+/* Maximum length of a colon-separated list of all the strings in an
  * array. */
 #define MAX_STRING_LIST_LEN 240    /* or less */
 
+
+Error
+LoadMechanismList(void)
+{
+    int i;
+
+    if (pk11_DefaultArray == NULL) {
+        pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
+        if (pk11_DefaultArray == NULL) {
+            /* should assert. This shouldn't happen */
+            return UNSPECIFIED_ERR;
+        }
+    }
+    if (mechanismStrings != NULL) {
+	return SUCCESS;
+    }
+
+    /* build the mechanismStrings array */
+    mechanismStrings = PORT_NewArray(MaskString, pk11_DefaultArraySize);
+    if (mechanismStrings == NULL) {
+	return OUT_OF_MEM_ERR;
+    }
+    numMechanismStrings = pk11_DefaultArraySize;
+    for (i = 0; i < numMechanismStrings; i++) {
+	const char *name = pk11_DefaultArray[i].name;
+	unsigned long flag = pk11_DefaultArray[i].flag;
+	/* map new name to old */
+	switch (flag) {
+	case SECMOD_FORTEZZA_FLAG:
+	    name = "FORTEZZA";
+	    break;
+	case SECMOD_SHA1_FLAG:
+	    name = "SHA1";
+	    break;
+	case SECMOD_CAMELLIA_FLAG:
+	    name = "CAMELLIA";
+	    break;
+	case SECMOD_RANDOM_FLAG:
+	    name = "RANDOM";
+	    break;
+	case SECMOD_FRIENDLY_FLAG:
+	    name = "FRIENDLY";
+	    break;
+	default:
+	    break;
+	}
+	mechanismStrings[i].name = name;
+	mechanismStrings[i].mask = SECMOD_InternaltoPubMechFlags(flag);
+    }
+    return SUCCESS;
+}
+
 /************************************************************************
  * 
  * g e t F l a g s F r o m S t r i n g
  *
  * Parses a mechanism list passed on the command line and converts it
  * to an unsigned long bitmask.
  * string is a colon-separated string of constants
  * array is an array of MaskStrings.
@@ -811,24 +842,16 @@ SetDefaultModule(char *moduleName, char 
     SECMODModule *module = NULL;
     PK11SlotInfo *slot;
     int s, i;
     unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings,
 	numMechanismStrings);
     PRBool found = PR_FALSE;
     Error errcode = UNSPECIFIED_ERR;
 
-    if (pk11_DefaultArray == NULL) {
-	pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
-	if (pk11_DefaultArray == NULL) {
-	    /* should assert. This shouldn't happen */
-	    goto loser;
-	}
-    }
-
     mechFlags =  SECMOD_PubMechFlagstoInternal(mechFlags);
 
     module = SECMOD_FindModule(moduleName);
     if(!module) {
 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
 	errcode = NO_SUCH_MODULE_ERR;
 	goto loser;
     }
@@ -889,25 +912,16 @@ UnsetDefaultModule(char *moduleName, cha
     SECMODModule * module = NULL;
     PK11SlotInfo *slot;
     int s, i;
     unsigned long mechFlags = getFlagsFromString(mechanisms,
 	mechanismStrings, numMechanismStrings);
     PRBool found = PR_FALSE;
     Error rv;
 
-    if (pk11_DefaultArray == NULL) {
-	pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
-	if (pk11_DefaultArray == NULL) {
-	    /* should assert. This shouldn't happen */
-	    rv = UNSPECIFIED_ERR;
-            goto loser;
-	}
-    }
-
     mechFlags =  SECMOD_PubMechFlagstoInternal(mechFlags);
 
     module = SECMOD_FindModule(moduleName);
     if(!module) {
 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
 	rv = NO_SUCH_MODULE_ERR;
         goto loser;
     }
--- a/security/nss/coreconf/WIN32.mk
+++ b/security/nss/coreconf/WIN32.mk
@@ -36,17 +36,21 @@ else
 	# Change the dots to spaces.
 	_CC_VERSION_WORDS := $(subst ., ,$(CC_VERSION))
 	_CC_VMAJOR  := $(word 1,$(_CC_VERSION_WORDS))
 	_CC_VMINOR  := $(word 2,$(_CC_VERSION_WORDS))
 	_CC_RELEASE := $(word 3,$(_CC_VERSION_WORDS))
 	_CC_BUILD   := $(word 4,$(_CC_VERSION_WORDS))
 	_MSC_VER     = $(_CC_VMAJOR)$(_CC_VMINOR)
 	_MSC_VER_6   = 1200
-	_MSC_VER_GE_18 := $(shell expr $(_MSC_VER) \>= 1800)
+	# VC10 (2010) is 16.00.30319.01, VC10SP1 is 16.00.40219.01.
+	_MSC_VER_GE_10SP1 := $(shell expr $(_MSC_VER) \> 1600 \| \
+		$(_MSC_VER) = 1600 \& $(_CC_RELEASE) \>= 40219)
+	# VC12 (2013).
+	_MSC_VER_GE_12 := $(shell expr $(_MSC_VER) \>= 1800)
 	ifeq ($(_CC_VMAJOR),14)
 	    # -DYNAMICBASE is only supported on VC8SP1 or newer,
 	    # so be very specific here!
 	    # VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762
 	    ifeq ($(_CC_RELEASE).$(_CC_BUILD),50727.42)
 		USE_DYNAMICBASE =
 	    else
 	    ifeq ($(_CC_RELEASE).$(_CC_BUILD),50727.762)
@@ -168,17 +172,17 @@ endif
 	LDFLAGS    += /FIXED:NO
     endif
 ifneq ($(_MSC_VER),$(_MSC_VER_6))
     # Convert certain deadly warnings to errors (see list at end of file)
     OS_CFLAGS += -we4002 -we4003 -we4004 -we4006 -we4009 -we4013 \
      -we4015 -we4028 -we4033 -we4035 -we4045 -we4047 -we4053 -we4054 -we4063 \
      -we4064 -we4078 -we4087 -we4090 -we4098 -we4390 -we4551 -we4553 -we4715
 
-    ifeq ($(_MSC_VER_GE_18),1)
+    ifeq ($(_MSC_VER_GE_12),1)
 	OS_CFLAGS += -FS
     endif
 endif # !MSVC6
 endif # NS_USE_GCC
 
 ifdef USE_64
 DEFINES += -DWIN64
 else
@@ -213,20 +217,20 @@ DEFINES += -D_WINDOWS
 
 # override default, which is ASFLAGS = CFLAGS
 ifdef NS_USE_GCC
 	AS	= $(CC)
 	ASFLAGS = $(INCLUDES)
 else
 ifdef USE_64
 	AS	= ml64.exe
-	ASFLAGS = -Cp -Sn -Zi $(INCLUDES)
+	ASFLAGS = -nologo -Cp -Sn -Zi $(INCLUDES)
 else
 	AS	= ml.exe
-	ASFLAGS = -Cp -Sn -Zi -coff $(INCLUDES)
+	ASFLAGS = -nologo -Cp -Sn -Zi -coff $(INCLUDES)
 endif
 endif
 
 #
 # override the definitions of RELEASE_TREE found in tree.mk
 #
 ifndef RELEASE_TREE
     ifdef BUILD_SHIP
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/cryptohi/cryptohi.h
+++ b/security/nss/lib/cryptohi/cryptohi.h
@@ -1,10 +1,10 @@
 /*
- * crypto.h - public data structures and prototypes for the crypto library
+ * cryptohi.h - public prototypes for the crypto library
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _CRYPTOHI_H_
 #define _CRYPTOHI_H_
 
--- a/security/nss/lib/cryptohi/keyhi.h
+++ b/security/nss/lib/cryptohi/keyhi.h
@@ -85,32 +85,32 @@ SECKEYPrivateKey *SECKEY_CreateDHPrivate
  */
 SECKEYPrivateKey *SECKEY_CreateECPrivateKey(SECKEYECParams *param,
                                            SECKEYPublicKey **pubk, void *cx);
 
 /*
 ** Create a subject-public-key-info based on a public key.
 */
 extern CERTSubjectPublicKeyInfo *
-SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *k);
+SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *k);
 
 /*
 ** Convert a base64 ascii encoded DER public key and challenge to spki,
 ** and verify the signature and challenge data are correct
 */
 extern CERTSubjectPublicKeyInfo *
 SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,
 								void *cx);
 
 /*
 ** Encode a  CERTSubjectPublicKeyInfo structure. into a
 ** DER encoded subject public key info. 
 */
 SECItem *
-SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk);
+SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk);
 
 /*
 ** Decode a DER encoded subject public key info into a
 ** CERTSubjectPublicKeyInfo structure.
 */
 extern CERTSubjectPublicKeyInfo *
 SECKEY_DecodeDERSubjectPublicKeyInfo(const SECItem *spkider);
 
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -1208,28 +1208,23 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateK
     default:
 	break;
     }
 
     PORT_FreeArena (arena, PR_FALSE);
     return NULL;
 }
 
-CERTSubjectPublicKeyInfo *
-SECKEY_CreateSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
+static CERTSubjectPublicKeyInfo *
+seckey_CreateSubjectPublicKeyInfo_helper(SECKEYPublicKey *pubk)
 {
     CERTSubjectPublicKeyInfo *spki;
     PLArenaPool *arena;
     SECItem params = { siBuffer, NULL, 0 };
 
-    if (!pubk) {
-        PORT_SetError(SEC_ERROR_INVALID_ARGS);
-        return NULL;
-    }
-
     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL) {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
 	return NULL;
     }
 
     spki = (CERTSubjectPublicKeyInfo *) PORT_ArenaZAlloc(arena, sizeof (*spki));
     if (spki != NULL) {
@@ -1327,26 +1322,46 @@ SECKEY_CreateSubjectPublicKeyInfo(SECKEY
     } else {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
     }
 
     PORT_FreeArena(arena, PR_FALSE);
     return NULL;
 }
 
+CERTSubjectPublicKeyInfo *
+SECKEY_CreateSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
+{
+    CERTSubjectPublicKeyInfo *spki;
+    SECKEYPublicKey *tempKey;
+
+    if (!pubk) {
+        PORT_SetError(SEC_ERROR_INVALID_ARGS);
+        return NULL;
+    }
+
+    tempKey = SECKEY_CopyPublicKey(pubk);
+    if (!tempKey) {
+        return NULL;
+    }
+    spki = seckey_CreateSubjectPublicKeyInfo_helper(tempKey);
+    SECKEY_DestroyPublicKey(tempKey);
+    return spki;
+}
+
 void
 SECKEY_DestroySubjectPublicKeyInfo(CERTSubjectPublicKeyInfo *spki)
 {
     if (spki && spki->arena) {
 	PORT_FreeArena(spki->arena, PR_FALSE);
     }
 }
 
 SECItem *
-SECKEY_EncodeDERSubjectPublicKeyInfo(SECKEYPublicKey *pubk)
+SECKEY_EncodeDERSubjectPublicKeyInfo(const SECKEYPublicKey *pubk)
 {
     CERTSubjectPublicKeyInfo *spki=NULL;
     SECItem *spkiDER=NULL;
 
     /* get the subjectpublickeyinfo */
     spki = SECKEY_CreateSubjectPublicKeyInfo(pubk);
     if( spki == NULL ) {
 	goto finish;
--- a/security/nss/lib/freebl/Makefile
+++ b/security/nss/lib/freebl/Makefile
@@ -130,31 +130,45 @@ ifdef NS_USE_GCC
 else
 # MSVC
     MPI_SRCS += mpi_x86_asm.c
     DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE 
     DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
     ifdef BUILD_OPT
 	OPTIMIZER += -Ox  # maximum optimization for freebl
     endif
+    # The Intel AES assembly code requires Visual C++ 2010 (10.0). The _xgetbv
+    # compiler intrinsic function requires Visual C++ 2010 (10.0) SP1.
+    ifeq ($(_MSC_VER_GE_10SP1),1)
+	DEFINES += -DUSE_HW_AES -DINTEL_GCM
+	ASFILES += intel-aes-x86-masm.asm intel-gcm-x86-masm.asm
+	EXTRA_SRCS += intel-gcm-wrap.c
+    endif
 endif
 else
     # -DMP_NO_MP_WORD
     DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
 ifdef NS_USE_GCC
 # Ideally, we should use amd64 assembly code, but it's not yet mingw-w64
 # compatible.
 else
 # MSVC
     ifdef BUILD_OPT
 	OPTIMIZER += -Ox  # maximum optimization for freebl
     endif
     ASFILES  = arcfour-amd64-masm.asm mpi_amd64_masm.asm mp_comba_amd64_masm.asm
     DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
     DEFINES += -DNSS_USE_COMBA
+    # The Intel AES assembly code requires Visual C++ 2010 (10.0). The _xgetbv
+    # compiler intrinsic function requires Visual C++ 2010 (10.0) SP1.
+    ifeq ($(_MSC_VER_GE_10SP1),1)
+	DEFINES += -DUSE_HW_AES -DINTEL_GCM
+	ASFILES += intel-aes-x64-masm.asm intel-gcm-x64-masm.asm
+	EXTRA_SRCS += intel-gcm-wrap.c
+    endif
     MPI_SRCS += mpi_amd64.c
 endif
 endif
 endif
 
 ifeq ($(OS_TARGET),IRIX)
 ifeq ($(USE_N32),1)
     ASFILES  = mpi_mips.s
--- a/security/nss/lib/freebl/blapi.h
+++ b/security/nss/lib/freebl/blapi.h
@@ -1,10 +1,10 @@
 /*
- * crypto.h - public data structures and prototypes for the crypto library
+ * blapi.h - public prototypes for the crypto library
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _BLAPI_H_
 #define _BLAPI_H_
 
@@ -1571,11 +1571,23 @@ PRBool BLAPI_SHVerifyFile(const char *sh
  **************************************************************************/
 PRBool BLAPI_VerifySelf(const char *name);
 
 /*********************************************************************/
 extern const SECHashObject * HASH_GetRawHashObject(HASH_HashType hashType);
 
 extern void BL_SetForkState(PRBool forked);
 
+#ifndef NSS_DISABLE_ECC
+/*
+** pepare an ECParam structure from DEREncoded params
+ */
+extern SECStatus EC_FillParams(PLArenaPool *arena,
+                               const SECItem *encodedParams, ECParams *params);
+extern SECStatus EC_DecodeParams(const SECItem *encodedParams,
+                                 ECParams **ecparams);
+extern SECStatus EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
+                               const ECParams *srcParams);
+#endif
+
 SEC_END_PROTOS
 
 #endif /* _BLAPI_H_ */
--- a/security/nss/lib/freebl/ctr.c
+++ b/security/nss/lib/freebl/ctr.c
@@ -7,16 +7,21 @@
 #endif
 #include "prtypes.h"
 #include "blapit.h"
 #include "blapii.h"
 #include "ctr.h"
 #include "pkcs11t.h"
 #include "secerr.h"
 
+#ifdef USE_HW_AES
+#include "intel-aes.h"
+#include "rijndael.h"
+#endif
+
 SECStatus
 CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
 		const unsigned char *param, unsigned int blocksize)
 {
     const CK_AES_CTR_PARAMS *ctrParams = (const CK_AES_CTR_PARAMS *)param;
 
     if (ctrParams->ulCounterBits == 0 ||
 	ctrParams->ulCounterBits > blocksize * PR_BITS_PER_BYTE) {
@@ -72,17 +77,17 @@ CTR_DestroyContext(CTRContext *ctr, PRBo
  * counter block are part of the counter, counterBits tells how many bits
  * are part of the counter. The counter block is blocksize long. It's a
  * big endian value.
  *
  * XXX Does not handle counter rollover.
  */
 static void
 ctr_GetNextCtr(unsigned char *counter, unsigned int counterBits,
-		unsigned int blocksize)
+	       unsigned int blocksize)
 {
     unsigned char *counterPtr = counter + blocksize - 1;
     unsigned char mask, count;
 
     PORT_Assert(counterBits <= blocksize*PR_BITS_PER_BYTE);
     while (counterBits >= PR_BITS_PER_BYTE) {
 	if (++(*(counterPtr--))) {
 	    return;
@@ -96,53 +101,53 @@ ctr_GetNextCtr(unsigned char *counter, u
     mask = (1 << counterBits)-1;
     count = ++(*counterPtr) & mask;
     *counterPtr = ((*counterPtr) & ~mask) | count;
     return;
 }
 
 static void
 ctr_xor(unsigned char *target, const unsigned char *x,
-	 const unsigned char *y, unsigned int count)
+	const unsigned char *y, unsigned int count)
 {
     unsigned int i;
     for (i=0; i < count; i++) {
 	*target++ = *x++ ^ *y++;
     }
 }
 
 SECStatus
 CTR_Update(CTRContext *ctr, unsigned char *outbuf,
-		unsigned int *outlen, unsigned int maxout,
-		const unsigned char *inbuf, unsigned int inlen,
-		unsigned int blocksize)
+	   unsigned int *outlen, unsigned int maxout,
+	   const unsigned char *inbuf, unsigned int inlen,
+	   unsigned int blocksize)
 {
     unsigned int tmp;
     SECStatus rv;
 
     if (maxout < inlen) {
 	*outlen = inlen;
 	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
 	return SECFailure;
     }
     *outlen = 0;
     if (ctr->bufPtr != blocksize) {
 	unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen);
-	ctr_xor(outbuf, inbuf, ctr->buffer+ctr->bufPtr, needed);
+	ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed);
 	ctr->bufPtr += needed;
 	outbuf += needed;
 	inbuf += needed;
 	*outlen += needed;
 	inlen -= needed;
 	if (inlen == 0) {
 	    return SECSuccess;
 	}
 	PORT_Assert(ctr->bufPtr == blocksize);
     }
-	
+
     while (inlen >= blocksize) {
 	rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
 			ctr->counter, blocksize, blocksize);
 	ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
 	if (rv != SECSuccess) {
 	    return SECFailure;
 	}
 	ctr_xor(outbuf, inbuf, ctr->buffer, blocksize);
@@ -160,8 +165,65 @@ CTR_Update(CTRContext *ctr, unsigned cha
     if (rv != SECSuccess) {
 	return SECFailure;
     }
     ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
     ctr->bufPtr = inlen;
     *outlen += inlen;
     return SECSuccess;
 }
+
+#if defined(USE_HW_AES) && defined(_MSC_VER)
+SECStatus
+CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
+		  unsigned int *outlen, unsigned int maxout,
+		  const unsigned char *inbuf, unsigned int inlen,
+		  unsigned int blocksize)
+{
+    unsigned int fullblocks;
+    unsigned int tmp;
+    SECStatus rv;
+
+    if (maxout < inlen) {
+	*outlen = inlen;
+	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+	return SECFailure;
+    }
+    *outlen = 0;
+    if (ctr->bufPtr != blocksize) {
+	unsigned int needed = PR_MIN(blocksize-ctr->bufPtr, inlen);
+	ctr_xor(outbuf, inbuf, ctr->buffer + ctr->bufPtr, needed);
+	ctr->bufPtr += needed;
+	outbuf += needed;
+	inbuf += needed;
+	*outlen += needed;
+	inlen -= needed;
+	if (inlen == 0) {
+	    return SECSuccess;
+	}
+	PORT_Assert(ctr->bufPtr == blocksize);
+    }
+
+    intel_aes_ctr_worker(((AESContext*)(ctr->context))->Nr)(
+	ctr, outbuf, outlen, maxout, inbuf, inlen, blocksize);
+    /* XXX intel_aes_ctr_worker should set *outlen. */
+    PORT_Assert(*outlen == 0);
+    fullblocks = (inlen/blocksize)*blocksize;
+    *outlen += fullblocks;
+    outbuf += fullblocks;
+    inbuf += fullblocks;
+    inlen -= fullblocks;
+
+    if (inlen == 0) {
+	return SECSuccess;
+    }
+    rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
+			ctr->counter, blocksize, blocksize);
+    ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
+    if (rv != SECSuccess) {
+	return SECFailure;
+    }
+    ctr_xor(outbuf, inbuf, ctr->buffer, inlen);
+    ctr->bufPtr = inlen;
+    *outlen += inlen;
+    return SECSuccess;
+}
+#endif
--- a/security/nss/lib/freebl/ctr.h
+++ b/security/nss/lib/freebl/ctr.h
@@ -36,9 +36,16 @@ CTRContext * CTR_CreateContext(void *con
 
 void CTR_DestroyContext(CTRContext *ctr, PRBool freeit);
 
 SECStatus CTR_Update(CTRContext *ctr, unsigned char *outbuf,
 			unsigned int *outlen, unsigned int maxout,
 			const unsigned char *inbuf, unsigned int inlen,
 			unsigned int blocksize);
 
+#ifdef USE_HW_AES
+SECStatus CTR_Update_HW_AES(CTRContext *ctr, unsigned char *outbuf,
+			unsigned int *outlen, unsigned int maxout,
+			const unsigned char *inbuf, unsigned int inlen,
+			unsigned int blocksize);
 #endif
+
+#endif
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/ecdecode.c
@@ -0,0 +1,610 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef NSS_DISABLE_ECC
+
+#ifdef FREEBL_NO_DEPEND
+#include "stubs.h"
+#endif
+
+#include "blapi.h"
+#include "secoid.h"
+#include "secitem.h"
+#include "secerr.h"
+#include "ec.h"
+#include "ecl-curve.h"
+
+#define CHECK_OK(func) if (func == NULL) goto cleanup
+#define CHECK_SEC_OK(func) if (SECSuccess != (rv = func)) goto cleanup
+
+/*
+ * Initializes a SECItem from a hexadecimal string
+ *
+ * Warning: This function ignores leading 00's, so any leading 00's
+ * in the hexadecimal string must be optional.
+ */
+static SECItem *
+hexString2SECItem(PLArenaPool *arena, SECItem *item, const char *str)
+{
+    int i = 0;
+    int byteval = 0;
+    int tmp = PORT_Strlen(str);
+
+    if ((tmp % 2) != 0) return NULL;
+    
+    /* skip leading 00's unless the hex string is "00" */
+    while ((tmp > 2) && (str[0] == '0') && (str[1] == '0')) {
+        str += 2;
+        tmp -= 2;
+    }
+
+    item->data = (unsigned char *) PORT_ArenaAlloc(arena, tmp/2);
+    if (item->data == NULL) return NULL;
+    item->len = tmp/2;
+
+    while (str[i]) {
+        if ((str[i] >= '0') && (str[i] <= '9'))
+	    tmp = str[i] - '0';
+	else if ((str[i] >= 'a') && (str[i] <= 'f'))
+	    tmp = str[i] - 'a' + 10;
+	else if ((str[i] >= 'A') && (str[i] <= 'F'))
+	    tmp = str[i] - 'A' + 10;
+	else
+	    return NULL;
+
+	byteval = byteval * 16 + tmp;
+	if ((i % 2) != 0) {
+	    item->data[i/2] = byteval;
+	    byteval = 0;
+	}
+	i++;
+    }
+
+    return item;
+}
+
+/* Copy all of the fields from srcParams into dstParams
+ */
+SECStatus
+EC_CopyParams(PLArenaPool *arena, ECParams *dstParams,
+	      const ECParams *srcParams)
+{
+    SECStatus rv = SECFailure;
+
+    dstParams->arena = arena;
+    dstParams->type = srcParams->type;
+    dstParams->fieldID.size = srcParams->fieldID.size;
+    dstParams->fieldID.type = srcParams->fieldID.type;
+    if (srcParams->fieldID.type == ec_field_GFp) {
+	CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.prime,
+	    &srcParams->fieldID.u.prime));
+    } else {
+	CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->fieldID.u.poly,
+	    &srcParams->fieldID.u.poly));
+    }
+    dstParams->fieldID.k1 = srcParams->fieldID.k1;
+    dstParams->fieldID.k2 = srcParams->fieldID.k2;
+    dstParams->fieldID.k3 = srcParams->fieldID.k3;
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.a,
+	&srcParams->curve.a));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.b,
+	&srcParams->curve.b));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curve.seed,
+	&srcParams->curve.seed));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->base,
+	&srcParams->base));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->order,
+	&srcParams->order));
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->DEREncoding,
+	&srcParams->DEREncoding));
+	dstParams->name = srcParams->name;
+    CHECK_SEC_OK(SECITEM_CopyItem(arena, &dstParams->curveOID,
+ 	&srcParams->curveOID));
+    dstParams->cofactor = srcParams->cofactor;
+
+    return SECSuccess;
+
+cleanup:
+    return SECFailure;
+}
+
+static SECStatus
+gf_populate_params(ECCurveName name, ECFieldType field_type, ECParams *params)
+{
+    SECStatus rv = SECFailure;
+    const ECCurveParams *curveParams;
+    /* 2 ['0'+'4'] + MAX_ECKEY_LEN * 2 [x,y] * 2 [hex string] + 1 ['\0'] */
+    char genenc[3 + 2 * 2 * MAX_ECKEY_LEN];
+
+    if ((name < ECCurve_noName) || (name > ECCurve_pastLastCurve)) goto cleanup;
+    params->name = name;
+    curveParams = ecCurve_map[params->name];
+    CHECK_OK(curveParams);
+    params->fieldID.size = curveParams->size;
+    params->fieldID.type = field_type;
+    if (field_type == ec_field_GFp) {
+	CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.prime, 
+	    curveParams->irr));
+    } else {
+	CHECK_OK(hexString2SECItem(params->arena, &params->fieldID.u.poly, 
+	    curveParams->irr));
+    }
+    CHECK_OK(hexString2SECItem(params->arena, &params->curve.a, 
+	curveParams->curvea));
+    CHECK_OK(hexString2SECItem(params->arena, &params->curve.b, 
+	curveParams->curveb));
+    genenc[0] = '0';
+    genenc[1] = '4';
+    genenc[2] = '\0';
+    strcat(genenc, curveParams->genx);
+    strcat(genenc, curveParams->geny);
+    CHECK_OK(hexString2SECItem(params->arena, &params->base, genenc));
+    CHECK_OK(hexString2SECItem(params->arena, &params->order, 
+    	curveParams->order));
+    params->cofactor = curveParams->cofactor;
+
+    rv = SECSuccess;
+
+cleanup:
+    return rv;
+}
+
+SECStatus
+EC_FillParams(PLArenaPool *arena, const SECItem *encodedParams,
+    ECParams *params)
+{
+    SECStatus rv = SECFailure;
+    SECOidTag tag;
+    SECItem oid = { siBuffer, NULL, 0};
+
+#if EC_DEBUG
+    int i;
+
+    printf("Encoded params in EC_DecodeParams: ");
+    for (i = 0; i < encodedParams->len; i++) {
+	    printf("%02x:", encodedParams->data[i]);
+    }
+    printf("\n");
+#endif
+
+    if ((encodedParams->len != ANSI_X962_CURVE_OID_TOTAL_LEN) &&
+	(encodedParams->len != SECG_CURVE_OID_TOTAL_LEN)) {
+	    PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+	    return SECFailure;
+    };
+
+    oid.len = encodedParams->len - 2;
+    oid.data = encodedParams->data + 2;
+    if ((encodedParams->data[0] != SEC_ASN1_OBJECT_ID) ||
+	((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)) { 
+	    PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+	    return SECFailure;
+    }
+
+    params->arena = arena;
+    params->cofactor = 0;
+    params->type = ec_params_named;
+    params->name = ECCurve_noName;
+
+    /* For named curves, fill out curveOID */
+    params->curveOID.len = oid.len;
+    params->curveOID.data = (unsigned char *) PORT_ArenaAlloc(arena, oid.len);
+    if (params->curveOID.data == NULL) goto cleanup;
+    memcpy(params->curveOID.data, oid.data, oid.len);
+
+#if EC_DEBUG
+    printf("Curve: %s\n", SECOID_FindOIDTagDescription(tag));
+#endif
+
+    switch (tag) {
+
+    /* Binary curves */
+
+    case SEC_OID_ANSIX962_EC_C2PNB163V1:
+	/* Populate params for c2pnb163v1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB163V2:
+	/* Populate params for c2pnb163v2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB163V3:
+	/* Populate params for c2pnb163v3 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB163V3, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB176V1:
+	/* Populate params for c2pnb176v1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB176V1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB191V1:
+	/* Populate params for c2tnb191v1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB191V2:
+	/* Populate params for c2tnb191v2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB191V3:
+	/* Populate params for c2tnb191v3 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB191V3, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB208W1:
+	/* Populate params for c2pnb208w1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB208W1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB239V1:
+	/* Populate params for c2tnb239v1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB239V2:
+	/* Populate params for c2tnb239v2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB239V3:
+	/* Populate params for c2tnb239v3 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB239V3, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB272W1:
+	/* Populate params for c2pnb272w1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB272W1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB304W1:
+	/* Populate params for c2pnb304w1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB304W1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB359V1:
+	/* Populate params for c2tnb359v1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB359V1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2PNB368W1:
+	/* Populate params for c2pnb368w1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_PNB368W1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_C2TNB431R1:
+	/* Populate params for c2tnb431r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_CHAR2_TNB431R1, ec_field_GF2m,
+	    params) );
+	break;
+	
+    case SEC_OID_SECG_EC_SECT113R1:
+	/* Populate params for sect113r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT113R2:
+	/* Populate params for sect113r2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_113R2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT131R1:
+	/* Populate params for sect131r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT131R2:
+	/* Populate params for sect131r2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_131R2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT163K1:
+	/* Populate params for sect163k1
+	 * (the NIST K-163 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163K1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT163R1:
+	/* Populate params for sect163r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT163R2:
+	/* Populate params for sect163r2
+	 * (the NIST B-163 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_163R2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT193R1:
+	/* Populate params for sect193r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT193R2:
+	/* Populate params for sect193r2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_193R2, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT233K1:
+	/* Populate params for sect233k1
+	 * (the NIST K-233 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233K1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT233R1:
+	/* Populate params for sect233r1
+	 * (the NIST B-233 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_233R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT239K1:
+	/* Populate params for sect239k1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_239K1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT283K1:
+        /* Populate params for sect283k1
+	 * (the NIST K-283 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283K1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT283R1:
+	/* Populate params for sect283r1
+	 * (the NIST B-283 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_283R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT409K1:
+	/* Populate params for sect409k1
+	 * (the NIST K-409 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409K1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT409R1:
+	/* Populate params for sect409r1
+	 * (the NIST B-409 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_409R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT571K1:
+	/* Populate params for sect571k1
+	 * (the NIST K-571 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571K1, ec_field_GF2m,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECT571R1:
+	/* Populate params for sect571r1
+	 * (the NIST B-571 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_CHAR2_571R1, ec_field_GF2m,
+	    params) );
+	break;
+
+    /* Prime curves */
+
+    case SEC_OID_ANSIX962_EC_PRIME192V1:
+	/* Populate params for prime192v1 aka secp192r1 
+	 * (the NIST P-192 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_PRIME192V2:
+	/* Populate params for prime192v2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V2, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_PRIME192V3:
+	/* Populate params for prime192v3 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_192V3, ec_field_GFp,
+	    params) );
+	break;
+	
+    case SEC_OID_ANSIX962_EC_PRIME239V1:
+	/* Populate params for prime239v1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_PRIME239V2:
+	/* Populate params for prime239v2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V2, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_PRIME239V3:
+	/* Populate params for prime239v3 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_239V3, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_ANSIX962_EC_PRIME256V1:
+	/* Populate params for prime256v1 aka secp256r1
+	 * (the NIST P-256 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_X9_62_PRIME_256V1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP112R1:
+        /* Populate params for secp112r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP112R2:
+        /* Populate params for secp112r2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_112R2, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP128R1:
+        /* Populate params for secp128r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP128R2:
+        /* Populate params for secp128r2 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_128R2, ec_field_GFp,
+	    params) );
+	break;
+	
+    case SEC_OID_SECG_EC_SECP160K1:
+        /* Populate params for secp160k1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160K1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP160R1:
+        /* Populate params for secp160r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP160R2:
+	/* Populate params for secp160r1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_160R2, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP192K1:
+	/* Populate params for secp192k1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_192K1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP224K1:
+	/* Populate params for secp224k1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224K1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP224R1:
+	/* Populate params for secp224r1 
+	 * (the NIST P-224 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_224R1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP256K1:
+	/* Populate params for secp256k1 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_256K1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP384R1:
+	/* Populate params for secp384r1
+	 * (the NIST P-384 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_384R1, ec_field_GFp,
+	    params) );
+	break;
+
+    case SEC_OID_SECG_EC_SECP521R1:
+	/* Populate params for secp521r1 
+	 * (the NIST P-521 curve)
+	 */
+	CHECK_SEC_OK( gf_populate_params(ECCurve_SECG_PRIME_521R1, ec_field_GFp,
+	    params) );
+	break;
+
+    default:
+	break;
+    };
+
+cleanup:
+    if (!params->cofactor) {
+	PORT_SetError(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE);
+#if EC_DEBUG
+	printf("Unrecognized curve, returning NULL params\n");
+#endif
+    }
+
+    return rv;
+}
+
+SECStatus
+EC_DecodeParams(const SECItem *encodedParams, ECParams **ecparams)
+{
+    PLArenaPool *arena;
+    ECParams *params;
+    SECStatus rv = SECFailure;
+
+    /* Initialize an arena for the ECParams structure */
+    if (!(arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE)))
+	return SECFailure;
+
+    params = (ECParams *)PORT_ArenaZAlloc(arena, sizeof(ECParams));
+    if (!params) {
+	PORT_FreeArena(arena, PR_TRUE);
+	return SECFailure;
+    }
+
+    /* Copy the encoded params */
+    SECITEM_AllocItem(arena, &(params->DEREncoding),
+	encodedParams->len);
+    memcpy(params->DEREncoding.data, encodedParams->data, encodedParams->len);
+
+    /* Fill out the rest of the ECParams structure based on 
+     * the encoded params 
+     */
+    rv = EC_FillParams(arena, encodedParams, params);
+    if (rv == SECFailure) {
+	PORT_FreeArena(arena, PR_TRUE);	
+	return SECFailure;
+    } else {
+	*ecparams = params;;
+	return SECSuccess;
+    }
+}
+
+#endif /* NSS_DISABLE_ECC */
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/intel-aes-x64-masm.asm
@@ -0,0 +1,971 @@
+; LICENSE:
+; This submission to NSS is to be made available under the terms of the
+; Mozilla Public License, v. 2.0. You can obtain one at http:
+; //mozilla.org/MPL/2.0/.
+;###############################################################################
+; Copyright(c) 2014, Intel Corp.
+; Developers and authors:
+; Shay Gueron and Vlad Krasnov
+; Intel Corporation, Israel Development Centre, Haifa, Israel
+; Please send feedback directly to crypto.feedback.alias@intel.com
+
+
+.DATA
+ALIGN 16
+Lmask dd 0c0f0e0dh,0c0f0e0dh,0c0f0e0dh,0c0f0e0dh
+Lmask192 dd 004070605h, 004070605h, 004070605h, 004070605h
+Lmask256 dd 00c0f0e0dh, 00c0f0e0dh, 00c0f0e0dh, 00c0f0e0dh
+Lcon1 dd 1,1,1,1
+Lcon2 dd 1bh,1bh,1bh,1bh
+
+.CODE
+
+ctx     textequ <rcx>
+output  textequ <rdx>
+input   textequ <r8>
+inputLen textequ <r9d>
+
+
+aes_rnd MACRO i
+    movdqu  xmm8, [i*16 + ctx]
+    aesenc  xmm0, xmm8
+    aesenc  xmm1, xmm8
+    aesenc  xmm2, xmm8
+    aesenc  xmm3, xmm8
+    aesenc  xmm4, xmm8
+    aesenc  xmm5, xmm8
+    aesenc  xmm6, xmm8
+    aesenc  xmm7, xmm8
+    ENDM
+
+aes_last_rnd MACRO i
+    movdqu  xmm8, [i*16 + ctx]
+    aesenclast  xmm0, xmm8
+    aesenclast  xmm1, xmm8
+    aesenclast  xmm2, xmm8
+    aesenclast  xmm3, xmm8
+    aesenclast  xmm4, xmm8
+    aesenclast  xmm5, xmm8
+    aesenclast  xmm6, xmm8
+    aesenclast  xmm7, xmm8
+    ENDM
+
+aes_dec_rnd MACRO i
+    movdqu  xmm8, [i*16 + ctx]
+    aesdec  xmm0, xmm8
+    aesdec  xmm1, xmm8
+    aesdec  xmm2, xmm8
+    aesdec  xmm3, xmm8
+    aesdec  xmm4, xmm8
+    aesdec  xmm5, xmm8
+    aesdec  xmm6, xmm8
+    aesdec  xmm7, xmm8
+    ENDM
+
+aes_dec_last_rnd MACRO i
+    movdqu  xmm8, [i*16 + ctx]
+    aesdeclast  xmm0, xmm8
+    aesdeclast  xmm1, xmm8
+    aesdeclast  xmm2, xmm8
+    aesdeclast  xmm3, xmm8
+    aesdeclast  xmm4, xmm8
+    aesdeclast  xmm5, xmm8
+    aesdeclast  xmm6, xmm8
+    aesdeclast  xmm7, xmm8
+    ENDM
+
+
+gen_aes_ecb_func MACRO enc, rnds
+
+LOCAL   loop8
+LOCAL   loop1
+LOCAL   bail
+
+        xor     inputLen, inputLen
+        mov     input,      [rsp + 1*8 + 8*4]
+        mov     inputLen,   [rsp + 1*8 + 8*5]
+
+        sub     rsp, 3*16
+
+        movdqu  [rsp + 0*16], xmm6
+        movdqu  [rsp + 1*16], xmm7
+        movdqu  [rsp + 2*16], xmm8
+
+        lea     ctx, [48+ctx]
+
+loop8:
+        cmp     inputLen, 8*16
+        jb      loop1
+
+        movdqu  xmm0, [0*16 + input]
+        movdqu  xmm1, [1*16 + input]
+        movdqu  xmm2, [2*16 + input]
+        movdqu  xmm3, [3*16 + input]
+        movdqu  xmm4, [4*16 + input]
+        movdqu  xmm5, [5*16 + input]
+        movdqu  xmm6, [6*16 + input]
+        movdqu  xmm7, [7*16 + input]
+
+        movdqu  xmm8, [0*16 + ctx]
+        pxor    xmm0, xmm8
+        pxor    xmm1, xmm8
+        pxor    xmm2, xmm8
+        pxor    xmm3, xmm8
+        pxor    xmm4, xmm8
+        pxor    xmm5, xmm8
+        pxor    xmm6, xmm8
+        pxor    xmm7, xmm8
+
+IF enc eq 1
+        rnd textequ <aes_rnd>
+        lastrnd textequ <aes_last_rnd>
+        aesinst textequ <aesenc>
+        aeslastinst textequ <aesenclast>
+ELSE
+        rnd textequ <aes_dec_rnd>
+        lastrnd textequ <aes_dec_last_rnd>
+        aesinst textequ <aesdec>
+        aeslastinst textequ <aesdeclast>
+ENDIF
+
+        i = 1
+        WHILE i LT rnds
+            rnd i
+            i = i+1
+            ENDM
+        lastrnd rnds
+
+        movdqu  [0*16 + output], xmm0
+        movdqu  [1*16 + output], xmm1
+        movdqu  [2*16 + output], xmm2
+        movdqu  [3*16 + output], xmm3
+        movdqu  [4*16 + output], xmm4
+        movdqu  [5*16 + output], xmm5
+        movdqu  [6*16 + output], xmm6
+        movdqu  [7*16 + output], xmm7
+
+        lea input, [8*16 + input]
+        lea output, [8*16 + output]
+        sub inputLen, 8*16
+        jmp loop8
+
+loop1:
+        cmp     inputLen, 1*16
+        jb      bail
+
+        movdqu  xmm0, [input]
+        movdqu  xmm7, [0*16 + ctx]
+        pxor    xmm0, xmm7
+
+        i = 1
+    WHILE i LT rnds
+            movdqu  xmm7, [i*16 + ctx]
+            aesinst  xmm0, xmm7
+            i = i+1
+        ENDM
+        movdqu  xmm7, [rnds*16 + ctx]
+        aeslastinst xmm0, xmm7
+
+        movdqu  [output], xmm0
+
+        lea input, [1*16 + input]
+        lea output, [1*16 + output]
+        sub inputLen, 1*16
+        jmp loop1
+
+bail:
+        xor rax, rax
+
+        movdqu  xmm6, [rsp + 0*16]
+        movdqu  xmm7, [rsp + 1*16]
+        movdqu  xmm8, [rsp + 2*16]
+        add     rsp, 3*16
+        ret
+ENDM
+
+intel_aes_encrypt_ecb_128 PROC
+gen_aes_ecb_func 1, 10
+intel_aes_encrypt_ecb_128 ENDP
+
+intel_aes_encrypt_ecb_192 PROC
+gen_aes_ecb_func 1, 12
+intel_aes_encrypt_ecb_192 ENDP
+
+intel_aes_encrypt_ecb_256 PROC
+gen_aes_ecb_func 1, 14
+intel_aes_encrypt_ecb_256 ENDP
+
+intel_aes_decrypt_ecb_128 PROC
+gen_aes_ecb_func 0, 10
+intel_aes_decrypt_ecb_128 ENDP
+
+intel_aes_decrypt_ecb_192 PROC
+gen_aes_ecb_func 0, 12
+intel_aes_decrypt_ecb_192 ENDP
+
+intel_aes_decrypt_ecb_256 PROC
+gen_aes_ecb_func 0, 14
+intel_aes_decrypt_ecb_256 ENDP
+
+
+KEY textequ <rcx>
+KS  textequ <rdx>
+ITR textequ <r8>
+
+intel_aes_encrypt_init_128  PROC
+
+    movdqu  xmm1, [KEY]
+    movdqu  [KS], xmm1
+    movdqa  xmm2, xmm1
+
+    lea ITR, Lcon1
+    movdqa  xmm0, [ITR]
+    lea ITR, Lmask
+    movdqa  xmm4, [ITR]
+
+    mov ITR, 8
+
+Lenc_128_ks_loop:
+        lea KS, [16 + KS]
+        dec ITR
+
+        pshufb  xmm2, xmm4
+        aesenclast  xmm2, xmm0
+        pslld   xmm0, 1
+        movdqa  xmm3, xmm1
+        pslldq  xmm3, 4
+        pxor    xmm1, xmm3
+        pslldq  xmm3, 4
+        pxor    xmm1, xmm3
+        pslldq  xmm3, 4
+        pxor    xmm1, xmm3
+        pxor    xmm1, xmm2
+        movdqu  [KS], xmm1
+        movdqa  xmm2, xmm1
+
+        jne Lenc_128_ks_loop
+
+    lea ITR, Lcon2
+    movdqa  xmm0, [ITR]
+
+    pshufb  xmm2, xmm4
+    aesenclast  xmm2, xmm0
+    pslld   xmm0, 1
+    movdqa  xmm3, xmm1
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pxor    xmm1, xmm2
+    movdqu  [16 + KS], xmm1
+    movdqa  xmm2, xmm1
+
+    pshufb  xmm2, xmm4
+    aesenclast  xmm2, xmm0
+    movdqa  xmm3, xmm1
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pxor    xmm1, xmm2
+    movdqu  [32 + KS], xmm1
+    movdqa  xmm2, xmm1
+
+    ret
+intel_aes_encrypt_init_128  ENDP
+
+
+intel_aes_decrypt_init_128  PROC
+
+    push    KS
+    push    KEY
+
+    call    intel_aes_encrypt_init_128
+
+    pop     KEY
+    pop     KS
+
+    movdqu  xmm0, [0*16 + KS]
+    movdqu  xmm1, [10*16 + KS]
+    movdqu  [10*16 + KS], xmm0
+    movdqu  [0*16 + KS], xmm1
+
+    i = 1
+    WHILE i LT 5
+        movdqu  xmm0, [i*16 + KS]
+        movdqu  xmm1, [(10-i)*16 + KS]
+
+        aesimc  xmm0, xmm0
+        aesimc  xmm1, xmm1
+
+        movdqu  [(10-i)*16 + KS], xmm0
+        movdqu  [i*16 + KS], xmm1
+
+        i = i+1
+    ENDM
+
+    movdqu  xmm0, [5*16 + KS]
+    aesimc  xmm0, xmm0
+    movdqu  [5*16 + KS], xmm0
+    ret
+intel_aes_decrypt_init_128  ENDP
+
+
+intel_aes_encrypt_init_192  PROC
+
+    sub     rsp, 16*2
+    movdqu  [16*0 + rsp], xmm6
+    movdqu  [16*1 + rsp], xmm7
+
+    movdqu  xmm1, [KEY]
+    mov     ITR, [16 + KEY]
+    movd    xmm3, ITR
+
+    movdqu  [KS], xmm1
+    movdqa  xmm5, xmm3
+
+    lea ITR, Lcon1
+    movdqu  xmm0, [ITR]
+    lea ITR, Lmask192
+    movdqu  xmm4, [ITR]
+
+    mov ITR, 4
+
+Lenc_192_ks_loop:
+        movdqa  xmm2, xmm3
+        pshufb  xmm2, xmm4
+        aesenclast xmm2, xmm0
+        pslld   xmm0, 1
+
+        movdqa  xmm6, xmm1
+        movdqa  xmm7, xmm3
+        pslldq  xmm6, 4
+        pslldq  xmm7, 4
+        pxor    xmm1, xmm6
+        pxor    xmm3, xmm7
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pxor    xmm1, xmm2
+        pshufd  xmm2, xmm1, 0ffh
+        pxor    xmm3, xmm2
+
+        movdqa  xmm6, xmm1
+        shufpd  xmm5, xmm1, 00h
+        shufpd  xmm6, xmm3, 01h
+
+        movdqu  [16 + KS], xmm5
+        movdqu  [32 + KS], xmm6
+
+        movdqa  xmm2, xmm3
+        pshufb  xmm2, xmm4
+        aesenclast  xmm2, xmm0
+        pslld   xmm0, 1
+
+        movdqa  xmm6, xmm1
+        movdqa  xmm7, xmm3
+        pslldq  xmm6, 4
+        pslldq  xmm7, 4
+        pxor    xmm1, xmm6
+        pxor    xmm3, xmm7
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pxor    xmm1, xmm2
+        pshufd  xmm2, xmm1, 0ffh
+        pxor    xmm3, xmm2
+
+        movdqu  [48 + KS], xmm1
+        movdqa  xmm5, xmm3
+
+        lea KS, [48 + KS]
+
+        dec ITR
+        jnz Lenc_192_ks_loop
+
+    movdqu  [16 + KS], xmm5
+
+    movdqu  xmm7, [16*1 + rsp]
+    movdqu  xmm6, [16*0 + rsp]
+    add rsp, 16*2
+    ret
+intel_aes_encrypt_init_192  ENDP
+
+intel_aes_decrypt_init_192  PROC
+    push    KS
+    push    KEY
+
+    call    intel_aes_encrypt_init_192
+
+    pop     KEY
+    pop     KS
+
+    movdqu  xmm0, [0*16 + KS]
+    movdqu  xmm1, [12*16 + KS]
+    movdqu  [12*16 + KS], xmm0
+    movdqu  [0*16 + KS], xmm1
+
+    i = 1
+    WHILE i LT 6
+        movdqu  xmm0, [i*16 + KS]
+        movdqu  xmm1, [(12-i)*16 + KS]
+
+        aesimc  xmm0, xmm0
+        aesimc  xmm1, xmm1
+
+        movdqu  [(12-i)*16 + KS], xmm0
+        movdqu  [i*16 + KS], xmm1
+
+        i = i+1
+    ENDM
+
+    movdqu  xmm0, [6*16 + KS]
+    aesimc  xmm0, xmm0
+    movdqu  [6*16 + KS], xmm0
+    ret
+intel_aes_decrypt_init_192  ENDP
+
+
+intel_aes_encrypt_init_256  PROC
+    sub     rsp, 16*2
+    movdqu  [16*0 + rsp], xmm6
+    movdqu  [16*1 + rsp], xmm7
+
+    movdqu  xmm1, [16*0 + KEY]
+    movdqu  xmm3, [16*1 + KEY]
+
+    movdqu  [16*0 + KS], xmm1
+    movdqu  [16*1 + KS], xmm3
+
+    lea ITR, Lcon1
+    movdqu  xmm0, [ITR]
+    lea ITR, Lmask256
+    movdqu  xmm5, [ITR]
+
+    pxor    xmm6, xmm6
+
+    mov ITR, 6
+
+Lenc_256_ks_loop:
+
+        movdqa  xmm2, xmm3
+        pshufb  xmm2, xmm5
+        aesenclast  xmm2, xmm0
+        pslld   xmm0, 1
+        movdqa  xmm4, xmm1
+        pslldq  xmm4, 4
+        pxor    xmm1, xmm4
+        pslldq  xmm4, 4
+        pxor    xmm1, xmm4
+        pslldq  xmm4, 4
+        pxor    xmm1, xmm4
+        pxor    xmm1, xmm2
+        movdqu  [16*2 + KS], xmm1
+
+        pshufd  xmm2, xmm1, 0ffh
+        aesenclast  xmm2, xmm6
+        movdqa  xmm4, xmm3
+        pslldq  xmm4, 4
+        pxor    xmm3, xmm4
+        pslldq  xmm4, 4
+        pxor    xmm3, xmm4
+        pslldq  xmm4, 4
+        pxor    xmm3, xmm4
+        pxor    xmm3, xmm2
+        movdqu  [16*3 + KS], xmm3
+
+        lea KS, [32 + KS]
+        dec ITR
+        jnz Lenc_256_ks_loop
+
+    movdqa  xmm2, xmm3
+    pshufb  xmm2, xmm5
+    aesenclast  xmm2, xmm0
+    movdqa  xmm4, xmm1
+    pslldq  xmm4, 4
+    pxor    xmm1, xmm4
+    pslldq  xmm4, 4
+    pxor    xmm1, xmm4
+    pslldq  xmm4, 4
+    pxor    xmm1, xmm4
+    pxor    xmm1, xmm2
+    movdqu  [16*2 + KS], xmm1
+
+    movdqu  xmm7, [16*1 + rsp]
+    movdqu  xmm6, [16*0 + rsp]
+    add rsp, 16*2
+    ret
+
+intel_aes_encrypt_init_256  ENDP
+
+
+intel_aes_decrypt_init_256  PROC
+    push    KS
+    push    KEY
+
+    call    intel_aes_encrypt_init_256
+
+    pop     KEY
+    pop     KS
+
+    movdqu  xmm0, [0*16 + KS]
+    movdqu  xmm1, [14*16 + KS]
+    movdqu  [14*16 + KS], xmm0
+    movdqu  [0*16 + KS], xmm1
+
+    i = 1
+    WHILE i LT 7
+        movdqu  xmm0, [i*16 + KS]
+        movdqu  xmm1, [(14-i)*16 + KS]
+
+        aesimc  xmm0, xmm0
+        aesimc  xmm1, xmm1
+
+        movdqu  [(14-i)*16 + KS], xmm0
+        movdqu  [i*16 + KS], xmm1
+
+        i = i+1
+    ENDM
+
+    movdqu  xmm0, [7*16 + KS]
+    aesimc  xmm0, xmm0
+    movdqu  [7*16 + KS], xmm0
+    ret
+intel_aes_decrypt_init_256  ENDP
+
+
+
+gen_aes_cbc_enc_func MACRO rnds
+
+LOCAL   loop1
+LOCAL   bail
+
+        mov     input,      [rsp + 1*8 + 8*4]
+        mov     inputLen,   [rsp + 1*8 + 8*5]
+
+        sub     rsp, 3*16
+
+        movdqu  [rsp + 0*16], xmm6
+        movdqu  [rsp + 1*16], xmm7
+        movdqu  [rsp + 2*16], xmm8
+
+        lea     ctx, [48+ctx]
+
+        movdqu  xmm0, [-32+ctx]
+
+        movdqu  xmm2, [0*16 + ctx]
+        movdqu  xmm3, [1*16 + ctx]
+        movdqu  xmm4, [2*16 + ctx]
+        movdqu  xmm5, [3*16 + ctx]
+        movdqu  xmm6, [4*16 + ctx]
+        movdqu  xmm7, [5*16 + ctx]
+
+loop1:
+        cmp     inputLen, 1*16
+        jb      bail
+
+        movdqu  xmm1, [input]
+        pxor    xmm1, xmm2
+        pxor    xmm0, xmm1
+
+        aesenc  xmm0, xmm3
+        aesenc  xmm0, xmm4
+        aesenc  xmm0, xmm5
+        aesenc  xmm0, xmm6
+        aesenc  xmm0, xmm7
+
+        i = 6
+    WHILE i LT rnds
+            movdqu  xmm8, [i*16 + ctx]
+            aesenc  xmm0, xmm8
+            i = i+1
+        ENDM
+        movdqu  xmm8, [rnds*16 + ctx]
+        aesenclast xmm0, xmm8
+
+        movdqu  [output], xmm0
+
+        lea input, [1*16 + input]
+        lea output, [1*16 + output]
+        sub inputLen, 1*16
+        jmp loop1
+
+bail:
+        movdqu  [-32+ctx], xmm0
+
+        xor rax, rax
+
+        movdqu  xmm6, [rsp + 0*16]
+        movdqu  xmm7, [rsp + 1*16]
+        movdqu  xmm8, [rsp + 2*16]
+        add     rsp, 3*16
+        ret
+
+ENDM
+
+gen_aes_cbc_dec_func MACRO rnds
+
+LOCAL   loop8
+LOCAL   loop1
+LOCAL   dec1
+LOCAL   bail
+
+        mov     input,      [rsp + 1*8 + 8*4]
+        mov     inputLen,   [rsp + 1*8 + 8*5]
+
+        sub     rsp, 3*16
+
+        movdqu  [rsp + 0*16], xmm6
+        movdqu  [rsp + 1*16], xmm7
+        movdqu  [rsp + 2*16], xmm8
+
+        lea     ctx, [48+ctx]
+
+loop8:
+        cmp     inputLen, 8*16
+        jb      dec1
+
+        movdqu  xmm0, [0*16 + input]
+        movdqu  xmm1, [1*16 + input]
+        movdqu  xmm2, [2*16 + input]
+        movdqu  xmm3, [3*16 + input]
+        movdqu  xmm4, [4*16 + input]
+        movdqu  xmm5, [5*16 + input]
+        movdqu  xmm6, [6*16 + input]
+        movdqu  xmm7, [7*16 + input]
+
+        movdqu  xmm8, [0*16 + ctx]
+        pxor    xmm0, xmm8
+        pxor    xmm1, xmm8
+        pxor    xmm2, xmm8
+        pxor    xmm3, xmm8
+        pxor    xmm4, xmm8
+        pxor    xmm5, xmm8
+        pxor    xmm6, xmm8
+        pxor    xmm7, xmm8
+
+        i = 1
+        WHILE i LT rnds
+            aes_dec_rnd i
+            i = i+1
+            ENDM
+        aes_dec_last_rnd rnds
+
+        movdqu  xmm8, [-32 + ctx]
+        pxor    xmm0, xmm8
+        movdqu  xmm8, [0*16 + input]
+        pxor    xmm1, xmm8
+        movdqu  xmm8, [1*16 + input]
+        pxor    xmm2, xmm8
+        movdqu  xmm8, [2*16 + input]
+        pxor    xmm3, xmm8
+        movdqu  xmm8, [3*16 + input]
+        pxor    xmm4, xmm8
+        movdqu  xmm8, [4*16 + input]
+        pxor    xmm5, xmm8
+        movdqu  xmm8, [5*16 + input]
+        pxor    xmm6, xmm8
+        movdqu  xmm8, [6*16 + input]
+        pxor    xmm7, xmm8
+        movdqu  xmm8, [7*16 + input]
+
+        movdqu  [0*16 + output], xmm0
+        movdqu  [1*16 + output], xmm1
+        movdqu  [2*16 + output], xmm2
+        movdqu  [3*16 + output], xmm3
+        movdqu  [4*16 + output], xmm4
+        movdqu  [5*16 + output], xmm5
+        movdqu  [6*16 + output], xmm6
+        movdqu  [7*16 + output], xmm7
+        movdqu  [-32 + ctx], xmm8
+
+        lea input, [8*16 + input]
+        lea output, [8*16 + output]
+        sub inputLen, 8*16
+        jmp loop8
+dec1:
+
+        movdqu  xmm3, [-32 + ctx]
+
+loop1:
+        cmp     inputLen, 1*16
+        jb      bail
+
+        movdqu  xmm0, [input]
+        movdqa  xmm4, xmm0
+        movdqu  xmm7, [0*16 + ctx]
+        pxor    xmm0, xmm7
+
+        i = 1
+    WHILE i LT rnds
+            movdqu  xmm7, [i*16 + ctx]
+            aesdec  xmm0, xmm7
+            i = i+1
+        ENDM
+        movdqu  xmm7, [rnds*16 + ctx]
+        aesdeclast xmm0, xmm7
+        pxor    xmm3, xmm0
+
+        movdqu  [output], xmm3
+        movdqa  xmm3, xmm4
+
+        lea input, [1*16 + input]
+        lea output, [1*16 + output]
+        sub inputLen, 1*16
+        jmp loop1
+
+bail:
+        movdqu  [-32 + ctx], xmm3
+        xor rax, rax
+
+        movdqu  xmm6, [rsp + 0*16]
+        movdqu  xmm7, [rsp + 1*16]
+        movdqu  xmm8, [rsp + 2*16]
+        add     rsp, 3*16
+        ret
+ENDM
+
+intel_aes_encrypt_cbc_128 PROC
+gen_aes_cbc_enc_func  10
+intel_aes_encrypt_cbc_128 ENDP
+
+intel_aes_encrypt_cbc_192 PROC
+gen_aes_cbc_enc_func  12
+intel_aes_encrypt_cbc_192 ENDP
+
+intel_aes_encrypt_cbc_256 PROC
+gen_aes_cbc_enc_func  14
+intel_aes_encrypt_cbc_256 ENDP
+
+intel_aes_decrypt_cbc_128 PROC
+gen_aes_cbc_dec_func  10
+intel_aes_decrypt_cbc_128 ENDP
+
+intel_aes_decrypt_cbc_192 PROC
+gen_aes_cbc_dec_func  12
+intel_aes_decrypt_cbc_192 ENDP
+
+intel_aes_decrypt_cbc_256 PROC
+gen_aes_cbc_dec_func  14
+intel_aes_decrypt_cbc_256 ENDP
+
+
+
+ctrCtx textequ <r10>
+CTR textequ <r11d>
+CTRSave textequ <eax>
+
+gen_aes_ctr_func MACRO rnds
+
+LOCAL   loop8
+LOCAL   loop1
+LOCAL   enc1
+LOCAL   bail
+
+        mov     input,      [rsp + 8*1 + 4*8]
+        mov     inputLen,   [rsp + 8*1 + 5*8]
+
+        mov     ctrCtx, ctx
+        mov     ctx, [8+ctrCtx]
+        lea     ctx, [48+ctx]
+
+        sub     rsp, 3*16
+        movdqu  [rsp + 0*16], xmm6
+        movdqu  [rsp + 1*16], xmm7
+        movdqu  [rsp + 2*16], xmm8
+
+
+        push    rbp
+        mov     rbp, rsp
+        sub     rsp, 8*16
+        and     rsp, -16
+
+
+        movdqu  xmm0, [16+ctrCtx]
+        mov     CTRSave, DWORD PTR [ctrCtx + 16 + 3*4]
+        bswap   CTRSave
+        movdqu  xmm1, [ctx + 0*16]
+
+        pxor    xmm0, xmm1
+
+        movdqa  [rsp + 0*16], xmm0
+        movdqa  [rsp + 1*16], xmm0
+        movdqa  [rsp + 2*16], xmm0
+        movdqa  [rsp + 3*16], xmm0
+        movdqa  [rsp + 4*16], xmm0
+        movdqa  [rsp + 5*16], xmm0
+        movdqa  [rsp + 6*16], xmm0
+        movdqa  [rsp + 7*16], xmm0
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 1*16 + 3*4], CTR
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 2*16 + 3*4], CTR
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 3*16 + 3*4], CTR
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 4*16 + 3*4], CTR
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 5*16 + 3*4], CTR
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 6*16 + 3*4], CTR
+
+        inc     CTRSave
+        mov     CTR, CTRSave
+        bswap   CTR
+        xor     CTR, DWORD PTR [ctx + 3*4]
+        mov     DWORD PTR [rsp + 7*16 + 3*4], CTR
+
+
+loop8:
+        cmp     inputLen, 8*16
+        jb      loop1
+
+        movdqu  xmm0, [0*16 + rsp]
+        movdqu  xmm1, [1*16 + rsp]
+        movdqu  xmm2, [2*16 + rsp]
+        movdqu  xmm3, [3*16 + rsp]
+        movdqu  xmm4, [4*16 + rsp]
+        movdqu  xmm5, [5*16 + rsp]
+        movdqu  xmm6, [6*16 + rsp]
+        movdqu  xmm7, [7*16 + rsp]
+
+        i = 1
+        WHILE i LE 8
+            aes_rnd i
+
+            inc     CTRSave
+            mov     CTR, CTRSave
+            bswap   CTR
+            xor     CTR, DWORD PTR [ctx + 3*4]
+            mov     DWORD PTR [rsp + (i-1)*16 + 3*4], CTR
+
+            i = i+1
+        ENDM
+        WHILE i LT rnds
+            aes_rnd i
+            i = i+1
+            ENDM
+        aes_last_rnd rnds
+
+        movdqu  xmm8, [0*16 + input]
+        pxor    xmm0, xmm8
+        movdqu  xmm8, [1*16 + input]
+        pxor    xmm1, xmm8
+        movdqu  xmm8, [2*16 + input]
+        pxor    xmm2, xmm8
+        movdqu  xmm8, [3*16 + input]
+        pxor    xmm3, xmm8
+        movdqu  xmm8, [4*16 + input]
+        pxor    xmm4, xmm8
+        movdqu  xmm8, [5*16 + input]
+        pxor    xmm5, xmm8
+        movdqu  xmm8, [6*16 + input]
+        pxor    xmm6, xmm8
+        movdqu  xmm8, [7*16 + input]
+        pxor    xmm7, xmm8
+
+        movdqu  [0*16 + output], xmm0
+        movdqu  [1*16 + output], xmm1
+        movdqu  [2*16 + output], xmm2
+        movdqu  [3*16 + output], xmm3
+        movdqu  [4*16 + output], xmm4
+        movdqu  [5*16 + output], xmm5
+        movdqu  [6*16 + output], xmm6
+        movdqu  [7*16 + output], xmm7
+
+        lea input, [8*16 + input]
+        lea output, [8*16 + output]
+        sub inputLen, 8*16
+        jmp loop8
+
+
+loop1:
+        cmp     inputLen, 1*16
+        jb      bail
+
+        movdqu  xmm0, [rsp]
+        add     rsp, 16
+
+        i = 1
+    WHILE i LT rnds
+            movdqu  xmm7, [i*16 + ctx]
+            aesenc  xmm0, xmm7
+            i = i+1
+        ENDM
+        movdqu  xmm7, [rnds*16 + ctx]
+        aesenclast xmm0, xmm7
+
+        movdqu  xmm7, [input]
+        pxor    xmm0, xmm7
+        movdqu  [output], xmm0
+
+        lea input, [1*16 + input]
+        lea output, [1*16 + output]
+        sub inputLen, 1*16
+        jmp loop1
+
+bail:
+
+        movdqu  xmm0, [rsp]
+        movdqu  xmm1, [ctx + 0*16]
+        pxor    xmm0, xmm1
+        movdqu  [16+ctrCtx], xmm0
+
+
+        xor     rax, rax
+        mov     rsp, rbp
+        pop     rbp
+
+        movdqu  xmm6, [rsp + 0*16]
+        movdqu  xmm7, [rsp + 1*16]
+        movdqu  xmm8, [rsp + 2*16]
+        add     rsp, 3*16
+
+        ret
+ENDM
+
+
+intel_aes_encrypt_ctr_128 PROC
+gen_aes_ctr_func  10
+intel_aes_encrypt_ctr_128 ENDP
+
+intel_aes_encrypt_ctr_192 PROC
+gen_aes_ctr_func  12
+intel_aes_encrypt_ctr_192 ENDP
+
+intel_aes_encrypt_ctr_256 PROC
+gen_aes_ctr_func  14
+intel_aes_encrypt_ctr_256 ENDP
+
+
+END
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/intel-aes-x86-masm.asm
@@ -0,0 +1,949 @@
+; LICENSE:
+; This submission to NSS is to be made available under the terms of the
+; Mozilla Public License, v. 2.0. You can obtain one at http:
+; //mozilla.org/MPL/2.0/.
+;###############################################################################
+; Copyright(c) 2014, Intel Corp.
+; Developers and authors:
+; Shay Gueron and Vlad Krasnov
+; Intel Corporation, Israel Development Centre, Haifa, Israel
+; Please send feedback directly to crypto.feedback.alias@intel.com
+
+
+.MODEL FLAT, C
+.XMM
+
+.DATA
+ALIGN 16
+Lmask dd 0c0f0e0dh,0c0f0e0dh,0c0f0e0dh,0c0f0e0dh
+Lmask192 dd 004070605h, 004070605h, 004070605h, 004070605h
+Lmask256 dd 00c0f0e0dh, 00c0f0e0dh, 00c0f0e0dh, 00c0f0e0dh
+Lcon1 dd 1,1,1,1
+Lcon2 dd 1bh,1bh,1bh,1bh
+
+.CODE
+
+ctx     textequ <ecx>
+output  textequ <edx>
+input   textequ <eax>
+inputLen textequ <edi>
+
+
+aes_rnd MACRO i
+    movdqu  xmm7, [i*16 + ctx]
+    aesenc  xmm0, xmm7
+    aesenc  xmm1, xmm7
+    aesenc  xmm2, xmm7
+    aesenc  xmm3, xmm7
+    aesenc  xmm4, xmm7
+    aesenc  xmm5, xmm7
+    aesenc  xmm6, xmm7
+    ENDM
+
+aes_last_rnd MACRO i
+    movdqu  xmm7, [i*16 + ctx]
+    aesenclast  xmm0, xmm7
+    aesenclast  xmm1, xmm7
+    aesenclast  xmm2, xmm7
+    aesenclast  xmm3, xmm7
+    aesenclast  xmm4, xmm7
+    aesenclast  xmm5, xmm7
+    aesenclast  xmm6, xmm7
+    ENDM
+
+aes_dec_rnd MACRO i
+    movdqu  xmm7, [i*16 + ctx]
+    aesdec  xmm0, xmm7
+    aesdec  xmm1, xmm7
+    aesdec  xmm2, xmm7
+    aesdec  xmm3, xmm7
+    aesdec  xmm4, xmm7
+    aesdec  xmm5, xmm7
+    aesdec  xmm6, xmm7
+    ENDM
+
+aes_dec_last_rnd MACRO i
+    movdqu  xmm7, [i*16 + ctx]
+    aesdeclast  xmm0, xmm7
+    aesdeclast  xmm1, xmm7
+    aesdeclast  xmm2, xmm7
+    aesdeclast  xmm3, xmm7
+    aesdeclast  xmm4, xmm7
+    aesdeclast  xmm5, xmm7
+    aesdeclast  xmm6, xmm7
+    ENDM
+
+
+gen_aes_ecb_func MACRO enc, rnds
+
+LOCAL   loop7
+LOCAL   loop1
+LOCAL   bail
+
+        push    inputLen
+
+        mov     ctx,    [esp + 2*4 + 0*4]
+        mov     output,     [esp + 2*4 + 1*4]
+        mov     input,      [esp + 2*4 + 4*4]
+        mov     inputLen,   [esp + 2*4 + 5*4]
+
+        lea     ctx, [44+ctx]
+
+loop7:
+        cmp     inputLen, 7*16
+        jb      loop1
+
+        movdqu  xmm0, [0*16 + input]
+        movdqu  xmm1, [1*16 + input]
+        movdqu  xmm2, [2*16 + input]
+        movdqu  xmm3, [3*16 + input]
+        movdqu  xmm4, [4*16 + input]
+        movdqu  xmm5, [5*16 + input]
+        movdqu  xmm6, [6*16 + input]
+
+        movdqu  xmm7, [0*16 + ctx]
+        pxor    xmm0, xmm7
+        pxor    xmm1, xmm7
+        pxor    xmm2, xmm7
+        pxor    xmm3, xmm7
+        pxor    xmm4, xmm7
+        pxor    xmm5, xmm7
+        pxor    xmm6, xmm7
+
+IF enc eq 1
+        rnd textequ <aes_rnd>
+        lastrnd textequ <aes_last_rnd>
+        aesinst textequ <aesenc>
+        aeslastinst textequ <aesenclast>
+ELSE
+        rnd textequ <aes_dec_rnd>
+        lastrnd textequ <aes_dec_last_rnd>
+        aesinst textequ <aesdec>
+        aeslastinst textequ <aesdeclast>
+ENDIF
+
+        i = 1
+        WHILE i LT rnds
+            rnd i
+            i = i+1
+            ENDM
+        lastrnd rnds
+
+        movdqu  [0*16 + output], xmm0
+        movdqu  [1*16 + output], xmm1
+        movdqu  [2*16 + output], xmm2
+        movdqu  [3*16 + output], xmm3
+        movdqu  [4*16 + output], xmm4
+        movdqu  [5*16 + output], xmm5
+        movdqu  [6*16 + output], xmm6
+
+        lea input, [7*16 + input]
+        lea output, [7*16 + output]
+        sub inputLen, 7*16
+        jmp loop7
+
+loop1:
+        cmp     inputLen, 1*16
+        jb      bail
+
+        movdqu  xmm0, [input]
+        movdqu  xmm7, [0*16 + ctx]
+        pxor    xmm0, xmm7
+
+        i = 1
+    WHILE i LT rnds
+            movdqu  xmm7, [i*16 + ctx]
+            aesinst  xmm0, xmm7
+            i = i+1
+        ENDM
+        movdqu  xmm7, [rnds*16 + ctx]
+        aeslastinst xmm0, xmm7
+
+        movdqu  [output], xmm0
+
+        lea input, [1*16 + input]
+        lea output, [1*16 + output]
+        sub inputLen, 1*16
+        jmp loop1
+
+bail:
+        xor eax, eax
+        pop     inputLen
+        ret
+
+ENDM
+
+ALIGN 16
+intel_aes_encrypt_ecb_128 PROC
+gen_aes_ecb_func 1, 10
+intel_aes_encrypt_ecb_128 ENDP
+
+ALIGN 16
+intel_aes_encrypt_ecb_192 PROC
+gen_aes_ecb_func 1, 12
+intel_aes_encrypt_ecb_192 ENDP
+
+ALIGN 16
+intel_aes_encrypt_ecb_256 PROC
+gen_aes_ecb_func 1, 14
+intel_aes_encrypt_ecb_256 ENDP
+
+ALIGN 16
+intel_aes_decrypt_ecb_128 PROC
+gen_aes_ecb_func 0, 10
+intel_aes_decrypt_ecb_128 ENDP
+
+ALIGN 16
+intel_aes_decrypt_ecb_192 PROC
+gen_aes_ecb_func 0, 12
+intel_aes_decrypt_ecb_192 ENDP
+
+ALIGN 16
+intel_aes_decrypt_ecb_256 PROC
+gen_aes_ecb_func 0, 14
+intel_aes_decrypt_ecb_256 ENDP
+
+
+KEY textequ <ecx>
+KS  textequ <edx>
+ITR textequ <eax>
+
+ALIGN 16
+intel_aes_encrypt_init_128  PROC
+
+    mov     KEY,        [esp + 1*4 + 0*4]
+    mov     KS,         [esp + 1*4 + 1*4]
+
+
+    movdqu  xmm1, [KEY]
+    movdqu  [KS], xmm1
+    movdqa  xmm2, xmm1
+
+    lea ITR, Lcon1
+    movdqa  xmm0, [ITR]
+    lea ITR, Lmask
+    movdqa  xmm4, [ITR]
+
+    mov ITR, 8
+
+Lenc_128_ks_loop:
+        lea KS, [16 + KS]
+        dec ITR
+
+        pshufb  xmm2, xmm4
+        aesenclast  xmm2, xmm0
+        pslld   xmm0, 1
+        movdqa  xmm3, xmm1
+        pslldq  xmm3, 4
+        pxor    xmm1, xmm3
+        pslldq  xmm3, 4
+        pxor    xmm1, xmm3
+        pslldq  xmm3, 4
+        pxor    xmm1, xmm3
+        pxor    xmm1, xmm2
+        movdqu  [KS], xmm1
+        movdqa  xmm2, xmm1
+
+        jne Lenc_128_ks_loop
+
+    lea ITR, Lcon2
+    movdqa  xmm0, [ITR]
+
+    pshufb  xmm2, xmm4
+    aesenclast  xmm2, xmm0
+    pslld   xmm0, 1
+    movdqa  xmm3, xmm1
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pxor    xmm1, xmm2
+    movdqu  [16 + KS], xmm1
+    movdqa  xmm2, xmm1
+
+    pshufb  xmm2, xmm4
+    aesenclast  xmm2, xmm0
+    movdqa  xmm3, xmm1
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pslldq  xmm3, 4
+    pxor    xmm1, xmm3
+    pxor    xmm1, xmm2
+    movdqu  [32 + KS], xmm1
+    movdqa  xmm2, xmm1
+
+    ret
+intel_aes_encrypt_init_128  ENDP
+
+
+ALIGN 16
+intel_aes_decrypt_init_128  PROC
+
+    mov     KEY,        [esp + 1*4 + 0*4]
+    mov     KS,         [esp + 1*4 + 1*4]
+
+    push    KS
+    push    KEY
+
+    call    intel_aes_encrypt_init_128
+
+    pop     KEY
+    pop     KS
+
+    movdqu  xmm0, [0*16 + KS]
+    movdqu  xmm1, [10*16 + KS]
+    movdqu  [10*16 + KS], xmm0
+    movdqu  [0*16 + KS], xmm1
+
+    i = 1
+    WHILE i LT 5
+        movdqu  xmm0, [i*16 + KS]
+        movdqu  xmm1, [(10-i)*16 + KS]
+
+        aesimc  xmm0, xmm0
+        aesimc  xmm1, xmm1
+
+        movdqu  [(10-i)*16 + KS], xmm0
+        movdqu  [i*16 + KS], xmm1
+
+        i = i+1
+    ENDM
+
+    movdqu  xmm0, [5*16 + KS]
+    aesimc  xmm0, xmm0
+    movdqu  [5*16 + KS], xmm0
+    ret
+intel_aes_decrypt_init_128  ENDP
+
+
+ALIGN 16
+intel_aes_encrypt_init_192  PROC
+
+    mov     KEY, [esp + 1*4 + 0*4]
+    mov     KS,  [esp + 1*4 + 1*4]
+
+    pxor    xmm3, xmm3
+    movdqu  xmm1, [KEY]
+    pinsrd  xmm3, DWORD PTR [16 + KEY], 0
+    pinsrd  xmm3, DWORD PTR [20 + KEY], 1
+
+    movdqu  [KS], xmm1
+    movdqa  xmm5, xmm3
+
+    lea ITR, Lcon1
+    movdqu  xmm0, [ITR]
+    lea ITR, Lmask192
+    movdqu  xmm4, [ITR]
+
+    mov ITR, 4
+
+Lenc_192_ks_loop:
+        movdqa  xmm2, xmm3
+        pshufb  xmm2, xmm4
+        aesenclast xmm2, xmm0
+        pslld   xmm0, 1
+
+        movdqa  xmm6, xmm1
+        movdqa  xmm7, xmm3
+        pslldq  xmm6, 4
+        pslldq  xmm7, 4
+        pxor    xmm1, xmm6
+        pxor    xmm3, xmm7
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pxor    xmm1, xmm2
+        pshufd  xmm2, xmm1, 0ffh
+        pxor    xmm3, xmm2
+
+        movdqa  xmm6, xmm1
+        shufpd  xmm5, xmm1, 00h
+        shufpd  xmm6, xmm3, 01h
+
+        movdqu  [16 + KS], xmm5
+        movdqu  [32 + KS], xmm6
+
+        movdqa  xmm2, xmm3
+        pshufb  xmm2, xmm4
+        aesenclast  xmm2, xmm0
+        pslld   xmm0, 1
+
+        movdqa  xmm6, xmm1
+        movdqa  xmm7, xmm3
+        pslldq  xmm6, 4
+        pslldq  xmm7, 4
+        pxor    xmm1, xmm6
+        pxor    xmm3, xmm7
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pslldq  xmm6, 4
+        pxor    xmm1, xmm6
+        pxor    xmm1, xmm2
+        pshufd  xmm2, xmm1, 0ffh
+        pxor    xmm3, xmm2
+
+        movdqu  [48 + KS], xmm1
+        movdqa  xmm5, xmm3
+
+        lea KS, [48 + KS]
+
+        dec ITR
+        jnz Lenc_192_ks_loop
+
+    movdqu  [16 + KS], xmm5
+ret
+intel_aes_encrypt_init_192  ENDP
+
+ALIGN 16
+intel_aes_decrypt_init_192  PROC
+    mov     KEY,        [esp + 1*4 + 0*4]
+    mov     KS,         [esp + 1*4 + 1*4]
+
+    push    KS
+    push    KEY
+
+    call    intel_aes_encrypt_init_192
+
+    pop     KEY
+    pop     KS
+
+    movdqu  xmm0, [0*16 + KS]
+    movdqu  xmm1, [12*16 + KS]
+    movdqu  [12*16 + KS], xmm0
+    movdqu  [0*16 + KS], xmm1
+
+    i = 1
+    WHILE i LT 6
+        movdqu  xmm0, [i*16 + KS]
+        movdqu  xmm1, [(12-i)*16 + KS]
+
+        aesimc  xmm0, xmm0
+        aesimc  xmm1, xmm1
+
+        movdqu  [(12-i)*16 + KS], xmm0
+        movdqu  [i*16 + KS], xmm1
+
+        i = i+1
+    ENDM
+
+    movdqu  xmm0, [6*16 + KS]
+    aesimc  x