mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[JAEGER] Add instrumentation for v8-deltablue.
This commit is contained in:
parent
b4effc041b
commit
b0e3e8c7ff
@ -1,3 +1,269 @@
|
||||
// Copyright 2008 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
// Simple framework for running the benchmark suites and
|
||||
// computing a score based on the timing measurements.
|
||||
|
||||
|
||||
// A benchmark has a name (string) and a function that will be run to
|
||||
// do the performance measurement. The optional setup and tearDown
|
||||
// arguments are functions that will be invoked before and after
|
||||
// running the benchmark, but the running time of these functions will
|
||||
// not be accounted for in the benchmark score.
|
||||
function Benchmark(name, run, setup, tearDown) {
|
||||
this.name = name;
|
||||
this.run = run;
|
||||
this.Setup = setup ? setup : function() { };
|
||||
this.TearDown = tearDown ? tearDown : function() { };
|
||||
}
|
||||
|
||||
|
||||
// Benchmark results hold the benchmark and the measured time used to
|
||||
// run the benchmark. The benchmark score is computed later once a
|
||||
// full benchmark suite has run to completion.
|
||||
function BenchmarkResult(benchmark, time) {
|
||||
this.benchmark = benchmark;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
|
||||
// Automatically convert results to numbers. Used by the geometric
|
||||
// mean computation.
|
||||
BenchmarkResult.prototype.valueOf = function() {
|
||||
return this.time;
|
||||
}
|
||||
|
||||
|
||||
// Suites of benchmarks consist of a name and the set of benchmarks in
|
||||
// addition to the reference timing that the final score will be based
|
||||
// on. This way, all scores are relative to a reference run and higher
|
||||
// scores implies better performance.
|
||||
function BenchmarkSuite(name, reference, benchmarks) {
|
||||
this.name = name;
|
||||
this.reference = reference;
|
||||
this.benchmarks = benchmarks;
|
||||
BenchmarkSuite.suites.push(this);
|
||||
}
|
||||
|
||||
|
||||
// Keep track of all declared benchmark suites.
|
||||
BenchmarkSuite.suites = [];
|
||||
|
||||
|
||||
// Scores are not comparable across versions. Bump the version if
|
||||
// you're making changes that will affect that scores, e.g. if you add
|
||||
// a new benchmark or change an existing one.
|
||||
BenchmarkSuite.version = '5';
|
||||
|
||||
|
||||
// To make the benchmark results predictable, we replace Math.random
|
||||
// with a 100% deterministic alternative.
|
||||
Math.random = (function() {
|
||||
var seed = 49734321;
|
||||
return function() {
|
||||
// Robert Jenkins' 32 bit integer hash function.
|
||||
seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff;
|
||||
seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
|
||||
seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff;
|
||||
seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff;
|
||||
seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff;
|
||||
seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
|
||||
return (seed & 0xfffffff) / 0x10000000;
|
||||
};
|
||||
})();
|
||||
|
||||
|
||||
// Runs all registered benchmark suites and optionally yields between
|
||||
// each individual benchmark to avoid running for too long in the
|
||||
// context of browsers. Once done, the final score is reported to the
|
||||
// runner.
|
||||
BenchmarkSuite.RunSuites = function(runner) {
|
||||
var continuation = null;
|
||||
var suites = BenchmarkSuite.suites;
|
||||
var length = suites.length;
|
||||
BenchmarkSuite.scores = [];
|
||||
var index = 0;
|
||||
function RunStep() {
|
||||
while (continuation || index < length) {
|
||||
if (continuation) {
|
||||
continuation = continuation();
|
||||
} else {
|
||||
var suite = suites[index++];
|
||||
if (runner.NotifyStart) runner.NotifyStart(suite.name);
|
||||
continuation = suite.RunStep(runner);
|
||||
}
|
||||
if (continuation && typeof window != 'undefined' && window.setTimeout) {
|
||||
window.setTimeout(RunStep, 25);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (runner.NotifyScore) {
|
||||
var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
|
||||
var formatted = BenchmarkSuite.FormatScore(100 * score);
|
||||
runner.NotifyScore(formatted);
|
||||
}
|
||||
}
|
||||
RunStep();
|
||||
}
|
||||
|
||||
|
||||
// Counts the total number of registered benchmarks. Useful for
|
||||
// showing progress as a percentage.
|
||||
BenchmarkSuite.CountBenchmarks = function() {
|
||||
var result = 0;
|
||||
var suites = BenchmarkSuite.suites;
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
result += suites[i].benchmarks.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Computes the geometric mean of a set of numbers.
|
||||
BenchmarkSuite.GeometricMean = function(numbers) {
|
||||
var log = 0;
|
||||
for (var i = 0; i < numbers.length; i++) {
|
||||
log += Math.log(numbers[i]);
|
||||
}
|
||||
return Math.pow(Math.E, log / numbers.length);
|
||||
}
|
||||
|
||||
|
||||
// Converts a score value to a string with at least three significant
|
||||
// digits.
|
||||
BenchmarkSuite.FormatScore = function(value) {
|
||||
if (value > 100) {
|
||||
return value.toFixed(0);
|
||||
} else {
|
||||
return value.toPrecision(3);
|
||||
}
|
||||
}
|
||||
|
||||
// Notifies the runner that we're done running a single benchmark in
|
||||
// the benchmark suite. This can be useful to report progress.
|
||||
BenchmarkSuite.prototype.NotifyStep = function(result) {
|
||||
this.results.push(result);
|
||||
if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
|
||||
}
|
||||
|
||||
|
||||
// Notifies the runner that we're done with running a suite and that
|
||||
// we have a result which can be reported to the user if needed.
|
||||
BenchmarkSuite.prototype.NotifyResult = function() {
|
||||
var mean = BenchmarkSuite.GeometricMean(this.results);
|
||||
var score = this.reference / mean;
|
||||
BenchmarkSuite.scores.push(score);
|
||||
if (this.runner.NotifyResult) {
|
||||
var formatted = BenchmarkSuite.FormatScore(100 * score);
|
||||
this.runner.NotifyResult(this.name, formatted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Notifies the runner that running a benchmark resulted in an error.
|
||||
BenchmarkSuite.prototype.NotifyError = function(error) {
|
||||
if (this.runner.NotifyError) {
|
||||
this.runner.NotifyError(this.name, error);
|
||||
}
|
||||
if (this.runner.NotifyStep) {
|
||||
this.runner.NotifyStep(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Runs a single benchmark for at least a second and computes the
|
||||
// average time it takes to run a single iteration.
|
||||
BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark) {
|
||||
var elapsed = 0;
|
||||
var start = new Date();
|
||||
for (var n = 0; elapsed < 50; n++) {
|
||||
benchmark.run();
|
||||
elapsed = new Date() - start;
|
||||
}
|
||||
var usec = (elapsed * 1000) / n;
|
||||
this.NotifyStep(new BenchmarkResult(benchmark, usec));
|
||||
}
|
||||
|
||||
|
||||
// This function starts running a suite, but stops between each
|
||||
// individual benchmark in the suite and returns a continuation
|
||||
// function which can be invoked to run the next benchmark. Once the
|
||||
// last benchmark has been executed, null is returned.
|
||||
BenchmarkSuite.prototype.RunStep = function(runner) {
|
||||
this.results = [];
|
||||
this.runner = runner;
|
||||
var length = this.benchmarks.length;
|
||||
var index = 0;
|
||||
var suite = this;
|
||||
|
||||
// Run the setup, the actual benchmark, and the tear down in three
|
||||
// separate steps to allow the framework to yield between any of the
|
||||
// steps.
|
||||
|
||||
function RunNextSetup() {
|
||||
if (index < length) {
|
||||
try {
|
||||
suite.benchmarks[index].Setup();
|
||||
} catch (e) {
|
||||
suite.NotifyError(e);
|
||||
return null;
|
||||
}
|
||||
return RunNextBenchmark;
|
||||
}
|
||||
suite.NotifyResult();
|
||||
return null;
|
||||
}
|
||||
|
||||
function RunNextBenchmark() {
|
||||
try {
|
||||
suite.RunSingleBenchmark(suite.benchmarks[index]);
|
||||
} catch (e) {
|
||||
suite.NotifyError(e);
|
||||
return null;
|
||||
}
|
||||
return RunNextTearDown;
|
||||
}
|
||||
|
||||
function RunNextTearDown() {
|
||||
try {
|
||||
suite.benchmarks[index++].TearDown();
|
||||
} catch (e) {
|
||||
suite.NotifyError(e);
|
||||
return null;
|
||||
}
|
||||
return RunNextSetup;
|
||||
}
|
||||
|
||||
// Start out running the setup.
|
||||
return RunNextSetup();
|
||||
}
|
||||
|
||||
|
||||
// Copyright 2008 Google Inc. All Rights Reserved.
|
||||
// Copyright 1996 John Maloney and Mario Wolczko.
|
||||
|
||||
@ -75,6 +341,7 @@ OrderedCollection.prototype.removeFirst = function () {
|
||||
|
||||
OrderedCollection.prototype.remove = function (elm) {
|
||||
var index = 0, skipped = 0;
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < this.elms.length; i++) {
|
||||
var value = this.elms[i];
|
||||
if (value != elm) {
|
||||
@ -84,8 +351,11 @@ OrderedCollection.prototype.remove = function (elm) {
|
||||
skipped++;
|
||||
}
|
||||
}
|
||||
/* END LOOP */
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < skipped; i++)
|
||||
this.elms.pop();
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
/* --- *
|
||||
@ -588,8 +858,10 @@ function Planner() {
|
||||
Planner.prototype.incrementalAdd = function (c) {
|
||||
var mark = this.newMark();
|
||||
var overridden = c.satisfy(mark);
|
||||
/* BEGIN LOOP */
|
||||
while (overridden != null)
|
||||
overridden = overridden.satisfy(mark);
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -609,14 +881,18 @@ Planner.prototype.incrementalRemove = function (c) {
|
||||
c.removeFromGraph();
|
||||
var unsatisfied = this.removePropagateFrom(out);
|
||||
var strength = Strength.REQUIRED;
|
||||
/* BEGIN LOOP */
|
||||
do {
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < unsatisfied.size(); i++) {
|
||||
var u = unsatisfied.at(i);
|
||||
if (u.strength == strength)
|
||||
this.incrementalAdd(u);
|
||||
}
|
||||
/* END LOOP */
|
||||
strength = strength.nextWeaker();
|
||||
} while (strength != Strength.WEAKEST);
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -649,6 +925,7 @@ Planner.prototype.makePlan = function (sources) {
|
||||
var mark = this.newMark();
|
||||
var plan = new Plan();
|
||||
var todo = sources;
|
||||
/* BEGIN LOOP */
|
||||
while (todo.size() > 0) {
|
||||
var c = todo.removeFirst();
|
||||
if (c.output().mark != mark && c.inputsKnown(mark)) {
|
||||
@ -657,6 +934,7 @@ Planner.prototype.makePlan = function (sources) {
|
||||
this.addConstraintsConsumingTo(c.output(), todo);
|
||||
}
|
||||
}
|
||||
/* END LOOP */
|
||||
return plan;
|
||||
}
|
||||
|
||||
@ -666,12 +944,14 @@ Planner.prototype.makePlan = function (sources) {
|
||||
*/
|
||||
Planner.prototype.extractPlanFromConstraints = function (constraints) {
|
||||
var sources = new OrderedCollection();
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < constraints.size(); i++) {
|
||||
var c = constraints.at(i);
|
||||
if (c.isInput() && c.isSatisfied())
|
||||
// not in plan already and eligible for inclusion
|
||||
sources.add(c);
|
||||
}
|
||||
/* END LOOP */
|
||||
return this.makePlan(sources);
|
||||
}
|
||||
|
||||
@ -691,6 +971,7 @@ Planner.prototype.extractPlanFromConstraints = function (constraints) {
|
||||
Planner.prototype.addPropagate = function (c, mark) {
|
||||
var todo = new OrderedCollection();
|
||||
todo.add(c);
|
||||
/* BEGIN LOOP */
|
||||
while (todo.size() > 0) {
|
||||
var d = todo.removeFirst();
|
||||
if (d.output().mark == mark) {
|
||||
@ -700,6 +981,7 @@ Planner.prototype.addPropagate = function (c, mark) {
|
||||
d.recalculate();
|
||||
this.addConstraintsConsumingTo(d.output(), todo);
|
||||
}
|
||||
/* END LOOP */
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -716,14 +998,18 @@ Planner.prototype.removePropagateFrom = function (out) {
|
||||
var unsatisfied = new OrderedCollection();
|
||||
var todo = new OrderedCollection();
|
||||
todo.add(out);
|
||||
/* BEGIN LOOP */
|
||||
while (todo.size() > 0) {
|
||||
var v = todo.removeFirst();
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < v.constraints.size(); i++) {
|
||||
var c = v.constraints.at(i);
|
||||
if (!c.isSatisfied())
|
||||
unsatisfied.add(c);
|
||||
}
|
||||
/* END LOOP */
|
||||
var determining = v.determinedBy;
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < v.constraints.size(); i++) {
|
||||
var next = v.constraints.at(i);
|
||||
if (next != determining && next.isSatisfied()) {
|
||||
@ -731,18 +1017,22 @@ Planner.prototype.removePropagateFrom = function (out) {
|
||||
todo.add(next.output());
|
||||
}
|
||||
}
|
||||
/* END LOOP */
|
||||
}
|
||||
/* END LOOP */
|
||||
return unsatisfied;
|
||||
}
|
||||
|
||||
Planner.prototype.addConstraintsConsumingTo = function (v, coll) {
|
||||
var determining = v.determinedBy;
|
||||
var cc = v.constraints;
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < cc.size(); i++) {
|
||||
var c = cc.at(i);
|
||||
if (c != determining && c.isSatisfied())
|
||||
coll.add(c);
|
||||
}
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
/* --- *
|
||||
@ -771,10 +1061,12 @@ Plan.prototype.constraintAt = function (index) {
|
||||
}
|
||||
|
||||
Plan.prototype.execute = function () {
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < this.size(); i++) {
|
||||
var c = this.constraintAt(i);
|
||||
c.execute();
|
||||
}
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
/* --- *
|
||||
@ -799,6 +1091,7 @@ function chainTest(n) {
|
||||
var prev = null, first = null, last = null;
|
||||
|
||||
// Build chain of n equality constraints
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i <= n; i++) {
|
||||
var name = "v" + i;
|
||||
var v = new Variable(name);
|
||||
@ -808,18 +1101,21 @@ function chainTest(n) {
|
||||
if (i == n) last = v;
|
||||
prev = v;
|
||||
}
|
||||
/* END LOOP */
|
||||
|
||||
new StayConstraint(last, Strength.STRONG_DEFAULT);
|
||||
var edit = new EditConstraint(first, Strength.PREFERRED);
|
||||
var edits = new OrderedCollection();
|
||||
edits.add(edit);
|
||||
var plan = planner.extractPlanFromConstraints(edits);
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < 100; i++) {
|
||||
first.value = i;
|
||||
plan.execute();
|
||||
if (last.value != i)
|
||||
alert("Chain test failed.");
|
||||
}
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -835,6 +1131,7 @@ function projectionTest(n) {
|
||||
var src = null, dst = null;
|
||||
|
||||
var dests = new OrderedCollection();
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < n; i++) {
|
||||
src = new Variable("src" + i, i);
|
||||
dst = new Variable("dst" + i, i);
|
||||
@ -842,21 +1139,26 @@ function projectionTest(n) {
|
||||
new StayConstraint(src, Strength.NORMAL);
|
||||
new ScaleConstraint(src, scale, offset, dst, Strength.REQUIRED);
|
||||
}
|
||||
/* END LOOP */
|
||||
|
||||
change(src, 17);
|
||||
if (dst.value != 1170) alert("Projection 1 failed");
|
||||
change(dst, 1050);
|
||||
if (src.value != 5) alert("Projection 2 failed");
|
||||
change(scale, 5);
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < n - 1; i++) {
|
||||
if (dests.at(i).value != i * 5 + 1000)
|
||||
alert("Projection 3 failed");
|
||||
}
|
||||
/* END LOOP */
|
||||
change(offset, 2000);
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < n - 1; i++) {
|
||||
if (dests.at(i).value != i * 5 + 2000)
|
||||
alert("Projection 4 failed");
|
||||
}
|
||||
/* END LOOP */
|
||||
}
|
||||
|
||||
function change(v, newValue) {
|
||||
@ -864,10 +1166,12 @@ function change(v, newValue) {
|
||||
var edits = new OrderedCollection();
|
||||
edits.add(edit);
|
||||
var plan = planner.extractPlanFromConstraints(edits);
|
||||
/* BEGIN LOOP */
|
||||
for (var i = 0; i < 10; i++) {
|
||||
v.value = newValue;
|
||||
plan.execute();
|
||||
}
|
||||
/* END LOOP */
|
||||
edit.destroyConstraint();
|
||||
}
|
||||
|
||||
@ -878,3 +1182,15 @@ function deltaBlue() {
|
||||
chainTest(100);
|
||||
projectionTest(100);
|
||||
}
|
||||
|
||||
function PrintResult(name, result) {
|
||||
}
|
||||
|
||||
|
||||
function PrintScore(score) {
|
||||
}
|
||||
|
||||
|
||||
BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
|
||||
NotifyScore: PrintScore });
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user