<!--
This is a stress test for crbug.com/1242269.
In the bug, a flaky use-after-free could happen depending on the ordering of
the Javascript ExecutionContext ContextDestroyed notification and GC finalization
of the GPUDevice in the page. Repeatingly creating an iframe, initializing a GPUDevice,
and then destroying the iframe can sometimes hit this and crash. This test does this
repeatedly with many iframes at once for 90 seconds.
-->
<head>
<script>
const iframes = [];
function removeOneIframe() {
setTimeout(function () {
document.body.removeChild(iframes.shift());
}, Math.random() * 500);
}
async function run() {
if (window.domAutomationController) {
window.domAutomationController.send('LOADED');
setTimeout(() => {
// Succeed if don't crash within 90 seconds.
window.domAutomationController.send('SUCCESS');
}, 90 * 1000);
}
while (true) {
const iframe = document.createElement("iframe");
iframe.setAttribute("id", "iframe");
document.body.appendChild(iframe);
iframes.push(iframe);
const head = iframe.contentWindow.document.getElementsByTagName('head')[0];
const script = iframe.contentWindow.document.createElement('script');
script.type = 'text/javascript';
script.innerText = `
navigator.gpu.requestAdapter().then((adapter) => {
adapter.requestDevice().then((val) => {
parent.removeOneIframe();
});
});
`;
head.appendChild(script);
// Wait a bit to yield to the event loop.
await new Promise(resolve => setTimeout(resolve, 0));
// Avoid having too many iframes in flight.
while (iframes.length > 100) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
}
</script>
</head>
<body onload="run()"></body>