This commit is contained in:
Hannes Verschore 2015-10-27 13:46:13 +01:00
Родитель d882254a78 8662ee6c3b
Коммит 93c3948454
11 изменённых файлов: 2029 добавлений и 4 удалений

2
.gitignore поставляемый
Просмотреть файл

@ -26,3 +26,5 @@ benchmarks/asmjs-apps/zlib/minigzipsh
driver/awfy.config
slave/awfy.config
**/*-results/
output/

30
database/migration-1.php Normal file
Просмотреть файл

@ -0,0 +1,30 @@
<?php
// Add entries for Servo in the awfy_vendor and awfy_mode.
$migrate = function() {
// INSERT an entry into awfy_vendor
mysql_query("INSERT INTO `awfy_vendor` (`name`, `vendor`, `csetURL`, `browser`, `rangeURL`) VALUES ('SpiderMonkey',
'Mozilla', 'https://github.com/servo/servo/commits/', 'Servo',
'https://github.com/servo/servo/compare/{from}...{to}');"
) or die(mysql_error());
// Get last inserted id
$vendor_id = mysql_insert_id();
// INSERT into awfy_mode with inserted vendor id
mysql_query("INSERT INTO `awfy_mode` (`vendor_id`, `mode`, `name`, `color`, `level`) VALUES ({$vendor_id}, 'servo',
'Servo', '#FF0000', 1);"
) or die(mysql_error());
};
$rollback = function() {
// Delete mode first
mysql_query("DELETE FROM `awfy_mode` WHERE `awfy_mode`.`mode`='servo' AND `awfy_mode`.`name`='Servo' AND
`awfy_mode`.`color`='#FF0000' AND `awfy_mode`.`level`=1;"
) or die(mysql_error());
// Delete vendor now
mysql_query("DELETE FROM `awfy_vendor` WHERE `awfy_vendor`.`name`='SpiderMonkey' AND
`awfy_vendor`.`vendor`='Mozilla' AND `awfy_vendor`.`csetURL`='https://github.com/servo/servo/commits/'
AND `awfy_vendor`.`browser`='Servo'; "
) or die(mysql_error());
};

Просмотреть файл

@ -96,7 +96,9 @@ class Builder(object):
info = self.retrieveInfo()
info["revision"] = puller.identify()
info["shell"] = True
# Deafult 'shell' to True only if it isn't set yet!
if 'shell' not in info:
info["shell"] = True
info["binary"] = os.path.abspath(self.binary())
fp = open(os.path.join(self.folder, "info.json"), "w")
@ -241,6 +243,28 @@ class V8Builder(Builder):
def binary(self):
return os.path.join(self.objdir(), 'd8')
class ServoBuilder(Builder):
def __init__(self, config, folder):
super(ServoBuilder, self).__init__(config, folder);
# Some other config here
def retrieveInfo(self):
info = {}
info["engine_type"] = "servo"
info['shell'] = False
return info
def objdir(self):
return os.path.join(self.folder, 'target')
def binary(self):
return os.path.join(self.objdir(), 'release', 'servo')
def make(self):
with utils.FolderChanger(self.folder):
args = [os.path.join('.', 'mach'), 'build' ,'--release']
Run(args, self.env.get())
def getBuilder(config, path):
# fingerprint the known builders
if os.path.exists(os.path.join(path, "js", "src")):
@ -249,6 +273,8 @@ def getBuilder(config, path):
return WebkitBuilder(config, path)
if os.path.exists(os.path.join(path, "v8", "LICENSE.v8")):
return V8Builder(config, path)
if os.path.exists(os.path.join(path, "components", "servo")):
return ServoBuilder(config, path)
raise Exception("Unknown builder")

Просмотреть файл

@ -23,6 +23,8 @@ class Default(object):
pass
elif engine == "ie":
pass
elif engine == "servo":
pass
else:
self.omit_ = True

Просмотреть файл

@ -54,7 +54,8 @@ if options.mode_rules is None:
"chrome,default:v8",
"chrome,turbofan:v8-turbofan",
"webkit,default:jsc",
"native,default:clang"
"native,default:clang",
"servo,default:servo"
]
#TODO:remove

Просмотреть файл

@ -2,8 +2,8 @@ import runners
import time
import os
import sys
import json
sys.path.insert(1, '../driver')
import utils
class ShellExecutor(object):
@ -45,7 +45,7 @@ class BrowserExecutor(object):
os.unlink("results")
def waitForResults(self):
timeout = int(utils.config.get('main', 'timeout')) * 60
timeout = utils.config.Timeout * 60
while not os.path.exists("results") and timeout > 0:
time.sleep(10)
timeout -= 10
@ -86,6 +86,25 @@ class FirefoxExecutor(BrowserExecutor):
# kill browser
runner.kill(process)
class ServoExecutor(BrowserExecutor):
def execute(self, page, env, args):
runner = runners.getRunner(self.engineInfo["platform"], {})
# kill all possible running instances.
runner.killall("servo")
# reset the result
self.resetResults()
# start browser
process = runner.start(self.engineInfo["binary"], args, env)
# wait for results
self.waitForResults()
# kill browser
runner.kill(process)
#class NativeExecutor(Executor):
#
@ -97,4 +116,6 @@ def getExecutor(engineInfo):
return ShellExecutor(engineInfo)
if engineInfo["engine_type"] == "firefox" and not engineInfo["shell"]:
return FirefoxExecutor(engineInfo)
if engineInfo["engine_type"] == "servo":
return ServoExecutor(engineInfo)

Просмотреть файл

@ -157,6 +157,8 @@ def getPuller(repo, path):
repo = "http://hg.mozilla.org/integration/mozilla-inbound"
elif repo == "webkit":
repo = "https://svn.webkit.org/repository/webkit/trunk"
elif repo == "servo":
repo = "https://github.com/servo/servo.git"
if "hg." in repo:
return HG(repo, path)

Просмотреть файл

@ -20,6 +20,7 @@ class FakeHandler(SimpleHTTPRequestHandler):
parsedParams = urlparse.urlparse(self.path)
self.localBenchmark(parsedParams.query)
self.send_response(200)
def do_POST(self):
length = int(self.headers.getheader('content-length', 0))
@ -29,6 +30,7 @@ class FakeHandler(SimpleHTTPRequestHandler):
return
self.localBenchmark(postdata)
self.send_response(200)
def localBenchmark(self, query = None):
if self.path.startswith("/submit"):

1059
website/servo/awfy.js Executable file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

727
website/servo/frontpage.js Executable file
Просмотреть файл

@ -0,0 +1,727 @@
// vim: set ts=4 sw=4 tw=99 et:
/* 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/. */
"use strict";
function Display(awfy, id, domid, elt)
{
this.awfy = awfy;
this.id = id;
this.domid = domid;
this.elt = elt;
this.attachedTips = [];
this.plot = null;
this.hovering = null;
this.graph = null;
this.orig_graph = null;
}
Display.prototype.setGraph = function (graph)
{
// We keep both the original dataset and the one we send and display to
// flot, so we can redraw and hide lines. In the future this should be
// tightened up, so that code working with the display graph uses "graph"
// and code (if any) working with the original data set uses "orig_graph".
// And really no code should be accessing "graph" until draw().
this.orig_graph = graph;
this.graph = graph;
}
Display.prototype.setup = function (graph)
{
this.setGraph(graph);
this.selectDelay = null;
if (graph.aggregate)
this.setHistoricalMidpoint();
else
this.aggregate = -1;
this.zoomInfo = { prev: null,
level: 'aggregate'
};
this.elt.bind("plothover", this.onHover.bind(this));
this.elt.bind('plotclick', this.onClick.bind(this));
this.elt.bind('plotselected', this.plotSelected.bind(this));
this.elt.bind('dblclick', (function () {
if (this.zoomInfo.level != 'aggregate')
this.unzoom();
}).bind(this));
}
Display.MaxPoints = 50;
Display.Months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
Display.prototype.shutdown = function () {
this.elt.unbind('plothover');
this.elt.unbind('plotclick');
this.elt.unbind('plotselected');
this.elt.unbind('dblclick');
if (this.hovering) {
this.hovering.remove();
this.hovering = null;
}
this.detachTips();
this.plot = null;
this.setGraph(null);
}
Display.prototype.shouldRefresh = function () {
if (this.graph) {
for (var i = 0; i < this.attachedTips.length; i++) {
var tooltip = this.attachedTips[i];
if (tooltip.attached())
return false;
}
if (this.zoomInfo.level != 'aggregate')
return false;
this.shutdown();
}
return true;
}
Display.prototype.setHistoricalMidpoint = function () {
// Find the range of historical points.
for (var i = 0; i < this.graph.timelist.length; i++) {
if (this.graph.timelist[i] >= this.graph.earliest)
break;
}
if (i && i != this.graph.timelist.length)
this.historical = i;
}
// Copy flot's tick algorithm.
Display.prototype.tickSize = function (min, max) {
var noTicks = 0.3 * Math.sqrt(this.elt.width());
var delta = (max - min) / noTicks;
var dec = -Math.floor(Math.log(delta) / Math.LN10);
var magn = Math.pow(10, -dec);
var norm = delta / magn;
var size;
if (norm < 1.5) {
size = 1;
} else if (norm < 3) {
size = 2;
if (norm > 2.25) {
size = 2.5;
++dec;
}
} else if (norm < 7.5) {
size = 5;
} else {
size = 10;
}
size *= magn;
return size;
};
Display.prototype.aggregateTicks = function () {
// Draw historical ticks at a higher density.
var ticks = this.tickSize(0, this.graph.timelist.length);
var list = [];
// This is all a bunch of hardcoded hacks for now.
var preticks, preticklist;
if (ticks == 5) {
preticks = 6;
preticklist = [2, 4];
} else if (ticks == 10) {
preticks = 9;
preticklist = [3, 6];
} else {
preticks = ticks;
}
var last_year = undefined;
var current_year = (new Date()).getFullYear();
for (var i = 0; i < this.historical; i += preticks) {
var d = new Date(this.graph.timelist[i] * 1000);
var text = Display.Months[d.getMonth()];
// Some graphs span over a year, so add in a hint when the year
// changes.
if ((i == 0 && d.getFullYear() != current_year) ||
(last_year && d.getFullYear() != last_year))
{
text += " " + d.getFullYear();
last_year = d.getFullYear();
}
// Add the tick mark, then try to add some more empty ones to
// make the graph appear denser.
list.push([i, text]);
if (preticklist) {
for (var j = 0; j < preticklist.length; j++) {
var v = i + preticklist[j];
if (v >= this.historical)
break;
list.push([v, ""]);
}
}
}
// Figure out where we should start placing sparser lines, since
// we don't want them too close to the historical lines.
i = list[list.length - 1][0] + ticks;
// If the aggregate graph has both historical and recent points,
for (; i < this.graph.timelist.length; i += ticks) {
var d = new Date(this.graph.timelist[Math.floor(i)] * 1000);
var text = Display.Months[d.getMonth()] + " " + d.getDate();
list.push([i, text]);
}
return list;
}
Display.prototype.draw = function () {
var options = { };
// We always start out by using the original graph, since we may modify
// this one locally. Start by stripping out any lines that should be
// hidden.
var new_info = [];
var new_lines = [];
for (var i = 0; i < this.orig_graph.info.length; i++) {
var info = this.orig_graph.info[i];
var mode = AWFYMaster.modes[info.modeid];
if (!mode)
continue;
// Strip JM+TI, BC
if (info.modeid == 12 || info.modeid == 15)
continue;
mode.used = true;
if (mode.hidden)
continue;
new_info.push(info);
new_lines.push(this.orig_graph.lines[i]);
}
this.graph = {
lines: new_lines,
info: new_info,
timelist: this.orig_graph.timelist,
earliest: this.orig_graph.earliest,
aggregate: this.orig_graph.aggregate,
direction: this.orig_graph.direction
};
options.lines = { show: true };
options.points = { fillColor: "#ffffff", show: true };
options.borderWidth = 1.5;
options.borderColor = "#BEBEBE";
options.legend = { show: false };
options.xaxis = { };
options.yaxis = { };
options.grid = { hoverable: true, clickable: true };
options.selection = { mode: 'x' }
// Aggregate view starts from 0. We space things out when zooming in.
if (this.graph.aggregate && this.awfy.type != 'overview')
options.yaxis.min = 0;
if (this.graph.direction == 1) {
options.yaxis.transform = function (v) {
return -v;
};
options.yaxis.inverseTransform = function (v) {
return -v;
};
}
if (this.graph.aggregate && this.historical) {
// If the graph has both historical and recent points, indicated by
// the "historical" midpoint, then we change some graph formatting
// to reflect that part of the graph has a greater time density.
//
// To make this work, we modified flot to pass in its plot variable
// when invoking this callback, in order to use c2p().
options.points.symbol = (function (ctx, x, y, radius, shadow, plot) {
var axis = plot.getAxes();
var rx = Math.round(axis.xaxis.c2p(x));
if (this.graph.timelist[rx] < this.graph.earliest) {
ctx.strokeRect(x - radius / 3, y - radius / 3, radius * 2/3, radius * 2/3);
// Disable clearRect due to bug in Firefox for Android (bug 936177)
//ctx.clearRect(x - radius / 4, y - radius / 4, radius / 2, radius / 2);
} else {
ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
}
}).bind(this);
options.xaxis.ticks = this.aggregateTicks();
options.xaxis.transform = (function (v) {
if (v < 30)
return v;
var total = this.graph.timelist.length - 30;
return 30 + (v - 30)/total * 30;
}).bind(this);
options.xaxis.inverseTransform = (function (v) {
if (v < 30)
return v;
var total = this.graph.timelist.length - 30;
return 30 + (v - 30)/30 * total;
}).bind(this);
}
options.yaxis.tickFormatter = function (v, axis) {
if (Math.round(v) != v)
return v.toFixed(2);
return v;
}
if (!options.xaxis.ticks) {
options.xaxis.tickFormatter = (function (v, axis) {
v = Math.round(v);
if (v < 0 || v >= this.graph.timelist.length)
return '';
var t = this.graph.timelist[v];
var d = new Date(t * 1000);
return Display.Months[d.getMonth()] + " " + d.getDate();
}).bind(this);
}
this.plot = $.plot(this.elt, this.graph.lines, options);
if (this.graph.direction == 1) {
var yaxisLabel = $("<div class='axisLabel yaxisLabel'></div>")
.text("Score")
.appendTo(this.elt);
} else {
var yaxisLabel = $("<div class='axisLabel yaxisLabel'></div>")
.text("Execution Time (ms)")
.appendTo(this.elt);
}
yaxisLabel.css("margin-top", yaxisLabel.width() / 2 - 20);
}
Display.prototype.plotSelected = function (event, ranges) {
this.selectDelay = new Date();
var from_x = Math.floor(ranges.xaxis.from);
if (from_x == ranges.xaxis.from)
from_x -= 1;
if (from_x < 0)
from_x = 0;
var to_x = Math.ceil(ranges.xaxis.to);
if (to_x == ranges.xaxis.to)
to_x += 1;
if (to_x >= this.graph.timelist.length)
to_x = this.graph.timelist.length - 1;
var start = this.graph.timelist[from_x];
var end = this.graph.timelist[to_x];
AWFY.trackZoom(start, end);
var prev = this.zoomInfo.prev;
if (prev && this.zoomInfo.level == 'month') {
// Estimate the number of datapoints we had in the old range.
var oldstart = AWFY.findX(prev, this.graph.timelist[0]);
var oldend = AWFY.findX(prev, this.graph.timelist[this.graph.timelist.length - 1]);
// Estimate the number of datapoints we'd have in the new range.
var newstart = AWFY.findX(prev, start);
var newend = AWFY.findX(prev, end);
// Some heuristics to figure out whether we should fetch more data.
var zoom = (newend - newstart) / (oldend - oldstart);
if ((zoom >= 0.8 && (newend - newstart >= Display.MaxPoints * 1.5)) ||
(newend - newstart >= Display.MaxPoints * 5))
{
// Okay! Trim the cached graph, then display.
var graph = AWFY.trim(prev, newstart, newend);
this.localZoom(graph);
return;
}
}
// If we already have the highest level of data, jump right in.
if (prev && this.zoomInfo.level == 'raw') {
var oldstart = AWFY.findX(prev, this.graph.timelist[0]);
var oldend = AWFY.findX(prev, this.graph.timelist[this.graph.timelist.length - 1]);
this.plot.clearSelection();
// If we can't really zoom in any more, don't bother.
if (oldend - oldstart < Display.MaxPoints / 2)
return;
// Require at least a few datapoints.
var newstart = AWFY.findX(prev, start);
var newend = AWFY.findX(prev, end);
if (oldend - oldstart <= 3)
return;
var graph = AWFY.trim(prev, newstart, newend);
this.localZoom(graph);
return;
}
// Disable further selections since we wait for the XHR to go through.
this.plot.disableSelection();
// Clear the cached graph, since we'll get a new one.
this.zoomInfo.prev = null;
if (this.zoomInfo.level == 'aggregate') {
this.awfy.requestZoom(this, 'condensed', start, end);
this.zoomInfo.level = 'month';
} else {
this.awfy.requestZoom(this, 'raw', start, end);
this.zoomInfo.level = 'raw';
}
}
Display.prototype.localZoom = function (graph) {
graph = AWFY.condense(graph, Display.MaxPoints);
this.setGraph(graph);
this.draw();
this.plot.enableSelection();
this.plot.clearSelection();
this.detachTips();
}
Display.prototype.completeZoom = function (graph, start, end) {
// Copy properties from the old graph before resetting.
graph.direction = this.graph.direction;
// Cache the original graph in case it's dense enough to zoom in more
// without fetching more points via XHR.
if (!this.zoomInfo.prev)
this.zoomInfo.prev = graph;
var first = AWFY.findX(graph, start);
var last = AWFY.findX(graph, end);
graph = AWFY.trim(graph, first, last);
// If we got a paltry number of datapoints, skip this and zoom in more.
if (this.zoomInfo.level == 'month' && graph.timelist.length < Display.MaxPoints / 2) {
this.zoomInfo.prev = null;
this.awfy.requestZoom(this, 'raw', start, end);
this.zoomInfo.level = 'raw';
return;
}
this.localZoom(graph);
}
Display.prototype.cancelZoom = function () {
this.plot.enableSelection();
this.plot.clearSelection();
// Reset the zoom level we think we have.
if (!this.zoomInfo.prev) {
if (this.zoomInfo.level == 'raw')
this.zoomInfo.level = 'month';
else if (this.zoomInfo.level == 'month')
this.zoomInfo.level = 'aggregate';
}
}
Display.prototype.unzoom = function () {
this.setGraph(AWFY.aggregate[this.id]);
this.setHistoricalMidpoint();
this.draw();
this.plot.enableSelection();
this.plot.clearSelection();
this.detachTips();
this.zoomInfo.level = 'aggregate';
AWFY.trackZoom(null, null);
}
Display.prototype.detachTips = function () {
for (var i = 0; i < this.attachedTips.length; i++)
this.attachedTips[i].detach();
this.attachedTips = [];
}
Display.prototype.createToolTip = function (item, extended) {
var so = extended ? '<strong>' : '';
var sc = extended ? '</strong>' : '';
// Figure out the line this corresponds to.
var line = this.graph.info[item.seriesIndex];
if (!line)
return;
var text = "";
var x = item.datapoint[0];
var y = item.datapoint[1];
// Show suite version.
if (line.data[x][3]) {
var suiteVersion = AWFYMaster.suiteversions[line.data[x][3]]["name"];
text += so + 'suite: ' + sc + suiteVersion + '<br>';
}
// Show score.
if (this.graph.direction == -1)
text += so + 'score: ' + sc + y.toFixed(2) + 'ms<br>';
else
text += so + 'score: ' + sc + y.toFixed() + '<br>';
// Find the point previous to this one.
var prev = null;
for (var i = x - 1; i >= 0; i--) {
if (line.data[i] && line.data[i][0]) {
prev = line.data[i];
break;
}
}
if (prev) {
// Compute a difference.
var diff = Math.round((y - prev[0]) * 10) / 10;
var perc = -Math.round(((y - prev[0]) / prev[0]) * 1000) / 10;
var better;
if ((perc < 0 && this.graph.direction == -1) ||
(perc > 0 && this.graph.direction == 1))
{
better = 'worse';
} else {
better = 'better';
}
perc = Math.abs(perc);
if (diff === diff) {
if (extended)
text += so + 'delta' + sc + ': ' + diff;
else
text += String.fromCharCode(916) + ': ' + diff;
if (this.graph.direction == -1)
text += 'ms';
text += ' (' + perc + '% ' + better + ')<br>';
}
}
// Find the vendor.
var mode = AWFYMaster.modes[line.modeid];
var vendor;
if (mode)
vendor = AWFYMaster.vendors[mode.vendor_id];
if (vendor) {
text += so + 'source: ' + sc +
vendor.browser +
' (' + mode.name + ')'+
'<br>';
}
// Find the datapoint.
var point = line.data[x];
if (extended) {
if (point.length > 1 && point[2] && point[1] != point[2]) {
if (vendor.rangeURL) {
var url = vendor.rangeURL
.replace("{from}", point[1])
.replace("{to}", point[2]);
text += so + 'revs: ' + sc +
'<a href="' + url + '">' + point[1] + " to " + point[2] + '</a>';
} else {
text += so + 'revs: ' + sc +
'<a href="' + vendor.url + point[1] + '">' + point[1] + '</a>' +
' to ' +
'<a href="' + vendor.url + point[2] + '">' + point[2] + '</a>';
}
} else {
text += so + 'rev: ' + sc +
'<a href="' + vendor.url + point[1] + '">' + point[1] + '</a>';
if (prev && vendor.rangeURL) {
var url = vendor.rangeURL
.replace("{from}", prev[1])
.replace("{to}", point[1])
.replace("{num}", point[1] - prev[1]);
text += ' (<a href="' + url + '">changelog</a>)';
}
}
text += '<br>';
} else {
if (point.length > 1 && point[2] && point[1] != point[2]) {
text += so + 'revs: ' + sc +
point[1] +
' to ' +
point[2] +
'<br>';
} else {
text += so + 'rev: ' + sc + point[1] + '<br>';
}
}
var pad = function (d) {
if (d == 0)
return '00';
else if (d < 10)
return '0' + d;
else
return '' + d;
}
// Format a year, if we should.
if (extended) {
var current_year = (new Date()).getFullYear();
var datefmt = function (t, forceYear, omitTime) {
var d = new Date(t * 1000);
var text = Display.Months[d.getMonth()] + ' ' + d.getDate();
if (d.getFullYear() != current_year || forceYear)
text += ', ' + d.getFullYear();
if (!omitTime && (d.getHours() || d.getMinutes())) {
text += ' ';
text += pad(d.getHours()) + ':' +
pad(d.getMinutes());
}
return text;
}
if (point.length > 1 &&
point[2] &&
point[1] != point[2] &&
x < this.graph.timelist.length - 1)
{
text += so + 'tested: ' + sc +
datefmt(this.graph.timelist[x], false, true) + ' to ' +
datefmt(this.graph.timelist[x + 1], true, true) + '<br>';
} else {
text += so + 'tested: ' + sc +
datefmt(this.graph.timelist[x], false, false) + '<br>';
}
} else {
// Include a short timestamp if we're looking at recent changesets.
var d = new Date(this.graph.timelist[x] * 1000);
var now = new Date();
text += so + 'tested: ' + sc;
if (this.graph.aggregate && x < this.historical)
text += 'around ';
text += Display.Months[d.getMonth()] + ' ' + d.getDate();
if (now.getFullYear() != d.getFullYear())
text += ', ' + d.getFullYear() + ' ';
else
text += ' ';
if (!this.graph.aggregate || x >= this.historical)
text += pad(d.getHours()) + ':' + pad(d.getMinutes()) + '<br>';
}
/*
// Regression doesn't work for servo-awfy yet! Skip it.
if (extended && point.length >= 5) {
if (!point[4]) {
text += so + 'regression: ' + sc + "zoom in to view regression info." + '<br>';
} else {
var id = Math.random();
while (document.getElementById("update_"+id))
id = Math.random();
text += so + 'regression?: ' + sc + "<span id='update_regression_" + id + "'><img src='loading.gif' height='12px'/></span>" + '<br>';
text += so + 'extra info: ' + sc + "<span id='update_info_" + id + "'><img src='loading.gif' height='12px'/></span>" + '<br>';
var subtest = AWFY.isSubtest();
$.get("data-info.php", {
subtest: subtest,
id: point[4]
}, function(data) {
var html = data.regression.status;
if (data.regression.id) {
html += " <a href='regressions/#regression/"+data.regression.id+"'>(view)</a>"
} else {
if (subtest)
html += " <a href='regressions/#add/subtest/"+point[4]+"'>(report regression)</a>"
else
html += " <a href='regressions/#add/"+point[4]+"'>(report regression)</a>"
}
document.getElementById("update_regression_"+id).innerHTML = html;
document.getElementById("update_info_"+id).innerHTML = data.info;
}, "json");
}
}
*/
return new ToolTip(item.pageX, item.pageY, item, text);
}
Display.prototype.onClick = function (event, pos, item) {
// Remove the existing hovertip.
if (this.hovering) {
this.hovering.remove();
this.hovering = null;
}
if (!item)
return;
if (this.selectDelay) {
// When unselecting a plot, the cursor might be over a point, which
// will give us annoying extra tooltips. To combat this, we force a
// small delay.
var d = new Date();
if (d - this.selectDelay <= 1000) {
this.plot.unhighlight();
return;
}
}
var tooltip = this.createToolTip(item, true);
tooltip.drawFloating();
this.lastToolTip = tooltip;
// The color of the line will be the series color.
var line = this.graph.info[item.seriesIndex];
if (!line)
return;
var mode = AWFYMaster.modes[line.modeid];
if (!mode)
return;
tooltip.attachLine(mode.color);
this.attachedTips.push(tooltip);
}
Display.prototype.areItemsEqual = function (item1, item2) {
return item1.seriesIndex == item2.seriesIndex &&
item1.dataIndex == item2.dataIndex &&
item1.datapoint[0] == item2.datapoint[0];
}
Display.prototype.onHover = function (event, pos, item) {
// Are we already hovering over something?
if (this.hovering) {
// If we're hovering over the same point, don't do anything.
if (item && this.areItemsEqual(item, this.hovering.item))
return;
// Otherwise, remove the div since we will redraw.
this.hovering.remove();
this.hovering = null;
}
// If we have a pinned tooltip that has not been moved yet, don't draw a
// second tooltip on top of it.
if (this.lastToolTip && !this.lastToolTip.dragged && !this.lastToolTip.closed)
return;
if (!item)
return;
this.hovering = this.createToolTip(item, false);
this.hovering.drawBasic();
}
Display.prototype.hideToolTips = function () {
for (var i = 0; i < this.attachedTips.length; i++)
this.attachedTips[i].hide();
}
Display.prototype.showToolTips = function () {
for (var i = 0; i < this.attachedTips.length; i++)
this.attachedTips[i].show();
}

153
website/servo/index.html Executable file
Просмотреть файл

@ -0,0 +1,153 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-language" content="en">
<title>Servo Benchmarking</title>
<link rel="stylesheet" title="Default Stylesheet" type="text/css" href="../style.css">
<link rel="shortcut icon" href="//www.arewefastyet.com/awfy_favicon.png">
<link href='//fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
<script type="text/javascript" src="../jquery/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="../jquery/jquery.ba-hashchange.min.js"></script>
<script type="text/javascript" src="../flot/jquery.flot.js"></script>
<script type="text/javascript" src="../flot/jquery.flot.selection.js"></script>
<script type="text/javascript" src="../data.php?file=master.js"></script>
<script type="text/javascript" src="awfy.js"></script>
<script type="text/javascript" src="frontpage.js"></script>
<script type="text/javascript" src="../tooltip.js"></script>
</head>
<body>
<!--[if IE 6]><body class="ie ie6"><![endif]-->
<!--[if IE 7]><body class="ie ie7"><![endif]-->
<!--[if IE 8]><body class="ie ie8"><![endif]-->
<!--[if IE 9]><body class="ie ie9"><![endif]-->
<!--[if gt IE 9]><body class="ie"><![endif]-->
<!--[if !IE ]><!-->
<body>
<!--<![endif]-->
<script type="text/javascript">
$(document).ready(function () {
AWFY.startup();
});
</script>
<header>
<div class='container'>
<h1><a href='#'>Servo-Benchmark</a></h1>
<div class='rightSide'>
<!-- <div><a href="/overview"><span>Overview</span></a></div> -->
<!--
<div class='userMenu'>
<a href="javascript:doPersonaLogin()" ng-if="!currentUser"><span>Login</span></a>
<a href="javascript:doPersonaLogout()" ng-if='currentUser'><span>Logout</span></a>
</div>
-->
</div>
</div>
</header>
<div class='content'>
<div class="graph-row">
<div id="message"></div>
<div id="navcontainer">
<ul id="legend"></ul>
<br><br>
<ul class="menu">
<li id="machinehook"><a href="#" id="machinedrop">Machines</a> &#187;
<ul id="machinelist"></ul>
</li>
<li id="breakdownhook"><a href="#" id="bkdrop">Breakdown</a> &#187;
<ul id="breakdownlist"></ul>
</li>
<li><a href='#' id="aboutdrop">About</a> &#187;</li>
</ul>
</div>
<div class="graph-container">
<div id="dromaeo-label">dromaeo time</div>
<div class="graph" id="dromaeo-graph"><h2>Loading...</h2></div>
</div>
</div>
<br><br><br>
<!--
<div class="graph-row">
<div class="graph-container">
<div id="v8-label">v8bench score</div>
<div class="graph" id="v8real-graph"><h2>Loading...</h2></div>
</div>
</div>
-->
</div>
<div id="breakdown">
</div>
<div id="about">
<h2>Benchmarking the performance of <a href="https://github.com/servo/servo">Mozilla Servo</a>.</h2>
<strong>Basic usage:</strong>
<ul>
<li>The x-axis is the date we ran tests, and the y-axis is the score of the benchmark.</li>
<li>The front page displays a hybrid of historical data, as well as the most recent samples.</li>
<li>You can click on a datapoint to see a tooltip with more information.</li>
<li>Tooltips will either give you the revision range used to condense a point, or the changelog that occurred in between two points.</li>
<li>Tooltips can be dragged around, for easier comparison.</li>
<li>Some benchmarks use time (lower is better), and some use points (higher is better). We orient all graphs so lower is better, visually.</li>
<li>Use the "machine" menu to see different computers' benchmark results.</li>
<li>Use the "Breakdown" menu to drill down into individual benchmarks.</li>
<li>You can click and highlight any area of any graph to zoom in. It might pause to download data.</li>
<li>You can unzoom by double-clicking inside a graph.</li>
<li>A graph will refresh every 5 minutes if it is not zoomed in and has no attached tooltips.</li>
</ul>
<strong>FAQ:</strong>
<ul>
<li>
<p>Who maintains this site?</p>
<p>This site is maintained by Mozilla-Servo team.</p>
</li>
<li>
<p>How does it work?</p>
<p>It is automated. Throughout the day, we checkout the latest source code to Mozilla Servo, and compile it. Then we run it through some benchmark suites, and tally up the scores into a database. This data gets exported as JSON which can then be easily plotted.</p>
</li>
<li>
<p>What are the graphs?</p>
<p>The graph currently shows Servo's performance on <a href="https://wiki.mozilla.org/Dromaeo">Dromaeo test suite</a>.</p>
</li>
<li>
<p>What do the hover tips mean?</p>
<p>"Source" is where we got the engine from. "Tested" is when we downloaded the engine, compiled, and tested it. "Rev" is the unique point in the engine's revision history we tested. If the datapoint represents a range, there may be multiple revs. These numbers/strings are for developers to see which changes happened in between points in the graph.</p>
</li>
<li>
<p>Is this open source?</p>
<p>Fo' sho', <a href="https://github.com/dhananjay92/arewefastyet">github.com/dhananjay92/arewefastyet</a></p>
<p>(Adapted from <a href="https://github.com/h4writer/arewefastyet/">github.com/h4writer/arewefastyet/</a>)</p>
</li>
<li>
<p>Suggestions?</p>
<p><a href="mailto:Dhananjay Nakrani<dhananjaynakrani@gmail.com>">dhananjaynakrani@gmail.com</a></p>
</ul>
</div>
<br>
</div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-58850314-2', 'auto');
ga('send', 'pageview');
</script>
<!-- Piwik -->
<script type="text/javascript">
var _paq = _paq || [];
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//arewefastyet.com/piwik/";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', 1]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<noscript><p><img src="//arewefastyet.com/piwik/piwik.php?idsite=1" style="border:0;" alt="" /></p></noscript>
<!-- End Piwik Code -->
</body>
</html>