This commit is contained in:
Phil Ringnalda 2015-04-18 17:06:13 -07:00
Родитель aa8a1c9e9f 8747c26535
Коммит 16abe9e8ad
234 изменённых файлов: 9298 добавлений и 2061 удалений

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -19,7 +19,7 @@
<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="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="6b0721ca0e92788df30daf8f7a5fb2863544f9c8">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

Просмотреть файл

@ -19,7 +19,7 @@
<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="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "bef174b279f8eff82b7a2d06414b0ccdd83dd06c",
"git_revision": "c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "64d5a983ba85c1fee6ffc533abdd696b36ca1405",
"revision": "31b41a3f708e732cbcf8fab8a51d1620ae1ebe82",
"repo_path": "integration/gaia-central"
}

Просмотреть файл

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="adb24954bf8068f21705b570450475d183336b2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

Просмотреть файл

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="6b0721ca0e92788df30daf8f7a5fb2863544f9c8">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="bef174b279f8eff82b7a2d06414b0ccdd83dd06c"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c6b04efa0f31a584e6ee0a46dd2b64c1e3c29adc"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f2f2f0cbee2f2517070dd194051d509c07cdacff"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<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="8a1ba73572c713e298ae53821d000fc3a5087b5f"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c7d4045742862a7cf3f0074902ebc7d1b339b0ee"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

Просмотреть файл

@ -13,8 +13,8 @@
"unpack": "True"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
},

Просмотреть файл

@ -13,8 +13,8 @@
"unpack": "True"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
},

Просмотреть файл

@ -15,8 +15,8 @@
"filename": "clang.tar.bz2"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
},

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "gcc.tar.xz"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
},

Просмотреть файл

@ -15,8 +15,8 @@
"filename": "clang.tar.bz2"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
},

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "setup.sh"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
},

Просмотреть файл

@ -1890,3 +1890,8 @@ pref("readinglist.server", "https://readinglist.services.mozilla.com/v1");
// Don't limit how many nodes we care about on desktop:
pref("reader.parse-node-limit", 0);
// Enable Service workers for desktop on non-release builds
#ifdef NIGHTLY_BUILD
pref("dom.serviceWorkers.enabled", true);
#endif

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "gcc.tar.xz"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "gcc.tar.xz"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -15,8 +15,8 @@
"filename": "clang.tar.bz2"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -15,8 +15,8 @@
"filename": "clang.tar.bz2"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "setup.sh"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -12,8 +12,8 @@
"filename": "setup.sh"
},
{
"size": 166506,
"digest": "f3c214fd571f21d64937584645212f8d7c2d12c9016be613bd2bc9cecd80b3d52a741423cc1ca69bd85fb924c3d0572c85a1734d12db1616df37abcc397e9252",
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
"filename": "sccache.tar.bz2"
}

Просмотреть файл

@ -13915,7 +13915,7 @@ nsDocShell::GetURLSearchParams()
}
void
nsDocShell::NotifyJSRunToCompletionStart()
nsDocShell::NotifyJSRunToCompletionStart(const char *aReason)
{
bool timelineOn = nsIDocShell::GetRecordProfileTimelineMarkers();

Просмотреть файл

@ -54,7 +54,7 @@ interface nsITabParent;
typedef unsigned long nsLoadFlags;
[scriptable, builtinclass, uuid(68ba7610-e33d-47ce-8fa2-af07af2422bc)]
[scriptable, builtinclass, uuid(bf78de98-9e88-498d-bc19-0e138f683939)]
interface nsIDocShell : nsIDocShellTreeItem
{
/**
@ -1039,7 +1039,7 @@ interface nsIDocShell : nsIDocShellTreeItem
* that execution has stopped. This only occurs when the Timeline devtool
* is collecting information.
*/
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStart();
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStart(in string aReason);
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStop();
/**

Просмотреть файл

@ -759,7 +759,10 @@ MainProcessRunnable::ReadMetadata()
nsresult rv =
qm->EnsureOriginIsInitialized(mPersistence, mGroup, mOrigin, mIsApp,
getter_AddRefs(mDirectory));
NS_ENSURE_SUCCESS(rv, rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
mResult = JS::AsmJSCache_StorageInitFailure;
return rv;
}
rv = mDirectory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -522,6 +522,7 @@ AutoJSAPI::StealException(JS::MutableHandle<JS::Value> aVal)
}
AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
const char *aReason,
bool aIsMainThread,
JSContext* aCx)
: AutoJSAPI(aGlobalObject, aIsMainThread,
@ -546,7 +547,7 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
}
if (mDocShellForJSRunToCompletion) {
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStart();
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStart(aReason);
}
}

Просмотреть файл

@ -318,11 +318,16 @@ private:
/*
* A class that represents a new script entry point.
*
* |aReason| should be a statically-allocated C string naming the reason we're
* invoking JavaScript code: "setTimeout", "event", and so on. The devtools use
* these strings to label JS execution in timeline and profiling displays.
*/
class MOZ_STACK_CLASS AutoEntryScript : public AutoJSAPI,
protected ScriptSettingsStackEntry {
public:
explicit AutoEntryScript(nsIGlobalObject* aGlobalObject,
AutoEntryScript(nsIGlobalObject* aGlobalObject,
const char *aReason,
bool aIsMainThread = NS_IsMainThread(),
// Note: aCx is mandatory off-main-thread.
JSContext* aCx = nullptr);

Просмотреть файл

@ -20,6 +20,9 @@
0x45f27d10, 0x987b, 0x11d2, \
{0xbd, 0x40, 0x00, 0x10, 0x5a, 0xa4, 0x5e, 0x89} }
#define SERVICEWORKERPERIODICUPDATER_CONTRACTID \
"@mozilla.org/service-worker-periodic-updater;1"
//The dom cannot provide the crypto or pkcs11 classes that
//were used in older days, so if someone wants to provide
//the service they must implement an object and give it

Просмотреть файл

@ -1063,7 +1063,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
// JSContext* cx = aes.cx();
nsIGlobalObject* nativeGlobal =
xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(wrappedJS->GetJSObject()));
AutoEntryScript aes(nativeGlobal);
AutoEntryScript aes(nativeGlobal, "message manager handler");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> object(cx, wrappedJS->GetJSObject());
@ -1567,7 +1567,8 @@ nsMessageManagerScriptExecutor::LoadScriptInternal(const nsAString& aURL,
JS::Rooted<JSObject*> global(rt, mGlobal->GetJSObject());
if (global) {
AutoEntryScript aes(xpc::NativeGlobal(global));
AutoEntryScript aes(xpc::NativeGlobal(global),
"message manager script load");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();
if (script) {

Просмотреть файл

@ -2703,7 +2703,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (createdInnerWindow) {
// AutoEntryScript required to invoke debugger hook, which is a
// Gecko-specific concept at present.
AutoEntryScript aes(newInnerWindow);
AutoEntryScript aes(newInnerWindow, "nsGlobalWindow report new global");
JS::Rooted<JSObject*> global(aes.cx(), newInnerWindow->GetWrapper());
JS_FireOnNewGlobalObject(aes.cx(), global);
}
@ -12323,6 +12323,13 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
sNestingLevel = timeout->mNestingLevel;
}
const char *reason;
if (timeout->mIsInterval) {
reason = "setInterval handler";
} else {
reason = "setTimeout handler";
}
nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
nsRefPtr<Function> callback = handler->GetCallback();
if (!callback) {
@ -12335,8 +12342,8 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
handler->GetLocation(&filename, &lineNo);
// New script entry point required, due to the "Create a script" sub-step of
// http://www.whatwg.org/specs/web-apps/current-work/#timer-initialization-steps
AutoEntryScript entryScript(this, true, aScx->GetNativeContext());
// http://www.whatwg.org/specs/web-apps/current-work/#timer-initialisation-steps
AutoEntryScript entryScript(this, reason, true, aScx->GetNativeContext());
JS::CompileOptions options(entryScript.cx());
options.setFileAndLine(filename, lineNo)
.setVersion(JSVERSION_DEFAULT);
@ -12348,7 +12355,7 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
ErrorResult ignored;
JS::Rooted<JS::Value> ignoredVal(CycleCollectedJSRuntime::Get()->Runtime());
callback->Call(me, handler->GetArgs(), &ignoredVal, ignored);
callback->Call(me, handler->GetArgs(), &ignoredVal, ignored, reason);
}
// We ignore any failures from calling EvaluateString() on the context or

Просмотреть файл

@ -1122,7 +1122,8 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
// New script entry point required, due to the "Create a script" sub-step of
// http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block
AutoEntryScript entryScript(globalObject, true, context->GetNativeContext());
AutoEntryScript entryScript(globalObject, "<script> element", true,
context->GetNativeContext());
JS::Rooted<JSObject*> global(entryScript.cx(),
globalObject->GetGlobalJSObject());

Просмотреть файл

@ -61,8 +61,11 @@ nsTraversal::TestNode(nsINode* aNode, mozilla::ErrorResult& aResult)
if (mFilter.HasWebIDLCallback()) {
AutoRestore<bool> inAcceptNode(mInAcceptNode);
mInAcceptNode = true;
// No need to pass in an execution reason, since the generated default,
// "NodeFilter.acceptNode", is pretty much exactly what we'd say anyway.
return mFilter.GetWebIDLCallback()->
AcceptNode(*aNode, aResult, CallbackObject::eRethrowExceptions);
AcceptNode(*aNode, aResult, nullptr,
CallbackObject::eRethrowExceptions);
}
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNode);

Просмотреть файл

@ -3191,7 +3191,7 @@ WrappedJSToDictionary(nsISupports* aObject, T& aDictionary)
// we need this AutoEntryScript here because the spec requires us to execute
// getters when parsing a dictionary
AutoEntryScript aes(global);
AutoEntryScript aes(global, "WebIDL dictionary creation");
aes.TakeOwnershipOfErrorReporting();
JS::Rooted<JS::Value> v(aes.cx(), JS::ObjectValue(*obj));

Просмотреть файл

@ -52,6 +52,7 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
ErrorResult& aRv,
const char* aExecutionReason,
ExceptionHandling aExceptionHandling,
JSCompartment* aCompartment,
bool aIsJSImplementedWebIDL)
@ -127,7 +128,8 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
return;
}
mAutoEntryScript.emplace(globalObject, mIsMainThread, cx);
mAutoEntryScript.emplace(globalObject, aExecutionReason,
mIsMainThread, cx);
mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
if (incumbent) {

Просмотреть файл

@ -177,6 +177,7 @@ protected:
// they will only be rethrown if that compartment's principal subsumes the
// principal of our (unwrapped) callback.
CallSetup(CallbackObject* aCallback, ErrorResult& aRv,
const char* aExecutionReason,
ExceptionHandling aExceptionHandling,
JSCompartment* aCompartment = nullptr,
bool aIsJSImplementedWebIDL = false);

Просмотреть файл

@ -4763,7 +4763,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
extraConditionForNull=extraConditionForNull)
elif (not type.hasNullableType and defaultValue and
isinstance(defaultValue, IDLNullValue)):
assert type.hasDictionaryType
assert type.hasDictionaryType()
assert defaultValue.type.isDictionary()
if not isOwningUnion and typeNeedsRooting(defaultValue.type):
ctorArgs = "cx"
@ -13759,9 +13759,9 @@ class CGCallback(CGClass):
self.baseName = baseName
self._deps = idlObject.getDeps()
self.idlObject = idlObject
name = idlObject.identifier.name
self.name = idlObject.identifier.name
if isJSImplementedDescriptor(descriptorProvider):
name = jsImplName(name)
self.name = jsImplName(self.name)
# For our public methods that needThisHandling we want most of the
# same args and the same return type as what CallbackMember
# generates. So we want to take advantage of all its
@ -13776,11 +13776,11 @@ class CGCallback(CGClass):
realMethods.extend(self.getMethodImpls(method))
realMethods.append(
ClassMethod("operator==", "bool",
[Argument("const %s&" % name, "aOther")],
[Argument("const %s&" % self.name, "aOther")],
inline=True, bodyInHeader=True,
const=True,
body=("return %s::operator==(aOther);\n" % baseName)))
CGClass.__init__(self, name,
CGClass.__init__(self, self.name,
bases=[ClassBase(baseName)],
constructors=self.getConstructors(),
methods=realMethods+getters+setters)
@ -13818,8 +13818,10 @@ class CGCallback(CGClass):
argnamesWithThis = ["s.GetContext()", "thisValJS"] + argnames
argnamesWithoutThis = ["s.GetContext()", "JS::UndefinedHandleValue"] + argnames
# Now that we've recorded the argnames for our call to our private
# method, insert our optional argument for deciding whether the
# CallSetup should re-throw exceptions on aRv.
# method, insert our optional arguments for the execution reason and for
# deciding whether the CallSetup should re-throw exceptions on aRv.
args.append(Argument("const char*", "aExecutionReason",
"nullptr"))
args.append(Argument("ExceptionHandling", "aExceptionHandling",
"eReportExceptions"))
# And the argument for communicating when exceptions should really be
@ -13835,13 +13837,17 @@ class CGCallback(CGClass):
setupCall = fill(
"""
CallSetup s(this, aRv, aExceptionHandling, aCompartment);
if (!aExecutionReason) {
aExecutionReason = "${executionReason}";
}
CallSetup s(this, aRv, aExecutionReason, aExceptionHandling, aCompartment);
if (!s.GetContext()) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return${errorReturn};
}
""",
errorReturn=errorReturn)
errorReturn=errorReturn,
executionReason=method.getPrettyName())
bodyWithThis = fill(
"""
@ -14145,6 +14151,8 @@ class CallbackMember(CGNativeMember):
# Since we don't need this handling, we're the actual method that
# will be called, so we need an aRethrowExceptions argument.
if not self.rethrowContentException:
args.append(Argument("const char*", "aExecutionReason",
"nullptr"))
args.append(Argument("ExceptionHandling", "aExceptionHandling",
"eReportExceptions"))
args.append(Argument("JSCompartment*", "aCompartment", "nullptr"))
@ -14162,10 +14170,10 @@ class CallbackMember(CGNativeMember):
if self.rethrowContentException:
# getArgs doesn't add the aExceptionHandling argument but does add
# aCompartment for us.
callSetup += ", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ "
callSetup += ', "%s", eRethrowContentExceptions, aCompartment, /* aIsJSImplementedWebIDL = */ ' % self.getPrettyName()
callSetup += toStringBool(isJSImplementedDescriptor(self.descriptorProvider))
else:
callSetup += ", aExceptionHandling, aCompartment"
callSetup += ', "%s", aExceptionHandling, aCompartment' % self.getPrettyName()
callSetup += ");\n"
return fill(
"""

Просмотреть файл

@ -1471,6 +1471,14 @@ class IDLDictionary(IDLObjectWithScope):
def isDictionary(self):
return True;
def canBeEmpty(self):
"""
Returns true if this dictionary can be empty (that is, it has no
required members and neither do any of its ancestors).
"""
return (all(member.optional for member in self.members) and
(not self.parent or self.parent.canBeEmpty()))
def finish(self, scope):
if self._finished:
return
@ -2133,7 +2141,7 @@ class IDLUnionType(IDLType):
IDLType.__init__(self, location, "")
self.memberTypes = memberTypes
self.hasNullableType = False
self.hasDictionaryType = False
self._dictionaryType = None
self.flatMemberTypes = None
self.builtin = False
@ -2189,10 +2197,10 @@ class IDLUnionType(IDLType):
if self.hasNullableType:
raise WebIDLError("Can't have more than one nullable types in a union",
[nullableType.location, self.flatMemberTypes[i].location])
if self.hasDictionaryType:
if self.hasDictionaryType():
raise WebIDLError("Can't have a nullable type and a "
"dictionary type in a union",
[dictionaryType.location,
[self._dictionaryType.location,
self.flatMemberTypes[i].location])
self.hasNullableType = True
nullableType = self.flatMemberTypes[i]
@ -2204,8 +2212,7 @@ class IDLUnionType(IDLType):
"dictionary type in a union",
[nullableType.location,
self.flatMemberTypes[i].location])
self.hasDictionaryType = True
dictionaryType = self.flatMemberTypes[i]
self._dictionaryType = self.flatMemberTypes[i]
elif self.flatMemberTypes[i].isUnion():
self.flatMemberTypes[i:i + 1] = self.flatMemberTypes[i].memberTypes
continue
@ -2244,6 +2251,13 @@ class IDLUnionType(IDLType):
return False
return True
def hasDictionaryType(self):
return self._dictionaryType is not None
def hasPossiblyEmptyDictionaryType(self):
return (self._dictionaryType is not None and
self._dictionaryType.inner.canBeEmpty())
def _getDependentObjects(self):
return set(self.memberTypes)
@ -3036,14 +3050,14 @@ class IDLNullValue(IDLObject):
def coerceToType(self, type, location):
if (not isinstance(type, IDLNullableType) and
not (type.isUnion() and type.hasNullableType) and
not (type.isUnion() and type.hasDictionaryType) and
not (type.isUnion() and type.hasDictionaryType()) and
not type.isDictionary() and
not type.isAny()):
raise WebIDLError("Cannot coerce null value to type %s." % type,
[location])
nullValue = IDLNullValue(self.location)
if type.isUnion() and not type.nullable() and type.hasDictionaryType:
if type.isUnion() and not type.nullable() and type.hasDictionaryType():
# We're actually a default value for the union's dictionary member.
# Use its type.
for t in type.flatMemberTypes:
@ -3608,7 +3622,7 @@ class IDLArgument(IDLObjectWithIdentifier):
self.type = type
if ((self.type.isDictionary() or
self.type.isUnion() and self.type.unroll().hasDictionaryType) and
self.type.isUnion() and self.type.unroll().hasDictionaryType()) and
self.optional and not self.defaultValue and not self.variadic):
# Default optional non-variadic dictionaries to null,
# for simplicity, so the codegen doesn't have to special-case this.
@ -3930,45 +3944,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def finish(self, scope):
IDLInterfaceMember.finish(self, scope)
overloadWithPromiseReturnType = None
overloadWithoutPromiseReturnType = None
for overload in self._overloads:
variadicArgument = None
arguments = overload.arguments
for (idx, argument) in enumerate(arguments):
if not argument.isComplete():
argument.complete(scope)
assert argument.type.isComplete()
if (argument.type.isDictionary() or
(argument.type.isUnion() and
argument.type.unroll().hasDictionaryType)):
# Dictionaries and unions containing dictionaries at the
# end of the list or followed by optional arguments must be
# optional.
if (not argument.optional and
all(arg.optional for arg in arguments[idx+1:])):
raise WebIDLError("Dictionary argument or union "
"argument containing a dictionary "
"not followed by a required argument "
"must be optional",
[argument.location])
# An argument cannot be a Nullable Dictionary
if argument.type.nullable():
raise WebIDLError("An argument cannot be a nullable "
"dictionary or nullable union "
"containing a dictionary",
[argument.location])
# Only the last argument can be variadic
if variadicArgument:
raise WebIDLError("Variadic argument is not last argument",
[variadicArgument.location])
if argument.variadic:
variadicArgument = argument
returnType = overload.returnType
if not returnType.isComplete():
returnType = returnType.complete(scope)
@ -3977,22 +3953,10 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
assert not isinstance(returnType.name, IDLUnresolvedIdentifier)
overload.returnType = returnType
if returnType.isPromise():
overloadWithPromiseReturnType = overload
else:
overloadWithoutPromiseReturnType = overload
# Make sure either all our overloads return Promises or none do
if overloadWithPromiseReturnType and overloadWithoutPromiseReturnType:
raise WebIDLError("We have overloads with both Promise and "
"non-Promise return types",
[overloadWithPromiseReturnType.location,
overloadWithoutPromiseReturnType.location])
if overloadWithPromiseReturnType and self._legacycaller:
raise WebIDLError("May not have a Promise return type for a "
"legacycaller.",
[overloadWithPromiseReturnType.location])
for argument in overload.arguments:
if not argument.isComplete():
argument.complete(scope)
assert argument.type.isComplete()
# Now compute various information that will be used by the
# WebIDL overload resolution algorithm.
@ -4022,12 +3986,67 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
distinguishingIndex),
[self.location, overload.location])
overloadWithPromiseReturnType = None
overloadWithoutPromiseReturnType = None
for overload in self._overloads:
if not overload.returnType.unroll().isExposedInAllOf(self.exposureSet):
returnType = overload.returnType
if not returnType.unroll().isExposedInAllOf(self.exposureSet):
raise WebIDLError("Overload returns a type that is not exposed "
"everywhere where the method is exposed",
[overload.location])
variadicArgument = None
arguments = overload.arguments
for (idx, argument) in enumerate(arguments):
assert argument.type.isComplete()
if ((argument.type.isDictionary() and
argument.type.inner.canBeEmpty())or
(argument.type.isUnion() and
argument.type.unroll().hasPossiblyEmptyDictionaryType())):
# Optional dictionaries and unions containing optional
# dictionaries at the end of the list or followed by
# optional arguments must be optional.
if (not argument.optional and
all(arg.optional for arg in arguments[idx+1:])):
raise WebIDLError("Dictionary argument or union "
"argument containing a dictionary "
"not followed by a required argument "
"must be optional",
[argument.location])
# An argument cannot be a Nullable Dictionary
if argument.type.nullable():
raise WebIDLError("An argument cannot be a nullable "
"dictionary or nullable union "
"containing a dictionary",
[argument.location])
# Only the last argument can be variadic
if variadicArgument:
raise WebIDLError("Variadic argument is not last argument",
[variadicArgument.location])
if argument.variadic:
variadicArgument = argument
if returnType.isPromise():
overloadWithPromiseReturnType = overload
else:
overloadWithoutPromiseReturnType = overload
# Make sure either all our overloads return Promises or none do
if overloadWithPromiseReturnType and overloadWithoutPromiseReturnType:
raise WebIDLError("We have overloads with both Promise and "
"non-Promise return types",
[overloadWithPromiseReturnType.location,
overloadWithoutPromiseReturnType.location])
if overloadWithPromiseReturnType and self._legacycaller:
raise WebIDLError("May not have a Promise return type for a "
"legacycaller.",
[overloadWithPromiseReturnType.location])
def overloadsForArgCount(self, argc):
return [overload for overload in self._overloads if
len(overload.arguments) == argc or

Просмотреть файл

@ -712,6 +712,7 @@ public:
// Dictionary tests
void PassDictionary(JSContext*, const Dict&);
void PassDictionary2(JSContext*, const Dict&);
void GetReadonlyDictionary(JSContext*, Dict&);
void GetReadonlyNullableDictionary(JSContext*, Nullable<Dict>&);
void GetWritableDictionary(JSContext*, Dict&);

Просмотреть файл

@ -685,6 +685,7 @@ interface TestInterface {
attribute byte otherAttributeRenamedFrom;
void passDictionary(optional Dict x);
void passDictionary2(Dict x);
[Cached, Pure]
readonly attribute Dict readonlyDictionary;
[Cached, Pure]

Просмотреть файл

@ -549,6 +549,7 @@ interface TestExampleInterface {
attribute byte otherAttributeRenamedFrom;
void passDictionary(optional Dict x);
void passDictionary2(Dict x);
[Cached, Pure]
readonly attribute Dict readonlyDictionary;
[Cached, Pure]

Просмотреть файл

@ -562,6 +562,7 @@ interface TestJSImplInterface {
attribute byte otherAttributeRenamedFrom;
void passDictionary(optional Dict x);
void passDictionary2(Dict x);
[Cached, Pure]
readonly attribute Dict readonlyDictionary;
[Cached, Pure]

Просмотреть файл

@ -241,7 +241,7 @@ nsGeolocationSettings::HandleGeolocationPerOriginSettingsChange(const JS::Value&
// because the spec requires calling getters when enumerating the key of a
// dictionary
AutoEntryScript aes(global);
AutoEntryScript aes(global, "geolocation.app_settings enumeration");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();
JS::AutoIdArray ids(cx, JS_Enumerate(cx, obj));
@ -317,7 +317,7 @@ nsGeolocationSettings::HandleGeolocationAlwaysPreciseChange(const JS::Value& aVa
NS_ENSURE_TRUE_VOID(global && global->GetGlobalJSObject());
// the spec requires calling getters when accessing array by index
AutoEntryScript aes(global);
AutoEntryScript aes(global, "geolocation.always_precise indexing");
aes.TakeOwnershipOfErrorReporting();
JSContext *cx = aes.cx();

Просмотреть файл

@ -33,7 +33,7 @@ interface nsIServiceWorkerInfo : nsISupports
readonly attribute DOMString waitingCacheName;
};
[scriptable, builtinclass, uuid(3cd3acce-8c80-4fcc-9265-067ebe8cab92)]
[scriptable, builtinclass, uuid(c05b3b45-7f39-458c-8097-afafc7d69b01)]
interface nsIServiceWorkerManager : nsISupports
{
/**
@ -124,6 +124,8 @@ interface nsIServiceWorkerManager : nsISupports
void sendPushEvent(in ACString scope, in DOMString data);
void sendPushSubscriptionChangedEvent(in ACString scope);
void updateAllRegistrations();
};
%{ C++

Просмотреть файл

@ -78,6 +78,7 @@
#include "nsIMutable.h"
#include "nsIObserverService.h"
#include "nsIScriptSecurityManager.h"
#include "nsIServiceWorkerManager.h"
#include "nsScreenManagerProxy.h"
#include "nsMemoryInfoDumper.h"
#include "nsServiceManagerUtils.h"
@ -1239,6 +1240,16 @@ ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL)
return true;
}
bool
ContentChild::RecvUpdateServiceWorkerRegistrations()
{
nsCOMPtr<nsIServiceWorkerManager> swm = mozilla::services::GetServiceWorkerManager();
if (swm) {
swm->UpdateAllRegistrations();
}
return true;
}
static CancelableTask* sFirstIdleTask;
static void FirstIdle(void)

Просмотреть файл

@ -301,6 +301,8 @@ public:
virtual bool RecvBidiKeyboardNotify(const bool& isLangRTL) override;
virtual bool RecvUpdateServiceWorkerRegistrations() override;
virtual bool RecvNotifyVisited(const URIParams& aURI) override;
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);

Просмотреть файл

@ -465,6 +465,8 @@ child:
*/
async BidiKeyboardNotify(bool isLangRTL);
async UpdateServiceWorkerRegistrations();
async DataStoreNotify(uint32_t aAppId, nsString aName,
nsString aManifestURL);

Просмотреть файл

@ -249,7 +249,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
// New script entry point required, due to the "Create a script" step of
// http://www.whatwg.org/specs/web-apps/current-work/#javascript-protocol
AutoEntryScript entryScript(innerGlobal, true,
AutoEntryScript entryScript(innerGlobal, "javascript: URI", true,
scriptContext->GetNativeContext());
JSContext* cx = entryScript.cx();
JS::Rooted<JSObject*> globalJSObject(cx, innerGlobal->GetGlobalJSObject());

Просмотреть файл

@ -8,8 +8,14 @@
#include "MediaTaskQueue.h"
#include "nsThreadUtils.h"
#include "TaskDispatcher.h"
#include "nsIAppShell.h"
#include "nsWidgetsCID.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Maybe.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/unused.h"
@ -18,13 +24,26 @@ namespace mozilla {
StaticRefPtr<AbstractThread> sMainThread;
ThreadLocal<AbstractThread*> AbstractThread::sCurrentThreadTLS;
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
class XPCOMThreadWrapper : public AbstractThread
{
public:
explicit XPCOMThreadWrapper(nsIThread* aTarget)
: AbstractThread(/* aRequireTailDispatch = */ false)
explicit XPCOMThreadWrapper(nsIThread* aTarget, bool aRequireTailDispatch)
: AbstractThread(aRequireTailDispatch)
, mTarget(aTarget)
{}
{
// Our current mechanism of implementing tail dispatch is appshell-specific.
// This is because a very similar mechanism already exists on the main
// thread, and we want to avoid making event dispatch on the main thread
// more complicated than it already is.
//
// If you need to use tail dispatch on other XPCOM threads, you'll need to
// implement an nsIThreadObserver to fire the tail dispatcher at the
// appropriate times.
MOZ_ASSERT_IF(aRequireTailDispatch,
NS_IsMainThread() && NS_GetCurrentThread() == aTarget);
}
virtual void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
@ -45,14 +64,30 @@ public:
virtual bool IsCurrentThreadIn() override
{
bool in = NS_GetCurrentThread() == mTarget;
MOZ_ASSERT_IF(in, GetCurrent() == this);
MOZ_ASSERT(in == (GetCurrent() == this));
return in;
}
virtual TaskDispatcher& TailDispatcher() override { MOZ_CRASH("Not implemented!"); }
void FireTailDispatcher() { MOZ_ASSERT(mTailDispatcher.isSome()); mTailDispatcher.reset(); }
virtual TaskDispatcher& TailDispatcher() override
{
MOZ_ASSERT(this == sMainThread); // See the comment in the constructor.
MOZ_ASSERT(IsCurrentThreadIn());
if (!mTailDispatcher.isSome()) {
mTailDispatcher.emplace(/* aIsTailDispatcher = */ true);
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &XPCOMThreadWrapper::FireTailDispatcher);
nsCOMPtr<nsIAppShell> appShell = do_GetService(kAppShellCID);
appShell->RunInStableState(event);
}
return mTailDispatcher.ref();
}
private:
nsRefPtr<nsIThread> mTarget;
Maybe<AutoTaskDispatcher> mTailDispatcher;
};
AbstractThread*
@ -70,7 +105,7 @@ AbstractThread::InitStatics()
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
MOZ_DIAGNOSTIC_ASSERT(mainThread);
sMainThread = new XPCOMThreadWrapper(mainThread.get());
sMainThread = new XPCOMThreadWrapper(mainThread.get(), /* aRequireTailDispatch = */ true);
ClearOnShutdown(&sMainThread);
if (!sCurrentThreadTLS.init()) {

Просмотреть файл

@ -106,8 +106,16 @@ private:
void
MediaTaskQueue::SyncDispatch(TemporaryRef<nsIRunnable> aRunnable) {
NS_WARNING("MediaTaskQueue::SyncDispatch is dangerous and deprecated. Stop using this!");
RefPtr<MediaTaskQueueSyncRunnable> task(new MediaTaskQueueSyncRunnable(aRunnable));
Dispatch(task);
nsRefPtr<MediaTaskQueueSyncRunnable> task(new MediaTaskQueueSyncRunnable(aRunnable));
// Tail dispatchers don't interact nicely with sync dispatch. We require that
// nothing is already in the tail dispatcher, and then sidestep it for this
// task.
MOZ_ASSERT_IF(AbstractThread::GetCurrent(),
!AbstractThread::GetCurrent()->TailDispatcher().HasTasksFor(this));
nsRefPtr<MediaTaskQueueSyncRunnable> taskRef = task;
Dispatch(taskRef.forget(), AssertDispatchSuccess, TailDispatch);
task->WaitUntilDone();
}
@ -121,6 +129,11 @@ MediaTaskQueue::AwaitIdle()
void
MediaTaskQueue::AwaitIdleLocked()
{
// Make the there are no tasks for this queue waiting in the caller's tail
// dispatcher.
MOZ_ASSERT_IF(AbstractThread::GetCurrent(),
!AbstractThread::GetCurrent()->TailDispatcher().HasTasksFor(this));
mQueueMonitor.AssertCurrentThreadOwns();
MOZ_ASSERT(mIsRunning || mTasks.empty());
while (mIsRunning) {
@ -131,6 +144,11 @@ MediaTaskQueue::AwaitIdleLocked()
void
MediaTaskQueue::AwaitShutdownAndIdle()
{
// Make the there are no tasks for this queue waiting in the caller's tail
// dispatcher.
MOZ_ASSERT_IF(AbstractThread::GetCurrent(),
!AbstractThread::GetCurrent()->TailDispatcher().HasTasksFor(this));
MonitorAutoLock mon(mQueueMonitor);
while (!mIsShutdown) {
mQueueMonitor.Wait();
@ -176,6 +194,11 @@ FlushableMediaTaskQueue::FlushAndDispatch(TemporaryRef<nsIRunnable> aRunnable)
void
FlushableMediaTaskQueue::FlushLocked()
{
// Make the there are no tasks for this queue waiting in the caller's tail
// dispatcher.
MOZ_ASSERT_IF(AbstractThread::GetCurrent(),
!AbstractThread::GetCurrent()->TailDispatcher().HasTasksFor(this));
mQueueMonitor.AssertCurrentThreadOwns();
MOZ_ASSERT(mIsFlushing);
@ -197,7 +220,7 @@ bool
MediaTaskQueue::IsCurrentThreadIn()
{
bool in = NS_GetCurrentThread() == mRunningThread;
MOZ_ASSERT_IF(in, GetCurrent() == this);
MOZ_ASSERT(in == (GetCurrent() == this));
return in;
}

Просмотреть файл

@ -20,7 +20,6 @@ const PC_ICE_CONTRACT = "@mozilla.org/dom/rtcicecandidate;1";
const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
const PC_IDENTITY_CONTRACT = "@mozilla.org/dom/rtcidentityassertion;1";
const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
@ -31,7 +30,6 @@ const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
const PC_IDENTITY_CID = Components.ID("{1abc7499-3c54-43e0-bd60-686e2703f072}");
const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
const PC_RECEIVER_CID = Components.ID("{d974b814-8fde-411c-8c45-b86791b81030}");
@ -272,22 +270,6 @@ RTCStatsReport.prototype = {
get mozPcid() { return this._pcid; }
};
function RTCIdentityAssertion() {}
RTCIdentityAssertion.prototype = {
classDescription: "RTCIdentityAssertion",
classID: PC_IDENTITY_CID,
contractID: PC_IDENTITY_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
Ci.nsIDOMGlobalPropertyInitializer]),
init: function(win) { this._win = win; },
__init: function(idp, name) {
this.idp = idp;
this.name = name;
}
};
function RTCPeerConnection() {
this._senders = [];
this._receivers = [];
@ -717,9 +699,10 @@ RTCPeerConnection.prototype = {
if (msg) {
// Set new identity and generate an event.
this._impl.peerIdentity = msg.identity;
let assertion = new this._win.RTCIdentityAssertion(
this._remoteIdp.provider, msg.identity);
this._resolvePeerIdentity(assertion);
this._resolvePeerIdentity(Cu.cloneInto({
idp: this._remoteIdp.provider,
name: msg.identity
}, this._win));
}
})
.catch(e => {
@ -1343,6 +1326,5 @@ this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
RTCRtpReceiver,
RTCRtpSender,
RTCStatsReport,
RTCIdentityAssertion,
PeerConnectionObserver]
);

Просмотреть файл

@ -4,7 +4,6 @@ component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
component {1abc7499-3c54-43e0-bd60-686e2703f072} PeerConnection.js
component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
@ -15,7 +14,6 @@ contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac6607
contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
contract @mozilla.org/dom/rtcidentityassertion;1 {1abc7499-3c54-43e0-bd60-686e2703f072}
contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}
contract @mozilla.org/dom/rtpsender;1 {4fff5d46-d827-4cd4-a970-8fd53977440e}
contract @mozilla.org/dom/rtpreceiver;1 {d974b814-8fde-411c-8c45-b86791b81030}

Просмотреть файл

@ -44,13 +44,15 @@ public:
virtual void AddTask(AbstractThread* aThread,
already_AddRefed<nsIRunnable> aRunnable,
AbstractThread::DispatchFailureHandling aFailureHandling = AbstractThread::AssertDispatchSuccess) = 0;
virtual bool HasTasksFor(AbstractThread* aThread) = 0;
};
/*
* AutoTaskDispatcher is a stack-scoped TaskDispatcher implementation that fires
* its queued tasks when it is popped off the stack.
*/
class MOZ_STACK_CLASS AutoTaskDispatcher : public TaskDispatcher
class AutoTaskDispatcher : public TaskDispatcher
{
public:
explicit AutoTaskDispatcher(bool aIsTailDispatcher = false) : mIsTailDispatcher(aIsTailDispatcher) {}
@ -88,6 +90,8 @@ public:
}
}
bool HasTasksFor(AbstractThread* aThread) override { return !!GetTaskGroup(aThread); }
private:
struct PerThreadTaskGroup
@ -131,16 +135,27 @@ private:
PerThreadTaskGroup& EnsureTaskGroup(AbstractThread* aThread)
{
for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
if (mTaskGroups[i]->mThread == aThread) {
return *mTaskGroups[i];
}
PerThreadTaskGroup* existing = GetTaskGroup(aThread);
if (existing) {
return *existing;
}
mTaskGroups.AppendElement(new PerThreadTaskGroup(aThread));
return *mTaskGroups.LastElement();
}
PerThreadTaskGroup* GetTaskGroup(AbstractThread* aThread)
{
for (size_t i = 0; i < mTaskGroups.Length(); ++i) {
if (mTaskGroups[i]->mThread == aThread) {
return mTaskGroups[i].get();
}
}
// Not found.
return nullptr;
}
// Task groups, organized by thread.
nsTArray<UniquePtr<PerThreadTaskGroup>> mTaskGroups;

Просмотреть файл

@ -58,7 +58,11 @@ private:
{
{
nsRefPtr<MediaTaskQueue> queue = reader->GetTaskQueue();
queue->Dispatch(NS_NewRunnableMethod(reader, &MP4Reader::Shutdown));
nsCOMPtr<nsIRunnable> task = NS_NewRunnableMethod(reader, &MP4Reader::Shutdown);
// Hackily bypass the tail dispatcher so that we can AwaitShutdownAndIdle.
// In production code we'd use BeginShutdown + promises.
queue->Dispatch(task.forget(), AbstractThread::AssertDispatchSuccess,
AbstractThread::TailDispatch);
queue->AwaitShutdownAndIdle();
}
decoder = nullptr;

Просмотреть файл

@ -21,9 +21,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=604067
/** Test for Bug 604067 **/
function documentVideo() {
return document.body.getElementsByTagName("iframe")[0]
.contentDocument.body.getElementsByTagName("video")[0];
}
function check() {
var v = document.body.getElementsByTagName("iframe")[0]
.contentDocument.body.getElementsByTagName("video")[0];
var v = documentVideo();
// Debug info for Bug 608634
ok(true, "iframe src=" + document.body.getElementsByTagName("iframe")[0].src);
@ -47,7 +51,15 @@ if (!t) {
var f = document.createElement("iframe");
f.src = t.name;
f.addEventListener("load", function() { SimpleTest.executeSoon(check); }, false);
f.addEventListener("load", function() {
if (documentVideo().error) {
info("Error occured by the time we got |load| - checking directly.");
check();
} else {
todo(false, "Error hasn't occurred yet - adding |error| event listener. This shouldn't happen, see bug 608634.");
documentVideo().addEventListener("error", check);
}
}, false);
document.body.appendChild(f);
}

Просмотреть файл

@ -773,7 +773,7 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args,
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
dom::AutoEntryScript aes(globalObject);
dom::AutoEntryScript aes(globalObject, "NPAPI doInvoke");
JSContext *cx = aes.cx();
if (!npobj || !result) {
@ -901,7 +901,7 @@ nsJSObjWrapper::NP_GetProperty(NPObject *npobj, NPIdentifier id,
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
dom::AutoEntryScript aes(globalObject);
dom::AutoEntryScript aes(globalObject, "NPAPI get");
JSContext *cx = aes.cx();
if (!npobj) {
@ -935,7 +935,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier npid,
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. NPAPI plugins are Gecko-specific and not in any spec.
dom::AutoEntryScript aes(globalObject);
dom::AutoEntryScript aes(globalObject, "NPAPI set");
JSContext *cx = aes.cx();
if (!npobj) {

Просмотреть файл

@ -1498,7 +1498,7 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
return false;
}
dom::AutoEntryScript aes(win);
dom::AutoEntryScript aes(win, "NPAPI NPN_evaluate");
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> obj(cx, nsNPObjWrapper::GetNewOrUsed(npp, cx, npobj));

Просмотреть файл

@ -225,7 +225,7 @@ protected:
JS::Rooted<JSObject*> rootedThenable(cx, mThenable);
mThen->Call(rootedThenable, resolveFunc, rejectFunc, rv,
CallbackObject::eRethrowExceptions,
"promise thenable", CallbackObject::eRethrowExceptions,
mPromise->Compartment());
rv.WouldReportJSException();
@ -630,8 +630,8 @@ Promise::CallInitFunction(const GlobalObject& aGlobal,
return;
}
aInit.Call(resolveFunc, rejectFunc, aRv, CallbackObject::eRethrowExceptions,
Compartment());
aInit.Call(resolveFunc, rejectFunc, aRv, "promise initializer",
CallbackObject::eRethrowExceptions, Compartment());
aRv.WouldReportJSException();
if (aRv.IsJSException()) {

Просмотреть файл

@ -205,7 +205,8 @@ WrapperPromiseCallback::Call(JSContext* aCx,
// PromiseReactionTask step 6
JS::Rooted<JS::Value> retValue(aCx);
mCallback->Call(value, &retValue, rv, CallbackObject::eRethrowExceptions,
mCallback->Call(value, &retValue, rv, "promise callback",
CallbackObject::eRethrowExceptions,
mNextPromise->Compartment());
rv.WouldReportJSException();

Просмотреть файл

@ -4,13 +4,10 @@
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/2013/WD-webrtc-20130910/#idl-def-RTCIdentityAssertion
* http://w3c.github.io/webrtc-pc/#idl-def-RTCIdentityAssertion
*/
[Pref="media.peerconnection.identity.enabled",
JSImplementation="@mozilla.org/dom/rtcidentityassertion;1",
Constructor(DOMString idp, DOMString name)]
interface RTCIdentityAssertion {
attribute DOMString idp;
attribute DOMString name;
dictionary RTCIdentityAssertion {
DOMString idp;
DOMString name;
};

Просмотреть файл

@ -34,6 +34,7 @@
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "mozilla/unused.h"
#include "nsContentUtils.h"
#include "nsGlobalWindow.h"
@ -3110,6 +3111,28 @@ ServiceWorkerManager::GetAllRegistrations(nsIArray** aResult)
return NS_OK;
}
static PLDHashOperator
UpdateEachRegistration(const nsACString& aKey,
ServiceWorkerRegistrationInfo* aInfo,
void* aUserArg) {
auto This = static_cast<ServiceWorkerManager*>(aUserArg);
MOZ_ASSERT(!aInfo->mScope.IsEmpty());
nsresult res = This->Update(NS_ConvertUTF8toUTF16(aInfo->mScope));
unused << NS_WARN_IF(NS_FAILED(res));
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
ServiceWorkerManager::UpdateAllRegistrations()
{
AssertIsOnMainThread();
mServiceWorkerRegistrationInfos.EnumerateRead(UpdateEachRegistration, this);
return NS_OK;
}
void
ServiceWorkerInfo::AppendWorker(ServiceWorker* aWorker)
{

Просмотреть файл

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ServiceWorkerPeriodicUpdater.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/unused.h"
#include "mozilla/Services.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/ContentParent.h"
#include "nsIServiceWorkerManager.h"
#define OBSERVER_TOPIC_IDLE_DAILY "idle-daily"
namespace mozilla {
namespace dom {
namespace workers {
NS_IMPL_ISUPPORTS(ServiceWorkerPeriodicUpdater, nsIObserver)
StaticRefPtr<ServiceWorkerPeriodicUpdater>
ServiceWorkerPeriodicUpdater::sInstance;
bool
ServiceWorkerPeriodicUpdater::sPeriodicUpdatesEnabled = true;
already_AddRefed<ServiceWorkerPeriodicUpdater>
ServiceWorkerPeriodicUpdater::GetSingleton()
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
if (!sInstance) {
sInstance = new ServiceWorkerPeriodicUpdater();
ClearOnShutdown(&sInstance);
}
nsRefPtr<ServiceWorkerPeriodicUpdater> copy(sInstance.get());
return copy.forget();
}
ServiceWorkerPeriodicUpdater::ServiceWorkerPeriodicUpdater()
{
Preferences::AddBoolVarCache(&sPeriodicUpdatesEnabled,
"dom.serviceWorkers.periodic-updates.enabled",
true);
}
ServiceWorkerPeriodicUpdater::~ServiceWorkerPeriodicUpdater()
{
}
NS_IMETHODIMP
ServiceWorkerPeriodicUpdater::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (strcmp(aTopic, OBSERVER_TOPIC_IDLE_DAILY) == 0 &&
sPeriodicUpdatesEnabled) {
// First, update all registrations in the parent process.
nsCOMPtr<nsIServiceWorkerManager> swm =
mozilla::services::GetServiceWorkerManager();
if (swm) {
swm->UpdateAllRegistrations();
}
// Now, tell all child processes to update their registrations as well.
nsTArray<ContentParent*> children;
ContentParent::GetAll(children);
for (uint32_t i = 0; i < children.Length(); i++) {
unused << children[i]->SendUpdateServiceWorkerRegistrations();
}
}
return NS_OK;
}
} // namespace workers
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
* 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_ServiceWorkerPeriodicUpdater_h
#define mozilla_ServiceWorkerPeriodicUpdater_h
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "mozilla/StaticPtr.h"
namespace mozilla {
namespace dom {
namespace workers {
/**
* This XPCOM component is main-process only, which means that it will never
* get instantiated in child processes. When we receive the idle-daily
* notification in this component, we iterate over all PContent children, and
* send each one a message that will trigger a call to
* nsIServiceWorkerManager::UpdateAllRegistrations() in all child processes.
*/
class ServiceWorkerPeriodicUpdater final : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
static already_AddRefed<ServiceWorkerPeriodicUpdater> GetSingleton();
private:
ServiceWorkerPeriodicUpdater();
~ServiceWorkerPeriodicUpdater();
static StaticRefPtr<ServiceWorkerPeriodicUpdater> sInstance;
static bool sPeriodicUpdatesEnabled;
};
} // namespace workers
} // namespace dom
} // namespace mozilla
#endif

Просмотреть файл

@ -297,7 +297,7 @@ WorkerRunnable::Run()
MOZ_ASSERT(IsCanceled(), "Subclass Cancel() didn't set IsCanceled()!");
return NS_OK;
}
}
// Track down the appropriate global to use for the AutoJSAPI/AutoEntryScript.
nsCOMPtr<nsIGlobalObject> globalObject;
@ -332,8 +332,9 @@ WorkerRunnable::Run()
Maybe<mozilla::dom::AutoEntryScript> aes;
JSContext* cx;
if (globalObject) {
aes.emplace(globalObject, isMainThread, isMainThread ? nullptr :
GetCurrentThreadJSContext());
aes.emplace(globalObject, "Worker runnable",
isMainThread,
isMainThread ? nullptr : GetCurrentThreadJSContext());
cx = aes->cx();
} else {
jsapi.Init();
@ -352,7 +353,8 @@ WorkerRunnable::Run()
// In the case of CompileScriptRunnnable, WorkerRun above can cause us to
// lazily create a global, so we construct aes here before calling PostRun.
if (targetIsWorkerThread && !aes && DefaultGlobalObject()) {
aes.emplace(DefaultGlobalObject(), false, GetCurrentThreadJSContext());
aes.emplace(DefaultGlobalObject(), "worker runnable",
false, GetCurrentThreadJSContext());
cx = aes->cx();
}

Просмотреть файл

@ -18,6 +18,7 @@ EXPORTS.mozilla.dom += [
EXPORTS.mozilla.dom.workers += [
'ServiceWorkerManager.h',
'ServiceWorkerPeriodicUpdater.h',
'WorkerDebuggerManager.h',
'Workers.h',
]
@ -68,6 +69,7 @@ UNIFIED_SOURCES += [
'ServiceWorkerContainer.cpp',
'ServiceWorkerEvents.cpp',
'ServiceWorkerManager.cpp',
'ServiceWorkerPeriodicUpdater.cpp',
'ServiceWorkerRegistrar.cpp',
'ServiceWorkerRegistration.cpp',
'ServiceWorkerScriptCache.cpp',

Просмотреть файл

@ -46,6 +46,19 @@ fetchXHR('synthesized-headers.txt', function(xhr) {
finish();
});
fetch('synthesized-redirect-real-file.txt', function(xhr) {
dump("Got status AARRGH " + xhr.status + " " + xhr.responseText + "\n");
my_ok(xhr.status == 200, "load should be successful");
my_ok(xhr.responseText == "This is a real file.\n", "Redirect to real file should complete.");
finish();
});
fetch('synthesized-redirect-synthesized.txt', function(xhr) {
my_ok(xhr.status == 200, "load should be successful");
my_ok(xhr.responseText == "synthesized response body", "load should have synthesized response");
finish();
});
fetchXHR('ignored.txt', function(xhr) {
my_ok(xhr.status == 404, "load should be uninterrupted");
finish();

Просмотреть файл

@ -0,0 +1 @@
This is a real file.

Просмотреть файл

@ -27,6 +27,18 @@ onfetch = function(ev) {
ev.respondWith(new Response("test-respondwith-response response body", {}));
}
else if (ev.request.url.contains("synthesized-redirect-real-file.txt")) {
ev.respondWith(Promise.resolve(
Response.redirect("fetch/real-file.txt")
));
}
else if (ev.request.url.contains("synthesized-redirect-synthesized.txt")) {
ev.respondWith(Promise.resolve(
Response.redirect("synthesized.txt")
));
}
else if (ev.request.url.contains("ignored.txt")) {
}

Просмотреть файл

@ -27,6 +27,7 @@ support-files =
fetch/fetch_worker_script.js
fetch/fetch_tests.js
fetch/deliver-gzip.sjs
fetch/real-file.txt
fetch/context/index.html
fetch/context/register.html
fetch/context/unregister.html
@ -68,11 +69,15 @@ support-files =
bug1151916_worker.js
bug1151916_driver.html
empty.js
periodic.sjs
periodic/frame.html
periodic/register.html
periodic/unregister.html
[test_unregister.html]
[test_installation_simple.html]
[test_fetch_event.html]
skip-if = true # Bug 1136780
skip-if = os != "linux" # Bug 1136780
[test_https_fetch.html]
[test_https_fetch_cloned_response.html]
[test_match_all.html]
@ -97,3 +102,5 @@ skip-if = true # Bug 1136780
[test_client_focus.html]
[test_bug1151916.html]
[test_empty_serviceworker.html]
[test_periodic_update.html]
skip-if = true # bug 1151974

Просмотреть файл

@ -0,0 +1,18 @@
function handleRequest(request, response) {
if (!getState('periodiccounter')) {
setState('periodiccounter', '1');
} else {
// Make sure that we pass a string value to setState!
setState('periodiccounter', "" + (parseInt(getState('periodiccounter')) + 1));
}
response.setHeader("Content-Type", "application/javascript", false);
response.write(getScript());
}
function getScript() {
return "onfetch = function(e) {" +
"if (e.request.url.indexOf('get-sw-version') > -1) {" +
"e.respondWith(new Response('" + getState('periodiccounter') + "'));" +
"}" +
"};";
}

Просмотреть файл

@ -0,0 +1,8 @@
<!DOCTYPE html>
<script>
fetch("get-sw-version").then(function(r) {
return r.text();
}).then(function(body) {
parent.callback(body);
});
</script>

Просмотреть файл

@ -0,0 +1,21 @@
<!DOCTYPE html>
<script>
var isDone = false;
function done() {
if (!isDone) {
parent.callback();
isDone = true;
}
}
navigator.serviceWorker.register("../periodic.sjs", {scope: "."})
.then(function(registration) {
if (registration.installing) {
registration.installing.onstatechange = function(e) {
done();
};
} else {
done();
}
});
</script>

Просмотреть файл

@ -0,0 +1,12 @@
<!DOCTYPE html>
<script>
navigator.serviceWorker.getRegistration(".").then(function(registration) {
registration.unregister().then(function(success) {
if (success) {
parent.callback();
} else {
dump("Unregister failed\n");
}
});
});
</script>

Просмотреть файл

@ -0,0 +1,98 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1112469 - Test the periodic update of service workers</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test"></pre>
<script class="testbody" type="text/javascript">
var oldSWVersion, newSWVersion;
function start() {
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
function testVersion(sw) {
// Verify that the service worker has been correctly updated.
testFrame("periodic/frame.html").then(function(body) {
newSWVersion = parseInt(body);
todo_is(newSWVersion, "2", "Expected correct new version");
ok(newSWVersion > oldSWVersion,
"The SW should be successfully updated, old: " + oldSWVersion +
", new: " + newSWVersion);
unregisterSW().then(function() {
SimpleTest.finish();
});
});
}
registerSW().then(function() {
return testFrame("periodic/frame.html").then(function(body) {
oldSWVersion = parseInt(body);
todo_is(oldSWVersion, "1", "Expected correct old version");
});
}).then(function() {
return navigator.serviceWorker.getRegistration("periodic/foo");
}).then(function(reg) {
reg.onupdatefound = function() {
reg.onupdatefound = null;
var sw = reg.installing;
sw.onstatechange = function() {
sw.onstatechange = null;
ok(!reg.waiting && reg.active, "New worker must get activated immediately");
testVersion(reg.active);
};
};
}).then(function() {
SpecialPowers.startPeriodicServiceWorkerUpdates();
});
}
function testFrame(src) {
return new Promise(function(resolve, reject) {
var iframe = document.createElement("iframe");
iframe.src = src;
window.callback = function(result) {
iframe.src = "about:blank";
document.body.removeChild(iframe);
iframe = null;
SpecialPowers.exactGC(window, function() {
resolve(result);
});
};
document.body.appendChild(iframe);
});
}
function registerSW() {
return testFrame("periodic/register.html");
}
function unregisterSW() {
return testFrame("periodic/unregister.html");
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [
["dom.serviceWorkers.exemptFromPerDomainMax", true],
["dom.serviceWorkers.enabled", true],
["dom.serviceWorkers.testing.enabled", true],
["dom.serviceWorkers.periodic-updates.enabled", true],
]}, function() {
start();
});
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -402,7 +402,7 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
// We are going to run script via EvaluateString, so we need a script entry
// point, but as this is XBL related it does not appear in the HTML spec.
AutoEntryScript entryScript(globalObject, true);
AutoEntryScript entryScript(globalObject, "XBL <field> initialization", true);
JSContext* cx = entryScript.cx();
NS_ASSERTION(!::JS_IsExceptionPending(cx),

Просмотреть файл

@ -294,7 +294,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement, JSAddonId* aAd
// We are going to run script via JS::Call, so we need a script entry point,
// but as this is XBL related it does not appear in the HTML spec.
dom::AutoEntryScript aes(global);
dom::AutoEntryScript aes(global, "XBL <constructor>/<destructor> invocation");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();

Просмотреть файл

@ -3563,7 +3563,7 @@ XULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
// Execute the precompiled script with the given version.
// We're about to run script via JS::CloneAndExecuteScript, so we need an
// AutoEntryScript. This is Gecko specific and not in any spec.
AutoEntryScript aes(mScriptGlobalObject);
AutoEntryScript aes(mScriptGlobalObject, "precompiled XUL <script> element");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> baseGlobal(cx, JS::CurrentGlobalOrNull(cx));

Просмотреть файл

@ -1385,7 +1385,7 @@ nsXULTemplateBuilder::InitHTMLTemplateRoot()
// We are going to run script via JS_SetProperty, so we need a script entry
// point, but as this is XUL related it does not appear in the HTML spec.
AutoEntryScript entryScript(innerWin, true);
AutoEntryScript entryScript(innerWin, "nsXULTemplateBuilder creation", true);
JSContext* jscontext = entryScript.cx();
JS::Rooted<JS::Value> v(jscontext);

Просмотреть файл

@ -96,6 +96,14 @@ public:
return mContext;
}
EGLSurface GetEGLSurface() {
return mSurface;
}
EGLDisplay GetEGLDisplay() {
return EGL_DISPLAY();
}
bool BindTex2DOffscreen(GLContext *aOffscreen);
void UnbindTex2DOffscreen(GLContext *aOffscreen);
void BindOffscreenFramebuffer();

Просмотреть файл

@ -230,17 +230,6 @@ GLContextEGL::GLContextEGL(
#ifdef DEBUG
printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
#endif
#if defined(MOZ_WIDGET_GONK)
if (!mIsOffscreen) {
mHwc = HwcComposer2D::GetInstance();
MOZ_ASSERT(!mHwc->Initialized());
if (mHwc->Init(EGL_DISPLAY(), mSurface, this)) {
NS_WARNING("HWComposer initialization failed!");
mHwc = nullptr;
}
}
#endif
}
GLContextEGL::~GLContextEGL()
@ -466,16 +455,13 @@ GLContextEGL::SwapBuffers()
? mSurfaceOverride
: mSurface;
if (surface) {
#ifdef MOZ_WIDGET_GONK
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION < 17
if (!mIsOffscreen) {
if (mHwc) {
return mHwc->Render(EGL_DISPLAY(), surface);
} else {
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), surface);
}
} else
// eglSwapBuffers() is called by hwcomposer.
return true;
}
#endif
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), surface);
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), surface);
} else {
return false;
}

Просмотреть файл

@ -661,16 +661,12 @@ LayerManagerComposite::Render()
/** Our more efficient but less powerful alter ego, if one is available. */
nsRefPtr<Composer2D> composer2D;
composer2D = mCompositor->GetWidget()->GetComposer2D();
// We can't use composert2D if we have layer effects, so only get it
// when we don't have any effects.
if (!haveLayerEffects) {
composer2D = mCompositor->GetWidget()->GetComposer2D();
}
if (!mTarget &&
// We can't use composert2D if we have layer effects
if (!mTarget && !haveLayerEffects &&
gfxPrefs::Composer2DCompositionEnabled() &&
composer2D && composer2D->TryRender(mRoot, mGeometryChanged))
composer2D && composer2D->HasHwc() && composer2D->TryRenderWithHwc(mRoot, mGeometryChanged))
{
LayerScope::SetHWComposed();
if (mFPS) {
@ -684,7 +680,7 @@ LayerManagerComposite::Render()
mInvalidRegion.SetEmpty();
mLastFrameMissedHWC = false;
return;
} else if (!mTarget) {
} else if (!mTarget && !haveLayerEffects) {
mLastFrameMissedHWC = !!composer2D;
}
@ -775,6 +771,10 @@ LayerManagerComposite::Render()
mCompositor->SetFBAcquireFence(mRoot);
}
if (composer2D) {
composer2D->Render();
}
mCompositor->GetWidget()->PostRender(this);
RecordFrame();

Просмотреть файл

@ -52,7 +52,19 @@ public:
* Currently, when TryRender() returns true, the entire framebuffer
* must have been rendered.
*/
virtual bool TryRender(Layer* aRoot, bool aGeometryChanged) = 0;
virtual bool TryRenderWithHwc(Layer* aRoot, bool aGeometryChanged) = 0;
/**
* Return true if Composer2D does composition. Return false if Composer2D
* failed the composition.
*/
virtual bool Render() = 0;
/**
* Return true if Composer2D has a fast composition hardware.
* Return false if Composer2D does not have a fast composition hardware.
*/
virtual bool HasHwc() = 0;
};
} // namespace layers

Просмотреть файл

@ -131,13 +131,19 @@ CompositorOGL::CreateContext()
caps, requireCompatProfile);
}
if (!context)
if (!context) {
context = gl::GLContextProvider::CreateForWindow(mWidget);
}
if (!context) {
NS_WARNING("Failed to create CompositorOGL context");
}
#ifdef MOZ_WIDGET_GONK
mWidget->SetNativeData(NS_NATIVE_OPENGL_CONTEXT,
reinterpret_cast<uintptr_t>(context.get()));
#endif
return context.forget();
}

Просмотреть файл

@ -72,7 +72,8 @@ TestShellCommandParent::RunCallback(const nsString& aResponse)
// We're about to run script via JS_CallFunctionValue, so we need an
// AutoEntryScript. This is just for testing and not in any spec.
dom::AutoEntryScript aes(
xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(&mCallback.toObject())));
xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(&mCallback.toObject())),
"TestShellCommand");
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));

Просмотреть файл

@ -281,7 +281,8 @@ WrapperAnswer::RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar,
const JSIDVariant& idVar, ReturnStatus* rs, JSVariant* result)
{
// We may run scripted getters.
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()));
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()),
"Cross-Process Object Wrapper 'get'");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();
@ -318,7 +319,8 @@ WrapperAnswer::RecvSet(const ObjectId& objId, const JSIDVariant& idVar, const JS
const JSVariant& receiverVar, ReturnStatus* rs)
{
// We may run scripted setters.
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()));
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()),
"Cross-Process Object Wrapper 'set'");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();
@ -379,7 +381,8 @@ WrapperAnswer::RecvCallOrConstruct(const ObjectId& objId,
JSVariant* result,
nsTArray<JSParam>* outparams)
{
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()));
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()),
"Cross-Process Object Wrapper call/construct");
aes.TakeOwnershipOfErrorReporting();
JSContext* cx = aes.cx();

Просмотреть файл

@ -80,11 +80,6 @@ GCTraceKindToAscii(JSGCTraceKind kind);
typedef void
(* JSTraceCallback)(JS::CallbackTracer* trc, void** thingp, JSGCTraceKind kind);
// Callback that JSTraceOp implementation can provide to return a string
// describing the reference traced with JS_CallTracer.
typedef void
(* JSTraceNamePrinter)(JSTracer* trc, char* buf, size_t bufsize);
enum WeakMapTraceKind {
DoNotTraceWeakMaps = 0,
TraceWeakMapValues = 1,
@ -94,80 +89,12 @@ enum WeakMapTraceKind {
class JS_PUBLIC_API(JSTracer)
{
public:
// Set debugging information about a reference to a traceable thing to prepare
// for the following call to JS_CallTracer.
//
// When printer is null, arg must be const char * or char * C string naming
// the reference and index must be either (size_t)-1 indicating that the name
// alone describes the reference or it must be an index into some array vector
// that stores the reference.
//
// When printer callback is not null, the arg and index arguments are
// available to the callback as debugPrintArg_ and debugPrintIndex_ fields
// of JSTracer.
//
// The storage for name or callback's arguments needs to live only until
// the following call to JS_CallTracer returns.
void setTracingDetails(JSTraceNamePrinter printer, const void* arg, size_t index) {
debugPrinter_ = printer;
debugPrintArg_ = arg;
debugPrintIndex_ = index;
}
void setTracingIndex(const char* name, size_t index) {
setTracingDetails(nullptr, (void*)name, index);
}
void setTracingName(const char* name) {
setTracingDetails(nullptr, (void*)name, InvalidIndex);
}
// Remove the currently set tracing details.
void clearTracingDetails() {
debugPrinter_ = nullptr;
debugPrintArg_ = nullptr;
}
const static size_t InvalidIndex = size_t(-1);
// Return true if tracing details are currently set.
bool hasTracingDetails() const;
// Get the string set with the most recent call to setTracingName or return
// fallback if a name printer function has been installed.
const char* tracingName(const char* fallback) const;
// Build a description of this edge in the heap graph. This call may invoke
// the debug printer, which may inspect arbitrary areas of the heap.
const char* getTracingEdgeName(char* buffer, size_t bufferSize);
// Access the currently active tracing details.
JSTraceNamePrinter debugPrinter() const;
const void* debugPrintArg() const;
size_t debugPrintIndex() const;
// Return the runtime set on the tracer.
JSRuntime* runtime() const { return runtime_; }
// Return the weak map tracing behavior set on this tracer.
WeakMapTraceKind eagerlyTraceWeakMaps() const { return eagerlyTraceWeakMaps_; }
#ifdef JS_GC_ZEAL
// Sets the "real" location for a marked reference, when passing the address
// directly is not feasable. This address is used for matching against the
// store buffer when verifying the correctness of the entrees there.
//
// This is currently complicated by our need to nest calls for Values
// stored as keys in hash tables.
void setTracingLocation(void* location);
void unsetTracingLocation();
void** tracingLocation(void** thingp);
#else
void setTracingLocation(void* location) {}
void unsetTracingLocation() {}
void** tracingLocation(void** thingp) { return nullptr; }
#endif
// An intermediate state on the road from C to C++ style dispatch.
enum TracerKindTag {
MarkingTracer,
@ -184,23 +111,24 @@ class JS_PUBLIC_API(JSTracer)
private:
JSRuntime* runtime_;
TracerKindTag tag;
JSTraceNamePrinter debugPrinter_;
const void* debugPrintArg_;
size_t debugPrintIndex_;
WeakMapTraceKind eagerlyTraceWeakMaps_;
#ifdef JS_GC_ZEAL
void* realLocation_;
#endif
};
namespace JS {
class AutoTracingName;
class AutoTracingIndex;
class AutoTracingCallback;
class AutoOriginalTraceLocation;
class JS_PUBLIC_API(CallbackTracer) : public JSTracer
{
public:
CallbackTracer(JSRuntime* rt, JSTraceCallback traceCallback,
WeakMapTraceKind weakTraceKind = TraceWeakMapValues)
: JSTracer(rt, JSTracer::CallbackTracer, weakTraceKind), callback(traceCallback)
: JSTracer(rt, JSTracer::CallbackTracer, weakTraceKind), callback(traceCallback),
contextName_(nullptr), contextIndex_(InvalidIndex), contextFunctor_(nullptr),
contextRealLocation_(nullptr)
{}
// Update the trace callback.
@ -216,10 +144,173 @@ class JS_PUBLIC_API(CallbackTracer) : public JSTracer
callback(this, thing, kind);
}
// Access to the tracing context:
// When tracing with a JS::CallbackTracer, we invoke the callback with the
// edge location and the type of target. This is useful for operating on
// the edge in the abstract or on the target thing, satisfying most common
// use cases. However, some tracers need additional detail about the
// specific edge that is being traced in order to be useful. Unfortunately,
// the raw pointer to the edge that we provide is not enough information to
// infer much of anything useful about that edge.
//
// In order to better support use cases that care in particular about edges
// -- as opposed to the target thing -- tracing implementations are
// responsible for providing extra context information about each edge they
// trace, as it is traced. This contains, at a minimum, an edge name and,
// when tracing an array, the index. Further specialization can be achived
// (with some complexity), by associating a functor with the tracer so
// that, when requested, the user can generate totally custom edge
// descriptions.
// Returns the current edge's name. It is only valid to call this when
// inside the trace callback, however, the edge name will always be set.
const char* contextName() const { MOZ_ASSERT(contextName_); return contextName_; }
// Returns the current edge's index, if marked as part of an array of edges.
// This must be called only inside the trace callback. When not tracing an
// array, the value will be InvalidIndex.
const static size_t InvalidIndex = size_t(-1);
size_t contextIndex() const { return contextIndex_; }
// Build a description of this edge in the heap graph. This call may invoke
// the context functor, if set, which may inspect arbitrary areas of the
// heap. On the other hand, the description provided by this method may be
// substantially more accurate and useful than those provided by only the
// contextName and contextIndex.
const char* getTracingEdgeName(char* buffer, size_t bufferSize);
// The trace implementation may associate a callback with one or more edges
// using AutoTracingDetails. This functor is called by getTracingEdgeName
// and is responsible for providing a textual representation of the
// currently being traced edge. The callback has access to the full heap,
// including the currently set tracing context.
class ContextFunctor {
public:
virtual void operator()(CallbackTracer* trc, char* buf, size_t bufsize) = 0;
};
// Return the original heap tracing location if the raw thingp reference
// has been moved. This is generally only useful for heap analyses that
// need to build an accurate model of the heap, and thus is only accurate
// when built with JS_GC_ZEAL.
void*const* tracingLocation(void** thingp) {
return contextRealLocation_ ? contextRealLocation_ : thingp;
}
private:
// Exposed publicly for several callers that need to check if the tracer
// calling them is of the right type.
JSTraceCallback callback;
friend class AutoTracingName;
const char* contextName_;
friend class AutoTracingIndex;
size_t contextIndex_;
friend class AutoTracingDetails;
ContextFunctor* contextFunctor_;
friend class AutoOriginalTraceLocation;
void*const* contextRealLocation_;
};
// Set the name portion of the tracer's context for the current edge.
class AutoTracingName
{
CallbackTracer* trc_;
const char *prior_;
public:
AutoTracingName(CallbackTracer* trc, const char* name) : trc_(trc), prior_(trc->contextName_) {
MOZ_ASSERT(name);
trc->contextName_ = name;
}
~AutoTracingName() {
MOZ_ASSERT(trc_->contextName_);
trc_->contextName_ = prior_;
}
};
// Set the index portion of the tracer's context for the current range.
class AutoTracingIndex
{
CallbackTracer* trc_;
public:
explicit AutoTracingIndex(JSTracer* trc, size_t initial = 0) : trc_(nullptr) {
if (trc->isCallbackTracer()) {
trc_ = trc->asCallbackTracer();
MOZ_ASSERT(trc_->contextIndex_ == CallbackTracer::InvalidIndex);
trc_->contextIndex_ = initial;
}
}
~AutoTracingIndex() {
if (trc_) {
MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex);
trc_->contextIndex_ = CallbackTracer::InvalidIndex;
}
}
void operator++() {
if (trc_) {
MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex);
++trc_->contextIndex_;
}
}
};
// Set a context callback for the trace callback to use, if it needs a detailed
// edge description.
class AutoTracingDetails
{
CallbackTracer* trc_;
public:
AutoTracingDetails(JSTracer* trc, CallbackTracer::ContextFunctor& func) : trc_(nullptr) {
if (trc->isCallbackTracer()) {
trc_ = trc->asCallbackTracer();
MOZ_ASSERT(trc_->contextFunctor_ == nullptr);
trc_->contextFunctor_ = &func;
}
}
~AutoTracingDetails() {
if (trc_) {
MOZ_ASSERT(trc_->contextFunctor_);
trc_->contextFunctor_ = nullptr;
}
}
};
// Some dynamic analyses depend on knowing the edge source location as it
// exists in the object graph. When marking some types of things, e.g. Value
// edges, it is necessary to copy into a temporary on the stack. This class
// records the original location if we need to copy the tracee, so that the
// relevant analyses can continue to operate correctly.
class AutoOriginalTraceLocation
{
#ifdef JS_GC_ZEAL
CallbackTracer *trc_;
public:
template <typename T>
AutoOriginalTraceLocation(JSTracer* trc, T*const* realLocation) : trc_(nullptr) {
if (trc->isCallbackTracer() && trc->asCallbackTracer()->contextRealLocation_ == nullptr) {
trc_ = trc->asCallbackTracer();
trc_->contextRealLocation_ = reinterpret_cast<void*const*>(realLocation);
}
}
~AutoOriginalTraceLocation() {
if (trc_) {
MOZ_ASSERT(trc_->contextRealLocation_);
trc_->contextRealLocation_ = nullptr;
}
}
#else
public:
template <typename T>
AutoOriginalTraceLocation(JSTracer* trc, T*const* realLocation) {}
#endif
};
} // namespace JS
@ -284,7 +375,7 @@ inline void
JS_CallHashSetObjectTracer(JSTracer* trc, HashSetEnum& e, JSObject* const& key, const char* name)
{
JSObject* updated = key;
trc->setTracingLocation(reinterpret_cast<void*>(&const_cast<JSObject*&>(key)));
JS::AutoOriginalTraceLocation reloc(trc, &key);
JS_CallUnbarrieredObjectTracer(trc, &updated, name);
if (updated != key)
e.rekeyFront(updated);

Просмотреть файл

@ -2043,6 +2043,9 @@ class MOZ_STACK_CLASS ModuleCompiler
case JS::AsmJSCache_QuotaExceeded:
cacheString = "not enough temporary storage quota to store in cache";
break;
case JS::AsmJSCache_StorageInitFailure:
cacheString = "storage initialization failed (consider filing a bug)";
break;
case JS::AsmJSCache_Disabled_Internal:
cacheString = "caching disabled by internal configuration (consider filing a bug)";
break;

Просмотреть файл

@ -839,7 +839,7 @@ HashableValue
HashableValue::mark(JSTracer* trc) const
{
HashableValue hv(*this);
trc->setTracingLocation((void*)this);
JS::AutoOriginalTraceLocation reloc(trc, (void**)this);
TraceEdge(trc, &hv.value, "key");
return hv;
}

Просмотреть файл

@ -42,36 +42,6 @@ void * const js::NullPtr::constNullValue = nullptr;
JS_PUBLIC_DATA(void * const) JS::NullPtr::constNullValue = nullptr;
/*
* There are two mostly separate mark paths. The first is a fast path used
* internally in the GC. The second is a slow path used for root marking and
* for API consumers like the cycle collector or Class::trace implementations.
*
* The fast path uses explicit stacks. The basic marking process during a GC is
* that all roots are pushed on to a mark stack, and then each item on the
* stack is scanned (possibly pushing more stuff) until the stack is empty.
*
* PushMarkStack pushes a GC thing onto the mark stack. In some cases (shapes
* or strings) it eagerly marks the object rather than pushing it. Popping and
* scanning is done by the processMarkStackTop method. For efficiency reasons
* like tail recursion elimination that method also implements the scanning of
* objects. For other GC things it uses helper methods.
*
* Most of the marking code outside Marking.cpp uses functions like MarkObject,
* MarkString, etc. These functions check if an object is in the compartment
* currently being GCed. If it is, they call PushMarkStack. Roots are pushed
* this way as well as pointers traversed inside trace hooks (for things like
* PropertyIteratorObjects). It is always valid to call a MarkX function
* instead of PushMarkStack, although it may be slower.
*
* The MarkX functions also handle non-GC object traversal. In this case, they
* call a callback for each object visited. This is a recursive process; the
* mark stacks are not involved. These callbacks may ask for the outgoing
* pointers to be visited. Eventually, this leads to the MarkChildren functions
* being called. These functions duplicate much of the functionality of
* scanning functions, but they don't push onto an explicit stack.
*/
static inline void
PushMarkStack(GCMarker* gcmarker, JSObject* thing) {
gcmarker->traverse(thing);
@ -106,14 +76,6 @@ PushMarkStack(GCMarker* gcmarker, JSString* thing);
static inline void
PushMarkStack(GCMarker* gcmarker, JS::Symbol* thing);
namespace js {
namespace gc {
static void MarkChildren(JSTracer* trc, ObjectGroup* group);
} /* namespace gc */
} /* namespace js */
/*** Object Marking ***/
#if defined(DEBUG)
@ -272,17 +234,6 @@ CheckMarkedThing<jsid>(JSTracer* trc, jsid id)
trc->runtime()->gc.state() == NO_INCREMENTAL || \
trc->runtime()->gc.state() == MARK_ROOTS);
#define FOR_EACH_GC_LAYOUT(D) \
D(Object, JSObject) \
D(String, JSString) \
D(Symbol, JS::Symbol) \
D(Script, JSScript) \
D(Shape, js::Shape) \
D(BaseShape, js::BaseShape) \
D(JitCode, js::jit::JitCode) \
D(LazyScript, js::LazyScript) \
D(ObjectGroup, js::ObjectGroup)
// A C++ version of JSGCTraceKind
enum class TraceKind {
#define NAMES(name, _) name,
@ -368,8 +319,8 @@ ConvertToBase(T* thingp)
return reinterpret_cast<typename PtrBaseGCType<T>::type*>(thingp);
}
template <typename T> void DispatchToTracer(JSTracer* trc, T* thingp, const char* name, size_t i);
template <typename T> void DoTracing(JS::CallbackTracer* trc, T* thingp, const char* name, size_t i);
template <typename T> void DispatchToTracer(JSTracer* trc, T* thingp, const char* name);
template <typename T> void DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name);
template <typename T> void DoMarking(GCMarker* gcmarker, T thing);
static bool ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Cell* cell);
static bool ShouldMarkCrossCompartment(JSTracer* trc, JSObject* src, Value val);
@ -378,14 +329,14 @@ template <typename T>
void
js::TraceEdge(JSTracer* trc, BarrieredBase<T>* thingp, const char* name)
{
DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name, JSTracer::InvalidIndex);
DispatchToTracer(trc, ConvertToBase(thingp->unsafeGet()), name);
}
template <typename T>
void
js::TraceManuallyBarrieredEdge(JSTracer* trc, T* thingp, const char* name)
{
DispatchToTracer(trc, ConvertToBase(thingp), name, JSTracer::InvalidIndex);
DispatchToTracer(trc, ConvertToBase(thingp), name);
}
template <typename T>
@ -393,16 +344,18 @@ void
js::TraceRoot(JSTracer* trc, T* thingp, const char* name)
{
JS_ROOT_MARKING_ASSERT(trc);
DispatchToTracer(trc, ConvertToBase(thingp), name, JSTracer::InvalidIndex);
DispatchToTracer(trc, ConvertToBase(thingp), name);
}
template <typename T>
void
js::TraceRange(JSTracer* trc, size_t len, BarrieredBase<T>* vec, const char* name)
{
JS::AutoTracingIndex index(trc);
for (auto i : MakeRange(len)) {
if (InternalGCMethods<T>::isMarkable(vec[i].get()))
DispatchToTracer(trc, ConvertToBase(vec[i].unsafeGet()), name, i);
DispatchToTracer(trc, ConvertToBase(vec[i].unsafeGet()), name);
++index;
}
}
@ -411,9 +364,11 @@ void
js::TraceRootRange(JSTracer* trc, size_t len, T* vec, const char* name)
{
JS_ROOT_MARKING_ASSERT(trc);
JS::AutoTracingIndex index(trc);
for (auto i : MakeRange(len)) {
if (InternalGCMethods<T>::isMarkable(vec[i]))
DispatchToTracer(trc, ConvertToBase(&vec[i]), name, i);
DispatchToTracer(trc, ConvertToBase(&vec[i]), name);
++index;
}
}
@ -433,7 +388,7 @@ js::TraceManuallyBarrieredCrossCompartmentEdge(JSTracer* trc, JSObject* src, T*
const char* name)
{
if (ShouldMarkCrossCompartment(trc, src, *dst))
DispatchToTracer(trc, dst, name, -1);
DispatchToTracer(trc, dst, name);
}
template void js::TraceManuallyBarrieredCrossCompartmentEdge<JSObject*>(JSTracer*, JSObject*,
JSObject**, const char*);
@ -445,7 +400,7 @@ void
js::TraceCrossCompartmentEdge(JSTracer* trc, JSObject* src, BarrieredBase<T>* dst, const char* name)
{
if (ShouldMarkCrossCompartment(trc, src, dst->get()))
DispatchToTracer(trc, dst->unsafeGet(), name, -1);
DispatchToTracer(trc, dst->unsafeGet(), name);
}
template void js::TraceCrossCompartmentEdge<Value>(JSTracer*, JSObject*, BarrieredBase<Value>*,
const char*);
@ -455,7 +410,7 @@ template void js::TraceCrossCompartmentEdge<Value>(JSTracer*, JSObject*, Barrier
// a sufficiently smart C++ compiler may be able to devirtualize some paths.
template <typename T>
void
DispatchToTracer(JSTracer* trc, T* thingp, const char* name, size_t i)
DispatchToTracer(JSTracer* trc, T* thingp, const char* name)
{
#define IS_SAME_TYPE_OR(name, type) mozilla::IsSame<type*, T>::value ||
static_assert(
@ -468,7 +423,7 @@ DispatchToTracer(JSTracer* trc, T* thingp, const char* name, size_t i)
if (trc->isMarkingTracer())
return DoMarking(static_cast<GCMarker*>(trc), *thingp);
return DoTracing(static_cast<JS::CallbackTracer*>(trc), thingp, name, i);
return DoCallback(trc->asCallbackTracer(), thingp, name);
}
template <typename T>
@ -542,8 +497,6 @@ DoMarking<Value>(GCMarker* gcmarker, Value val)
DoMarking(gcmarker, &val.toObject());
else if (val.isSymbol())
DoMarking(gcmarker, val.toSymbol());
else
gcmarker->clearTracingDetails();
}
template <>
@ -554,110 +507,6 @@ DoMarking<jsid>(GCMarker* gcmarker, jsid id)
DoMarking(gcmarker, JSID_TO_STRING(id));
else if (JSID_IS_SYMBOL(id))
DoMarking(gcmarker, JSID_TO_SYMBOL(id));
else
gcmarker->clearTracingDetails();
}
template <typename T>
void
DoTracing(JS::CallbackTracer* trc, T* thingp, const char* name, size_t i)
{
JSGCTraceKind kind = MapTypeToTraceKind<typename mozilla::RemovePointer<T>::Type>::kind;
trc->setTracingIndex(name, i);
trc->invoke((void**)thingp, kind);
trc->unsetTracingLocation();
}
template <>
void
DoTracing<Value>(JS::CallbackTracer* trc, Value* vp, const char* name, size_t i)
{
if (vp->isObject()) {
JSObject* prior = &vp->toObject();
JSObject* obj = prior;
DoTracing(trc, &obj, name, i);
if (obj != prior)
vp->setObjectOrNull(obj);
} else if (vp->isString()) {
JSString* prior = vp->toString();
JSString* str = prior;
DoTracing(trc, &str, name, i);
if (str != prior)
vp->setString(str);
} else if (vp->isSymbol()) {
JS::Symbol* prior = vp->toSymbol();
JS::Symbol* sym = prior;
DoTracing(trc, &sym, name, i);
if (sym != prior)
vp->setSymbol(sym);
} else {
/* Unset realLocation manually if we do not call MarkInternal. */
trc->unsetTracingLocation();
}
}
template <>
void
DoTracing<jsid>(JS::CallbackTracer* trc, jsid* idp, const char* name, size_t i)
{
if (JSID_IS_STRING(*idp)) {
JSString* prior = JSID_TO_STRING(*idp);
JSString* str = prior;
DoTracing(trc, &str, name, i);
if (str != prior)
*idp = NON_INTEGER_ATOM_TO_JSID(reinterpret_cast<JSAtom*>(str));
} else if (JSID_IS_SYMBOL(*idp)) {
JS::Symbol* prior = JSID_TO_SYMBOL(*idp);
JS::Symbol* sym = prior;
DoTracing(trc, &sym, name, i);
if (sym != prior)
*idp = SYMBOL_TO_JSID(sym);
} else {
/* Unset realLocation manually if we do not call MarkInternal. */
trc->unsetTracingLocation();
}
}
template<typename T>
static void
MarkInternal(JSTracer* trc, T** thingp)
{
T* thing = *thingp;
CheckMarkedThing(trc, thing);
if (trc->isMarkingTracer()) {
/*
* We may mark a Nursery thing outside the context of the
* MinorCollectionTracer because of a pre-barrier. The pre-barrier is
* not needed in this case because we perform a minor collection before
* each incremental slice.
*/
if (IsInsideNursery(thing))
return;
/*
* Don't mark permanent atoms, as they may be associated with another
* runtime. Note that PushMarkStack() also checks this, but the tests
* and maybeAlive write below should only be done on the main thread.
*/
if (ThingIsPermanentAtomOrWellKnownSymbol(thing))
return;
/*
* Don't mark things outside a compartment if we are in a
* per-compartment GC.
*/
if (!thing->zone()->isGCMarking())
return;
PushMarkStack(AsGCMarker(trc), thing);
SetMaybeAliveFlag(thing);
} else {
trc->asCallbackTracer()->invoke((void**)thingp, MapTypeToTraceKind<T>::kind);
trc->unsetTracingLocation();
}
trc->clearTracingDetails();
}
namespace js {
@ -666,24 +515,17 @@ namespace gc {
void
MarkPermanentAtom(JSTracer* trc, JSAtom* atom, const char* name)
{
trc->setTracingName(name);
MOZ_ASSERT(atom->isPermanent());
// We have to mark permanent atoms through a special method because the
// default DoMarking implementation automatically skips them. Fortunatly,
// atoms cannot refer to other GC things, so they do not need to go through
// the mark stack and may simply be marked directly.
CheckMarkedThing(trc, atom);
if (trc->isMarkingTracer()) {
// Atoms do not refer to other GC things so don't need to go on the mark stack.
// Additionally, PushMarkStack will ignore permanent atoms.
if (trc->isMarkingTracer())
atom->markIfUnmarked();
} else {
void* thing = atom;
trc->asCallbackTracer()->invoke(&thing, JSTRACE_STRING);
MOZ_ASSERT(thing == atom);
trc->unsetTracingLocation();
}
trc->clearTracingDetails();
else
DoCallback(trc->asCallbackTracer(), reinterpret_cast<JSString**>(&atom), name);
}
void
@ -691,23 +533,17 @@ MarkWellKnownSymbol(JSTracer* trc, JS::Symbol* sym)
{
if (!sym)
return;
trc->setTracingName("wellKnownSymbols");
MOZ_ASSERT(sym->isWellKnownSymbol());
// As per permanent atoms, the normal marking path is not adequate.
CheckMarkedThing(trc, sym);
if (trc->isMarkingTracer()) {
// Permanent atoms are marked before well-known symbols.
MOZ_ASSERT(sym->description()->isMarked());
sym->markIfUnmarked();
} else {
void* thing = sym;
trc->asCallbackTracer()->invoke(&thing, JSTRACE_SYMBOL);
MOZ_ASSERT(thing == sym);
trc->unsetTracingLocation();
DoCallback(trc->asCallbackTracer(), &sym, "wellKnownSymbol");
}
trc->clearTracingDetails();
}
template <typename T>
@ -974,38 +810,6 @@ js::gc::TraceManuallyBarrieredGenericPointerEdge(JSTracer* trc, Cell** thingp, c
CallTyped(f, (*thingp)->getTraceKind(), trc, thingp, name);
}
/*** Value Marking ***/
static inline void
MarkValueInternal(JSTracer* trc, Value* v)
{
if (v->isMarkable()) {
MOZ_ASSERT(v->toGCThing());
void* thing = v->toGCThing();
trc->setTracingLocation((void*)v);
if (v->isString()) {
JSString* str = static_cast<JSString*>(thing);
MarkInternal(trc, &str);
if (str != thing)
v->setString(str);
} else if (v->isObject()) {
JSObject* obj = static_cast<JSObject*>(thing);
MarkInternal(trc, &obj);
if (obj != thing)
v->setObjectOrNull(obj);
} else {
MOZ_ASSERT(v->isSymbol());
JS::Symbol* sym = static_cast<JS::Symbol*>(thing);
MarkInternal(trc, &sym);
if (sym != thing)
v->setSymbol(sym);
}
} else {
/* Unset realLocation manually if we do not call MarkInternal. */
trc->unsetTracingLocation();
}
}
/*** Type Marking ***/
void
@ -1018,14 +822,13 @@ TypeSet::MarkTypeRoot(JSTracer* trc, TypeSet::Type* v, const char* name)
void
TypeSet::MarkTypeUnbarriered(JSTracer* trc, TypeSet::Type* v, const char* name)
{
trc->setTracingName(name);
if (v->isSingletonUnchecked()) {
JSObject* obj = v->singleton();
MarkInternal(trc, &obj);
DispatchToTracer(trc, &obj, name);
*v = TypeSet::ObjectType(obj);
} else if (v->isGroupUnchecked()) {
ObjectGroup* group = v->group();
MarkInternal(trc, &group);
DispatchToTracer(trc, &group, name);
*v = TypeSet::ObjectType(group);
}
}
@ -1035,10 +838,12 @@ TypeSet::MarkTypeUnbarriered(JSTracer* trc, TypeSet::Type* v, const char* name)
void
gc::MarkObjectSlots(JSTracer* trc, NativeObject* obj, uint32_t start, uint32_t nslots)
{
MOZ_ASSERT(obj->isNative());
JS::AutoTracingIndex index(trc, start);
for (uint32_t i = start; i < (start + nslots); ++i) {
trc->setTracingDetails(GetObjectSlotName, obj, i);
MarkValueInternal(trc, obj->getSlotRef(i).unsafeGet());
HeapSlot& slot = obj->getSlotRef(i);
if (InternalGCMethods<Value>::isMarkable(slot))
DispatchToTracer(trc, slot.unsafeGet(), "object slot");
++index;
}
}
@ -1143,7 +948,7 @@ static inline void
ScanBaseShape(GCMarker* gcmarker, BaseShape* base);
void
BaseShape::markChildren(JSTracer* trc)
BaseShape::traceChildren(JSTracer* trc)
{
if (isOwned())
TraceEdge(trc, &unowned_, "base");
@ -1413,40 +1218,40 @@ ScanObjectGroup(GCMarker* gcmarker, ObjectGroup* group)
gcmarker->traverse(fun);
}
static void
gc::MarkChildren(JSTracer* trc, ObjectGroup* group)
void
js::ObjectGroup::traceChildren(JSTracer* trc)
{
unsigned count = group->getPropertyCount();
unsigned count = getPropertyCount();
for (unsigned i = 0; i < count; i++) {
if (ObjectGroup::Property* prop = group->getProperty(i))
if (ObjectGroup::Property* prop = getProperty(i))
TraceEdge(trc, &prop->id, "group_property");
}
if (group->proto().isObject())
TraceEdge(trc, &group->protoRaw(), "group_proto");
if (proto().isObject())
TraceEdge(trc, &protoRaw(), "group_proto");
if (group->newScript())
group->newScript()->trace(trc);
if (newScript())
newScript()->trace(trc);
if (group->maybePreliminaryObjects())
group->maybePreliminaryObjects()->trace(trc);
if (maybePreliminaryObjects())
maybePreliminaryObjects()->trace(trc);
if (group->maybeUnboxedLayout())
group->unboxedLayout().trace(trc);
if (maybeUnboxedLayout())
unboxedLayout().trace(trc);
if (ObjectGroup* unboxedGroup = group->maybeOriginalUnboxedGroup()) {
if (ObjectGroup* unboxedGroup = maybeOriginalUnboxedGroup()) {
TraceManuallyBarrieredEdge(trc, &unboxedGroup, "group_original_unboxed_group");
group->setOriginalUnboxedGroup(unboxedGroup);
setOriginalUnboxedGroup(unboxedGroup);
}
if (JSObject* descr = group->maybeTypeDescr()) {
if (JSObject* descr = maybeTypeDescr()) {
TraceManuallyBarrieredEdge(trc, &descr, "group_type_descr");
group->setTypeDescr(&descr->as<TypeDescr>());
setTypeDescr(&descr->as<TypeDescr>());
}
if (JSObject* fun = group->maybeInterpretedFunction()) {
if (JSObject* fun = maybeInterpretedFunction()) {
TraceManuallyBarrieredEdge(trc, &fun, "group_function");
group->setInterpretedFunction(&fun->as<JSFunction>());
setInterpretedFunction(&fun->as<JSFunction>());
}
}
@ -1625,7 +1430,7 @@ GCMarker::processMarkStackOther(uintptr_t tag, uintptr_t addr)
else
repush(obj);
} else if (tag == JitCodeTag) {
reinterpret_cast<jit::JitCode*>(addr)->trace(this);
reinterpret_cast<jit::JitCode*>(addr)->traceChildren(this);
}
}
@ -1888,54 +1693,24 @@ GCMarker::drainMarkStack(SliceBudget& budget)
template <typename T>
void
GCMarker::markChildren(T* thing)
GCMarker::dispatchToTraceChildren(T* thing)
{
thing->markChildren(this);
thing->traceChildren(this);
}
struct TraceChildrenFunctor {
template <typename T>
void operator()(JSTracer* trc, void* thing) {
static_cast<T*>(thing)->traceChildren(trc);
}
};
void
js::TraceChildren(JSTracer* trc, void* thing, JSGCTraceKind kind)
{
switch (kind) {
case JSTRACE_OBJECT:
static_cast<JSObject*>(thing)->markChildren(trc);
break;
case JSTRACE_SCRIPT:
static_cast<JSScript*>(thing)->markChildren(trc);
break;
case JSTRACE_STRING:
static_cast<JSString*>(thing)->markChildren(trc);
break;
case JSTRACE_SYMBOL:
static_cast<JS::Symbol*>(thing)->markChildren(trc);
break;
case JSTRACE_BASE_SHAPE:
static_cast<BaseShape*>(thing)->markChildren(trc);
break;
case JSTRACE_JITCODE:
static_cast<jit::JitCode*>(thing)->trace(trc);
break;
case JSTRACE_LAZY_SCRIPT:
static_cast<LazyScript*>(thing)->markChildren(trc);
break;
case JSTRACE_SHAPE:
static_cast<Shape*>(thing)->markChildren(trc);
break;
case JSTRACE_OBJECT_GROUP:
MarkChildren(trc, (ObjectGroup*)thing);
break;
default:
MOZ_CRASH("Invalid trace kind in TraceChildren.");
}
MOZ_ASSERT(thing);
TraceChildrenFunctor f;
CallTyped(f, kind, trc, thing);
}
#ifdef DEBUG

Просмотреть файл

@ -77,14 +77,6 @@ IsNullTaggedPointer(void* p)
/*** Externally Typed Marking ***/
/*
* Note: this must only be called by the GC and only when we are tracing through
* MarkRoots. It is explicitly for ConservativeStackMarking and should go away
* after we transition to exact rooting.
*/
void
MarkKind(JSTracer* trc, void** thingp, JSGCTraceKind kind);
void
TraceGenericPointerRoot(JSTracer* trc, Cell** thingp, const char* name);
@ -167,7 +159,7 @@ class HashKeyRef : public BufferableRef
typename Map::Ptr p = map->lookup(key);
if (!p)
return;
trc->setTracingLocation(&*p);
JS::AutoOriginalTraceLocation reloc(trc, (void**)&*p);
TraceManuallyBarrieredEdge(trc, &key, "HashKeyRef");
map->rekeyIfMoved(prior, key);
}

Просмотреть файл

@ -221,8 +221,8 @@ AutoGCRooter::trace(JSTracer* trc)
AutoObjectObjectHashMap::HashMapImpl& map = static_cast<AutoObjectObjectHashMap*>(this)->map;
for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) {
TraceRoot(trc, &e.front().value(), "AutoObjectObjectHashMap value");
trc->setTracingLocation((void*)&e.front().key());
JSObject* key = e.front().key();
JS::AutoOriginalTraceLocation reloc(trc, &e.front().key());
TraceRoot(trc, &key, "AutoObjectObjectHashMap key");
if (key != e.front().key())
e.rekeyFront(key);
@ -583,21 +583,14 @@ struct SetMaybeAliveFunctor {
};
void
BufferGrayRootsTracer::appendGrayRoot(Cell* thing, JSGCTraceKind kind)
BufferGrayRootsTracer::appendGrayRoot(TenuredCell* thing, JSGCTraceKind kind)
{
MOZ_ASSERT(runtime()->isHeapBusy());
if (bufferingGrayRootsFailed)
return;
GrayRoot root(thing, kind);
#ifdef DEBUG
root.debugPrinter = debugPrinter();
root.debugPrintArg = debugPrintArg();
root.debugPrintIndex = debugPrintIndex();
#endif
Zone* zone = TenuredCell::fromPointer(thing)->zone();
Zone* zone = thing->zone();
if (zone->isCollecting()) {
// See the comment on SetMaybeAliveFlag to see why we only do this for
// objects and scripts. We rely on gray root buffering for this to work,
@ -605,7 +598,7 @@ BufferGrayRootsTracer::appendGrayRoot(Cell* thing, JSGCTraceKind kind)
// incremental GCs (when we do gray root buffering).
CallTyped(SetMaybeAliveFunctor(), kind, thing);
if (!zone->gcGrayRoots.append(root))
if (!zone->gcGrayRoots.append(thing))
bufferingGrayRootsFailed = true;
}
}
@ -616,13 +609,8 @@ GCRuntime::markBufferedGrayRoots(JS::Zone* zone)
MOZ_ASSERT(grayBufferState == GrayBufferState::Okay);
MOZ_ASSERT(zone->isGCMarkingGray() || zone->isGCCompacting());
for (GrayRoot* elem = zone->gcGrayRoots.begin(); elem != zone->gcGrayRoots.end(); elem++) {
#ifdef DEBUG
marker.setTracingDetails(elem->debugPrinter, elem->debugPrintArg, elem->debugPrintIndex);
#endif
TraceManuallyBarrieredGenericPointerEdge(&marker, reinterpret_cast<Cell**>(&elem->thing),
"buffered gray root");
}
for (auto cell : zone->gcGrayRoots)
TraceManuallyBarrieredGenericPointerEdge(&marker, &cell, "buffered gray root");
}
void

Просмотреть файл

@ -55,11 +55,11 @@ StoreBuffer::WholeCellEdges::mark(JSTracer* trc) const
JSObject* object = static_cast<JSObject*>(edge);
if (object->is<ArgumentsObject>())
ArgumentsObject::trace(trc, object);
object->markChildren(trc);
object->traceChildren(trc);
return;
}
MOZ_ASSERT(kind == JSTRACE_JITCODE);
static_cast<jit::JitCode*>(edge)->trace(trc);
static_cast<jit::JitCode*>(edge)->traceChildren(trc);
}
void

Просмотреть файл

@ -29,6 +29,63 @@ using namespace js;
using namespace js::gc;
using mozilla::DebugOnly;
template <typename T>
void
DoCallback(JS::CallbackTracer* trc, T* thingp, const char* name)
{
JSGCTraceKind kind = MapTypeToTraceKind<typename mozilla::RemovePointer<T>::Type>::kind;
JS::AutoTracingName ctx(trc, name);
trc->invoke((void**)thingp, kind);
}
#define INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS(name, type) \
template void DoCallback<type*>(JS::CallbackTracer*, type**, const char*);
FOR_EACH_GC_LAYOUT(INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS);
#undef INSTANTIATE_ALL_VALID_TRACE_FUNCTIONS
template <>
void
DoCallback<Value>(JS::CallbackTracer* trc, Value* vp, const char* name)
{
if (vp->isObject()) {
JSObject* prior = &vp->toObject();
JSObject* obj = prior;
DoCallback(trc, &obj, name);
if (obj != prior)
vp->setObjectOrNull(obj);
} else if (vp->isString()) {
JSString* prior = vp->toString();
JSString* str = prior;
DoCallback(trc, &str, name);
if (str != prior)
vp->setString(str);
} else if (vp->isSymbol()) {
JS::Symbol* prior = vp->toSymbol();
JS::Symbol* sym = prior;
DoCallback(trc, &sym, name);
if (sym != prior)
vp->setSymbol(sym);
}
}
template <>
void
DoCallback<jsid>(JS::CallbackTracer* trc, jsid* idp, const char* name)
{
if (JSID_IS_STRING(*idp)) {
JSString* prior = JSID_TO_STRING(*idp);
JSString* str = prior;
DoCallback(trc, &str, name);
if (str != prior)
*idp = NON_INTEGER_ATOM_TO_JSID(reinterpret_cast<JSAtom*>(str));
} else if (JSID_IS_SYMBOL(*idp)) {
JS::Symbol* prior = JSID_TO_SYMBOL(*idp);
JS::Symbol* sym = prior;
DoCallback(trc, &sym, name);
if (sym != prior)
*idp = SYMBOL_TO_JSID(sym);
}
}
JS_PUBLIC_API(void)
JS_CallUnbarrieredValueTracer(JSTracer* trc, Value* valuep, const char* name)
{
@ -102,7 +159,7 @@ JS_CallTenuredObjectTracer(JSTracer* trc, JS::TenuredHeap<JSObject*>* objp, cons
if (!obj)
return;
trc->setTracingLocation((void*)objp);
JS::AutoOriginalTraceLocation reloc(trc, (void**)objp);
TraceManuallyBarrieredEdge(trc, &obj, name);
objp->setPtr(obj);
@ -329,61 +386,22 @@ JSTracer::JSTracer(JSRuntime* rt, TracerKindTag kindTag,
WeakMapTraceKind weakTraceKind /* = TraceWeakMapValues */)
: runtime_(rt)
, tag(kindTag)
, debugPrinter_(nullptr)
, debugPrintArg_(nullptr)
, debugPrintIndex_(size_t(-1))
, eagerlyTraceWeakMaps_(weakTraceKind)
#ifdef JS_GC_ZEAL
, realLocation_(nullptr)
#endif
{
}
bool
JSTracer::hasTracingDetails() const
{
return debugPrinter_ || debugPrintArg_;
}
const char*
JSTracer::tracingName(const char* fallback) const
JS::CallbackTracer::getTracingEdgeName(char* buffer, size_t bufferSize)
{
MOZ_ASSERT(hasTracingDetails());
return debugPrinter_ ? fallback : (const char*)debugPrintArg_;
}
const char*
JSTracer::getTracingEdgeName(char* buffer, size_t bufferSize)
{
if (debugPrinter_) {
debugPrinter_(this, buffer, bufferSize);
if (contextFunctor_) {
(*contextFunctor_)(this, buffer, bufferSize);
return buffer;
}
if (debugPrintIndex_ != size_t(-1)) {
JS_snprintf(buffer, bufferSize, "%s[%lu]",
(const char*)debugPrintArg_,
debugPrintIndex_);
if (contextIndex_ != InvalidIndex) {
JS_snprintf(buffer, bufferSize, "%s[%lu]", contextName_, contextIndex_);
return buffer;
}
return (const char*)debugPrintArg_;
}
JSTraceNamePrinter
JSTracer::debugPrinter() const
{
return debugPrinter_;
}
const void*
JSTracer::debugPrintArg() const
{
return debugPrintArg_;
}
size_t
JSTracer::debugPrintIndex() const
{
return debugPrintIndex_;
return contextName_;
}
void
@ -392,27 +410,6 @@ JS::CallbackTracer::setTraceCallback(JSTraceCallback traceCallback)
callback = traceCallback;
}
#ifdef JS_GC_ZEAL
void
JSTracer::setTracingLocation(void* location)
{
if (!realLocation_ || !location)
realLocation_ = location;
}
void
JSTracer::unsetTracingLocation()
{
realLocation_ = nullptr;
}
void**
JSTracer::tracingLocation(void** thingp)
{
return realLocation_ ? (void**)realLocation_ : thingp;
}
#endif
bool
MarkStack::init(JSGCMode gcMode)
{

Просмотреть файл

@ -253,11 +253,12 @@ class GCMarker : public JSTracer
template <typename T>
void markAndTraverse(T* thing) {
if (mark(thing))
markChildren(thing);
dispatchToTraceChildren(thing);
}
// We may not have concrete types yet, so this has to be out of the header.
template <typename T>
void markChildren(T* thing);
void dispatchToTraceChildren(T* thing);
// Mark the given GC thing, but do not trace its children. Return true
// if the thing became marked.
@ -304,8 +305,6 @@ class GCMarker : public JSTracer
void markAndScanString(JSObject* source, JSString* str);
void markAndScanSymbol(JSObject* source, JS::Symbol* sym);
void appendGrayRoot(void* thing, JSGCTraceKind kind);
/* The color is only applied to objects and functions. */
uint32_t color;
@ -332,7 +331,7 @@ class BufferGrayRootsTracer : public JS::CallbackTracer
// Set to false if we OOM while buffering gray roots.
bool bufferingGrayRootsFailed;
void appendGrayRoot(gc::Cell* thing, JSGCTraceKind kind);
void appendGrayRoot(gc::TenuredCell* thing, JSGCTraceKind kind);
public:
explicit BufferGrayRootsTracer(JSRuntime* rt)
@ -340,8 +339,8 @@ class BufferGrayRootsTracer : public JS::CallbackTracer
{}
static void grayTraceCallback(JS::CallbackTracer* trc, void** thingp, JSGCTraceKind kind) {
static_cast<BufferGrayRootsTracer*>(trc)->appendGrayRoot(static_cast<gc::Cell*>(*thingp),
kind);
auto tracer = static_cast<BufferGrayRootsTracer*>(trc);
tracer->appendGrayRoot(gc::TenuredCell::fromPointer(*thingp), kind);
}
bool failed() const { return bufferingGrayRootsFailed; }

Просмотреть файл

@ -133,7 +133,7 @@ AccumulateEdge(JS::CallbackTracer* jstrc, void** thingp, JSGCTraceKind kind)
node->edges[i].thing = *thingp;
node->edges[i].kind = kind;
node->edges[i].label = trc->tracingName("<unknown>");
node->edges[i].label = trc->contextName();
node->count++;
}
@ -312,9 +312,7 @@ AssertMarkedOrAllocated(const EdgeValue& edge)
return;
char msgbuf[1024];
const char* label = edge.label;
JS_snprintf(msgbuf, sizeof(msgbuf), "[barrier verifier] Unmarked edge: %s", label);
JS_snprintf(msgbuf, sizeof(msgbuf), "[barrier verifier] Unmarked edge: %s", edge.label);
MOZ_ReportAssertionFailure(msgbuf, __FILE__, __LINE__);
MOZ_CRASH();
}
@ -389,7 +387,7 @@ struct VerifyPostTracer : JS::CallbackTracer
int count;
/* The set of edges in the StoreBuffer at the end of verification. */
typedef HashSet<void**, PointerHasher<void**, 3>, SystemAllocPolicy> EdgeSet;
typedef HashSet<void*const*, PointerHasher<void*const*, 3>, SystemAllocPolicy> EdgeSet;
EdgeSet* edges;
VerifyPostTracer(JSRuntime* rt, JSTraceCallback callback)
@ -438,13 +436,13 @@ PostVerifierCollectStoreBufferEdges(JS::CallbackTracer* jstrc, void** thingp, JS
* only things that enter this callback are marked by the store buffer. The
* store buffer ensures that the real tracing location is set correctly.
*/
void** loc = trc->tracingLocation(thingp);
void*const* loc = trc->tracingLocation(thingp);
trc->edges->put(loc);
}
static void
AssertStoreBufferContainsEdge(VerifyPostTracer::EdgeSet* edges, void** loc, JSObject* dst)
AssertStoreBufferContainsEdge(VerifyPostTracer::EdgeSet* edges, void*const* loc, JSObject* dst)
{
if (edges->has(loc))
return;
@ -477,7 +475,7 @@ PostVerifierVisitEdge(JS::CallbackTracer* jstrc, void** thingp, JSGCTraceKind ki
* below. Since JSObject::markChildren handles this, the real trace
* location will be set correctly in these cases.
*/
void** loc = trc->tracingLocation(thingp);
void*const* loc = trc->tracingLocation(thingp);
AssertStoreBufferContainsEdge(trc->edges, loc, dst);
}

Просмотреть файл

@ -248,7 +248,7 @@ struct Zone : public JS::shadow::Zone,
CompartmentVector compartments;
// This compartment's gray roots.
typedef js::Vector<js::GrayRoot, 0, js::SystemAllocPolicy> GrayRootVector;
typedef js::Vector<js::gc::Cell*, 0, js::SystemAllocPolicy> GrayRootVector;
GrayRootVector gcGrayRoots;
// A set of edges from this zone to other zones.

Просмотреть файл

@ -639,7 +639,7 @@ JitCode::copyFrom(MacroAssembler& masm)
}
void
JitCode::trace(JSTracer* trc)
JitCode::traceChildren(JSTracer* trc)
{
// Note that we cannot mark invalidated scripts, since we've basically
// corrupted the code stream by injecting bailouts.
@ -2610,7 +2610,7 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool
// embedded in the JitCode. Perform one final trace of the
// JitCode for the incremental GC, as it must know about
// those edges.
ionCode->trace(zone->barrierTracer());
ionCode->traceChildren(zone->barrierTracer());
}
ionCode->setInvalidated();

Просмотреть файл

@ -107,7 +107,7 @@ class JitCode : public gc::TenuredCell
size_t instructionsSize() const {
return insnSize_;
}
void trace(JSTracer* trc);
void traceChildren(JSTracer* trc);
void finalize(FreeOp* fop);
void fixupAfterMovingGC() {}
void setInvalidated() {

Просмотреть файл

@ -5059,6 +5059,7 @@ enum AsmJSCacheResult
AsmJSCache_ModuleTooSmall,
AsmJSCache_SynchronousScript,
AsmJSCache_QuotaExceeded,
AsmJSCache_StorageInitFailure,
AsmJSCache_Disabled_Internal,
AsmJSCache_Disabled_ShellFlags,
AsmJSCache_Disabled_JitInspector,

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше