Merge m-c to fx-team

This commit is contained in:
Wes Kocher 2014-07-07 16:39:00 -07:00
commit 1c27a70a5e
123 changed files with 1839 additions and 820 deletions

View File

@ -26,7 +26,7 @@ function hookScreen(window) {
let nodePrincipal = window.document.nodePrincipal;
let origin = nodePrincipal.origin;
if (nodePrincipal.appStatus == nodePrincipal.APP_STATUS_NOT_INSTALLED) {
Cu.reportError('deny mozLockOrientation:' + origin + 'is not installed');
// Only inject screen mock for apps
return;
}

View File

@ -19,12 +19,12 @@
<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="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="bf9aaf39dd5a6491925a022db167c460f8207d34"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>

View File

@ -17,9 +17,9 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
@ -131,6 +131,6 @@
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="efd87a5797ca40fa2df256630c07e0dfb2f762dc"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="832f4acaf481a19031e479a40b03d9ce5370ddee"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="dd72bacb432efc5135a1f747d00aab91f898bddb"/>
<project name="android-sdk" path="sdk" remote="b2g" revision="8b1365af38c9a653df97349ee53a3f5d64fd590a"/>
</manifest>

View File

@ -15,11 +15,11 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>

View File

@ -19,12 +19,12 @@
<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="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="bf9aaf39dd5a6491925a022db167c460f8207d34"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>

View File

@ -17,9 +17,9 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
@ -143,7 +143,7 @@
<project name="platform/hardware/ril" path="hardware/ril" revision="c4e2ac95907a5519a0e09f01a0d8e27fec101af0"/>
<project name="platform/system/bluetooth" path="system/bluetooth" revision="e1eb226fa3ad3874ea7b63c56a9dc7012d7ff3c2"/>
<project name="platform/system/core" path="system/core" revision="bbf7212289fc8311e43f9d11e10788e310d36a08"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="dd72bacb432efc5135a1f747d00aab91f898bddb"/>
<project name="platform/system/qcom" path="system/qcom" revision="1cdab258b15258b7f9657da70e6f06ebd5a2fc25"/>
<project name="platform/vendor/qcom/msm8610" path="device/qcom/msm8610" revision="4ae5df252123591d5b941191790e7abed1bce5a4"/>
<project name="platform/vendor/qcom-opensource/wlan/prima" path="vendor/qcom/opensource/wlan/prima" revision="ce18b47b4a4f93a581d672bbd5cb6d12fe796ca9"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "278dd1b102a39cf2c48f11fe3038eaf8f0779d7d",
"revision": "02f96bd32a7d77bc1684f3ca745f0e810871159b",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,11 +17,11 @@
<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="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -15,11 +15,11 @@
<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="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->
<project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>

View File

@ -17,9 +17,9 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
@ -127,7 +127,7 @@
<project name="device-mako" path="device/lge/mako" remote="b2g" revision="78d17f0c117f0c66dd55ee8d5c5dde8ccc93ecba"/>
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="3a9a17613cc685aa232432566ad6cc607eab4ec1"/>
<project name="device/lge/mako-kernel" path="device/lge/mako-kernel" revision="d1729e53d71d711c8fde25eab8728ff2b9b4df0e"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="d0aa65b140a45016975ed0ecf35f280dd336e1d3"/>
<project name="platform_system_nfcd" path="system/nfcd" remote="b2g" revision="dd72bacb432efc5135a1f747d00aab91f898bddb"/>
<project name="platform/external/libnfc-nci" path="external/libnfc-nci" revision="7d33aaf740bbf6c7c6e9c34a92b371eda311b66b"/>
<project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="0e56e450367cd802241b27164a2979188242b95f"/>
<project name="platform/hardware/broadcom/wlan" path="hardware/broadcom/wlan" revision="0e1929fa3aa38bf9d40e9e953d619fab8164c82e"/>

View File

@ -17,11 +17,11 @@
<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="99f56d9db3cd37c684b01de6fed786421f47e2b7"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="1dc9e53393ae4680a174dffa44a958ec564ebbe8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="96cdde4b5b5d8d3785b36c3c68cd746aff3005cc"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="7f9ec13a30f1b2cc8bdb1a199b7da54b9ab8860f"/>
<project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
<!-- Stock Android things -->

View File

@ -264,6 +264,7 @@ Toolbox.prototype = {
// Load the toolbox-level actor fronts and utilities now
this._target.makeRemote().then(() => {
iframe.setAttribute("src", this._URL);
iframe.setAttribute("aria-label", toolboxStrings("toolbox.label"))
let domHelper = new DOMHelpers(iframe.contentWindow);
domHelper.onceDOMReady(domReady);
});
@ -814,6 +815,9 @@ Toolbox.prototype = {
};
iframe.setAttribute("src", definition.url);
if (definition.panelLabel) {
iframe.setAttribute("aria-label", definition.panelLabel);
}
// Depending on the host, iframe.contentWindow is not always
// defined at this moment. If it is not defined, we use an

View File

@ -70,6 +70,7 @@ Tools.options = {
icon: "chrome://browser/skin/devtools/tool-options.svg",
invertIconForLightTheme: true,
bgTheme: "theme-body",
panelLabel: l10n("options.panelLabel", toolboxStrings),
tooltip: l10n("optionsButton.tooltip", toolboxStrings),
inMenu: false,
isTargetSupported: function(target) {
@ -92,6 +93,7 @@ Tools.webConsole = {
url: "chrome://browser/content/devtools/webconsole.xul",
label: l10n("ToolboxTabWebconsole.label", webConsoleStrings),
menuLabel: l10n("MenuWebconsole.label", webConsoleStrings),
panelLabel: l10n("ToolboxWebConsole.panelLabel", webConsoleStrings),
tooltip: l10n("ToolboxWebconsole.tooltip", webConsoleStrings),
inMenu: true,
commands: "devtools/webconsole/console-commands",
@ -123,6 +125,7 @@ Tools.inspector = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/inspector/inspector.xul",
label: l10n("inspector.label", inspectorStrings),
panelLabel: l10n("inspector.panelLabel", inspectorStrings),
tooltip: l10n("inspector.tooltip", inspectorStrings),
inMenu: true,
commands: [
@ -157,6 +160,7 @@ Tools.jsdebugger = {
highlightedicon: "chrome://browser/skin/devtools/tool-debugger-paused.svg",
url: "chrome://browser/content/devtools/debugger.xul",
label: l10n("ToolboxDebugger.label", debuggerStrings),
panelLabel: l10n("ToolboxDebugger.panelLabel", debuggerStrings),
tooltip: l10n("ToolboxDebugger.tooltip", debuggerStrings),
inMenu: true,
commands: "devtools/debugger/debugger-commands",
@ -181,6 +185,7 @@ Tools.styleEditor = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/styleeditor.xul",
label: l10n("ToolboxStyleEditor.label", styleEditorStrings),
panelLabel: l10n("ToolboxStyleEditor.panelLabel", styleEditorStrings),
tooltip: l10n("ToolboxStyleEditor.tooltip2", styleEditorStrings),
inMenu: true,
commands: "devtools/styleeditor/styleeditor-commands",
@ -203,6 +208,7 @@ Tools.shaderEditor = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/shadereditor.xul",
label: l10n("ToolboxShaderEditor.label", shaderEditorStrings),
panelLabel: l10n("ToolboxShaderEditor.panelLabel", shaderEditorStrings),
tooltip: l10n("ToolboxShaderEditor.tooltip", shaderEditorStrings),
isTargetSupported: function(target) {
@ -223,6 +229,7 @@ Tools.canvasDebugger = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/canvasdebugger.xul",
label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings),
panelLabel: l10n("ToolboxCanvasDebugger.panelLabel", canvasDebuggerStrings),
tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings),
isTargetSupported: function(target) {
return !target.isAddon;
@ -241,6 +248,7 @@ Tools.webAudioEditor = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/webaudioeditor.xul",
label: l10n("ToolboxWebAudioEditor1.label", webAudioEditorStrings),
panelLabel: l10n("ToolboxWebAudioEditor1.panelLabel", webAudioEditorStrings),
tooltip: l10n("ToolboxWebAudioEditor1.tooltip", webAudioEditorStrings),
isTargetSupported: function(target) {
return !target.isAddon;
@ -262,6 +270,7 @@ Tools.jsprofiler = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/profiler.xul",
label: l10n("profiler.label", profilerStrings),
panelLabel: l10n("profiler.panelLabel", profilerStrings),
tooltip: l10n("profiler.tooltip2", profilerStrings),
inMenu: true,
commands: "devtools/profiler/commands",
@ -287,6 +296,7 @@ Tools.netMonitor = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/netmonitor.xul",
label: l10n("netmonitor.label", netMonitorStrings),
panelLabel: l10n("netmonitor.panelLabel", netMonitorStrings),
tooltip: l10n("netmonitor.tooltip", netMonitorStrings),
inMenu: true,
@ -309,6 +319,7 @@ Tools.scratchpad = {
invertIconForLightTheme: true,
url: "chrome://browser/content/devtools/scratchpad.xul",
label: l10n("scratchpad.label", scratchpadStrings),
panelLabel: l10n("scratchpad.panelLabel", scratchpadStrings),
tooltip: l10n("scratchpad.tooltip", scratchpadStrings),
inMenu: false,
commands: "devtools/scratchpad/scratchpad-commands",

View File

@ -15,6 +15,10 @@
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxCanvasDebugger.label=Canvas
# LOCALIZATION NOTE (ToolboxCanvasDebugger.panelLabel):
# This is used as the label for the toolbox panel.
ToolboxCanvasDebugger.panelLabel=Canvas Panel
# LOCALIZATION NOTE (ToolboxCanvasDebugger.tooltip):
# This string is displayed in the tooltip of the tab when the Shader Editor is
# displayed inside the developer tools window.

View File

@ -15,6 +15,10 @@
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxDebugger.label=Debugger
# LOCALIZATION NOTE (ToolboxDebugger.panelLabel):
# This is used as the label for the toolbox panel.
ToolboxDebugger.panelLabel=Debugger Panel
# LOCALIZATION NOTE (DebuggerWindowTitle):
# The title displayed for the debugger window.
DebuggerWindowTitle=Browser Debugger

View File

@ -36,6 +36,7 @@ nodeMenu.tooltiptext=Node operations
inspector.label=Inspector
inspector.commandkey=C
inspector.accesskey=I
inspector.panelLabel=Inspector Panel
# LOCALIZATION NOTE (markupView.more.*)
# When there are too many nodes to load at once, we will offer to

View File

@ -15,6 +15,10 @@
# displayed inside the developer tools window and in the Developer Tools Menu.
netmonitor.label=Network
# LOCALIZATION NOTE (netmonitor.panelLabel):
# This is used as the label for the toolbox panel.
netmonitor.panelLabel=Network Panel
# LOCALIZATION NOTE (netmonitor.commandkey, netmonitor.accesskey)
# Used for the menuitem in the tool menu
netmonitor.commandkey=Q

View File

@ -15,6 +15,10 @@
# displayed inside the developer tools window and in the Developer Tools Menu.
profiler.label=Profiler
# LOCALIZATION NOTE (profiler.panelLabel):
# This is used as the label for the toolbox panel.
profiler.panelLabel=Profiler Panel
# LOCALIZATION NOTE (profiler2.commandkey, profiler.accesskey)
# Used for the menuitem in the tool menu
profiler2.commandkey=VK_F5

View File

@ -95,6 +95,10 @@ connectionTimeout=Connection timeout. Check the Error Console on both ends for p
# in the Developer Tools Menu.
scratchpad.label=Scratchpad
# LOCALIZATION NOTE (scratchpad.panelLabel): this is used as the
# label for the toolbox panel.
scratchpad.panelLabel=Scratchpad Panel
# LOCALIZATION NOTE (scratchpad.tooltip): This string is displayed in the
# tooltip of the tab when the Scratchpad is displayed inside the developer tools
# window.

View File

@ -15,6 +15,10 @@
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxShaderEditor.label=Shader Editor
# LOCALIZATION NOTE (ToolboxShaderEditor.panelLabel):
# This is used as the label for the toolbox panel.
ToolboxShaderEditor.panelLabel=Shader Editor Panel
# LOCALIZATION NOTE (ToolboxShaderEditor.tooltip):
# This string is displayed in the tooltip of the tab when the Shader Editor is
# displayed inside the developer tools window.

View File

@ -73,6 +73,10 @@ saveStyleSheet.commandkey=S
# displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxStyleEditor.label=Style Editor
# LOCALIZATION NOTE (ToolboxStyleEditor.panelLabel):
# This is used as the label for the toolbox panel.
ToolboxStyleEditor.panelLabel=Style Editor Panel
# LOCALIZATION NOTE (ToolboxStyleEditor.tooltip2):
# This string is displayed in the tooltip of the tab when the style editor is
# displayed inside the developer tools window.

View File

@ -35,10 +35,18 @@ toolbox.titleTemplate=%1$S - %2$S
# name when no tool is selected.
toolbox.defaultTitle=Developer Tools
# LOCALIZATION NOTE (toolbox.label): This is used as the label for the
# toolbox as a whole
toolbox.label=Developer Tools
# LOCALIZATION NOTE (optionsButton.tooltip): This is used as the tooltip
# for the options panel tab.
optionsButton.tooltip=Toolbox Options
# LOCALIZATION NOTE (options.panelLabel): This is used as the label for the
# toolbox panel.
options.panelLabel=Toolbox Options Panel
# LOCALIZATION NOTE (options.toolNotSupported): This is the template
# used to add a * marker to the label for the Options Panel tool checkbox for the
# tool which is not supported for the current toolbox target.

View File

@ -16,6 +16,10 @@
# is displayed inside the developer tools window and in the Developer Tools Menu.
ToolboxWebAudioEditor1.label=Web Audio
# LOCALIZATION NOTE (ToolboxWebAudioEditor1.panelLabel):
# This is used as the label for the toolbox panel.
ToolboxWebAudioEditor1.panelLabel=Web Audio Panel
# LOCALIZATION NOTE (ToolboxWebAudioEditor1.tooltip):
# This string is displayed in the tooltip of the tab when the Web Audio Editor is
# displayed inside the developer tools window.

View File

@ -167,6 +167,10 @@ MenuWebconsole.label=Web Console
# label of the tab in the devtools window.
ToolboxTabWebconsole.label=Console
# LOCALIZATION NOTE (ToolboxWebConsole.panelLabel): the string used as the
# label for the toolbox panel.
ToolboxWebConsole.panelLabel=Console Panel
# LOCALIZATION NOTE (ToolboxWebconsole.tooltip): the string displayed in the
# tooltip of the tab when the Web Console is displayed inside the developer
# tools window.

View File

@ -819,7 +819,7 @@ class Automation(object):
xrePath = None, certPath = None,
debuggerInfo = None, symbolsPath = None,
timeout = -1, maxTime = None, onLaunch = None,
webapprtChrome = False, screenshotOnFail=False, testPath=None):
webapprtChrome = False, screenshotOnFail=False, testPath=None, bisectChunk=None):
"""
Run the app, log the duration it took to execute, return the status code.
Kills the app if it runs for longer than |maxTime| seconds, or outputs nothing for |timeout| seconds.

View File

@ -47,10 +47,12 @@ VideoChunk::~VideoChunk()
void
VideoSegment::AppendFrame(already_AddRefed<Image>&& aImage,
TrackTicks aDuration,
const IntSize& aIntrinsicSize)
const IntSize& aIntrinsicSize,
bool aForceBlack)
{
VideoChunk* chunk = AppendChunk(aDuration);
VideoFrame frame(aImage, ThebesIntSize(aIntrinsicSize));
frame.SetForceBlack(aForceBlack);
chunk->mFrame.TakeFrom(&frame);
}

View File

@ -96,8 +96,10 @@ public:
VideoSegment();
~VideoSegment();
void AppendFrame(already_AddRefed<Image>&& aImage, TrackTicks aDuration,
const IntSize& aIntrinsicSize);
void AppendFrame(already_AddRefed<Image>&& aImage,
TrackTicks aDuration,
const IntSize& aIntrinsicSize,
bool aForceBlack = false);
const VideoFrame* GetFrameAt(TrackTicks aOffset, TrackTicks* aStart = nullptr)
{
VideoChunk* c = FindChunkContaining(aOffset, aStart);

View File

@ -207,8 +207,10 @@ VideoTrackEncoder::AppendVideoSegment(const VideoSegment& aSegment)
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
nsRefPtr<layers::Image> image = chunk.mFrame.GetImage();
mRawSegment.AppendFrame(image.forget(), chunk.GetDuration(),
chunk.mFrame.GetIntrinsicSize().ToIntSize());
mRawSegment.AppendFrame(image.forget(),
chunk.GetDuration(),
chunk.mFrame.GetIntrinsicSize().ToIntSize(),
chunk.mFrame.GetForceBlack());
iter.Next();
}

View File

@ -129,12 +129,12 @@ nsRefPtr<PlanarYCbCrImage> GStreamerReader::GetImageFromBuffer(GstBuffer* aBuffe
data.mYChannel = GST_BUFFER_DATA(aBuffer);
data.mYStride = gst_video_format_get_row_stride(mFormat, 0, mPicture.width);
data.mYSize = gfx::IntSize(data.mYStride,
gst_video_format_get_component_height(mFormat, 0, mPicture.height));
data.mYSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 0, mPicture.width),
gst_video_format_get_component_height(mFormat, 0, mPicture.height));
data.mYSkip = 0;
data.mCbCrStride = gst_video_format_get_row_stride(mFormat, 1, mPicture.width);
data.mCbCrSize = gfx::IntSize(data.mCbCrStride,
gst_video_format_get_component_height(mFormat, 1, mPicture.height));
data.mCbCrSize = gfx::IntSize(gst_video_format_get_component_width(mFormat, 1, mPicture.width),
gst_video_format_get_component_height(mFormat, 1, mPicture.height));
data.mCbChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 1,
mPicture.width, mPicture.height);
data.mCrChannel = data.mYChannel + gst_video_format_get_component_offset(mFormat, 2,

View File

@ -0,0 +1,49 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "VideoSegment.h"
using namespace mozilla;
namespace mozilla {
namespace layer {
class Image;
}
}
TEST(VideoSegment, TestAppendFrameForceBlack)
{
nsRefPtr<layers::Image> testImage = nullptr;
VideoSegment segment;
segment.AppendFrame(testImage.forget(),
mozilla::TrackTicks(90000),
mozilla::gfx::IntSize(640, 480),
true);
VideoSegment::ChunkIterator iter(segment);
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
EXPECT_TRUE(chunk.mFrame.GetForceBlack());
iter.Next();
}
}
TEST(VideoSegment, TestAppendFrameNotForceBlack)
{
nsRefPtr<layers::Image> testImage = nullptr;
VideoSegment segment;
segment.AppendFrame(testImage.forget(),
mozilla::TrackTicks(90000),
mozilla::gfx::IntSize(640, 480));
VideoSegment::ChunkIterator iter(segment);
while (!iter.IsEnded()) {
VideoChunk chunk = *iter;
EXPECT_FALSE(chunk.mFrame.GetForceBlack());
iter.Next();
}
}

View File

@ -4,6 +4,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/MathAlgorithms.h"
#include "nestegg/nestegg.h"
#include "VorbisTrackEncoder.h"
#include "VP8TrackEncoder.h"
#include "WebMWriter.h"
@ -224,3 +227,149 @@ TEST(WebMWriter, FLUSH_NEEDED)
// Have data because the previous cluster is closed.
EXPECT_TRUE(writer.HaveValidCluster());
}
struct WebMioData {
nsTArray<uint8_t> data;
CheckedInt<size_t> offset;
};
static int webm_read(void* aBuffer, size_t aLength, void* aUserData)
{
NS_ASSERTION(aUserData, "aUserData must point to a valid WebMioData");
WebMioData* ioData = static_cast<WebMioData*>(aUserData);
// Check the read length.
if (aLength > ioData->data.Length()) {
NS_ERROR("Invalid read length");
return -1;
}
// Check eos.
if (ioData->offset.value() >= ioData->data.Length()) {
return 0;
}
size_t oldOffset = ioData->offset.value();
ioData->offset += aLength;
if (!ioData->offset.isValid() ||
(ioData->offset.value() > ioData->data.Length())) {
return -1;
}
memcpy(aBuffer, ioData->data.Elements()+oldOffset, aLength);
return 1;
}
static int webm_seek(int64_t aOffset, int aWhence, void* aUserData)
{
NS_ASSERTION(aUserData, "aUserData must point to a valid WebMioData");
WebMioData* ioData = static_cast<WebMioData*>(aUserData);
if (Abs(aOffset) > ioData->data.Length()) {
NS_ERROR("Invalid aOffset");
return -1;
}
switch (aWhence) {
case NESTEGG_SEEK_END:
{
CheckedInt<size_t> tempOffset = ioData->data.Length();
ioData->offset = tempOffset + aOffset;
break;
}
case NESTEGG_SEEK_CUR:
ioData->offset += aOffset;
break;
case NESTEGG_SEEK_SET:
ioData->offset = aOffset;
break;
default:
NS_ERROR("Unknown whence");
return -1;
}
if (!ioData->offset.isValid()) {
NS_ERROR("Invalid offset");
return -1;
}
return 1;
}
static int64_t webm_tell(void* aUserData)
{
NS_ASSERTION(aUserData, "aUserData must point to a valid WebMioData");
WebMioData* ioData = static_cast<WebMioData*>(aUserData);
return ioData->offset.isValid() ? ioData->offset.value() : -1;
}
TEST(WebMWriter, bug970774_aspect_ratio)
{
TestWebMWriter writer(ContainerWriter::CREATE_AUDIO_TRACK |
ContainerWriter::CREATE_VIDEO_TRACK);
// Set vorbis metadata.
int channel = 1;
int sampleRate = 44100;
writer.SetVorbisMetadata(channel, sampleRate);
// Set vp8 metadata
int32_t width = 640;
int32_t height = 480;
int32_t displayWidth = 1280;
int32_t displayHeight = 960;
TrackRate aTrackRate = 90000;
writer.SetVP8Metadata(width, height, displayWidth,
displayHeight, aTrackRate);
// write the first I-Frame.
writer.AppendDummyFrame(EncodedFrame::VP8_I_FRAME, FIXED_DURATION);
// write the second I-Frame.
writer.AppendDummyFrame(EncodedFrame::VP8_I_FRAME, FIXED_DURATION);
// Get the metadata and the first cluster.
nsTArray<nsTArray<uint8_t> > encodedBuf;
writer.GetContainerData(&encodedBuf, 0);
// Flatten the encodedBuf.
WebMioData ioData;
ioData.offset = 0;
for(uint32_t i = 0 ; i < encodedBuf.Length(); ++i) {
ioData.data.AppendElements(encodedBuf[i]);
}
// Use nestegg to verify the information in metadata.
nestegg* context = nullptr;
nestegg_io io;
io.read = webm_read;
io.seek = webm_seek;
io.tell = webm_tell;
io.userdata = static_cast<void*>(&ioData);
int rv = nestegg_init(&context, io, nullptr, -1);
EXPECT_EQ(rv, 0);
unsigned int ntracks = 0;
rv = nestegg_track_count(context, &ntracks);
EXPECT_EQ(rv, 0);
EXPECT_EQ(ntracks, (unsigned int)2);
for (unsigned int track = 0; track < ntracks; ++track) {
int id = nestegg_track_codec_id(context, track);
EXPECT_NE(id, -1);
int type = nestegg_track_type(context, track);
if (type == NESTEGG_TRACK_VIDEO) {
nestegg_video_params params;
rv = nestegg_track_video_params(context, track, &params);
EXPECT_EQ(rv, 0);
EXPECT_EQ(width, static_cast<int32_t>(params.width));
EXPECT_EQ(height, static_cast<int32_t>(params.height));
EXPECT_EQ(displayWidth, static_cast<int32_t>(params.display_width));
EXPECT_EQ(displayHeight, static_cast<int32_t>(params.display_height));
} else if (type == NESTEGG_TRACK_AUDIO) {
nestegg_audio_params params;
rv = nestegg_track_audio_params(context, track, &params);
EXPECT_EQ(rv, 0);
EXPECT_EQ(channel, static_cast<int>(params.channels));
EXPECT_EQ(static_cast<double>(sampleRate), params.rate);
}
}
if (context) {
nestegg_destroy(context);
}
}

View File

@ -9,6 +9,7 @@ LIBRARY_NAME = 'media_gtest'
UNIFIED_SOURCES += [
'TestAudioCompactor.cpp',
'TestTrackEncoder.cpp',
'TestVideoSegment.cpp'
]
if CONFIG['MOZ_WEBM_ENCODER']:

View File

@ -66,15 +66,22 @@ nsresult MediaOmxReader::Init(MediaDecoderReader* aCloneDonor)
return NS_OK;
}
void MediaOmxReader::Shutdown()
void MediaOmxReader::ReleaseDecoder()
{
ReleaseMediaResources();
if (mOmxDecoder.get()) {
mOmxDecoder->ReleaseDecoder();
}
mOmxDecoder.clear();
}
void MediaOmxReader::Shutdown()
{
ReleaseMediaResources();
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &MediaOmxReader::ReleaseDecoder);
NS_DispatchToMainThread(event);
}
bool MediaOmxReader::IsWaitingMediaResources()
{
if (!mOmxDecoder.get()) {

View File

@ -104,6 +104,8 @@ public:
// ANDROID_VERSION < 19
void CheckAudioOffload();
#endif
void ReleaseDecoder();
};
} // namespace mozilla

View File

@ -4,17 +4,29 @@
navigator.mozGetUserMedia({audio: true}, function(stream) {
stream.getAudioTracks()[0].enabled = false;
var testAudio = document.getElementById('testAudio');
// temporary log for bug 1031137.
["abort", "canplay", "canplaythrough", "durationchange", "emptied", "ended",
"error", "loadeddata", "loadedmetadata", "loadstart", "pause", "play",
"playing", "progress", "ratechange", "seeked", "seeking", "stalled", "suspend",
"timeupdate", "volumechange", "waiting"].forEach(function(v) {
testAudio.addEventListener(v, function() {
dump("event received: " + v + "\n");
});
});
// Wait some time for good measure
var eventReceived = 0;
testAudio.addEventListener("timeupdate", function() {
dump("timeupdate received (index:" + eventReceived + ")\n");
if (++eventReceived == 3) {
document.querySelector("html").className = "";
}
})
});
testAudio.mozSrcObject = stream;
testAudio.play();
}, function(err) {
console.log(err);
dump(err + "\n");
});
</script>

View File

@ -879,12 +879,8 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
wheelEvent.deltaMode = aDeltaMode;
wheelEvent.isMomentum =
(aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
wheelEvent.isPixelOnlyDevice =
(aOptions & WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE) != 0;
NS_ENSURE_TRUE(
!wheelEvent.isPixelOnlyDevice ||
aDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL,
NS_ERROR_INVALID_ARG);
wheelEvent.mIsNoLineOrPageDelta =
(aOptions & WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE) != 0;
wheelEvent.customizedByUserPrefs =
(aOptions & WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS) != 0;
wheelEvent.lineOrPageDeltaX = aLineOrPageDeltaX;

View File

@ -248,6 +248,20 @@ CameraControlImpl::OnPreviewStateChange(CameraControlListener::PreviewState aNew
}
}
void
CameraControlImpl::OnRateLimitPreview(bool aLimit)
{
// This function runs on neither the Main Thread nor the Camera Thread.
RwLockAutoEnterRead lock(mListenerLock);
DOM_CAMERA_LOGI("OnRateLimitPreview: %d\n", aLimit);
for (uint32_t i = 0; i < mListeners.Length(); ++i) {
CameraControlListener* l = mListeners[i];
l->OnRateLimitPreview(aLimit);
}
}
bool
CameraControlImpl::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
{

View File

@ -67,6 +67,7 @@ protected:
void OnFacesDetected(const nsTArray<Face>& aFaces);
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength, const nsAString& aMimeType);
void OnRateLimitPreview(bool aLimit);
bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight);
void OnRecorderStateChange(CameraControlListener::RecorderState aState,
int32_t aStatus = -1, int32_t aTrackNumber = -1);

View File

@ -64,6 +64,7 @@ public:
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) { }
virtual void OnShutter() { }
virtual void OnRateLimitPreview(bool aLimit) { }
virtual bool OnNewPreviewFrame(layers::Image* aFrame, uint32_t aWidth, uint32_t aHeight)
{
return false;

View File

@ -4,6 +4,15 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CameraPreviewMediaStream.h"
#include "CameraCommon.h"
/**
* Maximum number of outstanding invalidates before we start to drop frames;
* if we hit this threshold, it is an indicator that the main thread is
* either very busy or the device is busy elsewhere (e.g. encoding or
* persisting video data).
*/
#define MAX_INVALIDATE_PENDING 4
using namespace mozilla::layers;
using namespace mozilla::dom;
@ -13,7 +22,9 @@ namespace mozilla {
CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
: MediaStream(aWrapper)
, mMutex("mozilla::camera::CameraPreviewMediaStream")
, mFrameCallback(nullptr)
, mInvalidatePending(0)
, mDiscardedFrames(0)
, mRateLimit(false)
{
SetGraphImpl(MediaStreamGraph::GetInstance());
mIsConsumed = false;
@ -103,22 +114,53 @@ CameraPreviewMediaStream::Destroy()
}
void
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
CameraPreviewMediaStream::Invalidate()
{
MutexAutoLock lock(mMutex);
TimeStamp now = TimeStamp::Now();
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
--mInvalidatePending;
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
VideoFrameContainer* output = mVideoOutputs[i];
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(output, &VideoFrameContainer::Invalidate);
NS_DispatchToMainThread(event);
output->Invalidate();
}
}
void
CameraPreviewMediaStream::RateLimit(bool aLimit)
{
mRateLimit = aLimit;
}
void
CameraPreviewMediaStream::SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage)
{
{
MutexAutoLock lock(mMutex);
if (mInvalidatePending > 0) {
if (mRateLimit || mInvalidatePending > MAX_INVALIDATE_PENDING) {
++mDiscardedFrames;
DOM_CAMERA_LOGW("Discard preview frame %d, %d invalidation(s) pending",
mDiscardedFrames, mInvalidatePending);
return;
}
DOM_CAMERA_LOGI("Update preview frame, %d invalidation(s) pending",
mInvalidatePending);
}
mDiscardedFrames = 0;
TimeStamp now = TimeStamp::Now();
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
VideoFrameContainer* output = mVideoOutputs[i];
output->SetCurrentFrame(aIntrinsicSize, aImage, now);
}
++mInvalidatePending;
}
if (mFrameCallback) {
mFrameCallback->OnNewFrame(aIntrinsicSize, aImage);
}
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &CameraPreviewMediaStream::Invalidate);
NS_DispatchToMainThread(event);
}
void
@ -126,7 +168,7 @@ CameraPreviewMediaStream::ClearCurrentFrame()
{
MutexAutoLock lock(mMutex);
for (uint32_t i = 0; i < mVideoOutputs.Length(); ++i) {
for (nsTArray<nsRefPtr<VideoFrameContainer> >::size_type i = 0; i < mVideoOutputs.Length(); ++i) {
VideoFrameContainer* output = mVideoOutputs[i];
output->ClearCurrentFrame();
nsCOMPtr<nsIRunnable> event =

View File

@ -11,13 +11,8 @@
namespace mozilla {
class CameraPreviewFrameCallback {
public:
virtual void OnNewFrame(const gfxIntSize& aIntrinsicSize, layers::Image* aImage) = 0;
};
/**
* This is a stream for camere preview.
* This is a stream for camera preview.
*
* XXX It is a temporary fix of SourceMediaStream.
* A camera preview requests no delay and no buffering stream.
@ -40,20 +35,21 @@ public:
virtual void RemoveListener(MediaStreamListener* aListener) MOZ_OVERRIDE;
virtual void Destroy();
void Invalidate();
// Call these on any thread.
void SetCurrentFrame(const gfxIntSize& aIntrinsicSize, Image* aImage);
void ClearCurrentFrame();
void SetFrameCallback(CameraPreviewFrameCallback* aCallback) {
mFrameCallback = aCallback;
}
void RateLimit(bool aLimit);
protected:
// mMutex protects all the class' fields.
// This class is not registered to MediaStreamGraph.
// It needs to protect all the fields.
Mutex mMutex;
CameraPreviewFrameCallback* mFrameCallback;
int32_t mInvalidatePending;
uint32_t mDiscardedFrames;
bool mRateLimit;
};
}

View File

@ -214,7 +214,7 @@ protected:
DOMCameraControlListener* mListener;
// our viewfinder stream
CameraPreviewMediaStream* mInput;
nsRefPtr<CameraPreviewMediaStream> mInput;
// set once when this object is created
nsCOMPtr<nsPIDOMWindow> mWindow;

View File

@ -287,6 +287,12 @@ DOMCameraControlListener::OnShutter()
NS_DispatchToMainThread(new Callback(mDOMCameraControl));
}
void
DOMCameraControlListener::OnRateLimitPreview(bool aLimit)
{
mStream->RateLimit(aLimit);
}
bool
DOMCameraControlListener::OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight)
{

View File

@ -28,6 +28,7 @@ public:
virtual void OnRecorderStateChange(RecorderState aState, int32_t aStatus, int32_t aTrackNum) MOZ_OVERRIDE;
virtual void OnConfigurationChange(const CameraListenerConfiguration& aConfiguration) MOZ_OVERRIDE;
virtual void OnShutter() MOZ_OVERRIDE;
virtual void OnRateLimitPreview(bool aLimit) MOZ_OVERRIDE;
virtual bool OnNewPreviewFrame(layers::Image* aImage, uint32_t aWidth, uint32_t aHeight) MOZ_OVERRIDE;
virtual void OnUserError(UserContext aContext, nsresult aError) MOZ_OVERRIDE;

View File

@ -1682,6 +1682,12 @@ nsGonkCameraControl::GetRecorderProfileManagerImpl()
return profileMgr.forget();
}
void
nsGonkCameraControl::OnRateLimitPreview(bool aLimit)
{
CameraControlImpl::OnRateLimitPreview(aLimit);
}
void
nsGonkCameraControl::OnNewPreviewFrame(layers::TextureClient* aBuffer)
{
@ -1744,6 +1750,12 @@ OnFacesDetected(nsGonkCameraControl* gc, camera_frame_metadata_t* aMetaData)
gc->OnFacesDetected(aMetaData);
}
void
OnRateLimitPreview(nsGonkCameraControl* gc, bool aLimit)
{
gc->OnRateLimitPreview(aLimit);
}
void
OnNewPreviewFrame(nsGonkCameraControl* gc, layers::TextureClient* aBuffer)
{

View File

@ -52,10 +52,11 @@ public:
void OnFacesDetected(camera_frame_metadata_t* aMetaData);
void OnTakePictureComplete(uint8_t* aData, uint32_t aLength);
void OnTakePictureError();
void OnRateLimitPreview(bool aLimit);
void OnNewPreviewFrame(layers::TextureClient* aBuffer);
void OnRecorderEvent(int msg, int ext1, int ext2);
void OnSystemError(CameraControlListener::SystemContext aWhere, nsresult aError);
// See ICameraControl.h for getter/setter return values.
virtual nsresult Set(uint32_t aKey, const nsAString& aValue) MOZ_OVERRIDE;
virtual nsresult Get(uint32_t aKey, nsAString& aValue) MOZ_OVERRIDE;
@ -84,6 +85,7 @@ public:
protected:
~nsGonkCameraControl();
using CameraControlImpl::OnRateLimitPreview;
using CameraControlImpl::OnNewPreviewFrame;
using CameraControlImpl::OnAutoFocusComplete;
using CameraControlImpl::OnFacesDetected;
@ -178,6 +180,7 @@ private:
};
// camera driver callbacks
void OnRateLimitPreview(nsGonkCameraControl* gc, bool aLimit);
void OnTakePictureComplete(nsGonkCameraControl* gc, uint8_t* aData, uint32_t aLength);
void OnTakePictureError(nsGonkCameraControl* gc);
void OnAutoFocusComplete(nsGonkCameraControl* gc, bool aSuccess);

View File

@ -44,6 +44,12 @@ GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, ui
DOM_CAMERA_LOGT("%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget);
}
void
GonkCameraHardware::OnRateLimitPreview(bool aLimit)
{
::OnRateLimitPreview(mTarget, aLimit);
}
void
GonkCameraHardware::OnNewFrame()
{

View File

@ -55,6 +55,8 @@ public:
static sp<GonkCameraHardware> Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId);
virtual void Close();
virtual void OnRateLimitPreview(bool aLimit);
// derived from GonkNativeWindowNewFrameCallback
virtual void OnNewFrame() MOZ_OVERRIDE;

View File

@ -170,6 +170,7 @@ GonkCameraSource::GonkCameraSource(
mStarted(false),
mNumFramesEncoded(0),
mTimeBetweenFrameCaptureUs(0),
mRateLimit(false),
mFirstFrameTimeUs(0),
mNumFramesDropped(0),
mNumGlitches(0),
@ -589,6 +590,10 @@ status_t GonkCameraSource::reset() {
}
}
stopCameraRecording();
if (mRateLimit) {
mRateLimit = false;
mCameraHw->OnRateLimitPreview(false);
}
releaseCamera();
if (mCollectStats) {
@ -692,51 +697,65 @@ status_t GonkCameraSource::read(
void GonkCameraSource::dataCallbackTimestamp(int64_t timestampUs,
int32_t msgType, const sp<IMemory> &data) {
bool rateLimit;
bool prevRateLimit;
CS_LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs);
Mutex::Autolock autoLock(mLock);
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
releaseOneRecordingFrame(data);
return;
}
if (mNumFramesReceived > 0) {
CHECK(timestampUs > mLastFrameTimestampUs);
if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
++mNumGlitches;
{
Mutex::Autolock autoLock(mLock);
if (!mStarted || (mNumFramesReceived == 0 && timestampUs < mStartTimeUs)) {
CS_LOGV("Drop frame at %lld/%lld us", timestampUs, mStartTimeUs);
releaseOneRecordingFrame(data);
return;
}
}
// May need to skip frame or modify timestamp. Currently implemented
// by the subclass CameraSourceTimeLapse.
if (skipCurrentFrame(timestampUs)) {
releaseOneRecordingFrame(data);
return;
}
mLastFrameTimestampUs = timestampUs;
if (mNumFramesReceived == 0) {
mFirstFrameTimeUs = timestampUs;
// Initial delay
if (mStartTimeUs > 0) {
if (timestampUs < mStartTimeUs) {
// Frame was captured before recording was started
// Drop it without updating the statistical data.
releaseOneRecordingFrame(data);
return;
if (mNumFramesReceived > 0) {
CHECK(timestampUs > mLastFrameTimestampUs);
if (timestampUs - mLastFrameTimestampUs > mGlitchDurationThresholdUs) {
++mNumGlitches;
}
mStartTimeUs = timestampUs - mStartTimeUs;
}
}
++mNumFramesReceived;
CHECK(data != NULL && data->size() > 0);
mFramesReceived.push_back(data);
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
mFrameTimes.push_back(timeUs);
CS_LOGV("initial delay: %lld, current time stamp: %lld",
mStartTimeUs, timeUs);
mFrameAvailableCondition.signal();
// May need to skip frame or modify timestamp. Currently implemented
// by the subclass CameraSourceTimeLapse.
if (skipCurrentFrame(timestampUs)) {
releaseOneRecordingFrame(data);
return;
}
mLastFrameTimestampUs = timestampUs;
if (mNumFramesReceived == 0) {
mFirstFrameTimeUs = timestampUs;
// Initial delay
if (mStartTimeUs > 0) {
if (timestampUs < mStartTimeUs) {
// Frame was captured before recording was started
// Drop it without updating the statistical data.
releaseOneRecordingFrame(data);
return;
}
mStartTimeUs = timestampUs - mStartTimeUs;
}
}
++mNumFramesReceived;
// If a backlog is building up in the receive queue, we are likely
// resource constrained and we need to throttle
prevRateLimit = mRateLimit;
rateLimit = mFramesReceived.empty();
mRateLimit = rateLimit;
CHECK(data != NULL && data->size() > 0);
mFramesReceived.push_back(data);
int64_t timeUs = mStartTimeUs + (timestampUs - mFirstFrameTimeUs);
mFrameTimes.push_back(timeUs);
CS_LOGV("initial delay: %lld, current time stamp: %lld",
mStartTimeUs, timeUs);
mFrameAvailableCondition.signal();
}
if(prevRateLimit != rateLimit) {
mCameraHw->OnRateLimitPreview(rateLimit);
}
}
bool GonkCameraSource::isMetaDataStoredInVideoBuffers() const {

View File

@ -127,6 +127,7 @@ private:
List<sp<IMemory> > mFramesReceived;
List<sp<IMemory> > mFramesBeingEncoded;
List<int64_t> mFrameTimes;
bool mRateLimit;
int64_t mFirstFrameTimeUs;
int32_t mNumFramesDropped;

View File

@ -1397,7 +1397,7 @@ private:
default: return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
SECKEYPublicKey* pubKey;
SECKEYPublicKey* pubKey = nullptr;
mPrivateKey = PK11_GenerateKeyPair(slot.get(), mMechanism, param, &pubKey,
PR_FALSE, PR_FALSE, nullptr);
mPublicKey = pubKey;

View File

@ -349,7 +349,8 @@ private:
#ifdef MOZ_WIDGET_GONK
nsString mLastStatus;
void DispatchMountChangeEvent(nsAString& aVolumeStatus);
void DispatchStatusChangeEvent(nsAString& aStatus);
void DispatchStorageStatusChangeEvent(nsAString& aVolumeStatus);
#endif
// nsIDOMDeviceStorage.type

View File

@ -4194,14 +4194,32 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
#ifdef MOZ_WIDGET_GONK
void
nsDOMDeviceStorage::DispatchMountChangeEvent(nsAString& aVolumeStatus)
nsDOMDeviceStorage::DispatchStatusChangeEvent(nsAString& aStatus)
{
if (aVolumeStatus == mLastStatus) {
if (aStatus == mLastStatus) {
// We've already sent this status, don't bother sending it again.
return;
}
mLastStatus = aVolumeStatus;
mLastStatus = aStatus;
DeviceStorageChangeEventInit init;
init.mBubbles = true;
init.mCancelable = false;
init.mPath = mStorageName;
init.mReason = aStatus;
nsRefPtr<DeviceStorageChangeEvent> event =
DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("change"),
init);
event->SetTrusted(true);
bool ignore;
DispatchEvent(event, &ignore);
}
void
nsDOMDeviceStorage::DispatchStorageStatusChangeEvent(nsAString& aVolumeStatus)
{
DeviceStorageChangeEventInit init;
init.mBubbles = true;
init.mCancelable = false;
@ -4209,7 +4227,7 @@ nsDOMDeviceStorage::DispatchMountChangeEvent(nsAString& aVolumeStatus)
init.mReason = aVolumeStatus;
nsRefPtr<DeviceStorageChangeEvent> event =
DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("change"),
DeviceStorageChangeEvent::Constructor(this, NS_LITERAL_STRING("storage-state-change"),
init);
event->SetTrusted(true);
@ -4268,9 +4286,15 @@ nsDOMDeviceStorage::Observe(nsISupports *aSubject,
}
DeviceStorageFile dsf(mStorageType, mStorageName);
nsString status;
nsString status, storageStatus;
// Get Status (one of "available, unavailable, shared")
dsf.GetStatus(status);
DispatchMountChangeEvent(status);
DispatchStatusChangeEvent(status);
// Get real volume status (defined in dom/system/gonk/nsIVolume.idl)
dsf.GetStorageStatus(storageStatus);
DispatchStorageStatusChangeEvent(storageStatus);
return NS_OK;
}
#endif

View File

@ -5096,7 +5096,7 @@ EventStateManager::DeltaAccumulator::InitLineOrPageDelta(
if (IsInTransaction()) {
// If wheel event type is changed, reset the values.
if (mHandlingDeltaMode != aEvent->deltaMode ||
mHandlingPixelOnlyDevice != aEvent->isPixelOnlyDevice) {
mIsNoLineOrPageDeltaDevice != aEvent->mIsNoLineOrPageDelta) {
Reset();
} else {
// If the delta direction is changed, we should reset only the
@ -5111,13 +5111,12 @@ EventStateManager::DeltaAccumulator::InitLineOrPageDelta(
}
mHandlingDeltaMode = aEvent->deltaMode;
mHandlingPixelOnlyDevice = aEvent->isPixelOnlyDevice;
mIsNoLineOrPageDeltaDevice = aEvent->mIsNoLineOrPageDelta;
// If it's handling neither pixel scroll mode for pixel only device nor
// delta values multiplied by prefs, we must not modify lineOrPageDelta
// If it's handling neither a device that does not provide line or page deltas
// nor delta values multiplied by prefs, we must not modify lineOrPageDelta
// values.
if (!(mHandlingDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL &&
mHandlingPixelOnlyDevice) &&
if (!mIsNoLineOrPageDeltaDevice &&
!EventStateManager::WheelPrefs::GetInstance()->
NeedToComputeLineOrPageDelta(aEvent)) {
// Set the delta values to mX and mY. They would be used when above block
@ -5178,7 +5177,7 @@ EventStateManager::DeltaAccumulator::Reset()
mX = mY = 0.0;
mPendingScrollAmountX = mPendingScrollAmountY = 0.0;
mHandlingDeltaMode = UINT32_MAX;
mHandlingPixelOnlyDevice = false;
mIsNoLineOrPageDeltaDevice = false;
}
nsIntPoint

View File

@ -702,7 +702,7 @@ protected:
private:
DeltaAccumulator() :
mX(0.0), mY(0.0), mPendingScrollAmountX(0.0), mPendingScrollAmountY(0.0),
mHandlingDeltaMode(UINT32_MAX), mHandlingPixelOnlyDevice(false)
mHandlingDeltaMode(UINT32_MAX), mIsNoLineOrPageDeltaDevice(false)
{
}
@ -718,7 +718,7 @@ protected:
TimeStamp mLastTime;
uint32_t mHandlingDeltaMode;
bool mHandlingPixelOnlyDevice;
bool mIsNoLineOrPageDeltaDevice;
static DeltaAccumulator* sInstance;
};

File diff suppressed because it is too large Load Diff

View File

@ -104,6 +104,7 @@ function MozInputMethod() { }
MozInputMethod.prototype = {
_inputcontext: null,
_wrappedInputContext: null,
_layouts: {},
_window: null,
_isSystem: false,
@ -211,7 +212,7 @@ MozInputMethod.prototype = {
if (!WindowMap.isActive(this._window)) {
return null;
}
return this._inputcontext;
return this._wrappedInputContext;
},
set oninputcontextchange(handler) {
@ -226,6 +227,7 @@ MozInputMethod.prototype = {
if (this._inputcontext) {
this._inputcontext.destroy();
this._inputcontext = null;
this._wrappedInputContext = null;
this._mgmt._supportsSwitching = false;
}
@ -236,6 +238,10 @@ MozInputMethod.prototype = {
this._inputcontext = new MozInputContext(data);
this._inputcontext.init(this._window);
// inputcontext will be exposed as a WebIDL object. Create its
// content-side object explicitly to avoid Bug 1001325.
this._wrappedInputContext =
this._window.MozInputContext._create(this._window, this._inputcontext);
}
let event = new this._window.Event("inputcontextchange",

View File

@ -48,7 +48,7 @@ interface nsIRunnable;
interface nsICompositionStringSynthesizer;
interface nsITranslationNodeList;
[scriptable, uuid(6f10cbf8-bd4e-4c56-8a5a-35641efcf286)]
[scriptable, uuid(46e3f206-9a8f-4d66-8248-7ec6a37de45a)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -468,9 +468,11 @@ interface nsIDOMWindowUtils : nsISupports {
* scroll.
* @param aOptions Set following flags.
*/
const unsigned long WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE = 0x0001;
const unsigned long WHEEL_EVENT_CAUSED_BY_MOMENTUM = 0x0002;
const unsigned long WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS = 0x0004;
const unsigned long WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE = 0x0001;
// @deprecated Use WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE.
const unsigned long WHEEL_EVENT_CAUSED_BY_PIXEL_ONLY_DEVICE = 0x0001;
const unsigned long WHEEL_EVENT_CAUSED_BY_MOMENTUM = 0x0002;
const unsigned long WHEEL_EVENT_CUSTOMIZED_BY_USER_PREFS = 0x0004;
// If any of the following flags is specified this method will throw an
// exception in case the relevant overflowDelta has an unexpected value.
const unsigned long WHEEL_EVENT_EXPECTED_OVERFLOW_DELTA_X_ZERO = 0x0010;

View File

@ -12,8 +12,15 @@ function peerReadyCb(evt) {
let peer = nfc.getNFCPeer(evt.detail);
ok(peer instanceof MozNFCPeer, "Should get a NFCPeer object.");
// reset callback and NFC Hardware.
// reset callback.
nfc.onpeerready = null;
emulator.deactivate();
}
function peerLostCb() {
log("peerLostCb called");
ok(true);
nfc.onpeerlost = null;
toggleNFC(false).then(runNextTest);
}
@ -23,6 +30,7 @@ function handleTechnologyDiscoveredRE0(msg) {
is(msg.techList[0], "P2P", "check for correct tech type");
nfc.onpeerready = peerReadyCb;
nfc.onpeerlost = peerLostCb;
let request = nfc.checkP2PRegistration(MANIFEST_URL);
request.onsuccess = function (evt) {

View File

@ -286,7 +286,7 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
isRegisteredP2PTarget: function isRegisteredP2PTarget(appId, event) {
let targetInfo = this.peerTargetsMap[appId];
// Check if it is a registered target for the 'event'
return ((targetInfo != null) && (targetInfo.event & event !== 0));
return ((targetInfo != null) && ((targetInfo.event & event) !== 0));
},
notifyPeerEvent: function notifyPeerEvent(appId, event) {
@ -527,7 +527,7 @@ Nfc.prototype = {
gSystemMessenger.broadcastMessage("nfc-manager-tech-lost", message);
// Notify 'PeerLost' to appropriate registered target, if any
gMessageManager.notifyPeerEvent(this.currentPeerAppId, NFC.NFC_PEER_EVENT_LOST);
gMessageManager.notifyPeerEvent(gMessageManager.currentPeerAppId, NFC.NFC_PEER_EVENT_LOST);
delete this.sessionTokenMap[this._currentSessionId];
this._currentSessionId = null;
this.currentPeerAppId = null;

View File

@ -315,7 +315,7 @@ interface MozWifiManager : EventTarget {
* An event listener that is called with information about the signal
* strength and link speed every 5 seconds.
*/
attribute EventHandler onconnectionInfoUpdate;
attribute EventHandler onconnectioninfoupdate;
/**
* These two events fire when the wifi system is brought online or taken
@ -328,5 +328,5 @@ interface MozWifiManager : EventTarget {
* An event listener that is called with information about the number
* of wifi stations connected to wifi hotspot every 5 seconds.
*/
attribute EventHandler onstationInfoUpdate;
attribute EventHandler onstationinfoupdate;
};

View File

@ -77,10 +77,10 @@ MozWifiCapabilities.prototype = {
function DOMWifiManager() {
this.defineEventHandlerGetterSetter("onstatuschange");
this.defineEventHandlerGetterSetter("onconnectionInfoUpdate");
this.defineEventHandlerGetterSetter("onconnectioninfoupdate");
this.defineEventHandlerGetterSetter("onenabled");
this.defineEventHandlerGetterSetter("ondisabled");
this.defineEventHandlerGetterSetter("onstationInfoUpdate");
this.defineEventHandlerGetterSetter("onstationinfoupdate");
}
DOMWifiManager.prototype = {
@ -117,9 +117,9 @@ DOMWifiManager.prototype = {
"WifiManager:onconnecting", "WifiManager:onassociate",
"WifiManager:onconnect", "WifiManager:ondisconnect",
"WifiManager:onwpstimeout", "WifiManager:onwpsfail",
"WifiManager:onwpsoverlap", "WifiManager:connectionInfoUpdate",
"WifiManager:onwpsoverlap", "WifiManager:connectioninfoupdate",
"WifiManager:onauthenticating", "WifiManager:onconnectingfailed",
"WifiManager:stationInfoUpdate"];
"WifiManager:stationinfoupdate"];
this.initDOMRequestHelper(aWindow, messages);
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
@ -379,7 +379,7 @@ DOMWifiManager.prototype = {
this._fireStatusChangeEvent();
break;
case "WifiManager:connectionInfoUpdate":
case "WifiManager:connectioninfoupdate":
this._lastConnectionInfo = this._convertConnectionInfo(msg);
this._fireConnectionInfoUpdate(msg);
break;
@ -394,7 +394,7 @@ DOMWifiManager.prototype = {
this._connectionStatus = "authenticating";
this._fireStatusChangeEvent();
break;
case "WifiManager:stationInfoUpdate":
case "WifiManager:stationinfoupdate":
this._stationNumber = msg.station;
this._fireStationInfoUpdate(msg);
break;
@ -426,7 +426,7 @@ DOMWifiManager.prototype = {
},
_fireStationInfoUpdate: function onStationInfoUpdate(info) {
var evt = new this._window.MozWifiStationInfoEvent("stationInfoUpdate",
var evt = new this._window.MozWifiStationInfoEvent("stationinfoupdate",
{ station: this._stationNumber}
);
this.__DOM_IMPL__.dispatchEvent(evt);

View File

@ -1112,7 +1112,7 @@ var WifiManager = (function() {
function getWifiHotspotStatus() {
wifiCommand.hostapdGetStations(function(result) {
notify("stationInfoUpdate", {station: result});
notify("stationinfoupdate", {station: result});
});
}
@ -2324,8 +2324,8 @@ function WifiWorker() {
});
};
WifiManager.onstationInfoUpdate = function() {
self._fireEvent("stationInfoUpdate", { station: this.station });
WifiManager.onstationinfoupdate = function() {
self._fireEvent("stationinfoupdate", { station: this.station });
};
// Read the 'wifi.enabled' setting in order to start with a known
@ -2511,8 +2511,8 @@ WifiWorker.prototype = {
}
self._lastConnectionInfo = info;
debug("Firing connectionInfoUpdate: " + uneval(info));
self._fireEvent("connectionInfoUpdate", info);
debug("Firing connectioninfoupdate: " + uneval(info));
self._fireEvent("connectioninfoupdate", info);
});
}

View File

@ -954,6 +954,7 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
int *tx, int *ty)
{
const cairo_rectangle_int_t *clip_extents = &clip_path->extents;
cairo_rectangle_int_t surface_extents;
cairo_bool_t need_translate;
cairo_surface_t *surface;
cairo_clip_path_t *prev;
@ -967,27 +968,36 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
}
clip_extents = &clip_path->extents;
if (_cairo_surface_get_extents (target, &surface_extents))
{
_cairo_rectangle_intersect(&surface_extents, clip_extents);
}
else
{
surface_extents = *clip_extents;
}
if (clip_path->surface != NULL &&
clip_path->surface->backend == target->backend)
{
*tx = clip_extents->x;
*ty = clip_extents->y;
*tx = surface_extents.x;
*ty = surface_extents.y;
return clip_path->surface;
}
surface = _cairo_surface_create_similar_scratch (target,
CAIRO_CONTENT_ALPHA,
clip_extents->width,
clip_extents->height);
surface_extents.width,
surface_extents.height);
if (surface == NULL) {
surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
clip_extents->width,
clip_extents->height);
surface_extents.width,
surface_extents.height);
}
if (unlikely (surface->status))
return surface;
need_translate = clip_extents->x | clip_extents->y;
need_translate = surface_extents.x | surface_extents.y;
if (clip_path->flags & CAIRO_CLIP_PATH_IS_BOX &&
clip_path->path.maybe_fill_region)
{
@ -1009,8 +1019,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
if (need_translate) {
_cairo_path_fixed_translate (&clip_path->path,
_cairo_fixed_from_int (-clip_extents->x),
_cairo_fixed_from_int (-clip_extents->y));
_cairo_fixed_from_int (-surface_extents.x),
_cairo_fixed_from_int (-surface_extents.y));
}
status = _cairo_surface_fill (surface,
CAIRO_OPERATOR_ADD,
@ -1022,8 +1032,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
NULL);
if (need_translate) {
_cairo_path_fixed_translate (&clip_path->path,
_cairo_fixed_from_int (clip_extents->x),
_cairo_fixed_from_int (clip_extents->y));
_cairo_fixed_from_int (surface_extents.x),
_cairo_fixed_from_int (surface_extents.y));
}
if (unlikely (status))
@ -1043,8 +1053,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
{
if (need_translate) {
_cairo_path_fixed_translate (&prev->path,
_cairo_fixed_from_int (-clip_extents->x),
_cairo_fixed_from_int (-clip_extents->y));
_cairo_fixed_from_int (-surface_extents.x),
_cairo_fixed_from_int (-surface_extents.y));
}
status = _cairo_surface_fill (surface,
CAIRO_OPERATOR_IN,
@ -1056,8 +1066,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
NULL);
if (need_translate) {
_cairo_path_fixed_translate (&prev->path,
_cairo_fixed_from_int (clip_extents->x),
_cairo_fixed_from_int (clip_extents->y));
_cairo_fixed_from_int (surface_extents.x),
_cairo_fixed_from_int (surface_extents.y));
}
if (unlikely (status))
@ -1077,8 +1087,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
_cairo_pattern_init_for_surface (&pattern, prev_surface);
pattern.base.filter = CAIRO_FILTER_NEAREST;
cairo_matrix_init_translate (&pattern.base.matrix,
clip_extents->x - prev_tx,
clip_extents->y - prev_ty);
surface_extents.x - prev_tx,
surface_extents.y - prev_ty);
status = _cairo_surface_paint (surface,
CAIRO_OPERATOR_IN,
&pattern.base,
@ -1094,8 +1104,8 @@ _cairo_clip_path_get_surface (cairo_clip_path_t *clip_path,
prev = prev->prev;
}
*tx = clip_extents->x;
*ty = clip_extents->y;
*tx = surface_extents.x;
*ty = surface_extents.y;
cairo_surface_destroy (clip_path->surface);
return clip_path->surface = surface;

View File

@ -3565,9 +3565,11 @@ _clip_and_composite_polygon (cairo_image_surface_t *dst,
return status;
}
_cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask))
return CAIRO_STATUS_SUCCESS;
if (_cairo_operator_bounded_by_mask(op)) {
_cairo_box_round_to_rectangle (&polygon->extents, &extents->mask);
if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask))
return CAIRO_STATUS_SUCCESS;
}
if (antialias != CAIRO_ANTIALIAS_NONE) {
composite_spans_info_t info;

View File

@ -489,7 +489,7 @@ public:
return false;
// then the image data
if (mCompresseddata.get() && !WriteToStream(mCompresseddata.get(), mDatasize))
if (mCompresseddata.get() && !WriteToStream(mCompresseddata, mDatasize))
return false;
// then pad out to 4 bytes
@ -518,12 +518,12 @@ private:
mPacket.stride = aImage->Stride();
mPacket.dataSize = aImage->GetSize().height * aImage->Stride();
mCompresseddata = std::auto_ptr<char>(
(char*)moz_malloc(LZ4::maxCompressedSize(mPacket.dataSize)));
mCompresseddata =
new char[LZ4::maxCompressedSize(mPacket.dataSize)];
if (mCompresseddata.get()) {
int ndatasize = LZ4::compress((char*)aImage->GetData(),
mPacket.dataSize,
mCompresseddata.get());
mCompresseddata);
if (ndatasize > 0) {
mDatasize = ndatasize;
@ -550,7 +550,7 @@ protected:
// Packet data
DebugGLData::TexturePacket mPacket;
std::auto_ptr<char> mCompresseddata;
nsAutoArrayPtr<char> mCompresseddata;
uint32_t mDatasize;
};
@ -651,7 +651,7 @@ public:
nsresult rv = NS_OK;
while ((d = mList.popFirst()) != nullptr) {
std::auto_ptr<DebugGLData> cleaner(d);
nsAutoPtr<DebugGLData> cleaner(d);
if (!d->Write()) {
rv = NS_ERROR_FAILURE;
break;

View File

@ -1,3 +1,3 @@
{
"expect-hazards": 2
"expect-hazards": 4
}

View File

@ -419,6 +419,7 @@ void
ForkJoinNursery::forwardFromTenured(ForkJoinNurseryCollectionTracer *trc)
{
JSObject *objs[ArenaCellCount];
ArenaLists &lists = tenured_->arenas;
for (size_t k=0; k < FINALIZE_LIMIT; k++) {
AllocKind kind = (AllocKind)k;
if (!IsFJNurseryAllocable(kind))
@ -429,22 +430,21 @@ ForkJoinNursery::forwardFromTenured(ForkJoinNurseryCollectionTracer *trc)
// handled.
JS_ASSERT(kind <= FINALIZE_OBJECT_LAST);
// Clear the free list that we're currently allocating out of.
lists.purge(kind);
// Since we only purge once, there must not currently be any partially
// full arenas left to allocate out of, or we would break out early.
JS_ASSERT(!lists.getArenaAfterCursor(kind));
ArenaIter ai;
ai.init(const_cast<Allocator *>(tenured_), kind);
for (; !ai.done(); ai.next()) {
// Do the walk in two steps to avoid problems resulting from allocating
// into the arena that's being walked: ArenaCellIter is not safe for that.
// It can happen during evacuation.
//
// ArenaCellIterUnderFinalize requires any free list to be flushed into
// its arena, and since we may allocate within traceObject() we must
// purge before each arena scan. This is probably not very expensive,
// it's constant work, and inlined.
//
if (isEvacuating_ && lists.arenaIsInUse(ai.get(), kind))
break;
// Use ArenaCellIterUnderFinalize, not ...UnderGC, because that side-steps
// some assertions in the latter that are wrong for PJS collection.
size_t numObjs = 0;
tenured_->arenas.purge(kind);
for (ArenaCellIterUnderFinalize i(ai.get()); !i.done(); i.next())
objs[numObjs++] = i.get<JSObject>();
for (size_t i=0; i < numObjs; i++)

View File

@ -0,0 +1,28 @@
var countG = 0;
function g() {
switch(countG++) {
case 0: return 42;
case 1: return "yo";
case 2: return {};
}
}
var countFault = 0;
function uceFault() {
if (countFault++ == 4)
uceFault = function() { return true }
return false;
}
function f() {
var x = !g();
if (uceFault() || uceFault()) {
assertEq(x, false);
return 0;
}
return 1;
}
f();
f();
f();

View File

@ -321,6 +321,40 @@ function rstring_length(i) {
return i;
}
var uceFault_arguments_length_1 = eval(uneval(uceFault).replace('uceFault', 'uceFault_arguments_length_1'));
function rarguments_length_1(i) {
var x = arguments.length;
if (uceFault_arguments_length_1(i) || uceFault_arguments_length_1(i))
assertEq(x, 1);
return i;
}
var uceFault_arguments_length_3 = eval(uneval(uceFault).replace('uceFault', 'uceFault_arguments_length_3'));
function rarguments_length_3(i) {
var x = arguments.length;
if (uceFault_arguments_length_3(i) || uceFault_arguments_length_3(i))
assertEq(x, 3);
return i;
}
function ret_argumentsLength() { return arguments.length; }
var uceFault_inline_arguments_length_1 = eval(uneval(uceFault).replace('uceFault', 'uceFault_inline_arguments_length_1'));
function rinline_arguments_length_1(i) {
var x = ret_argumentsLength.apply(this, arguments);
if (uceFault_inline_arguments_length_1(i) || uceFault_inline_arguments_length_1(i))
assertEq(x, 1);
return i;
}
var uceFault_inline_arguments_length_3 = eval(uneval(uceFault).replace('uceFault', 'uceFault_inline_arguments_length_3'));
function rinline_arguments_length_3(i) {
var x = ret_argumentsLength.apply(this, arguments);
if (uceFault_inline_arguments_length_3(i) || uceFault_inline_arguments_length_3(i))
assertEq(x, 3);
return i;
}
var uceFault_floor_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_floor_number'));
function rfloor_number(i) {
var x = Math.floor(i + 0.1111);
@ -510,6 +544,10 @@ for (i = 0; i < 100; i++) {
rconcat_string(i);
rconcat_number(i);
rstring_length(i);
rarguments_length_1(i);
rarguments_length_3(i, 0, 1);
rinline_arguments_length_1(i);
rinline_arguments_length_3(i, 0, 1);
rfloor_number(i);
rfloor_object(i);
rround_number(i);

View File

@ -815,18 +815,18 @@ class MOZ_STACK_CLASS ModuleCompiler
public:
class Func
{
PropertyName *name_;
bool defined_;
uint32_t srcOffset_;
uint32_t endOffset_;
Signature sig_;
PropertyName *name_;
Label *code_;
unsigned compileTime_;
uint32_t srcBegin_;
uint32_t srcEnd_;
uint32_t compileTime_;
bool defined_;
public:
Func(PropertyName *name, Signature &&sig, Label *code)
: name_(name), defined_(false), srcOffset_(0), endOffset_(0), sig_(Move(sig)),
code_(code), compileTime_(0)
: sig_(Move(sig)), name_(name), code_(code), srcBegin_(0), srcEnd_(0),
compileTime_(0), defined_(false)
{}
PropertyName *name() const { return name_; }
@ -838,19 +838,19 @@ class MOZ_STACK_CLASS ModuleCompiler
// The begin/end char range is relative to the beginning of the module.
// hence the assertions.
JS_ASSERT(fn->pn_pos.begin > m.moduleStart());
JS_ASSERT(fn->pn_pos.begin > m.srcStart());
JS_ASSERT(fn->pn_pos.begin <= fn->pn_pos.end);
srcOffset_ = fn->pn_pos.begin - m.moduleStart();
endOffset_ = fn->pn_pos.end - m.moduleStart();
srcBegin_ = fn->pn_pos.begin - m.srcStart();
srcEnd_ = fn->pn_pos.end - m.srcStart();
}
uint32_t srcOffset() const { JS_ASSERT(defined_); return srcOffset_; }
uint32_t endOffset() const { JS_ASSERT(defined_); return endOffset_; }
uint32_t srcBegin() const { JS_ASSERT(defined_); return srcBegin_; }
uint32_t srcEnd() const { JS_ASSERT(defined_); return srcEnd_; }
Signature &sig() { return sig_; }
const Signature &sig() const { return sig_; }
Label *code() const { return code_; }
unsigned compileTime() const { return compileTime_; }
void accumulateCompileTime(unsigned ms) { compileTime_ += ms; }
uint32_t compileTime() const { return compileTime_; }
void accumulateCompileTime(uint32_t ms) { compileTime_ += ms; }
};
class Global
@ -1137,15 +1137,15 @@ class MOZ_STACK_CLASS ModuleCompiler
return false;
}
uint32_t funcStart = parser_.pc->maybeFunction->pn_body->pn_pos.begin;
uint32_t offsetToEndOfUseAsm = tokenStream().currentToken().pos.end;
uint32_t srcStart = parser_.pc->maybeFunction->pn_body->pn_pos.begin;
uint32_t srcBodyStart = tokenStream().currentToken().pos.end;
// "use strict" should be added to the source if we are in an implicit
// strict context, see also comment above addUseStrict in
// js::FunctionToString.
bool strict = parser_.pc->sc->strict && !parser_.pc->sc->hasExplicitUseStrict();
module_ = cx_->new_<AsmJSModule>(parser_.ss, funcStart, offsetToEndOfUseAsm, strict);
module_ = cx_->new_<AsmJSModule>(parser_.ss, srcStart, srcBodyStart, strict);
if (!module_)
return false;
@ -1212,7 +1212,7 @@ class MOZ_STACK_CLASS ModuleCompiler
SlowFunction sf;
sf.name = func.name();
sf.ms = func.compileTime();
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcOffset(), &sf.line, &sf.column);
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &sf.line, &sf.column);
return slowFunctions_.append(sf);
}
@ -1226,7 +1226,7 @@ class MOZ_STACK_CLASS ModuleCompiler
Label &interruptLabel() { return interruptLabel_; }
bool hasError() const { return errorString_ != nullptr; }
const AsmJSModule &module() const { return *module_.get(); }
uint32_t moduleStart() const { return module_->funcStart(); }
uint32_t srcStart() const { return module_->srcStart(); }
ParseNode *moduleFunctionNode() const { return moduleFunctionNode_; }
PropertyName *moduleFunctionName() const { return moduleFunctionName_; }
@ -1394,7 +1394,7 @@ class MOZ_STACK_CLASS ModuleCompiler
for (unsigned i = 0; i < args.length(); i++)
argCoercions[i] = args[i].toCoercion();
AsmJSModule::ReturnType retType = func->sig().retType().toModuleReturnType();
return module_->addExportedFunction(func->name(), func->srcOffset(), func->endOffset(),
return module_->addExportedFunction(func->name(), func->srcBegin(), func->srcEnd(),
maybeFieldName, Move(argCoercions), retType);
}
bool addExit(unsigned ffiIndex, PropertyName *name, Signature &&sig, unsigned *exitIndex) {
@ -1439,9 +1439,10 @@ class MOZ_STACK_CLASS ModuleCompiler
bool finishGeneratingFunction(Func &func, MIRGenerator &mir, CodeGenerator &codegen) {
JS_ASSERT(func.defined() && func.code()->bound());
uint32_t beginOffset = func.code()->offset();
uint32_t endOffset = masm_.currentOffset();
if (!module_->addFunctionCodeRange(func.name(), beginOffset, endOffset))
PropertyName *name = func.name();
uint32_t codeBegin = func.code()->offset();
uint32_t codeEnd = masm_.currentOffset();
if (!module_->addFunctionCodeRange(name, codeBegin, codeEnd))
return false;
jit::IonScriptCounts *counts = codegen.extractScriptCounts();
@ -1452,22 +1453,18 @@ class MOZ_STACK_CLASS ModuleCompiler
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
unsigned line = 0, column = 0;
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcOffset(), &line, &column);
unsigned startCodeOffset = func.code()->offset();
unsigned endCodeOffset = masm_.currentOffset();
if (!module_->addProfiledFunction(func.name(), startCodeOffset, endCodeOffset, line, column))
tokenStream().srcCoords.lineNumAndColumnIndex(func.srcBegin(), &line, &column);
if (!module_->addProfiledFunction(name, codeBegin, codeEnd, line, column))
return false;
# ifdef JS_ION_PERF
// Per-block profiling info uses significantly more memory so only store
// this information if it is actively requested.
if (PerfBlockEnabled()) {
// Per-block profiling info uses significantly more memory so only
// store this information if it is actively requested.
mir.perfSpewer().noteBlocksOffsets();
unsigned endInlineCodeOffset = mir.perfSpewer().endInlineCode.offset();
if (!module_->addPerfProfiledBlocks(func.name(), startCodeOffset, endInlineCodeOffset,
endCodeOffset, mir.perfSpewer().basicBlocks()))
{
AsmJSPerfSpewer &ps = mir.perfSpewer();
ps.noteBlocksOffsets();
unsigned inlineEnd = ps.endInlineCode.offset();
if (!module_->addProfiledBlocks(name, codeBegin, inlineEnd, codeEnd, ps.basicBlocks()))
return false;
}
}
# endif
#endif
@ -5423,11 +5420,11 @@ CheckFunctionsSequential(ModuleCompiler &m)
IonSpewNewFunction(&mir->graph(), NullPtr());
if (!OptimizeMIR(mir))
return m.failOffset(func->srcOffset(), "internal compiler failure (probably out of memory)");
return m.failOffset(func->srcBegin(), "internal compiler failure (probably out of memory)");
LIRGraph *lir = GenerateLIR(mir);
if (!lir)
return m.failOffset(func->srcOffset(), "internal compiler failure (probably out of memory)");
return m.failOffset(func->srcBegin(), "internal compiler failure (probably out of memory)");
func->accumulateCompileTime((PRMJ_Now() - before) / PRMJ_USEC_PER_MSEC);
@ -5687,7 +5684,7 @@ CheckFunctionsParallel(ModuleCompiler &m)
// If failure was triggered by a helper thread, report error.
if (void *maybeFunc = HelperThreadState().maybeAsmJSFailedFunction()) {
ModuleCompiler::Func *func = reinterpret_cast<ModuleCompiler::Func *>(maybeFunc);
return m.failOffset(func->srcOffset(), "allocation failure during compilation");
return m.failOffset(func->srcBegin(), "allocation failure during compilation");
}
// Otherwise, the error occurred on the main thread and was already reported.
@ -5872,7 +5869,7 @@ AssertStackAlignment(MacroAssembler &masm)
Label ok;
JS_ASSERT(IsPowerOfTwo(StackAlignment));
masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(StackAlignment - 1), &ok);
masm.assumeUnreachable("Stack should be aligned.");
masm.breakpoint();
masm.bind(&ok);
#endif
}
@ -5927,16 +5924,6 @@ static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * siz
NonVolatileRegs.fpus().size() * sizeof(double);
#endif
// On ARM/MIPS, we need to include an extra word of space at the top of the
// stack so we can explicitly store the return address before making the call
// to C++ or Ion. On x86/x64, this isn't necessary since the call instruction
// pushes the return address.
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
static const unsigned MaybeRetAddr = sizeof(void*);
#else
static const unsigned MaybeRetAddr = 0;
#endif
static bool
GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFunc)
{
@ -6229,10 +6216,10 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
invokeArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
// At the point of the call, the stack layout shall be (sp grows to the left):
// | retaddr | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
// The first padding ensures double-alignment of argv; the second ensures
// sp is aligned.
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes) + MaybeRetAddr, StackAlignment);
// | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
// The padding between stack args and argv ensures that sp is aligned. The
// padding between argv and retaddr ensures that argv is aligned.
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes), StackAlignment);
unsigned argvBytes = Max<size_t>(1, exit.sig().args().length()) * sizeof(Value);
unsigned stackDec = StackDecrementForCall(masm, offsetToArgv + argvBytes);
masm.reserveStack(stackDec);
@ -6313,67 +6300,15 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
masm.ret();
}
static void
GenerateOOLConvert(ModuleCompiler &m, RetType retType, Label *throwLabel)
{
MacroAssembler &masm = m.masm();
MIRType typeArray[] = { MIRType_Pointer, // cx
MIRType_Pointer }; // argv
MIRTypeVector callArgTypes(m.cx());
callArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
// The stack is assumed to be aligned. The frame is allocated by GenerateFFIIonExit and
// the stack usage here needs to kept in sync with GenerateFFIIonExit.
// Store value
unsigned offsetToArgv = StackArgBytes(callArgTypes) + MaybeRetAddr;
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToArgv));
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
Register activation = ABIArgGenerator::NonArgReturnVolatileReg1;
LoadAsmJSActivationIntoRegister(masm, activation);
// Store real arguments
ABIArgMIRTypeIter i(callArgTypes);
// argument 0: cx
if (i->kind() == ABIArg::GPR) {
LoadJSContextFromActivation(masm, activation, i->gpr());
} else {
LoadJSContextFromActivation(masm, activation, scratch);
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
// argument 1: argv
Address argv(StackPointer, offsetToArgv);
if (i->kind() == ABIArg::GPR) {
masm.computeEffectiveAddress(argv, i->gpr());
} else {
masm.computeEffectiveAddress(argv, scratch);
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
JS_ASSERT(i.done());
// Call
AssertStackAlignment(masm);
switch (retType.which()) {
case RetType::Signed:
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToInt32));
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
break;
case RetType::Double:
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToNumber));
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnDoubleReg);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
}
}
// On ARM/MIPS, we need to include an extra word of space at the top of the
// stack so we can explicitly store the return address before making the call
// to C++ or Ion. On x86/x64, this isn't necessary since the call instruction
// pushes the return address.
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
static const unsigned MaybeRetAddr = sizeof(void*);
#else
static const unsigned MaybeRetAddr = 0;
#endif
static void
GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit,
@ -6391,60 +6326,64 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
masm.push(ra);
#endif
// Store the frame pointer in AsmJSActivation::exitFP for stack unwinding.
Register activation = ABIArgGenerator::NonArgReturnVolatileReg0;
LoadAsmJSActivationIntoRegister(masm, activation);
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfExitFP()));
// 'callee' stays live throughout much of the Ion exit and 'scratch' is
// constantly clobbered.
Register callee = ABIArgGenerator::NonArgReturnVolatileReg0;
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
// Ion does not preserve nonvolatile registers, so we have to preserve them.
// Store the frame pointer in AsmJSActivation::exitFP for stack unwinding.
LoadAsmJSActivationIntoRegister(masm, scratch);
masm.storePtr(StackPointer, Address(scratch, AsmJSActivation::offsetOfExitFP()));
// Even though the caller has saved volatile registers, we still need to
// save/restore globally-pinned asm.js registers at Ion calls since Ion does
// not preserve non-volatile registers.
#if defined(JS_CODEGEN_X64)
masm.Push(HeapReg);
unsigned savedRegBytes = 1 * sizeof(void*); // HeapReg
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
masm.PushRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
unsigned savedRegBytes = 2 * sizeof(void*); // HeapReg, GlobalReg
#else
unsigned savedRegBytes = 0;
#endif
// The stack frame is used for the call into Ion and also for calls into C for OOL
// conversion of the result. A frame large enough for both is allocated.
//
// Arguments to the Ion function are in the following order on the stack:
// | return address | descriptor | callee | argc | this | arg1 | arg2 | ...
unsigned argBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
unsigned offsetToArgs = MaybeRetAddr;
unsigned stackDecForIonCall = StackDecrementForCall(masm, argBytes + offsetToArgs);
// The same stack frame is used for the call into Ion and (possibly) a call
// into C++ to coerce the return type. To do this, we compute the amount of
// space required for both calls and take the maximum. In both cases,
// include space for savedRegBytes, since these go below the Ion/coerce.
// Reserve space for a call to AsmJSImm_CoerceInPlace_* and an array of values used by
// OOLConvert which reuses the same frame. This code needs to be kept in sync with the
// stack usage in GenerateOOLConvert.
MIRType typeArray[] = { MIRType_Pointer, MIRType_Pointer }; // cx, argv
MIRTypeVector callArgTypes(m.cx());
callArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
unsigned oolExtraBytes = sizeof(Value) + MaybeRetAddr;
unsigned stackDecForOOLCall = StackDecrementForCall(masm, callArgTypes, oolExtraBytes);
// Ion calls use the following stack layout (sp grows to the left):
// | return address | descriptor | callee | argc | this | arg1 | arg2 | ...
unsigned offsetToArgs = MaybeRetAddr;
unsigned argBytes = 3 * sizeof(size_t) + (1 + exit.sig().args().length()) * sizeof(Value);
unsigned totalIonBytes = offsetToArgs + argBytes + savedRegBytes;
unsigned ionFrameSize = StackDecrementForCall(masm, totalIonBytes);
// Coercion calls use the following stack layout (sp grows to the left):
// | stack args | Value argv[1] | ...
MIRTypeVector coerceArgTypes(m.cx());
coerceArgTypes.infallibleAppend(MIRType_Pointer); // cx
coerceArgTypes.infallibleAppend(MIRType_Pointer); // argv
unsigned bytesAfterArgs = sizeof(Value) + savedRegBytes;
unsigned coerceFrameSize = StackDecrementForCall(masm, coerceArgTypes, bytesAfterArgs);
// Allocate a frame large enough for both of the above calls.
unsigned stackDec = Max(stackDecForIonCall, stackDecForOOLCall);
masm.reserveStack(stackDec);
AssertStackAlignment(masm);
unsigned framePushed = Max(ionFrameSize, coerceFrameSize);
masm.reserveStack(framePushed);
// 1. Descriptor
size_t argOffset = offsetToArgs;
uint32_t descriptor = MakeFrameDescriptor(masm.framePushed(), JitFrame_Entry);
uint32_t descriptor = MakeFrameDescriptor(framePushed, JitFrame_Entry);
masm.storePtr(ImmWord(uintptr_t(descriptor)), Address(StackPointer, argOffset));
argOffset += sizeof(size_t);
// 2. Callee
Register callee = ABIArgGenerator::NonArgReturnVolatileReg0;
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg1;
// 2.1. Get ExitDatum
unsigned globalDataOffset = m.module().exitIndexToGlobalDataOffset(exitIndex);
#if defined(JS_CODEGEN_X64)
CodeOffsetLabel label2 = masm.leaRipRelative(callee);
m.masm().append(AsmJSGlobalAccess(CodeOffsetLabel(label2.offset()), globalDataOffset));
m.masm().append(AsmJSGlobalAccess(masm.leaRipRelative(callee), globalDataOffset));
#elif defined(JS_CODEGEN_X86)
CodeOffsetLabel label2 = masm.movlWithPatch(Imm32(0), callee);
m.masm().append(AsmJSGlobalAccess(CodeOffsetLabel(label2.offset()), globalDataOffset));
m.masm().append(AsmJSGlobalAccess(masm.movlWithPatch(Imm32(0), callee), globalDataOffset));
#else
masm.lea(Operand(GlobalReg, globalDataOffset), callee);
#endif
@ -6456,6 +6395,10 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
masm.storePtr(callee, Address(StackPointer, argOffset));
argOffset += sizeof(size_t);
// 2.4. Load callee executable entry point
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
masm.loadBaselineOrIonNoArgCheck(callee, callee, SequentialExecution, nullptr);
// 3. Argc
unsigned argc = exit.sig().args().length();
masm.storePtr(ImmWord(uintptr_t(argc)), Address(StackPointer, argOffset));
@ -6466,26 +6409,22 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
argOffset += sizeof(Value);
// 5. Fill the arguments
unsigned offsetToCallerStackArgs = masm.framePushed() + AsmJSFrameSize;
unsigned offsetToCallerStackArgs = framePushed + AsmJSFrameSize;
FillArgumentArray(m, exit.sig().args(), argOffset, offsetToCallerStackArgs, scratch);
argOffset += exit.sig().args().length() * sizeof(Value);
JS_ASSERT(argOffset == offsetToArgs + argBytes);
// Get the pointer to the ion code
Label done, oolConvert;
Label *maybeDebugBreakpoint = nullptr;
#ifdef DEBUG
Label ionFailed;
maybeDebugBreakpoint = &ionFailed;
masm.branchIfFunctionHasNoScript(callee, &ionFailed);
// 6. Store asm.js pinned registers
#if defined(JS_CODEGEN_X64)
unsigned savedHeapOffset = framePushed - sizeof(void*);
masm.storePtr(HeapReg, Address(StackPointer, savedHeapOffset));
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
unsigned savedHeapOffset = framePushed - 1 * sizeof(void*);
unsigned savedGlobalOffset = framePushed - 2 * sizeof(void*);
masm.storePtr(HeapReg, Address(StackPointer, savedHeapOffset));
masm.storePtr(GlobalReg, Address(StackPointer, savedGlobalOffset));
#endif
masm.loadPtr(Address(callee, JSFunction::offsetOfNativeOrScript()), callee);
masm.loadBaselineOrIonNoArgCheck(callee, callee, SequentialExecution, maybeDebugBreakpoint);
AssertStackAlignment(masm);
{
// Enable Activation.
//
@ -6557,14 +6496,9 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
masm.storePtr(reg2, Address(reg0, offsetOfJitJSContext));
}
#ifdef DEBUG
masm.branchTestMagicValue(Assembler::Equal, JSReturnOperand, JS_ION_ERROR, throwLabel);
masm.branchTestMagic(Assembler::Equal, JSReturnOperand, &ionFailed);
#else
masm.branchTestMagic(Assembler::Equal, JSReturnOperand, throwLabel);
#endif
uint32_t oolConvertFramePushed = masm.framePushed();
Label oolConvert;
switch (exit.sig().retType().which()) {
case RetType::Void:
break;
@ -6580,37 +6514,79 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
break;
}
Label done;
masm.bind(&done);
masm.freeStack(stackDec);
// Restore non-volatile registers saved in the prologue.
JS_ASSERT(masm.framePushed() == framePushed);
#if defined(JS_CODEGEN_X64)
masm.Pop(HeapReg);
masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg);
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
masm.loadConstantDouble(GenericNaN(), NANReg);
masm.PopRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
masm.loadPtr(Address(StackPointer, savedHeapOffset), HeapReg);
masm.loadPtr(Address(StackPointer, savedGlobalOffset), GlobalReg);
#endif
masm.freeStack(framePushed);
// Clear exitFP before the frame is destroyed.
LoadAsmJSActivationIntoRegister(masm, activation);
masm.storePtr(ImmWord(0), Address(activation, AsmJSActivation::offsetOfExitFP()));
LoadAsmJSActivationIntoRegister(masm, scratch);
masm.storePtr(ImmWord(0), Address(scratch, AsmJSActivation::offsetOfExitFP()));
masm.ret();
JS_ASSERT(masm.framePushed() == 0);
// oolConvert
if (oolConvert.used()) {
masm.bind(&oolConvert);
masm.setFramePushed(oolConvertFramePushed);
GenerateOOLConvert(m, exit.sig().retType(), throwLabel);
masm.setFramePushed(0);
masm.setFramePushed(framePushed);
// Store return value into argv[0]
unsigned offsetToArgv = StackArgBytes(coerceArgTypes);
JS_ASSERT(offsetToArgv % sizeof(Value) == 0);
masm.storeValue(JSReturnOperand, Address(StackPointer, offsetToArgv));
ABIArgMIRTypeIter i(coerceArgTypes);
// argument 0: cx
LoadAsmJSActivationIntoRegister(masm, scratch);
if (i->kind() == ABIArg::GPR) {
LoadJSContextFromActivation(masm, scratch, i->gpr());
} else {
LoadJSContextFromActivation(masm, scratch, scratch);
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
// argument 1: argv
Address argv(StackPointer, offsetToArgv);
if (i->kind() == ABIArg::GPR) {
masm.computeEffectiveAddress(argv, i->gpr());
} else {
masm.computeEffectiveAddress(argv, scratch);
masm.storePtr(scratch, Address(StackPointer, i->offsetFromArgBase()));
}
i++;
JS_ASSERT(i.done());
// Call coercion function
AssertStackAlignment(masm);
switch (exit.sig().retType().which()) {
case RetType::Signed:
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToInt32));
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
masm.unboxInt32(Address(StackPointer, offsetToArgv), ReturnReg);
break;
case RetType::Double:
masm.call(AsmJSImmPtr(AsmJSImm_CoerceInPlace_ToNumber));
masm.branchTest32(Assembler::Zero, ReturnReg, ReturnReg, throwLabel);
masm.loadDouble(Address(StackPointer, offsetToArgv), ReturnDoubleReg);
break;
default:
MOZ_ASSUME_UNREACHABLE("Unsupported convert type");
}
masm.jump(&done);
masm.setFramePushed(0);
}
#ifdef DEBUG
masm.bind(&ionFailed);
masm.assumeUnreachable("AsmJS to IonMonkey call failed.");
#endif
JS_ASSERT(masm.framePushed() == 0);
}
// See "asm.js FFI calls" comment above.
@ -6646,7 +6622,7 @@ GenerateStackOverflowExit(ModuleCompiler &m, Label *throwLabel)
MIRTypeVector argTypes(m.cx());
argTypes.infallibleAppend(MIRType_Pointer); // cx
unsigned stackDec = StackDecrementForCall(masm, argTypes, MaybeRetAddr);
unsigned stackDec = StackDecrementForCall(masm, argTypes);
masm.reserveStack(stackDec);
ABIArgMIRTypeIter i(argTypes);

View File

@ -468,8 +468,8 @@ HandleDynamicLinkFailure(JSContext *cx, CallArgs args, AsmJSModule &module, Hand
if (cx->isExceptionPending())
return false;
uint32_t begin = module.offsetToEndOfUseAsm();
uint32_t end = module.funcEndBeforeCurly();
uint32_t begin = module.srcBodyStart(); // starts right after 'use asm'
uint32_t end = module.srcEndBeforeCurly();
Rooted<JSFlatString*> src(cx, module.scriptSource()->substring(cx, begin, end));
if (!src)
return false;
@ -818,8 +818,8 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
{
AsmJSModule &module = ModuleFunctionToModuleObject(fun).module();
uint32_t begin = module.funcStart();
uint32_t end = module.funcEndAfterCurly();
uint32_t begin = module.srcStart();
uint32_t end = module.srcEndAfterCurly();
ScriptSource *source = module.scriptSource();
StringBuffer out(cx);
@ -917,8 +917,8 @@ js::AsmJSFunctionToString(JSContext *cx, HandleFunction fun)
{
AsmJSModule &module = FunctionToEnclosingModule(fun);
const AsmJSModule::ExportedFunction &f = FunctionToExportedFunction(fun, module);
uint32_t begin = module.funcStart() + f.startOffsetInModule();
uint32_t end = module.funcStart() + f.endOffsetInModule();
uint32_t begin = module.srcStart() + f.startOffsetInModule();
uint32_t end = module.srcStart() + f.endOffsetInModule();
ScriptSource *source = module.scriptSource();
StringBuffer out(cx);

View File

@ -75,10 +75,10 @@ DeallocateExecutableMemory(uint8_t *code, size_t totalBytes)
#endif
}
AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t funcStart,
uint32_t offsetToEndOfUseAsm, bool strict)
: funcStart_(funcStart),
offsetToEndOfUseAsm_(offsetToEndOfUseAsm),
AsmJSModule::AsmJSModule(ScriptSource *scriptSource, uint32_t srcStart, uint32_t srcBodyStart,
bool strict)
: srcStart_(srcStart),
srcBodyStart_(srcBodyStart),
scriptSource_(scriptSource),
globalArgumentName_(nullptr),
importArgumentName_(nullptr),
@ -278,10 +278,10 @@ AsmJSModule::finish(ExclusiveContext *cx, TokenStream &tokenStream, MacroAssembl
uint32_t endBeforeCurly = tokenStream.currentToken().pos.end;
uint32_t endAfterCurly = tokenStream.peekTokenPos().end;
JS_ASSERT(endBeforeCurly >= offsetToEndOfUseAsm_);
JS_ASSERT(endAfterCurly >= offsetToEndOfUseAsm_);
pod.funcLength_ = endBeforeCurly - funcStart_;
pod.funcLengthWithRightBrace_ = endAfterCurly - funcStart_;
JS_ASSERT(endBeforeCurly >= srcBodyStart_);
JS_ASSERT(endAfterCurly >= srcBodyStart_);
pod.srcLength_ = endBeforeCurly - srcStart_;
pod.srcLengthWithRightBrace_ = endAfterCurly - srcStart_;
// The global data section sits immediately after the executable (and
// other) data allocated by the MacroAssembler, so ensure it is
@ -337,6 +337,8 @@ AsmJSModule::finish(ExclusiveContext *cx, TokenStream &tokenStream, MacroAssembl
CodeRange &c = codeRanges_[i];
c.begin_ = masm.actualOffset(c.begin_);
c.end_ = masm.actualOffset(c.end_);
JS_ASSERT(c.begin_ <= c.end_);
JS_ASSERT_IF(i > 0, codeRanges_[i - 1].end_ <= c.begin_);
}
#endif
JS_ASSERT(pod.functionBytes_ % AsmJSPageSize == 0);
@ -510,14 +512,6 @@ RedirectCall(void *fun, ABIFunctionType type)
return fun;
}
#ifdef DEBUG
static void
AssumeUnreachable()
{
MOZ_CRASH("Reached unreachable code in asm.js");
}
#endif
static void *
AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
{
@ -578,10 +572,6 @@ AddressOf(AsmJSImmKind kind, ExclusiveContext *cx)
return RedirectCall(FuncCast(ecmaPow), Args_Double_DoubleDouble);
case AsmJSImm_ATan2D:
return RedirectCall(FuncCast(ecmaAtan2), Args_Double_DoubleDouble);
#ifdef DEBUG
case AsmJSImm_AssumeUnreachable:
return RedirectCall(FuncCast(AssumeUnreachable), Args_General0);
#endif
case AsmJSImm_Invalid:
break;
}
@ -1224,7 +1214,7 @@ AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) con
{
AutoUnprotectCodeForClone cloneGuard(cx, *this);
*moduleOut = cx->new_<AsmJSModule>(scriptSource_, funcStart_, offsetToEndOfUseAsm_, pod.strict_);
*moduleOut = cx->new_<AsmJSModule>(scriptSource_, srcStart_, srcBodyStart_, pod.strict_);
if (!*moduleOut)
return false;
@ -1681,11 +1671,11 @@ js::LookupAsmJSModuleInCache(ExclusiveContext *cx,
if (!moduleChars.match(parser))
return true;
uint32_t funcStart = parser.pc->maybeFunction->pn_body->pn_pos.begin;
uint32_t offsetToEndOfUseAsm = parser.tokenStream.currentToken().pos.end;
uint32_t srcStart = parser.pc->maybeFunction->pn_body->pn_pos.begin;
uint32_t srcBodyStart = parser.tokenStream.currentToken().pos.end;
bool strict = parser.pc->sc->strict && !parser.pc->sc->hasExplicitUseStrict();
ScopedJSDeletePtr<AsmJSModule> module(
cx->new_<AsmJSModule>(parser.ss, funcStart, offsetToEndOfUseAsm, strict));
cx->new_<AsmJSModule>(parser.ss, srcStart, srcBodyStart, strict));
if (!module)
return false;
cursor = module->deserialize(cx, cursor);
@ -1706,7 +1696,7 @@ js::LookupAsmJSModuleInCache(ExclusiveContext *cx,
module->staticallyLink(cx);
parser.tokenStream.advance(module->funcEndBeforeCurly());
parser.tokenStream.advance(module->srcEndBeforeCurly());
int64_t usecAfter = PRMJ_Now();
int ms = (usecAfter - usecBefore) / PRMJ_USEC_PER_MSEC;

View File

@ -490,8 +490,8 @@ class AsmJSModule
uint32_t minHeapLength_;
uint32_t numGlobalVars_;
uint32_t numFFIs_;
uint32_t funcLength_;
uint32_t funcLengthWithRightBrace_;
uint32_t srcLength_;
uint32_t srcLengthWithRightBrace_;
bool strict_;
bool hasArrayView_;
} pod;
@ -499,8 +499,8 @@ class AsmJSModule
// These two fields need to be kept out pod as they depend on the position
// of the module within the ScriptSource and thus aren't invariant with
// respect to caching.
const uint32_t funcStart_;
const uint32_t offsetToEndOfUseAsm_;
const uint32_t srcStart_;
const uint32_t srcBodyStart_;
Vector<Global, 0, SystemAllocPolicy> globals_;
Vector<Exit, 0, SystemAllocPolicy> exits_;
@ -533,8 +533,8 @@ class AsmJSModule
mutable bool codeIsProtected_;
public:
explicit AsmJSModule(ScriptSource *scriptSource, uint32_t functStart,
uint32_t offsetToEndOfUseAsm, bool strict);
explicit AsmJSModule(ScriptSource *scriptSource, uint32_t srcStart, uint32_t srcBodyStart,
bool strict);
void trace(JSTracer *trc);
~AsmJSModule();
@ -559,18 +559,19 @@ class AsmJSModule
return loadedFromCache_;
}
// funcStart() refers to the offset in the ScriptSource to the beginning
// of the function. If the function has been created with the Function
// constructor, this will be the first character in the function source.
// Otherwise, it will be the opening parenthesis of the arguments list.
uint32_t funcStart() const {
return funcStart_;
// srcStart() refers to the offset in the ScriptSource to the beginning of
// the asm.js module function. If the function has been created with the
// Function constructor, this will be the first character in the function
// source. Otherwise, it will be the opening parenthesis of the arguments
// list.
uint32_t srcStart() const {
return srcStart_;
}
// offsetToEndOfUseAsm() refers to the offset in the ScriptSource to the end
// srcBodyStart() refers to the offset in the ScriptSource to the end
// of the 'use asm' string-literal token.
uint32_t offsetToEndOfUseAsm() const {
return offsetToEndOfUseAsm_;
uint32_t srcBodyStart() const {
return srcBodyStart_;
}
// While these functions may be accessed at any time, their values will
@ -697,8 +698,6 @@ class AsmJSModule
bool addFunctionCodeRange(PropertyName *name, uint32_t begin, uint32_t end) {
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
JS_ASSERT(name->isTenured());
JS_ASSERT(begin <= end);
JS_ASSERT_IF(!codeRanges_.empty(), codeRanges_.back().end() <= begin);
if (functionNames_.length() >= UINT32_MAX)
return false;
CodeRange codeRange(CodeRange::Function, begin, end, functionNames_.length());
@ -745,11 +744,11 @@ class AsmJSModule
return functionCounts_.append(counts);
}
#if defined(MOZ_VTUNE) || defined(JS_ION_PERF)
bool addProfiledFunction(PropertyName *name, unsigned startCodeOffset, unsigned endCodeOffset,
bool addProfiledFunction(PropertyName *name, unsigned codeStart, unsigned codeEnd,
unsigned line, unsigned column)
{
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
ProfiledFunction func(name, startCodeOffset, endCodeOffset, line, column);
ProfiledFunction func(name, codeStart, codeEnd, line, column);
return profiledFunctions_.append(func);
}
unsigned numProfiledFunctions() const {
@ -762,13 +761,11 @@ class AsmJSModule
}
#endif
#ifdef JS_ION_PERF
bool addPerfProfiledBlocks(PropertyName *name, unsigned startCodeOffset,
unsigned endInlineCodeOffset, unsigned endCodeOffset,
jit::BasicBlocksVector &basicBlocks)
bool addProfiledBlocks(PropertyName *name, unsigned codeBegin, unsigned inlineEnd,
unsigned codeEnd, jit::BasicBlocksVector &basicBlocks)
{
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
ProfiledBlocksFunction func(name, startCodeOffset, endInlineCodeOffset, endCodeOffset,
basicBlocks);
ProfiledBlocksFunction func(name, codeBegin, inlineEnd, codeEnd, basicBlocks);
return perfProfiledBlocksFunctions_.append(mozilla::Move(func));
}
unsigned numPerfBlocksFunctions() const {
@ -845,13 +842,13 @@ class AsmJSModule
JS_ASSERT(isFinished());
return pod.numFFIs_;
}
uint32_t funcEndBeforeCurly() const {
uint32_t srcEndBeforeCurly() const {
JS_ASSERT(isFinished());
return funcStart_ + pod.funcLength_;
return srcStart_ + pod.srcLength_;
}
uint32_t funcEndAfterCurly() const {
uint32_t srcEndAfterCurly() const {
JS_ASSERT(isFinished());
return funcStart_ + pod.funcLengthWithRightBrace_;
return srcStart_ + pod.srcLengthWithRightBrace_;
}
uint8_t *codeBase() const {
JS_ASSERT(isFinished());

View File

@ -8570,7 +8570,7 @@ CodeGenerator::visitAsmJSCall(LAsmJSCall *ins)
Label ok;
JS_ASSERT(IsPowerOfTwo(StackAlignment));
masm.branchTestPtr(Assembler::Zero, StackPointer, Imm32(StackAlignment - 1), &ok);
masm.assumeUnreachable("Stack should be aligned.");
masm.breakpoint();
masm.bind(&ok);
#endif

View File

@ -1429,6 +1429,12 @@ SnapshotIterator::SnapshotIterator()
{
}
int32_t
SnapshotIterator::readOuterNumActualArgs() const
{
return fp_->numActualArgs();
}
uintptr_t
SnapshotIterator::fromStack(int32_t offset) const
{

View File

@ -1339,24 +1339,18 @@ void
MacroAssembler::assumeUnreachable(const char *output)
{
#ifdef DEBUG
RegisterSet regs = RegisterSet::Volatile();
PushRegsInMask(regs);
Register temp = regs.takeGeneral();
if (!IsCompilingAsmJS()) {
RegisterSet regs = RegisterSet::Volatile();
PushRegsInMask(regs);
Register temp = regs.takeGeneral();
// With ASLR, we can't rely on 'output' to point to the
// same char array after serialization/deserialization.
// It is not possible until we modify AsmJsImmPtr and
// the underlying "patching" mechanism.
if (IsCompilingAsmJS()) {
setupUnalignedABICall(0, temp);
callWithABINoProfiling(AsmJSImm_AssumeUnreachable);
} else {
setupUnalignedABICall(1, temp);
movePtr(ImmPtr(output), temp);
passABIArg(temp);
callWithABINoProfiling(JS_FUNC_TO_DATA_PTR(void *, AssumeUnreachable_));
PopRegsInMask(RegisterSet::Volatile());
}
PopRegsInMask(RegisterSet::Volatile());
#endif
breakpoint();

View File

@ -329,6 +329,8 @@ class SnapshotIterator
return snapshot_.numAllocationsRead() < numAllocations();
}
int32_t readOuterNumActualArgs() const;
public:
// Exhibits frame properties contained in the snapshot.
uint32_t pcOffset() const;

View File

@ -6255,11 +6255,7 @@ class MNot
}
bool writeRecoverData(CompactBufferWriter &writer) const;
bool canRecoverOnBailout() const {
// Non objects are recoverable and objects that cannot emulate
// undefined get folded into 'true' by GVN.
// So the only way to reach this function with an operand that
// is an object is when that object might emulate undefined.
return !operandMightEmulateUndefined_;
return true;
}
};
@ -9362,6 +9358,12 @@ class MArgumentsLength : public MNullaryInstruction
}
void computeRange(TempAllocator &alloc);
bool writeRecoverData(CompactBufferWriter &writer) const;
bool canRecoverOnBailout() const {
return true;
}
};
// This MIR instruction is used to get an argument from the actual arguments.

View File

@ -501,7 +501,6 @@ RNot::recover(JSContext *cx, SnapshotIterator &iter) const
RootedValue v(cx, iter.read());
RootedValue result(cx);
MOZ_ASSERT(!v.isObject());
result.setBoolean(!ToBoolean(v));
iter.storeInstructionResult(result);
@ -559,6 +558,28 @@ MStringLength::writeRecoverData(CompactBufferWriter &writer) const
return true;
}
bool
MArgumentsLength::writeRecoverData(CompactBufferWriter &writer) const
{
MOZ_ASSERT(canRecoverOnBailout());
writer.writeUnsigned(uint32_t(RInstruction::Recover_ArgumentsLength));
return true;
}
RArgumentsLength::RArgumentsLength(CompactBufferReader &reader)
{ }
bool
RArgumentsLength::recover(JSContext *cx, SnapshotIterator &iter) const
{
RootedValue result(cx);
result.setInt32(iter.readOuterNumActualArgs());
iter.storeInstructionResult(result);
return true;
}
bool
MFloor::writeRecoverData(CompactBufferWriter &writer) const
{

View File

@ -33,6 +33,7 @@ namespace jit {
_(Not) \
_(Concat) \
_(StringLength) \
_(ArgumentsLength) \
_(Floor) \
_(Round) \
_(CharCodeAt) \
@ -292,7 +293,7 @@ class RConcat MOZ_FINAL : public RInstruction
class RStringLength MOZ_FINAL : public RInstruction
{
public:
public:
RINSTRUCTION_HEADER_(StringLength)
virtual uint32_t numOperands() const {
@ -302,6 +303,19 @@ public:
bool recover(JSContext *cx, SnapshotIterator &iter) const;
};
class RArgumentsLength MOZ_FINAL : public RInstruction
{
public:
RINSTRUCTION_HEADER_(ArgumentsLength)
virtual uint32_t numOperands() const {
return 0;
}
bool recover(JSContext *cx, SnapshotIterator &iter) const;
};
class RFloor MOZ_FINAL : public RInstruction
{
public:

View File

@ -1849,7 +1849,8 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
masm.ma_mov(Imm32(0), d, NoSetCond, Assembler::AboveOrEqual);
masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below);
}
return masm.append(AsmJSHeapAccess(bo.getOffset()));
masm.append(AsmJSHeapAccess(bo.getOffset()));
return true;
}
bool
@ -1916,7 +1917,8 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, ptrReg,
ToRegister(ins->value()), Offset, Assembler::Below);
}
return masm.append(AsmJSHeapAccess(bo.getOffset()));
masm.append(AsmJSHeapAccess(bo.getOffset()));
return true;
}
bool

View File

@ -2067,7 +2067,7 @@ MacroAssemblerARMCompat::movePtr(AsmJSImmPtr imm, Register dest)
else
rs = L_LDR;
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
ma_movPatchable(Imm32(-1), dest, Always, rs);
}
void

View File

@ -566,11 +566,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
}
void call(const CallSiteDesc &desc, const Register reg) {
call(reg);
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
append(desc, currentOffset(), framePushed_);
}
void call(const CallSiteDesc &desc, Label *label) {
call(label);
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
append(desc, currentOffset(), framePushed_);
}
void branch(JitCode *c) {

View File

@ -1985,7 +1985,8 @@ CodeGeneratorMIPS::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
}
masm.bind(&done);
return masm.append(AsmJSHeapAccess(bo.getOffset()));
masm.append(AsmJSHeapAccess(bo.getOffset()));
return true;
}
bool
@ -2061,7 +2062,8 @@ CodeGeneratorMIPS::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
}
masm.bind(&rejoin);
return masm.append(AsmJSHeapAccess(bo.getOffset()));
masm.append(AsmJSHeapAccess(bo.getOffset()));
return true;
}
bool

View File

@ -1795,8 +1795,7 @@ MacroAssemblerMIPSCompat::movePtr(ImmPtr imm, Register dest)
void
MacroAssemblerMIPSCompat::movePtr(AsmJSImmPtr imm, Register dest)
{
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()),
imm.kind()));
append(AsmJSAbsoluteLink(CodeOffsetLabel(nextOffset().getOffset()), imm.kind()));
ma_liPatchable(dest, Imm32(-1));
}

View File

@ -414,11 +414,11 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
}
void call(const CallSiteDesc &desc, const Register reg) {
call(reg);
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
append(desc, currentOffset(), framePushed_);
}
void call(const CallSiteDesc &desc, Label *label) {
call(label);
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
append(desc, currentOffset(), framePushed_);
}
void branch(JitCode *c) {

View File

@ -737,9 +737,6 @@ enum AsmJSImmKind
AsmJSImm_LogD,
AsmJSImm_PowD,
AsmJSImm_ATan2D,
#ifdef DEBUG
AsmJSImm_AssumeUnreachable,
#endif
AsmJSImm_Invalid
};
@ -800,21 +797,22 @@ class AssemblerShared
return !enoughMemory_;
}
bool append(const CallSiteDesc &desc, size_t currentOffset, size_t framePushed) {
void append(const CallSiteDesc &desc, size_t currentOffset, size_t framePushed) {
// framePushed does not include AsmJSFrameSize, so add it in here (see
// CallSite::stackDepth).
return callsites_.append(CallSite(desc, currentOffset, framePushed + AsmJSFrameSize));
CallSite callsite(desc, currentOffset, framePushed + AsmJSFrameSize);
enoughMemory_ &= callsites_.append(callsite);
}
CallSiteVector &&extractCallSites() { return Move(callsites_); }
bool append(AsmJSHeapAccess access) { return asmJSHeapAccesses_.append(access); }
void append(AsmJSHeapAccess access) { enoughMemory_ &= asmJSHeapAccesses_.append(access); }
AsmJSHeapAccessVector &&extractAsmJSHeapAccesses() { return Move(asmJSHeapAccesses_); }
bool append(AsmJSGlobalAccess access) { return asmJSGlobalAccesses_.append(access); }
void append(AsmJSGlobalAccess access) { enoughMemory_ &= asmJSGlobalAccesses_.append(access); }
size_t numAsmJSGlobalAccesses() const { return asmJSGlobalAccesses_.length(); }
AsmJSGlobalAccess asmJSGlobalAccess(size_t i) const { return asmJSGlobalAccesses_[i]; }
bool append(AsmJSAbsoluteLink link) { return asmJSAbsoluteLinks_.append(link); }
void append(AsmJSAbsoluteLink link) { enoughMemory_ &= asmJSAbsoluteLinks_.append(link); }
size_t numAsmJSAbsoluteLinks() const { return asmJSAbsoluteLinks_.length(); }
AsmJSAbsoluteLink asmJSAbsoluteLink(size_t i) const { return asmJSAbsoluteLinks_[i]; }
};

View File

@ -669,11 +669,11 @@ class MacroAssemblerX86Shared : public Assembler
void call(const CallSiteDesc &desc, Label *label) {
call(label);
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
append(desc, currentOffset(), framePushed_);
}
void call(const CallSiteDesc &desc, Register reg) {
call(reg);
enoughMemory_ &= append(desc, currentOffset(), framePushed_);
append(desc, currentOffset(), framePushed_);
}
void callIon(Register callee) {
call(callee);

View File

@ -545,7 +545,7 @@ class Assembler : public AssemblerX86Shared
}
void mov(AsmJSImmPtr imm, Register dest) {
masm.movq_i64r(-1, dest.code());
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
}
void mov(const Operand &src, Register dest) {
movq(src, dest);

View File

@ -274,7 +274,9 @@ CodeGeneratorX64::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
default: MOZ_ASSUME_UNREACHABLE("unexpected array type");
}
uint32_t after = masm.size();
return skipNote || masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(ins->output())));
if (!skipNote)
masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(ins->output())));
return true;
}
bool
@ -322,7 +324,9 @@ CodeGeneratorX64::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
}
}
uint32_t after = masm.size();
return skipNote || masm.append(AsmJSHeapAccess(before, after));
if (!skipNote)
masm.append(AsmJSHeapAccess(before, after));
return true;
}
bool
@ -335,8 +339,8 @@ CodeGeneratorX64::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins)
label = masm.loadRipRelativeInt32(ToRegister(ins->output()));
else
label = masm.loadRipRelativeDouble(ToFloatRegister(ins->output()));
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
bool
@ -352,8 +356,8 @@ CodeGeneratorX64::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins)
label = masm.storeRipRelativeInt32(ToRegister(ins->value()));
else
label = masm.storeRipRelativeDouble(ToFloatRegister(ins->value()));
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
bool
@ -367,8 +371,8 @@ CodeGeneratorX64::visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins)
CodeOffsetLabel label = masm.leaRipRelative(tmp);
masm.loadPtr(Operand(tmp, index, TimesEight, 0), out);
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
bool
@ -377,8 +381,8 @@ CodeGeneratorX64::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins)
MAsmJSLoadFFIFunc *mir = ins->mir();
CodeOffsetLabel label = masm.loadRipRelativeInt64(ToRegister(ins->output()));
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
void

View File

@ -260,7 +260,7 @@ class Assembler : public AssemblerX86Shared
}
void mov(AsmJSImmPtr imm, Register dest) {
masm.movl_i32r(-1, dest.code());
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), imm.kind()));
}
void mov(const Operand &src, Register dest) {
movl(src, dest);
@ -341,7 +341,7 @@ class Assembler : public AssemblerX86Shared
}
void cmpl(AsmJSAbsoluteAddress lhs, Register rhs) {
masm.cmpl_rm_force32(rhs.code(), (void*)-1);
enoughMemory_ &= append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind()));
append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind()));
}
CodeOffsetLabel cmplWithPatch(Register lhs, Imm32 rhs) {
masm.cmpl_ir_force32(rhs.value, lhs.code());

View File

@ -308,7 +308,8 @@ CodeGeneratorX86::loadAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const
uint32_t before = masm.size();
loadViewTypeElement(vt, srcAddr, out);
uint32_t after = masm.size();
return masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out)));
masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out)));
return true;
}
bool
@ -381,7 +382,8 @@ CodeGeneratorX86::visitAsmJSLoadHeap(LAsmJSLoadHeap *ins)
loadViewTypeElement(vt, srcAddr, out);
uint32_t after = masm.size();
masm.bind(ool->rejoin());
return masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out), cmp.offset()));
masm.append(AsmJSHeapAccess(before, after, vt, ToAnyRegister(out), cmp.offset()));
return true;
}
bool
@ -420,14 +422,14 @@ CodeGeneratorX86::storeViewTypeElement(ArrayBufferView::ViewType vt, const LAllo
}
template<typename T>
bool
void
CodeGeneratorX86::storeAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
const T &dstAddr)
{
uint32_t before = masm.size();
storeViewTypeElement(vt, value, dstAddr);
uint32_t after = masm.size();
return masm.append(AsmJSHeapAccess(before, after));
masm.append(AsmJSHeapAccess(before, after));
}
bool
@ -463,14 +465,17 @@ CodeGeneratorX86::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
// immediate in the instruction. This displacement will fixed up when the
// base address is known during dynamic linking (AsmJSModule::initHeap).
PatchedAbsoluteAddress dstAddr((void *) ptr->toConstant()->toInt32());
return storeAndNoteViewTypeElement(vt, value, dstAddr);
storeAndNoteViewTypeElement(vt, value, dstAddr);
return true;
}
Register ptrReg = ToRegister(ptr);
Address dstAddr(ptrReg, 0);
if (mir->skipBoundsCheck())
return storeAndNoteViewTypeElement(vt, value, dstAddr);
if (mir->skipBoundsCheck()) {
storeAndNoteViewTypeElement(vt, value, dstAddr);
return true;
}
CodeOffsetLabel cmp = masm.cmplWithPatch(ptrReg, Imm32(0));
Label rejoin;
@ -480,7 +485,8 @@ CodeGeneratorX86::visitAsmJSStoreHeap(LAsmJSStoreHeap *ins)
storeViewTypeElement(vt, value, dstAddr);
uint32_t after = masm.size();
masm.bind(&rejoin);
return masm.append(AsmJSHeapAccess(before, after, cmp.offset()));
masm.append(AsmJSHeapAccess(before, after, cmp.offset()));
return true;
}
bool
@ -497,8 +503,8 @@ CodeGeneratorX86::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins)
label = masm.movssWithPatch(PatchedAbsoluteAddress(), ToFloatRegister(ins->output()));
else
label = masm.movsdWithPatch(PatchedAbsoluteAddress(), ToFloatRegister(ins->output()));
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
bool
@ -516,8 +522,8 @@ CodeGeneratorX86::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins)
label = masm.movssWithPatch(ToFloatRegister(ins->value()), PatchedAbsoluteAddress());
else
label = masm.movsdWithPatch(ToFloatRegister(ins->value()), PatchedAbsoluteAddress());
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
bool
@ -528,8 +534,8 @@ CodeGeneratorX86::visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins)
Register index = ToRegister(ins->index());
Register out = ToRegister(ins->output());
CodeOffsetLabel label = masm.movlWithPatch(PatchedAbsoluteAddress(), index, TimesFour, out);
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
bool
@ -539,8 +545,8 @@ CodeGeneratorX86::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins)
Register out = ToRegister(ins->output());
CodeOffsetLabel label = masm.movlWithPatch(PatchedAbsoluteAddress(), out);
return masm.append(AsmJSGlobalAccess(CodeOffsetLabel(label.offset()), mir->globalDataOffset()));
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
return true;
}
void

View File

@ -36,8 +36,8 @@ class CodeGeneratorX86 : public CodeGeneratorX86Shared
void loadViewTypeElement(ArrayBufferView::ViewType vt, const T &srcAddr,
const LDefinition *out);
template<typename T>
bool storeAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
const T &dstAddr);
void storeAndNoteViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
const T &dstAddr);
template<typename T>
void storeViewTypeElement(ArrayBufferView::ViewType vt, const LAllocation *value,
const T &dstAddr);

View File

@ -1195,9 +1195,6 @@ JS_InitStandardClasses(JSContext *cx, HandleObject obj)
#define EAGER_ATOM(name) NAME_OFFSET(name)
static js::Class DummyClass;
static js::Class SentinelClass;
typedef struct JSStdName {
size_t atomOffset; /* offset of atom pointer in JSAtomState */
JSProtoKey key;

View File

@ -667,6 +667,10 @@ class ArenaLists
return arenaListsToSweep[thingKind];
}
ArenaHeader *getArenaAfterCursor(AllocKind thingKind) const {
return arenaLists[thingKind].arenaAfterCursor();
}
bool arenaListsAreEmpty() const {
for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
/*
@ -780,6 +784,15 @@ class ArenaLists
return false;
}
/* Check if |aheader|'s arena is in use. */
bool arenaIsInUse(ArenaHeader *aheader, AllocKind kind) const {
JS_ASSERT(aheader);
const FreeList &freeList = freeLists[kind];
if (freeList.isEmpty())
return false;
return aheader == freeList.arenaHeader();
}
MOZ_ALWAYS_INLINE void *allocateFromFreeList(AllocKind thingKind, size_t thingSize) {
return freeLists[thingKind].allocate(thingSize);
}

View File

@ -176,6 +176,20 @@ nsInlineFrame::PeekOffsetCharacter(bool aForward, int32_t* aOffset,
return CONTINUE;
}
void
nsInlineFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
nsFrameList* overflowFrames = GetOverflowFrames();
if (overflowFrames) {
// Fixup the parent pointers for any child frames on the OverflowList.
// nsIFrame::DestroyFrom depends on that to find the sticky scroll
// container (an ancestor).
nsIFrame* lineContainer = nsLayoutUtils::FindNearestBlockAncestor(this);
DrainSelfOverflowListInternal(eForDestroy, lineContainer);
}
nsContainerFrame::DestroyFrom(aDestructRoot);
}
void
nsInlineFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
@ -422,11 +436,12 @@ nsInlineFrame::DrainSelfOverflowListInternal(DrainFlags aFlags,
if (aLineContainer && aLineContainer->GetPrevContinuation()) {
ReparentFloatsForInlineChild(aLineContainer, firstChild, true);
}
const bool inFirstLine = (aFlags & eInFirstLine);
const bool doReparentSC =
(aFlags & eInFirstLine) && !(aFlags & eForDestroy);
RestyleManager* restyleManager = PresContext()->RestyleManager();
for (nsIFrame* f = firstChild; f; f = f->GetNextSibling()) {
f->SetParent(this);
if (inFirstLine) {
if (doReparentSC) {
restyleManager->ReparentStyleContext(f);
nsLayoutUtils::MarkDescendantsDirty(f);
}

View File

@ -63,6 +63,8 @@ public:
virtual FrameSearchResult PeekOffsetCharacter(bool aForward, int32_t* aOffset,
bool aRespectClusters = true) MOZ_OVERRIDE;
virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
// nsIHTMLReflow overrides
virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
InlineMinWidthData *aData) MOZ_OVERRIDE;
@ -165,6 +167,9 @@ private:
enum DrainFlags {
eDontReparentFrames = 1, // skip reparenting the overflow list frames
eInFirstLine = 2, // the request is for an inline descendant of a nsFirstLineFrame
eForDestroy = 4, // the request is from DestroyFrom; in this case we do the
// minimal work required since the frame is about to be
// destroyed (just fixup parent pointers)
};
/**
* Move any frames on our overflow list to the end of our principal list.

View File

@ -1959,7 +1959,7 @@ pref("layout.css.overflow-clip-box.enabled", false);
pref("layout.css.grid.enabled", false);
// Is support for CSS box-decoration-break enabled?
pref("layout.css.box-decoration-break.enabled", false);
pref("layout.css.box-decoration-break.enabled", true);
// Is layout of CSS outline-style:auto enabled?
pref("layout.css.outline-style-auto.enabled", false);

View File

@ -1 +1 @@
NSPR_4_10_7_BETA2
NSPR_4_10_7_BETA3

Some files were not shown because too many files have changed in this diff Show More