diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /js/src/devtools/gc-ubench/shell-bench.js | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/devtools/gc-ubench/shell-bench.js')
-rw-r--r-- | js/src/devtools/gc-ubench/shell-bench.js | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/js/src/devtools/gc-ubench/shell-bench.js b/js/src/devtools/gc-ubench/shell-bench.js new file mode 100644 index 0000000000..9640cddce9 --- /dev/null +++ b/js/src/devtools/gc-ubench/shell-bench.js @@ -0,0 +1,147 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +var FPS = 60; +var gNumSamples = 500; + +// This requires a gHost to have been created that provides host-specific +// facilities. See eg spidermonkey.js. + +loadRelativeToScript("argparse.js"); +loadRelativeToScript("harness.js"); +loadRelativeToScript("sequencer.js"); +loadRelativeToScript("scheduler.js"); +loadRelativeToScript("perf.js"); +loadRelativeToScript("test_list.js"); + +var gPerf = new PerfTracker(); + +var tests = new Map(); +foreach_test_file(f => loadRelativeToScript(f)); +for (const [name, info] of tests.entries()) { + if ("enabled" in info && !info.enabled) { + tests.delete(name); + } +} + +function tick(loadMgr, timestamp) { + gPerf.before_mutator(timestamp); + gHost.start_turn(); + const events = loadMgr.tick(timestamp); + gHost.end_turn(); + gPerf.after_mutator(timestamp); + return events; +} + +function run(opts, loads) { + const sequence = []; + for (const mut of loads) { + if (tests.has(mut)) { + sequence.push(mut); + } else if (mut === "all") { + sequence.push(...tests.keys()); + } else { + sequence.push(...[...tests.keys()].filter(t => t.includes(mut))); + } + } + if (loads.length === 0) { + sequence.push(...tests.keys()); + } + + const loadMgr = new AllocationLoadManager(tests); + const perf = new FrameHistory(gNumSamples); + + const mutators = sequence.map(name => new SingleMutatorSequencer(loadMgr.getByName(name), gPerf, opts.duration)); + let sequencer; + if (opts.sequencer == 'cycle') { + sequencer = new ChainSequencer(mutators); + } else if (opts.sequencer == 'find50') { + const seekers = mutators.map(s => new Find50Sequencer(s, loadMgr)); + sequencer = new ChainSequencer(seekers); + } + + const schedulerCtors = { + keepup: OptimizeForFrameRate, + vsync: VsyncScheduler, + }; + const scheduler = new schedulerCtors[opts.sched](gPerf); + + perf.start(); + + const t0 = gHost.now(); + + let possible = 0; + let frames = 0; + loadMgr.startSequencer(sequencer); + print(`${loadMgr.activeLoad().name} starting`); + while (loadMgr.load_running()) { + const timestamp = gHost.now(); + const completed = scheduler.tick(loadMgr, timestamp); + const after_tick = gHost.now(); + + perf.on_frame(timestamp); + + if (completed) { + print(`${loadMgr.lastActive.name} ended`); + if (loadMgr.load_running()) { + print(`${loadMgr.activeLoad().name} starting`); + } + } + + frames++; + if (completed) { + possible += (loadMgr.testDurationMS / 1000) * FPS; + const elapsed = ((after_tick - t0) / 1000).toFixed(2); + print(` observed ${frames} / ${possible} frames in ${elapsed} seconds`); + } + + scheduler.wait_for_next_frame(t0, timestamp, after_tick); + } +} + +function report_results() { + for (const result of gPerf.results) { + const { + load, + elapsed_time, + mutating, + mutating_and_gc_fraction, + suspended, + full_time, + frames, + dropped_60fps_frames, + dropped_60fps_fraction, + minorGCs, + majorGCs, + } = result; + + const drop_pct = percent(dropped_60fps_fraction); + const mut_pct = percent(mutating_and_gc_fraction); + const mut_sec = mutating.toFixed(2); + const full_sec = full_time.toFixed(2); + const susp_sec = suspended.toFixed(2); + print(`${load.name}: + ${frames} (60fps) frames seen out of expected ${Math.floor(full_time * 60)} + ${dropped_60fps_frames} = ${drop_pct} 60fps frames dropped + ${mut_pct} of run spent mutating and GCing (${mut_sec}sec out of ${full_sec}sec vs ${susp_sec} sec waiting) + ${minorGCs} minor GCs, ${majorGCs} major GCs +`); + } +} + +var argparse = new ArgParser("JS shell microbenchmark runner"); +argparse.add_argument(["--duration", "-d"], { + default: gDefaultTestDuration, + help: "how long to run mutators for (in seconds)" +}); +argparse.add_argument("--sched", { + default: "keepup", + options: ["keepup", "vsync"], + help: "frame scheduler" +}); +argparse.add_argument("--sequencer", { + default: "cycle", + options: ["cycle", "find50"], + help: "mutator sequencer" +}); |