jlaskey@3: /* jlaskey@7: * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. jlaskey@3: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jlaskey@3: * jlaskey@3: * This code is free software; you can redistribute it and/or modify it jlaskey@3: * under the terms of the GNU General Public License version 2 only, as jlaskey@3: * published by the Free Software Foundation. jlaskey@3: * jlaskey@3: * This code is distributed in the hope that it will be useful, but WITHOUT jlaskey@3: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jlaskey@3: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jlaskey@3: * version 2 for more details (a copy is included in the LICENSE file that jlaskey@3: * accompanied this code). jlaskey@3: * jlaskey@3: * You should have received a copy of the GNU General Public License version jlaskey@3: * 2 along with this work; if not, write to the Free Software Foundation, jlaskey@3: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jlaskey@3: * jlaskey@3: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jlaskey@3: * or visit www.oracle.com if you need additional information or have any jlaskey@3: * questions. jlaskey@3: */ jlaskey@3: jlaskey@3: /** jlaskey@3: * @subtest jlaskey@3: */ jlaskey@3: jlaskey@3: var tests = [ lagergren@693: {name:"box2d", files:["box2d.js"], suite:"Box2DBenchmark"}, lagergren@693: {name:"code-load", files:["code-load.js"], suite:"CodeLoad"}, lagergren@693: {name:"crypto", files:["crypto.js"], suite:"Crypto"}, lagergren@693: {name:"deltablue", files:["deltablue.js"], suite:"DeltaBlue"}, lagergren@693: {name:"earley-boyer", files:["earley-boyer.js"], suite:"EarleyBoyer"}, lagergren@693: {name:"gbemu", files:["gbemu-part1.js", "gbemu-part2.js"], suite:"GameboyBenchmark"}, lagergren@693: {name:"mandreel", files:["mandreel.js"], suite:"MandreelBenchmark"}, lagergren@693: {name:"navier-stokes", files:["navier-stokes.js"], suite:"NavierStokes"}, lagergren@693: {name:"pdfjs", files:["pdfjs.js"], suite:"PdfJS"}, lagergren@693: {name:"raytrace", files:["raytrace.js"], suite:"RayTrace"}, lagergren@693: {name:"regexp", files:["regexp.js"], suite:"RegExpSuite"}, lagergren@693: {name:"richards", files:["richards.js"], suite:"Richards"}, lagergren@693: {name:"splay", files:["splay.js"], suite:"Splay"}, lagergren@693: {name:"typescript", files:["typescript.js", "typescript-input.js", "typescript-compiler.js"], suite:"typescript"} lagergren@693: //zlib currently disabled - requires read lagergren@693: // {name:"zlib", files:["zlib.js", "zlib-data.js"], suite:"zlib"}, jlaskey@3: ]; jlaskey@3: var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__; jlaskey@3: jlaskey@3: // TODO: why is this path hard coded when it's defined in project properties? sundar@19: var path = dir + "../external/octane/"; jlaskey@3: jlaskey@3: var runtime = ""; jlaskey@3: var verbose = false; jlaskey@3: jlaskey@3: var numberOfIterations = 5; jlaskey@3: jlaskey@3: function endsWith(str, suffix) { jlaskey@3: return str.indexOf(suffix, str.length - suffix.length) !== -1; jlaskey@3: } jlaskey@3: lagergren@139: function should_compile_only(name) { lagergren@295: return (typeof compile_only !== 'undefined') lagergren@139: } lagergren@139: lagergren@693: function load_bench(arg) { lagergren@693: lagergren@693: for (var idx = 0; idx < arg.files.length; idx++) { lagergren@693: var f = arg.files[idx]; lagergren@693: var file = f.split('/'); lagergren@693: var file_name = path + file[file.length - 1]; lagergren@693: lagergren@693: var compile_and_return = should_compile_only(file_name); lagergren@693: if (compile_and_return) { lagergren@693: if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them lagergren@693: return true; lagergren@693: } lagergren@693: } lagergren@693: lagergren@693: print_verbose(arg, "loading '" + arg.name + "' [" + f + "]..."); lagergren@693: load(file_name); lagergren@693: } lagergren@693: lagergren@693: if (compile_and_return) { lagergren@693: print_always(arg, "Compiled OK"); lagergren@693: } lagergren@693: return !compile_and_return; lagergren@693: lagergren@693: } lagergren@693: jlaskey@3: function run_one_benchmark(arg, iters) { lagergren@693: lagergren@693: if (!load_bench(arg)) { jlaskey@3: return; lagergren@693: } jlaskey@3: jlaskey@3: var success = true; jlaskey@3: var current_name; jlaskey@3: jlaskey@3: if (iters == undefined) { jlaskey@3: iters = numberOfIterations; jlaskey@3: } else { jlaskey@3: numberOfIterations = iters; jlaskey@3: } lagergren@295: lagergren@295: var benchmarks = eval(arg.suite + ".benchmarks"); lagergren@295: var min_score = 1e9; lagergren@295: var max_score = 0; lagergren@295: var mean_score = 0; lagergren@298: lagergren@298: try { lagergren@298: for (var x = 0; x < benchmarks.length ; x++) { lagergren@693: //do warmup run lagergren@693: //reset random number generator needed as of octane 9 before each run lagergren@693: BenchmarkSuite.ResetRNG(); lagergren@298: benchmarks[x].Setup(); lagergren@298: } lagergren@693: BenchmarkSuite.ResetRNG(); lagergren@693: print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")"); lagergren@298: lagergren@298: var scores = []; lagergren@298: lagergren@298: var min_time_ms = min_time * 1000; lagergren@298: var len = benchmarks.length; lagergren@298: lagergren@298: for (var it = 0; it < iters + 1; it++) { lagergren@298: //every iteration must take a minimum of 10 secs lagergren@298: var ops = 0; lagergren@298: var elapsed = 0; lagergren@298: var start = new Date; lagergren@298: do { lagergren@298: for (var i = 0; i < len; i++) { lagergren@298: benchmarks[i].run(); lagergren@693: //important - no timing here like elapsed = new Date() - start, as in the lagergren@693: //original harness. This will make timing very non-deterministic. lagergren@693: //NOTHING else must live in this loop lagergren@298: } lagergren@298: ops += len; lagergren@298: elapsed = new Date - start; lagergren@298: } while (elapsed < min_time * 1000); lagergren@298: lagergren@298: var score = ops / elapsed * 1000 * 60; lagergren@298: scores.push(score); lagergren@298: var name = it == 0 ? "warmup" : "iteration " + it; lagergren@693: print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute"); lagergren@298: } lagergren@298: lagergren@298: for (var x = 0; x < benchmarks.length ; x++) { lagergren@298: benchmarks[x].TearDown(); lagergren@298: } lagergren@298: lagergren@298: for (var x = 1; x < iters + 1 ; x++) { lagergren@298: mean_score += scores[x]; lagergren@298: min_score = Math.min(min_score, scores[x]); lagergren@298: max_score = Math.max(max_score, scores[x]); lagergren@298: } lagergren@298: mean_score /= iters; lagergren@298: lagergren@298: } catch (e) { lagergren@298: print_always("*** Aborted and setting score to zero. Reason: " + e); lagergren@298: mean_score = min_score = max_score = 0; lagergren@298: scores = [0]; lagergren@295: } lagergren@298: lagergren@693: var res = mean_score.toFixed(0); lagergren@295: if (verbose) { lagergren@295: res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0); lagergren@295: } lagergren@693: print_always(arg, res); lagergren@295: } jlaskey@3: lagergren@693: function print_always(arg, x) { lagergren@693: print("[" + arg.name + "] " + x); lagergren@295: } jlaskey@3: lagergren@693: function print_verbose(arg, x) { lagergren@295: if (verbose) { lagergren@693: print_always(arg, x) jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: function run_suite(tests, iters) { jlaskey@3: for (var idx = 0; idx < tests.length; idx++) { lagergren@139: run_one_benchmark(tests[idx], iters); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: runtime = "command line"; jlaskey@3: jlaskey@3: var args = []; lagergren@298: jlaskey@3: if (typeof $ARGS !== 'undefined') { jlaskey@3: args = $ARGS; jlaskey@3: } else if (typeof arguments !== 'undefined' && arguments.length != 0) { jlaskey@3: args = arguments; jlaskey@3: } jlaskey@3: jlaskey@3: var new_args = []; jlaskey@3: for (i in args) { jlaskey@3: if (args[i].toString().indexOf(' ') != -1) { jlaskey@3: args[i] = args[i].replace(/\/$/, ''); jlaskey@3: var s = args[i].split(' '); jlaskey@3: for (j in s) { jlaskey@3: new_args.push(s[j]); jlaskey@3: } jlaskey@3: } else { jlaskey@3: new_args.push(args[i]); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: if (new_args.length != 0) { jlaskey@3: args = new_args; jlaskey@3: } jlaskey@3: jlaskey@3: var tests_found = []; jlaskey@3: var iters = undefined; lagergren@295: var min_time = 5; jlaskey@3: jlaskey@3: for (var i = 0; i < args.length; i++) { jlaskey@3: arg = args[i]; jlaskey@3: if (arg == "--iterations") { jlaskey@3: iters = +args[++i]; jlaskey@3: } else if (arg == "--runtime") { jlaskey@3: runtime = args[++i]; jlaskey@3: } else if (arg == "--verbose") { jlaskey@3: verbose = true; lagergren@295: } else if (arg == "--min-time") { lagergren@295: min_time = +args[++i]; jlaskey@3: } else if (arg == "") { jlaskey@3: continue; //skip jlaskey@3: } else { lagergren@295: var found = false; lagergren@295: for (j in tests) { lagergren@693: if (tests[j].name === arg) { lagergren@295: tests_found.push(tests[j]); lagergren@295: found = true; lagergren@295: break; lagergren@295: } lagergren@295: } lagergren@295: if (!found) { lagergren@295: var str = "unknown test name: '" + arg + "' -- valid names are: "; lagergren@295: for (j in tests) { lagergren@295: if (j != 0) { lagergren@295: str += ", "; lagergren@295: } lagergren@693: str += "'" + tests[j].name + "'"; lagergren@295: } lagergren@295: throw str; lagergren@295: } jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: if (tests_found.length == 0) { jlaskey@3: for (i in tests) { lagergren@295: tests_found.push(tests[i]); jlaskey@3: } jlaskey@3: } jlaskey@3: jlaskey@3: tests_found.sort(); jlaskey@3: lagergren@295: load(path + 'base.js'); jlaskey@3: run_suite(tests_found, iters); jlaskey@3: jlaskey@3: jlaskey@3: