tor-browser

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

shell-bench.js (4184B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 var FPS = 60;
      6 var gNumSamples = 500;
      7 
      8 // This requires a gHost to have been created that provides host-specific
      9 // facilities. See eg spidermonkey.js.
     10 
     11 loadRelativeToScript("argparse.js");
     12 loadRelativeToScript("harness.js");
     13 loadRelativeToScript("sequencer.js");
     14 loadRelativeToScript("scheduler.js");
     15 loadRelativeToScript("perf.js");
     16 loadRelativeToScript("test_list.js");
     17 
     18 var gPerf = new PerfTracker();
     19 
     20 var tests = new Map();
     21 foreach_test_file(f => loadRelativeToScript(f));
     22 for (const [name, info] of tests.entries()) {
     23  if ("enabled" in info && !info.enabled) {
     24    tests.delete(name);
     25  }
     26 }
     27 
     28 function tick(loadMgr, timestamp) {
     29  gPerf.before_mutator(timestamp);
     30  gHost.start_turn();
     31  const events = loadMgr.tick(timestamp);
     32  gHost.end_turn();
     33  gPerf.after_mutator(timestamp);
     34  return events;
     35 }
     36 
     37 function run(opts, loads) {
     38  const sequence = [];
     39  for (const mut of loads) {
     40    if (tests.has(mut)) {
     41      sequence.push(mut);
     42    } else if (mut === "all") {
     43      sequence.push(...tests.keys());
     44    } else {
     45      sequence.push(...[...tests.keys()].filter(t => t.includes(mut)));
     46    }
     47  }
     48  if (loads.length === 0) {
     49    sequence.push(...tests.keys());
     50  }
     51 
     52  const loadMgr = new AllocationLoadManager(tests);
     53  const perf = new FrameHistory(gNumSamples);
     54 
     55  const mutators = sequence.map(name => new SingleMutatorSequencer(loadMgr.getByName(name), gPerf, opts.duration));
     56  let sequencer;
     57  if (opts.sequencer == 'cycle') {
     58    sequencer = new ChainSequencer(mutators);
     59  } else if (opts.sequencer == 'find50') {
     60    const seekers = mutators.map(s => new Find50Sequencer(s, loadMgr));
     61    sequencer = new ChainSequencer(seekers);
     62  }
     63 
     64  const schedulerCtors = {
     65    keepup: OptimizeForFrameRate,
     66    vsync: VsyncScheduler,
     67  };
     68  const scheduler = new schedulerCtors[opts.sched](gPerf);
     69 
     70  perf.start();
     71 
     72  const t0 = gHost.now();
     73 
     74  let possible = 0;
     75  let frames = 0;
     76  loadMgr.startSequencer(sequencer);
     77  print(`${loadMgr.activeLoad().name} starting`);
     78  while (loadMgr.load_running()) {
     79    const timestamp = gHost.now();
     80    const completed = scheduler.tick(loadMgr, timestamp);
     81    const after_tick = gHost.now();
     82 
     83    perf.on_frame(timestamp);
     84 
     85    if (completed) {
     86      print(`${loadMgr.lastActive.name} ended`);
     87      if (loadMgr.load_running()) {
     88        print(`${loadMgr.activeLoad().name} starting`);
     89      }
     90    }
     91 
     92    frames++;
     93    if (completed) {
     94      possible += (loadMgr.testDurationMS / 1000) * FPS;
     95      const elapsed = ((after_tick - t0) / 1000).toFixed(2);
     96      print(`  observed ${frames} / ${possible} frames in ${elapsed} seconds`);
     97    }
     98 
     99    scheduler.wait_for_next_frame(t0, timestamp, after_tick);
    100  }
    101 }
    102 
    103 function report_results() {
    104  for (const result of gPerf.results) {
    105    const {
    106      load,
    107      elapsed_time,
    108      mutating,
    109      mutating_and_gc_fraction,
    110      suspended,
    111      full_time,
    112      frames,
    113      dropped_60fps_frames,
    114      dropped_60fps_fraction,
    115      minorGCs,
    116      majorGCs,
    117    } = result;
    118 
    119    const drop_pct = percent(dropped_60fps_fraction);
    120    const mut_pct = percent(mutating_and_gc_fraction);
    121    const mut_sec = mutating.toFixed(2);
    122    const full_sec = full_time.toFixed(2);
    123    const susp_sec = suspended.toFixed(2);
    124    print(`${load.name}:
    125  ${frames} (60fps) frames seen out of expected ${Math.floor(full_time * 60)}
    126  ${dropped_60fps_frames} = ${drop_pct} 60fps frames dropped
    127  ${mut_pct} of run spent mutating and GCing (${mut_sec}sec out of ${full_sec}sec vs ${susp_sec} sec waiting)
    128  ${minorGCs} minor GCs, ${majorGCs} major GCs
    129 `);
    130  }
    131 }
    132 
    133 var argparse = new ArgParser("JS shell microbenchmark runner");
    134 argparse.add_argument(["--duration", "-d"], {
    135  default: gDefaultTestDuration,
    136  help: "how long to run mutators for (in seconds)"
    137 });
    138 argparse.add_argument("--sched", {
    139  default: "keepup",
    140  options: ["keepup", "vsync"],
    141  help: "frame scheduler"
    142 });
    143 argparse.add_argument("--sequencer", {
    144  default: "cycle",
    145  options: ["cycle", "find50"],
    146  help: "mutator sequencer"
    147 });