• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28var worker_scripts = [
29  "../csvparser.js",
30  "../splaytree.js",
31  "../codemap.js",
32  "../consarray.js",
33  "../profile.js",
34  "../profile_view.js",
35  "../logreader.js",
36  "../arguments.js",
37  "../tickprocessor.js",
38  "composer.js",
39  "gnuplot-4.6.3-emscripten.js"
40];
41
42
43function plotWorker() {
44  var worker = null;
45
46  function initialize() {
47    ui.freeze();
48    worker = new Worker("worker.js");
49    running = false;
50
51    worker.postMessage({ "call" : "load scripts",
52                         "args" : worker_scripts });
53
54    worker.addEventListener("message", function(event) {
55      var call = delegateList[event.data["call"]];
56      call(event.data["args"]);
57    });
58  }
59
60  function scriptLoaded() {
61    ui.thaw();
62  }
63
64  // Public methods.
65  this.run = function(filename,
66                      resx, resy,
67                      distortion,
68                      range_start, range_end) {
69    var args = {
70      'file'        : filename,
71      'resx'        : resx,
72      'resy'        : resy,
73      'distortion'  : distortion,
74      'range_start' : range_start,
75      'range_end'   : range_end
76    }
77    worker.postMessage({ 'call' : 'run', 'args' : args });
78  }
79
80  this.reset = function() {
81    if (worker) worker.terminate();
82    initialize();
83  }
84
85  var delegateList = {
86    "log"         : log,
87    "error"       : logError,
88    "displayplot" : displayplot,
89    "displayprof" : displayprof,
90    "range"       : setRange,
91    "script"      : scriptLoaded,
92    "reset"       : this.reset
93  }
94}
95
96
97function UIWrapper() {
98  var input_elements = ["range_start",
99                        "range_end",
100                        "distortion",
101                        "start",
102                        "file"];
103
104  var other_elements = ["log",
105                        "plot",
106                        "prof",
107                        "instructions",
108                        "credits",
109                        "toggledisplay"];
110
111  for (var i in input_elements) {
112    var id = input_elements[i];
113    this[id] = document.getElementById(id);
114  }
115
116  for (var i in other_elements) {
117    var id = other_elements[i];
118    this[id] = document.getElementById(id);
119  }
120
121  this.freeze = function() {
122    this.plot.style.webkitFilter = "grayscale(1)";
123    this.prof.style.color = "#bbb";
124    for (var i in input_elements) {
125      this[input_elements[i]].disabled = true;
126    }
127  }
128
129  this.thaw = function() {
130    this.plot.style.webkitFilter = "";
131    this.prof.style.color = "#000";
132    for (var i in input_elements) {
133      this[input_elements[i]].disabled = false;
134    }
135  }
136
137  this.reset = function() {
138    this.thaw();
139    this.log.value = "";
140    this.range_start.value = "automatic";
141    this.range_end.value = "automatic";
142    this.toggle("plot");
143    this.plot.src = "";
144    this.prof.value = "";
145  }
146
147  this.toggle = function(mode) {
148    if (mode) this.toggledisplay.next_mode = mode;
149    if (this.toggledisplay.next_mode == "plot") {
150      this.toggledisplay.next_mode = "prof";
151      this.plot.style.display = "block";
152      this.prof.style.display = "none";
153      this.toggledisplay.innerHTML = "Show profile";
154    } else {
155      this.toggledisplay.next_mode = "plot";
156      this.plot.style.display = "none";
157      this.prof.style.display = "block";
158      this.toggledisplay.innerHTML = "Show plot";
159    }
160  }
161
162  this.info = function(field) {
163    var down_arrow = "\u25bc";
164    var right_arrow = "\u25b6";
165    if (field && this[field].style.display != "none") field = null;  // Toggle.
166    this.credits.style.display = "none";
167    this.instructions.style.display = "none";
168    if (!field) return;
169    this[field].style.display = "block";
170  }
171}
172
173
174function log(text) {
175  ui.log.value += text;
176  ui.log.scrollTop = ui.log.scrollHeight;
177}
178
179
180function logError(text) {
181  if (ui.log.value.length > 0 &&
182      ui.log.value[ui.log.value.length-1] != "\n") {
183    ui.log.value += "\n";
184  }
185  ui.log.value += "ERROR: " + text + "\n";
186  ui.log.scrollTop = ui.log.scrollHeight;
187  error_logged = true;
188}
189
190
191function displayplot(args) {
192  if (error_logged) {
193    log("Plot failed.\n\n");
194  } else {
195    log("Displaying plot. Total time: " +
196        (Date.now() - timer) / 1000 + "ms.\n\n");
197    var blob = new Blob([new Uint8Array(args.contents).buffer],
198                        { "type" : "image\/svg+xml" });
199    window.URL = window.URL || window.webkitURL;
200    ui.plot.src = window.URL.createObjectURL(blob);
201  }
202
203  ui.thaw();
204  ui.toggle("plot");
205}
206
207
208function displayprof(args) {
209  if (error_logged) return;
210  ui.prof.value = args;
211  this.prof.style.color = "";
212  ui.toggle("prof");
213}
214
215
216function start(event) {
217  error_logged = false;
218  ui.freeze();
219
220  try {
221    var file = getSelectedFile();
222    var distortion = getDistortion();
223    var range = getRange();
224  } catch (e) {
225    logError(e.message);
226    display();
227    return;
228  }
229
230  timer = Date.now();
231  worker.run(file, kResX, kResY, distortion, range[0], range[1]);
232}
233
234
235function getSelectedFile() {
236  var file = ui.file.files[0];
237  if (!file) throw Error("No valid file selected.");
238  return file;
239}
240
241
242function getDistortion() {
243  var input_distortion =
244      parseInt(ui.distortion.value, 10);
245  if (isNaN(input_distortion)) {
246    input_distortion = ui.distortion.value = 4500;
247  }
248  return input_distortion / 1000000;
249}
250
251
252function getRange() {
253  var input_start =
254      parseInt(ui.range_start.value, 10);
255  if (isNaN(input_start)) input_start = undefined;
256  var input_end =
257      parseInt(ui.range_end.value, 10);
258  if (isNaN(input_end)) input_end = undefined;
259  return [input_start, input_end];
260}
261
262
263function setRange(args) {
264  ui.range_start.value = args.start.toFixed(1);
265  ui.range_end.value = args.end.toFixed(1);
266}
267
268
269function onload() {
270  kResX = 1200;
271  kResY = 600;
272  error_logged = false;
273  ui = new UIWrapper();
274  ui.reset();
275  ui.info(null);
276  worker = new plotWorker();
277  worker.reset();
278}
279
280
281var kResX;
282var kResY;
283var error_logged;
284var ui;
285var worker;
286var timer;
287