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.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package jdk.nashorn.internal.performance;
27
28import java.io.OutputStream;
29import java.util.concurrent.Callable;
30import java.util.concurrent.ExecutionException;
31import java.util.concurrent.Future;
32import java.util.concurrent.TimeUnit;
33import java.util.concurrent.TimeoutException;
34import jdk.nashorn.internal.objects.Global;
35import jdk.nashorn.internal.runtime.Context;
36import jdk.nashorn.internal.runtime.ScriptFunction;
37import jdk.nashorn.internal.runtime.ScriptRuntime;
38
39@SuppressWarnings("javadoc")
40public class PerformanceWrapper extends jdk.nashorn.tools.Shell {
41
42    int _numberOfIterations;
43    int _runsPerIteration;
44
45    protected void runCompileOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL) throws Throwable {
46        final String[] args = { name, "--compile-only=true", "-dump-on-error", "--", testURL };
47
48        final long[] times = new long[numberOfIterations + 1];
49        times[0] = System.nanoTime(); // Calendar.getInstance().getTimeInMillis();
50
51        for (int iteration = 1; iteration <= numberOfIterations; iteration++) {
52            for (int i = 0; i < runsPerIteration; i++) {
53                run(System.in, System.out, System.err, args);
54            }
55            times[iteration] = System.nanoTime();
56        }
57
58        for (int i = 0; i < numberOfIterations; i++) {
59            System.out.println("Iteration " + (i + 1) + " average time: " + ((times[i + 1] - times[i]) / (float)runsPerIteration) / 1000000.0 + " ms.");
60        }
61    }
62
63    protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL) throws Throwable {
64        runExecuteOnlyTest(name, numberOfIterations, runsPerIteration, testURL, System.out, System.err, new String[0]);
65    }
66
67    protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL, final OutputStream out, final OutputStream err) throws Throwable {
68        runExecuteOnlyTest(name, numberOfIterations, runsPerIteration, testURL, out, err, new String[0]);
69    }
70
71
72    protected void runExecuteOnlyTest(final String name, final int numberOfIterations, final int runsPerIteration, final String testURL, final OutputStream out, final OutputStream err, final String[] newargs) throws Throwable {
73        final String[] args=new String[newargs.length+1];
74        System.arraycopy(newargs, 0, args, 1, newargs.length);
75        args[0]=name;
76
77//      for (String s: args)
78//          System.out.println(s);
79
80        _numberOfIterations = numberOfIterations;
81        _runsPerIteration = runsPerIteration;
82        run(System.in, out, err, args);
83//      System.out.println("overridableRun finished");
84    }
85
86    @Override
87    protected Object apply(final ScriptFunction target, final Object self) {
88        if (_runsPerIteration == 0 && _numberOfIterations == 0) {
89            final Global global = jdk.nashorn.internal.runtime.Context.getGlobal();
90            final ScriptFunction _target = target;
91            final Object _self = self;
92
93            class MyThread implements Callable<Object> {
94                @Override
95                public Object call() {
96                    Context.setGlobal(global);
97                    //just execute and return script is sufficient
98                    final Object scriptRuntimeApplyResult = ScriptRuntime.apply(_target, _self);
99                    return scriptRuntimeApplyResult;
100                }
101            }
102
103            final java.util.concurrent.ThreadPoolExecutor executor = new java.util.concurrent.ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new java.util.concurrent.ArrayBlockingQueue<Runnable>(10));
104            final MyThread myThread = new MyThread();
105            // executor.execute(myThread);
106            Object result;
107            Future<?> futureResult = null;
108
109            try {
110                futureResult = executor.submit(myThread);
111                final String timeout = System.getProperty("timeout.value");
112                int tmout = 0;
113                if (timeout != null) {
114                    try {
115                        tmout = Integer.parseInt(timeout);
116                    } catch (final Exception e) {
117                        e.printStackTrace();
118                    }
119                }
120                if (tmout != 0) {
121                    result = futureResult.get(10, TimeUnit.MINUTES);
122                } else {
123                    result = futureResult.get();
124                }
125            } catch (final InterruptedException | ExecutionException e) {
126                e.printStackTrace();
127                return null;
128            } catch (final TimeoutException e) {
129                System.out.println("timeout while script execution");
130                futureResult.cancel(true);
131                return null;
132            }
133
134            return result;
135        }
136
137        final long[] times = new long[_numberOfIterations + 1];
138        times[0] = System.nanoTime();
139        for (int iteration = 1; iteration <= _numberOfIterations; iteration++) {
140            for (int i = 0; i < _runsPerIteration; i++) {
141                // empty
142            }
143            times[iteration] = System.nanoTime();
144        }
145
146        for (int i = 0; i < _numberOfIterations; i++) {
147            System.out.println("Iteration " + (i + 1) + " average time: " + ((times[i + 1] - times[i]) / (float)_runsPerIteration) / 1000000.0 + " ms.");
148        }
149
150        return ScriptRuntime.apply(target, self);
151    }
152}
153