tor-browser

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

weak-marking-budget.js (2404B)


      1 // Make enterWeakMarkingMode expensive so it gets forced into a single slice.
      2 
      3 gczeal(0); // We need full control here.
      4 
      5 var keys = [];
      6 var maps = Array(1000).fill().map(() => new WeakMap);
      7 for (const map of maps) {
      8  for (let i = 0; i < 100; i++) {
      9    // The key will die the next major collection , but will need to be put
     10    // into the ephemeron table first.
     11    let key = {};
     12    keys.push(key);
     13    map.set(key, {}); 
     14  }
     15 }
     16 
     17 minorgc();
     18 keys = undefined;
     19 
     20 // Slowly work forward until we reach Mark.
     21 startgc(10);
     22 while (["Prepare", "MarkRoots"].includes(gcstate())) {
     23    gcslice(10);
     24 }
     25 assertEq(gcstate(), "Mark");
     26 
     27 // This will yield before leaving marking, in order to give the first sweep
     28 // slice a full budget.
     29 print("gcslice(10000) #1");
     30 gcslice(10000);
     31 assertEq(gcstate(), "Mark");
     32 
     33 // First Sweep slice will hit the long enterWeakMarkingMode and yield as soon as
     34 // the budget runs out, and set up the next Sweep slice to finish.
     35 print("gcslice(10000) #2");
     36 gcslice(10000);
     37 assertEq(gcstate(), "Sweep");
     38 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, true);
     39 
     40 // This slice will finish the marking, but will go way over budget and so will
     41 // yield as soon as the marking is done. This will still be during Sweep (in the
     42 // middle of sweepWeakCaches).
     43 print("gcslice(1) #3");
     44 // Use more than gcslice(1) because it is possible to get a few things added to
     45 // the mark stack from read barriers.
     46 gcslice(100);
     47 assertEq(gcstate(), "Sweep");
     48 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, false);
     49 
     50 // There's still a lot of sweeping left to do, because all of the dead stuff
     51 // needs to be finalized.
     52 finishgc();
     53 
     54 // Do another GC without a slow enterWMM, to confirm that the extra slice is not
     55 // requested. (The previous GC will have thrown out all of the WeakMaps'
     56 // entries, so this will just be doing one step for each of the 1000 WeakMaps
     57 // instead of 1000 * (1 + 100) for the WeakMaps plus their keys.)
     58 startgc(10);
     59 while (["Prepare", "MarkRoots"].includes(gcstate())) {
     60    gcslice(10);
     61 }
     62 assertEq(gcstate(), "Mark");
     63 
     64 gcslice(10000);
     65 assertEq(gcstate(), "Mark");
     66 
     67 gcslice(1);
     68 assertEq(gcstate(), "Sweep");
     69 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, false);
     70 
     71 gcslice(1);
     72 assertEq(gcstate(), "Sweep");
     73 hasFunction["currentgc"] && assertEq(currentgc().finishMarkingDuringSweeping, false);