tor-browser

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

Memory-takeCensus-08.js (2349B)


      1 // Debugger.Memory.prototype.takeCensus: test by: 'count' breakdown
      2 
      3 let g = newGlobal({newCompartment: true});
      4 let dbg = new Debugger(g);
      5 
      6 g.eval(`
      7       var stuff = [];
      8       function add(n, c) {
      9         for (let i = 0; i < n; i++)
     10           stuff.push(c());
     11       }
     12 
     13       let count = 0;
     14 
     15       function obj() { return { count: count++ }; }
     16       obj.factor = 1;
     17 
     18       // This creates a closure (a function JSObject) that has captured
     19       // a Call object. So each call creates two items.
     20       function fun() { let v = count; return () => { return v; } }
     21       fun.factor = 2;
     22 
     23       function str() { return 'perambulator' + count++; }
     24       str.factor = 1;
     25 
     26       // Eval a fresh text each time, allocating:
     27       // - a fresh ScriptSourceObject
     28       // - a new JSScripts, not an eval cache hits
     29       // - a fresh prototype object
     30       // - a fresh Call object, since the eval makes 'ev' heavyweight
     31       // - the new function itself
     32       function ev()  {
     33         return eval(\`(function () { return \${ count++ } })\`);
     34       }
     35       ev.factor = 5;
     36 
     37       // A new object (1) with a new shape (2) with a new atom (3)
     38       function shape() { return { [ 'theobroma' + count++ ]: count }; }
     39       shape.factor = 3;
     40       `);
     41 
     42 let baseline = 0;
     43 function countIncreasedByAtLeast(n) {
     44  let oldBaseline = baseline;
     45 
     46  // Since a census counts only reachable objects, one might assume that calling
     47  // GC here would have no effect on the census results. But GC also throws away
     48  // JIT code and any objects it might be holding (template objects, say);
     49  // takeCensus reaches those. Shake everything loose that we can, to make the
     50  // census approximate reachability a bit more closely, and make our results a
     51  // bit more predictable.
     52  gc(g, 'shrinking');
     53 
     54  baseline = dbg.memory.takeCensus({ breakdown: { by: 'count' } }).count;
     55  return baseline >= oldBaseline + n;
     56 }
     57 
     58 countIncreasedByAtLeast(0);
     59 
     60 g.add(100, g.obj);
     61 assertEq(countIncreasedByAtLeast(g.obj.factor * 100), true);
     62 
     63 g.add(100, g.fun);
     64 assertEq(countIncreasedByAtLeast(g.fun.factor * 100), true);
     65 
     66 g.add(100, g.str);
     67 assertEq(countIncreasedByAtLeast(g.str.factor * 100), true);
     68 
     69 g.add(100, g.ev);
     70 assertEq(countIncreasedByAtLeast(g.ev.factor * 100), true);
     71 
     72 g.add(100, g.shape);
     73 assertEq(countIncreasedByAtLeast(g.shape.factor * 100), true);