1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58

content / test / data / gpu / webgpu-stress-request-device-and-remove-loop.html [blame]

<!--
  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>