aoqi@0: /* aoqi@0: * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. attila@962: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. attila@962: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). attila@962: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. attila@962: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: /** aoqi@0: * @subtest aoqi@0: */ hannesw@1034: var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__; hannesw@1034: load(dir + "octane-payload.js"); aoqi@0: attila@963: var runtime = undefined; aoqi@0: var verbose = false; aoqi@0: aoqi@0: var numberOfIterations = 5; aoqi@0: aoqi@0: function endsWith(str, suffix) { aoqi@0: return str.indexOf(suffix, str.length - suffix.length) !== -1; aoqi@0: } aoqi@0: aoqi@0: function should_compile_only(name) { aoqi@0: return (typeof compile_only !== 'undefined') aoqi@0: } aoqi@0: aoqi@0: function load_bench(arg) { aoqi@0: aoqi@0: for (var idx = 0; idx < arg.files.length; idx++) { hannesw@1034: var f = arg.files[idx]; hannesw@1034: var file = f.split('/'); hannesw@1034: var file_name = path + file[file.length - 1]; attila@962: hannesw@1034: var compile_and_return = should_compile_only(file_name); hannesw@1034: if (compile_and_return) { hannesw@1034: if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them hannesw@1034: return true; hannesw@1034: } attila@962: } attila@962: hannesw@1034: print_verbose(arg, "loading '" + arg.name + "' [" + f + "]... " + file_name); hannesw@1034: load(file_name); lagergren@693: } lagergren@693: attila@963: if (typeof arg.before !== 'undefined') { hannesw@1034: arg.before(); aoqi@0: } aoqi@0: aoqi@0: if (compile_and_return) { hannesw@1034: print_always(arg, "Compiled OK"); aoqi@0: } aoqi@0: return !compile_and_return; aoqi@0: aoqi@0: } aoqi@0: attila@963: aoqi@0: function run_one_benchmark(arg, iters) { aoqi@0: aoqi@0: if (!load_bench(arg)) { hannesw@1034: return; attila@962: } attila@962: aoqi@0: var success = true; aoqi@0: var current_name; attila@962: aoqi@0: if (iters == undefined) { hannesw@1034: iters = numberOfIterations; aoqi@0: } else { hannesw@1034: numberOfIterations = iters; aoqi@0: } attila@962: aoqi@0: var benchmarks = eval(arg.suite + ".benchmarks"); aoqi@0: var min_score = 1e9; aoqi@0: var max_score = 0; aoqi@0: var mean_score = 0; aoqi@0: aoqi@0: try { hannesw@1034: for (var x = 0; x < benchmarks.length ; x++) { hannesw@1034: //do warmup run hannesw@1034: //reset random number generator needed as of octane 9 before each run hannesw@1034: BenchmarkSuite.ResetRNG(); hannesw@1034: benchmarks[x].Setup(); hannesw@1034: } attila@962: BenchmarkSuite.ResetRNG(); hannesw@1034: print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds"); aoqi@0: hannesw@1034: var scores = []; aoqi@0: hannesw@1034: var min_time_ms = min_time * 1000; hannesw@1034: var len = benchmarks.length; aoqi@0: hannesw@1034: for (var it = 0; it < iters + 1; it++) { hannesw@1034: //every iteration must take a minimum of 10 secs hannesw@1034: var ops = 0; hannesw@1034: var elapsed = 0; hannesw@1034: var start = new Date; hannesw@1034: do { hannesw@1034: for (var i = 0; i < len; i++) { hannesw@1034: benchmarks[i].run(); hannesw@1034: //important - no timing here like elapsed = new Date() - start, as in the hannesw@1034: //original harness. This will make timing very non-deterministic. hannesw@1034: //NOTHING else must live in this loop hannesw@1034: } hannesw@1034: ops += len; hannesw@1034: elapsed = new Date - start; hannesw@1034: } while (elapsed < min_time * 1000); hannesw@1034: hannesw@1034: var score = ops / elapsed * 1000 * 60; hannesw@1034: scores.push(score); hannesw@1034: var name = it == 0 ? "warmup" : "iteration " + it; hannesw@1034: print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute"); hannesw@1034: hannesw@1034: // optional per-iteration cleanup hook hannesw@1034: if (typeof arg.cleanUpIteration == "function") { hannesw@1034: arg.cleanUpIteration(); hannesw@1034: } attila@962: } attila@962: hannesw@1034: for (var x = 0; x < benchmarks.length ; x++) { hannesw@1034: benchmarks[x].TearDown(); hannesw@1034: } attila@962: hannesw@1034: for (var x = 1; x < iters + 1 ; x++) { hannesw@1034: mean_score += scores[x]; hannesw@1034: min_score = Math.min(min_score, scores[x]); hannesw@1034: max_score = Math.max(max_score, scores[x]); hannesw@1034: } hannesw@1034: mean_score /= iters; aoqi@0: } catch (e) { hannesw@1034: print_always(arg, "*** Aborted and setting score to zero. Reason: " + e); hannesw@1034: if (is_this_nashorn() && e instanceof java.lang.Throwable) { hannesw@1034: e.printStackTrace(); hannesw@1034: } hannesw@1034: mean_score = min_score = max_score = 0; hannesw@1034: scores = [0]; aoqi@0: } aoqi@0: aoqi@0: var res = mean_score.toFixed(0); aoqi@0: if (verbose) { hannesw@1034: res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0); aoqi@0: } aoqi@0: print_always(arg, res); aoqi@0: } aoqi@0: attila@963: function runtime_string() { attila@963: return runtime == undefined ? "" : ("[" + runtime + "] "); attila@963: } attila@963: aoqi@0: function print_always(arg, x) { attila@963: print(runtime_string() + "[" + arg.name + "] " + x); aoqi@0: } aoqi@0: aoqi@0: function print_verbose(arg, x) { aoqi@0: if (verbose) { hannesw@1034: print_always(arg, x) aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: function run_suite(tests, iters) { aoqi@0: for (var idx = 0; idx < tests.length; idx++) { hannesw@1034: run_one_benchmark(tests[idx], iters); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: var args = []; aoqi@0: aoqi@0: if (typeof $ARGS !== 'undefined') { aoqi@0: args = $ARGS; aoqi@0: } else if (typeof arguments !== 'undefined' && arguments.length != 0) { aoqi@0: args = arguments; attila@962: } aoqi@0: aoqi@0: var new_args = []; aoqi@0: for (i in args) { aoqi@0: if (args[i].toString().indexOf(' ') != -1) { hannesw@1034: args[i] = args[i].replace(/\/$/, ''); hannesw@1034: var s = args[i].split(' '); hannesw@1034: for (j in s) { hannesw@1034: new_args.push(s[j]); hannesw@1034: } aoqi@0: } else { hannesw@1034: new_args.push(args[i]); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: if (new_args.length != 0) { aoqi@0: args = new_args; aoqi@0: } aoqi@0: aoqi@0: var tests_found = []; aoqi@0: var iters = undefined; aoqi@0: var min_time = 5; aoqi@0: attila@962: for (var i = 0; i < args.length; i++) { aoqi@0: arg = args[i]; aoqi@0: if (arg == "--iterations") { hannesw@1034: iters = +args[++i]; hannesw@1034: if (isNaN(iters)) { hannesw@1034: throw "'--iterations' must be followed by integer"; hannesw@1034: } aoqi@0: } else if (arg == "--runtime") { hannesw@1034: runtime = args[++i]; aoqi@0: } else if (arg == "--verbose") { hannesw@1034: verbose = true; aoqi@0: } else if (arg == "--min-time") { hannesw@1034: min_time = +args[++i]; hannesw@1034: if (isNaN(iters)) { hannesw@1034: throw "'--min-time' must be followed by integer"; hannesw@1034: } aoqi@0: } else if (arg == "") { hannesw@1034: continue; //skip aoqi@0: } else { hannesw@1034: var found = false; hannesw@1034: for (j in tests) { hannesw@1034: if (tests[j].name === arg) { hannesw@1034: tests_found.push(tests[j]); hannesw@1034: found = true; hannesw@1034: break; hannesw@1034: } attila@962: } hannesw@1034: if (!found) { hannesw@1034: var str = "unknown test name: '" + arg + "' -- valid names are: "; hannesw@1034: for (j in tests) { hannesw@1034: if (j != 0) { hannesw@1034: str += ", "; hannesw@1034: } hannesw@1034: str += "'" + tests[j].name + "'"; hannesw@1034: } hannesw@1034: throw str; attila@962: } aoqi@0: } aoqi@0: } aoqi@0: attila@962: if (tests_found.length == 0) { aoqi@0: for (i in tests) { hannesw@1034: tests_found.push(tests[i]); aoqi@0: } attila@962: } aoqi@0: attila@963: // returns false for rhino, v8 and all other javascript runtimes, true for Nashorn attila@963: function is_this_nashorn() { attila@963: return typeof Error.dumpStack == 'function' attila@963: } attila@963: attila@963: if (is_this_nashorn()) { attila@963: try { hannesw@1034: read = readFully; attila@963: } catch (e) { hannesw@1034: print("ABORTING: Cannot find 'readFully'. You must have scripting enabled to use this test harness. (-scripting)"); hannesw@1034: throw e; attila@963: } attila@963: } attila@963: attila@963: // run tests in alphabetical order by name attila@963: tests_found.sort(function(a, b) { attila@963: if (a.name < b.name) { hannesw@1034: return -1; attila@963: } else if (a.name > b.name) { hannesw@1034: return 1; attila@963: } else { hannesw@1034: return 0; attila@963: } attila@963: }); aoqi@0: aoqi@0: load(path + 'base.js'); aoqi@0: run_suite(tests_found, iters);