tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_event_handler_cc.html (2554B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Test for cycle collection of event handlers</title>
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
      8  <script>
      9    SimpleTest.waitForExplicitFinish();
     10 
     11    function listener() {}
     12 
     13    function make_weak_ref(obj) {
     14      let m = new WeakMap;
     15      m.set(obj, {});
     16      return m;
     17    }
     18 
     19    function weak_ref_dead(r) {
     20      return !SpecialPowers.nondeterministicGetWeakMapKeys(r).length;
     21    }
     22 
     23    function setupTarget1() {
     24      let ifr = document.getElementById("target1");
     25      let doc = ifr.contentDocument;
     26      let b = doc.createElement("button");
     27      doc.body.appendChild(b);
     28      b.onclick = listener;
     29      ifr.remove();
     30      return make_weak_ref(b);
     31    }
     32 
     33    function setupTarget2() {
     34      let ifr = document.getElementById("target2");
     35      let doc = ifr.contentDocument;
     36      let b = doc.createElement("button");
     37      doc.body.appendChild(b);
     38      let setFunc = new ifr.contentWindow.Function(`
     39           var b = document.querySelector("button");
     40           var proto = parent.HTMLElement.prototype;
     41           var setter = Object.getOwnPropertyDescriptor(proto, "onclick").set;
     42           // Here the current global (and hence CallbackObject global) will be
     43           // the parent, the callback will be a known-live thing from the
     44           // parent, but the incumbent global will be the child.
     45           setter.call(b, parent.listener);
     46         `);
     47      setFunc();
     48      ifr.remove();
     49      return make_weak_ref(b);
     50    }
     51 
     52    var ref1;
     53    var ref2;
     54    var maxCounter = 20;
     55 
     56    function GCCCUntilCollected() {
     57      SpecialPowers.exactGC(function () {
     58        SpecialPowers.forceCC();
     59        SpecialPowers.forceGC();
     60        SpecialPowers.forceGC();
     61 
     62        if ((!weak_ref_dead(ref1) || !weak_ref_dead(ref2)) && --maxCounter > 0) {
     63          requestIdleCallback(GCCCUntilCollected, {timeout: 250});
     64          return;
     65        }
     66 
     67        ok(weak_ref_dead(ref1),
     68           "Should collect cycle through callback global");
     69        ok(weak_ref_dead(ref2),
     70           "Should collect cycle through incumbent global");
     71 
     72        SimpleTest.finish();
     73      });
     74    }
     75 
     76    addLoadEvent(function() {
     77      ref1 = setupTarget1();
     78      ref2 = setupTarget2();
     79      GCCCUntilCollected();
     80    });
     81  </script>
     82 </head>
     83 <body>
     84 <p id="display"></p>
     85 <div id="content" style="display: none"></div>
     86 <iframe id="target1"></iframe>
     87 <iframe id="target2"></iframe>
     88 <pre id="test"></pre>
     89 </body>
     90 </html>