Enable HAVE_AVFOUNDATION_VIDEO_OUTPUT on PLATFORM(IOSMAC)
[WebKit-https.git] / PerformanceTests / ARES-6 / driver.js
1 /*
2  * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 "use strict";
26
27 class Driver {
28     constructor(statusCell, triggerCell, triggerLink, magicCell, summaryCell, key)
29     {
30         this._benchmarks = new Map();
31         this._statusCell = statusCell;
32         this._triggerCell = triggerCell;
33         this._triggerLink = triggerLink;
34         this._magicCell = magicCell;
35         this._summary = new Stats(summaryCell, "summary");
36         this._key = key;
37         if (isInBrowser)
38             window[key] = this;
39     }
40     
41     addBenchmark(benchmark)
42     {
43         this._benchmarks.set(benchmark, new Results(benchmark));
44     }
45     
46     readyTrigger() 
47     {
48         if (isInBrowser) {
49             this._triggerCell.addEventListener('click', this._triggerLink);
50             this._triggerCell.classList.add('ready');
51         }
52     }
53     
54     disableTrigger() 
55     {
56         if (isInBrowser) {
57             this._triggerCell.removeEventListener('click', this._triggerLink);
58             this._triggerCell.classList.remove('ready');
59         }
60     }
61     
62     start(numIterations)
63     {
64         this.disableTrigger();
65         this._updateIterations();
66
67         this._summary.reset();
68         for (let [benchmark, results] of this._benchmarks)
69             results.reset();
70         this._isRunning = true;
71         this._startIterations = this._numIterations = numIterations;
72         this._iterator = null;
73         this._iterate();
74     }
75     
76     reportResult(...args)
77     {
78         this._benchmarks.get(this._benchmark).reportResult(...args);
79         this._recomputeSummary();
80         this._iterate();
81     }
82     
83     reportError(...args)
84     {
85         if (isInBrowser)
86             console.log("Error encountered: ", ...args);
87
88         this._benchmarks.get(this._benchmark).reportError(...args);
89
90         if (isInBrowser) {
91             this._statusCell.innerHTML = "Test failure \u2014 error in console";
92             this._statusCell.classList.add("failed");
93         } else
94             print("Test failure");
95     }
96     
97     _recomputeSummary()
98     {
99         class Geomean {
100             constructor()
101             {
102                 this._count = 0;
103                 this._sum = 0;
104             }
105             
106             add(value)
107             {
108                 this._count++;
109                 this._sum += Math.log(value);
110             }
111             
112             get result()
113             {
114                 return Math.exp(this._sum * (1 / this._count));
115             }
116         }
117         
118         let statses = [];
119         for (let results of this._benchmarks.values()) {
120             for (let subResult of Results.subResults)
121                 statses.push(results[subResult]);
122         }
123
124         let numIterations = Math.min(...statses.map(stats => stats.numIterations));
125         let data = new Array(numIterations);
126         for (let i = 0; i < data.length; ++i)
127             data[i] = new Geomean();
128         
129         for (let stats of statses) {
130             for (let i = 0; i < data.length; ++i)
131                 data[i].add(stats.valueForIteration(i));
132         }
133         
134         let geomeans = data.map(geomean => geomean.result);
135         
136         this._summary.reset(...geomeans);
137     }
138     
139     _iterate()
140     {
141         this._benchmark = this._iterator ? this._iterator.next().value : null;
142         if (!this._benchmark) {
143             if (!this._numIterations) {
144                 if (isInBrowser) {
145                     this._statusCell.innerHTML = "Restart";
146                     this.readyTrigger();
147                 } else
148                     print("Success! Benchmark is now finished.");
149                 return;
150             }
151             this._numIterations--;
152             this._updateIterations();
153             this._iterator = this._benchmarks.keys();
154             this._benchmark = this._iterator.next().value;
155         }
156         
157         this._benchmarks.get(this._benchmark).reportRunning();
158         
159         let benchmark = this._benchmark;
160         if (isInBrowser) {
161             window.setTimeout(() => {
162                 if (!this._isRunning)
163                     return;
164                 
165                 this._magicCell.contentDocument.body.textContent = "";
166                 this._magicCell.contentDocument.body.innerHTML = "<iframe id=\"magicFrame\" frameborder=\"0\">";
167                 
168                 let magicFrame = this._magicCell.contentDocument.getElementById("magicFrame");
169                 magicFrame.contentDocument.open();
170                 magicFrame.contentDocument.write(
171                     `<!DOCTYPE html><head><title>benchmark payload</title></head><body><script>` +
172                     `window.onerror = top.${this._key}.reportError.bind(top.${this._key});\n` +
173                     `function reportResult()\n` +
174                     `{\n` +
175                     `    var driver = top.${this._key};\n` +
176                     `    driver.reportResult.apply(driver, arguments);\n` +
177                     `}\n` +
178                     `</script>\n` +
179                     `${this._benchmark.code}</body></html>`);
180             }, 100);
181         } else {
182             Promise.resolve(20).then(() => {
183                 if (!this._isRunning)
184                     return;
185                 
186                 try {
187                     print(`Running... ${this._benchmark.name} ( ${this._numIterations + 1}  to go)`);
188                     benchmark.run();
189                     print("\n");
190                 } catch(e) {
191                     print(e);
192                     print(e.stack);
193                 }
194             });
195         }
196     }
197     
198     _updateIterations()
199     {
200         if (isInBrowser) {
201             this._statusCell.innerHTML = "Running Tests... " + ( this._startIterations - this._numIterations ) + "/" + this._startIterations;
202         }
203         
204     }
205 }