run-octane.js revision 842:75e8d1a4ba23
1143883Sphilip/*
2143883Sphilip * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3143883Sphilip * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4143883Sphilip *
5143883Sphilip * This code is free software; you can redistribute it and/or modify it
6143883Sphilip * under the terms of the GNU General Public License version 2 only, as
7143883Sphilip * published by the Free Software Foundation.
8143883Sphilip *
9143883Sphilip * This code is distributed in the hope that it will be useful, but WITHOUT
10143883Sphilip * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11143883Sphilip * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12143883Sphilip * version 2 for more details (a copy is included in the LICENSE file that
13143883Sphilip * accompanied this code).
14143883Sphilip *
15143883Sphilip * You should have received a copy of the GNU General Public License version
16143883Sphilip * 2 along with this work; if not, write to the Free Software Foundation,
17143883Sphilip * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18143883Sphilip *
19143883Sphilip * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20143883Sphilip * or visit www.oracle.com if you need additional information or have any
21143883Sphilip * questions.
22143883Sphilip */
23143883Sphilip
24143883Sphilip/**
25143883Sphilip * @subtest
26143883Sphilip */
27143883Sphilip
28203687Sgavinvar read = readFully;
29203687Sgavin
30143883Sphilipfunction initZlib() {
31143883Sphilip    zlib = new BenchmarkSuite('zlib', [152815148], [
32143883Sphilip						    new Benchmark('zlib', false, true, 10,
33143883Sphilip								  runZlib, undefined, tearDownZlib, null, 3)]);
34143883Sphilip}
35157365Sbrueffer
36157365Sbrueffervar tests = [
37157365Sbrueffer    {name:"box2d",         files:["box2d.js"],                         suite:"Box2DBenchmark"},
38157365Sbrueffer    {name:"code-load",     files:["code-load.js"],                     suite:"CodeLoad"},
39143883Sphilip    {name:"crypto",        files:["crypto.js"],                        suite:"Crypto"},
40157365Sbrueffer    {name:"deltablue",     files:["deltablue.js"],                     suite:"DeltaBlue"},
41157365Sbrueffer    {name:"earley-boyer",  files:["earley-boyer.js"],                  suite:"EarleyBoyer"},
42157365Sbrueffer    {name:"gbemu",         files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"},
43157365Sbrueffer    {name:"mandreel",      files:["mandreel.js"],                      suite:"MandreelBenchmark"},
44157365Sbrueffer    {name:"navier-stokes", files:["navier-stokes.js"],                 suite:"NavierStokes"},
45157365Sbrueffer    {name:"pdfjs",         files:["pdfjs.js"],                         suite:"PdfJS"},
46157365Sbrueffer    {name:"raytrace",      files:["raytrace.js"],                      suite:"RayTrace"},
47157365Sbrueffer    {name:"regexp",        files:["regexp.js"],                        suite:"RegExpSuite"},
48143883Sphilip    {name:"richards",      files:["richards.js"],                      suite:"Richards"},
49143883Sphilip    {name:"splay",         files:["splay.js"],                         suite:"Splay"},
50143883Sphilip    {name:"typescript",    files:["typescript.js", "typescript-input.js", "typescript-compiler.js"], suite:"typescript"},
51143883Sphilip    //zlib currently disabled - requires read
52143883Sphilip    {name:"zlib",          files:["zlib.js", "zlib-data.js"], suite:"zlib", before:initZlib}
53143883Sphilip];
54143883Sphilipvar dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
55143883Sphilip
56143883Sphilip// TODO: why is this path hard coded when it's defined in project properties?
57143883Sphilipvar path = dir + "../external/octane/";
58143883Sphilip
59143883Sphilipvar runtime = "";
60148066Shrsvar verbose = false;
61143883Sphilip
62143883Sphilipvar numberOfIterations = 5;
63143883Sphilip
64143883Sphilipfunction endsWith(str, suffix) {
65143883Sphilip    return str.indexOf(suffix, str.length - suffix.length) !== -1;
66143883Sphilip}
67143883Sphilip
68143883Sphilipfunction should_compile_only(name) {
69143883Sphilip    return (typeof compile_only !== 'undefined')
70143883Sphilip}
71143883Sphilip
72143883Sphilipfunction load_bench(arg) {
73143883Sphilip
74143883Sphilip    for (var idx = 0; idx < arg.files.length; idx++) {
75143883Sphilip	var f = arg.files[idx];
76143883Sphilip	var file = f.split('/');
77147432Sru	var file_name = path + file[file.length - 1];
78143883Sphilip
79143883Sphilip	var compile_and_return = should_compile_only(file_name);
80143883Sphilip	if (compile_and_return) {
81143883Sphilip	    if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
82143883Sphilip		return true;
83143883Sphilip	    }
84143883Sphilip	}
85143883Sphilip
86143883Sphilip	print_verbose(arg, "loading '" + arg.name + "' [" + f + "]...");
87143883Sphilip	load(file_name);
88143883Sphilip    }
89143883Sphilip
90143883Sphilip    if (typeof arg.before !== 'undefined') {
91143883Sphilip	arg.before();
92143883Sphilip    }
93143883Sphilip
94143883Sphilip    if (compile_and_return) {
95143883Sphilip	print_always(arg, "Compiled OK");
96143883Sphilip    }
97143883Sphilip    return !compile_and_return;
98143883Sphilip
99143883Sphilip}
100143883Sphilip
101143883Sphilip
102143883Sphilipfunction run_one_benchmark(arg, iters) {
103143883Sphilip
104143883Sphilip    if (!load_bench(arg)) {
105143883Sphilip	return;
106143883Sphilip    }
107143883Sphilip
108143883Sphilip    var success = true;
109143883Sphilip    var current_name;
110143883Sphilip
111143883Sphilip    if (iters == undefined) {
112143883Sphilip	iters = numberOfIterations;
113143883Sphilip    } else {
114143883Sphilip	numberOfIterations = iters;
115143883Sphilip    }
116143883Sphilip
117143883Sphilip    var benchmarks = eval(arg.suite + ".benchmarks");
118143883Sphilip    var min_score  = 1e9;
119143883Sphilip    var max_score  = 0;
120143883Sphilip    var mean_score = 0;
121143883Sphilip
122143883Sphilip    try {
123143883Sphilip	for (var x = 0; x < benchmarks.length ; x++) {
124143883Sphilip	    //do warmup run
125143883Sphilip	    //reset random number generator needed as of octane 9 before each run
126143883Sphilip	    BenchmarkSuite.ResetRNG();
127143883Sphilip	    benchmarks[x].Setup();
128143883Sphilip	}
129143883Sphilip	BenchmarkSuite.ResetRNG();
130143883Sphilip	print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
131143883Sphilip
132143883Sphilip	var scores = [];
133143883Sphilip
134143883Sphilip	var min_time_ms = min_time * 1000;
135143883Sphilip	var len = benchmarks.length;
136143883Sphilip
137143883Sphilip	for (var it = 0; it < iters + 1; it++) {
138143883Sphilip	    //every iteration must take a minimum of 10 secs
139143883Sphilip	    var ops = 0;
140143883Sphilip	    var elapsed = 0;
141143883Sphilip	    var start = new Date;
142143883Sphilip	    do {
143143883Sphilip		for (var i = 0; i < len; i++) {
144143883Sphilip		    benchmarks[i].run();
145143883Sphilip		    //important - no timing here like elapsed = new Date() - start, as in the
146143883Sphilip		    //original harness. This will make timing very non-deterministic.
147143883Sphilip		    //NOTHING else must live in this loop
148143883Sphilip		}
149143883Sphilip		ops += len;
150143883Sphilip		elapsed = new Date - start;
151143883Sphilip	    } while (elapsed < min_time * 1000);
152143883Sphilip
153143883Sphilip	    var score = ops / elapsed * 1000 * 60;
154143883Sphilip	    scores.push(score);
155143883Sphilip	    var name = it == 0 ? "warmup" : "iteration " + it;
156143883Sphilip	    print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
157143883Sphilip	}
158143883Sphilip
159143883Sphilip	for (var x = 0; x < benchmarks.length ; x++) {
160143883Sphilip	    benchmarks[x].TearDown();
161143883Sphilip	}
162143883Sphilip
163143883Sphilip	for (var x = 1; x < iters + 1 ; x++) {
164143883Sphilip	    mean_score += scores[x];
165143883Sphilip	    min_score = Math.min(min_score, scores[x]);
166143883Sphilip	    max_score = Math.max(max_score, scores[x]);
167143883Sphilip	}
168143883Sphilip	mean_score /= iters;
169152109Sphilip
170143883Sphilip    } catch (e) {
171143883Sphilip	print_always("*** Aborted and setting score to zero. Reason: " + e);
172143883Sphilip	if (e instanceof java.lang.Throwable) {
173143883Sphilip	    e.printStackTrace();
174143883Sphilip	}
175143883Sphilip	mean_score = min_score = max_score = 0;
176	scores = [0];
177    }
178
179    var res = mean_score.toFixed(0);
180    if (verbose) {
181	res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
182    }
183    print_always(arg, res);
184}
185
186function print_always(arg, x) {
187    print("[" + arg.name + "] " + x);
188}
189
190function print_verbose(arg, x) {
191    if (verbose) {
192	print_always(arg, x)
193    }
194}
195
196function run_suite(tests, iters) {
197    for (var idx = 0; idx < tests.length; idx++) {
198	run_one_benchmark(tests[idx], iters);
199    }
200}
201
202runtime = "command line";
203
204var args = [];
205
206if (typeof $ARGS !== 'undefined') {
207    args = $ARGS;
208} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
209    args = arguments;
210}
211
212var new_args = [];
213for (i in args) {
214    if (args[i].toString().indexOf(' ') != -1) {
215	args[i] = args[i].replace(/\/$/, '');
216	var s = args[i].split(' ');
217	for (j in s) {
218	    new_args.push(s[j]);
219	}
220    } else {
221	new_args.push(args[i]);
222    }
223}
224
225if (new_args.length != 0) {
226    args = new_args;
227}
228
229var tests_found = [];
230var iters = undefined;
231var min_time = 5;
232
233for (var i = 0; i < args.length; i++) {
234    arg = args[i];
235    if (arg == "--iterations") {
236	iters = +args[++i];
237	if (isNaN(iters)) {
238	    throw "'--iterations' must be followed by integer";
239	}
240    } else if (arg == "--runtime") {
241	runtime = args[++i];
242    } else if (arg == "--verbose") {
243	verbose = true;
244    } else if (arg == "--min-time") {
245	min_time = +args[++i];
246	if (isNaN(iters)) {
247	    throw "'--min-time' must be followed by integer";
248	}
249    } else if (arg == "") {
250	continue; //skip
251    } else {
252	var found = false;
253	for (j in tests) {
254	    if (tests[j].name === arg) {
255		tests_found.push(tests[j]);
256		found = true;
257		break;
258	    }
259	}
260	if (!found) {
261	    var str = "unknown test name: '" + arg + "' -- valid names are: ";
262	    for (j in tests) {
263		if (j != 0) {
264		    str += ", ";
265		}
266		str += "'" + tests[j].name + "'";
267	    }
268	    throw str;
269	}
270    }
271}
272
273if (tests_found.length == 0) {
274    for (i in tests) {
275	tests_found.push(tests[i]);
276    }
277}
278
279tests_found.sort();
280
281load(path + 'base.js');
282run_suite(tests_found, iters);
283
284
285
286