| // Debugger.Memory.prototype.takeCensus: test by: 'count' breakdown |
| |
| let g = newGlobal(); |
| let dbg = new Debugger(g); |
| |
| g.eval(` |
| var stuff = []; |
| function add(n, c) { |
| for (let i = 0; i < n; i++) |
| stuff.push(c()); |
| } |
| |
| let count = 0; |
| |
| function obj() { return { count: count++ }; } |
| obj.factor = 1; |
| |
| // This creates a closure (a function JSObject) that has captured |
| // a Call object. So each call creates two items. |
| function fun() { let v = count; return () => { return v; } } |
| fun.factor = 2; |
| |
| function str() { return 'perambulator' + count++; } |
| str.factor = 1; |
| |
| // Eval a fresh text each time, allocating: |
| // - a fresh ScriptSourceObject |
| // - a new JSScripts, not an eval cache hits |
| // - a fresh prototype object |
| // - a fresh Call object, since the eval makes 'ev' heavyweight |
| // - the new function itself |
| function ev() { |
| return eval(\`(function () { return \${ count++ } })\`); |
| } |
| ev.factor = 5; |
| |
| // A new object (1) with a new shape (2) with a new atom (3) |
| function shape() { return { [ 'theobroma' + count++ ]: count }; } |
| shape.factor = 3; |
| `); |
| |
| let baseline = 0; |
| function countIncreasedByAtLeast(n) { |
| let oldBaseline = baseline; |
| |
| // Since a census counts only reachable objects, one might assume that calling |
| // GC here would have no effect on the census results. But GC also throws away |
| // JIT code and any objects it might be holding (template objects, say); |
| // takeCensus reaches those. Shake everything loose that we can, to make the |
| // census approximate reachability a bit more closely, and make our results a |
| // bit more predictable. |
| gc(g, 'shrinking'); |
| |
| baseline = dbg.memory.takeCensus({ breakdown: { by: 'count' } }).count; |
| return baseline >= oldBaseline + n; |
| } |
| |
| countIncreasedByAtLeast(0); |
| |
| g.add(100, g.obj); |
| assertEq(countIncreasedByAtLeast(g.obj.factor * 100), true); |
| |
| g.add(100, g.fun); |
| assertEq(countIncreasedByAtLeast(g.fun.factor * 100), true); |
| |
| g.add(100, g.str); |
| assertEq(countIncreasedByAtLeast(g.str.factor * 100), true); |
| |
| g.add(100, g.ev); |
| assertEq(countIncreasedByAtLeast(g.ev.factor * 100), true); |
| |
| g.add(100, g.shape); |
| assertEq(countIncreasedByAtLeast(g.shape.factor * 100), true); |