Mon, 07 Dec 2015 13:15:47 -0800
Merge
1 /*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
24 /**
25 * @subtest
26 */
27 var dir = typeof(__DIR__) == 'undefined' ? "test/script/basic/" : __DIR__;
28 load(dir + "octane-payload.js");
30 var runtime = undefined;
31 var verbose = false;
33 var numberOfIterations = 5;
35 function endsWith(str, suffix) {
36 return str.indexOf(suffix, str.length - suffix.length) !== -1;
37 }
39 function should_compile_only(name) {
40 return (typeof compile_only !== 'undefined')
41 }
43 function load_bench(arg) {
45 for (var idx = 0; idx < arg.files.length; idx++) {
46 var f = arg.files[idx];
47 var file = f.split('/');
48 var file_name = path + file[file.length - 1];
50 var compile_and_return = should_compile_only(file_name);
51 if (compile_and_return) {
52 if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
53 return true;
54 }
55 }
57 print_verbose(arg, "loading '" + arg.name + "' [" + f + "]... " + file_name);
58 load(file_name);
59 }
61 if (typeof arg.before !== 'undefined') {
62 arg.before();
63 }
65 if (compile_and_return) {
66 print_always(arg, "Compiled OK");
67 }
68 return !compile_and_return;
70 }
73 function run_one_benchmark(arg, iters) {
75 if (!load_bench(arg)) {
76 return;
77 }
79 var success = true;
80 var current_name;
82 if (iters == undefined) {
83 iters = numberOfIterations;
84 } else {
85 numberOfIterations = iters;
86 }
88 var benchmarks = eval(arg.suite + ".benchmarks");
89 var min_score = 1e9;
90 var max_score = 0;
91 var mean_score = 0;
93 try {
94 for (var x = 0; x < benchmarks.length ; x++) {
95 //do warmup run
96 //reset random number generator needed as of octane 9 before each run
97 BenchmarkSuite.ResetRNG();
98 benchmarks[x].Setup();
99 }
100 BenchmarkSuite.ResetRNG();
101 print_verbose(arg, "running '" + arg.name + "' for " + iters + " iterations of no less than " + min_time + " seconds");
103 var scores = [];
105 var min_time_ms = min_time * 1000;
106 var len = benchmarks.length;
108 for (var it = 0; it < iters + 1; it++) {
109 //every iteration must take a minimum of 10 secs
110 var ops = 0;
111 var elapsed = 0;
112 var start = new Date;
113 do {
114 for (var i = 0; i < len; i++) {
115 benchmarks[i].run();
116 //important - no timing here like elapsed = new Date() - start, as in the
117 //original harness. This will make timing very non-deterministic.
118 //NOTHING else must live in this loop
119 }
120 ops += len;
121 elapsed = new Date - start;
122 } while (elapsed < min_time * 1000);
124 var score = ops / elapsed * 1000 * 60;
125 scores.push(score);
126 var name = it == 0 ? "warmup" : "iteration " + it;
127 print_verbose(arg, name + " finished " + score.toFixed(0) + " ops/minute");
129 // optional per-iteration cleanup hook
130 if (typeof arg.cleanUpIteration == "function") {
131 arg.cleanUpIteration();
132 }
133 }
135 for (var x = 0; x < benchmarks.length ; x++) {
136 benchmarks[x].TearDown();
137 }
139 for (var x = 1; x < iters + 1 ; x++) {
140 mean_score += scores[x];
141 min_score = Math.min(min_score, scores[x]);
142 max_score = Math.max(max_score, scores[x]);
143 }
144 mean_score /= iters;
145 } catch (e) {
146 print_always(arg, "*** Aborted and setting score to zero. Reason: " + e);
147 if (is_this_nashorn() && e instanceof java.lang.Throwable) {
148 e.printStackTrace();
149 }
150 mean_score = min_score = max_score = 0;
151 scores = [0];
152 }
154 var res = mean_score.toFixed(0);
155 if (verbose) {
156 res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
157 }
158 print_always(arg, res);
159 }
161 function runtime_string() {
162 return runtime == undefined ? "" : ("[" + runtime + "] ");
163 }
165 function print_always(arg, x) {
166 print(runtime_string() + "[" + arg.name + "] " + x);
167 }
169 function print_verbose(arg, x) {
170 if (verbose) {
171 print_always(arg, x)
172 }
173 }
175 function run_suite(tests, iters) {
176 for (var idx = 0; idx < tests.length; idx++) {
177 run_one_benchmark(tests[idx], iters);
178 }
179 }
181 var args = [];
183 if (typeof $ARGS !== 'undefined') {
184 args = $ARGS;
185 } else if (typeof arguments !== 'undefined' && arguments.length != 0) {
186 args = arguments;
187 }
189 var new_args = [];
190 for (i in args) {
191 if (args[i].toString().indexOf(' ') != -1) {
192 args[i] = args[i].replace(/\/$/, '');
193 var s = args[i].split(' ');
194 for (j in s) {
195 new_args.push(s[j]);
196 }
197 } else {
198 new_args.push(args[i]);
199 }
200 }
202 if (new_args.length != 0) {
203 args = new_args;
204 }
206 var tests_found = [];
207 var iters = undefined;
208 var min_time = 5;
210 for (var i = 0; i < args.length; i++) {
211 arg = args[i];
212 if (arg == "--iterations") {
213 iters = +args[++i];
214 if (isNaN(iters)) {
215 throw "'--iterations' must be followed by integer";
216 }
217 } else if (arg == "--runtime") {
218 runtime = args[++i];
219 } else if (arg == "--verbose") {
220 verbose = true;
221 } else if (arg == "--min-time") {
222 min_time = +args[++i];
223 if (isNaN(iters)) {
224 throw "'--min-time' must be followed by integer";
225 }
226 } else if (arg == "") {
227 continue; //skip
228 } else {
229 var found = false;
230 for (j in tests) {
231 if (tests[j].name === arg) {
232 tests_found.push(tests[j]);
233 found = true;
234 break;
235 }
236 }
237 if (!found) {
238 var str = "unknown test name: '" + arg + "' -- valid names are: ";
239 for (j in tests) {
240 if (j != 0) {
241 str += ", ";
242 }
243 str += "'" + tests[j].name + "'";
244 }
245 throw str;
246 }
247 }
248 }
250 if (tests_found.length == 0) {
251 for (i in tests) {
252 tests_found.push(tests[i]);
253 }
254 }
256 // returns false for rhino, v8 and all other javascript runtimes, true for Nashorn
257 function is_this_nashorn() {
258 return typeof Error.dumpStack == 'function'
259 }
261 if (is_this_nashorn()) {
262 try {
263 read = readFully;
264 } catch (e) {
265 print("ABORTING: Cannot find 'readFully'. You must have scripting enabled to use this test harness. (-scripting)");
266 throw e;
267 }
268 }
270 // run tests in alphabetical order by name
271 tests_found.sort(function(a, b) {
272 if (a.name < b.name) {
273 return -1;
274 } else if (a.name > b.name) {
275 return 1;
276 } else {
277 return 0;
278 }
279 });
281 load(path + 'base.js');
282 run_suite(tests_found, iters);