Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: os == 'linux' && os_version == '24.04' && arch == 'x86_64' && debug && verify-standalone OR ccov
- Manifest: dom/base/test/mochitest.toml
<!DOCTYPE html>
<html>
<!-- Script delazification strategy is not supposed to have any observable
side-effect. To make it observable, the ScriptLoader is instrumented to
trigger notifications on the script tag. These notifications are used to
validate that the strategy is used as execpected. This does not garantee
that all functions are delazified properly, but this should be checked in
the JS engine test suite.
-->
<head>
<meta charset="utf-8">
<title>Test for triggering eager delazification.</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="application/javascript">
async function WaitForScriptNotification() {
var url = "file_delazification_strategy.html";
var iframe = document.createElement("iframe");
// Call the resolve function when the notification is one of the expected
// notifications. This is made to be used by a promise and provided to
// notification observer.
function resolve_with_notification(resolve, subject, topic, data) {
const param = {};
for (const line of data.split("\n")) {
const m = line.match(/^([^:]+):(.+)/);
param[m[1]] = m[2];
}
// If we have multiple script tags in the loaded source, make sure
// we only watch a single one.
if (param.id != "watchme")
return;
switch (param.event) {
case "delazification:OnDemandOnly":
case "delazification:ConcurrentDepthFirst":
case "delazification:ParseEverythingEagerly":
resolve(param.event.replace("delazification:", ""));
break;
case "compile:main thread":
resolve(param.event);
break;
}
}
// Create an notification observer, which resolves a promise.
let log_notification;
let scriptLoaderTrace = new Promise((resolve, reject) => {
log_notification = resolve_with_notification.bind(this, resolve);
});
// Wait until the iframe is fully loaded.
await new Promise(resolve => {
iframe.onload = resolve;
iframe.src = url;
document.body.appendChild(iframe);
});
// Register all notifications.
SpecialPowers.Services.obs.addObserver(log_notification, "ScriptLoaderTest");
// Add a script tag, which will trigger one of the previous
// notifications..
let script = document.createElement("script");
script.setAttribute("id", "watchme");
script.setAttribute("src", "file_delazification_strategy.js");
iframe.contentDocument.body.appendChild(script);
// Wait for the notification emitted by ScriptLoader, while processing the
// previous script.
let result = await scriptLoaderTrace;
SpecialPowers.Services.obs.removeObserver(log_notification, "ScriptLoaderTest");
document.body.removeChild(iframe);
return result;
}
// Setting dom.expose_test_interfaces pref causes the
// nsScriptLoadRequest to fire notifications on script tags, with
// information about its internal state. The ScriptLoader source send
// notifications to trace these and resolve a promise with the path taken
// by the script loader.
//
// Setting dom.script_loader.bytecode_cache.enabled to false in order
// to prevent the bytecode cache to perturb this test case.
//
// Setting dom.script_loader.external_scripts.speculate_* are used to
// force off-main-thread compilation, while hoping that we have enough
// processors to run the test case
//
// Setting dom.delazification.* are used to select the delazification
// strategy and to check that it is well selected.
promise_test(async function() {
await SpecialPowers.pushPrefEnv({set: [
['dom.expose_test_interfaces', true],
['dom.script_loader.bytecode_cache.enabled', false],
['dom.script_loader.external_scripts.speculate_non_parser_inserted.enable', true],
['dom.script_loader.external_scripts.speculate_async.enabled', true],
['dom.script_loader.external_scripts.speculate_link_preload.enabled', true],
// Parse everything eagerly
['dom.script_loader.delazification.strategy', 255],
['dom.script_loader.delazification.max_size', 0],
['dom.script_loader.delazification.min_mem', 0],
]});
assert_equals(await WaitForScriptNotification(), "OnDemandOnly",
"[1] AttemptAsyncScriptCompile: On demand only");
}, "Check that max_size can disable delazification strategy");
promise_test(async function() {
await SpecialPowers.pushPrefEnv({set: [
['dom.expose_test_interfaces', true],
['dom.script_loader.bytecode_cache.enabled', false],
// Enable OffMainThread compilation for everything, and cross-fingers
// about the number of CPU.
['dom.script_loader.external_scripts.speculate_non_parser_inserted.enable', true],
['dom.script_loader.external_scripts.speculate_async.enabled', true],
['dom.script_loader.external_scripts.speculate_link_preload.enabled', true],
// Parse everything eagerly
['dom.script_loader.delazification.strategy', 255],
['dom.script_loader.delazification.max_size', 10485760],
// 4 TB should of RAM be enough.
['dom.script_loader.delazification.min_mem', 4096],
]});
assert_equals(await WaitForScriptNotification(), "OnDemandOnly",
"[2] AttemptAsyncScriptCompile: On demand only");
}, "Check that min_mem can disable delazification strategy");
promise_test(async function() {
await SpecialPowers.pushPrefEnv({set: [
['dom.expose_test_interfaces', true],
['dom.script_loader.bytecode_cache.enabled', false],
// Enable OffMainThread compilation for everything, and cross-fingers
// about the number of CPU.
['dom.script_loader.external_scripts.speculate_non_parser_inserted.enable', true],
['dom.script_loader.external_scripts.speculate_async.enabled', true],
['dom.script_loader.external_scripts.speculate_link_preload.enabled', true],
['dom.script_loader.delazification.max_size', 10485760],
['dom.script_loader.delazification.min_mem', 0],
]});
await SpecialPowers.pushPrefEnv({set: [
['dom.script_loader.delazification.strategy', 0],
]});
assert_equals(await WaitForScriptNotification(), "OnDemandOnly",
"[3] AttemptAsyncScriptCompile: On demand only");
await SpecialPowers.pushPrefEnv({set: [
['dom.script_loader.delazification.strategy', 2],
]});
assert_equals(await WaitForScriptNotification(), "ConcurrentDepthFirst",
"[3] AttemptAsyncScriptCompile: Concurrent Depth First");
await SpecialPowers.pushPrefEnv({set: [
['dom.script_loader.delazification.strategy', 255],
]});
assert_equals(await WaitForScriptNotification(), "ParseEverythingEagerly",
"[3] AttemptAsyncScriptCompile: Parse Everything Eagerly");
}, "Check enabling delazification strategy works");
done();
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1753709">Mozilla Bug 1753709</a>
</body>
</html>