diff options
Diffstat (limited to 'deps/v8/tools/parse-processor.html')
-rw-r--r-- | deps/v8/tools/parse-processor.html | 154 |
1 files changed, 117 insertions, 37 deletions
diff --git a/deps/v8/tools/parse-processor.html b/deps/v8/tools/parse-processor.html index e41fffbd5f..1e67e4a281 100644 --- a/deps/v8/tools/parse-processor.html +++ b/deps/v8/tools/parse-processor.html @@ -62,10 +62,43 @@ code is governed by a BSD-style license that can be found in the LICENSE file. overflow-y: scroll; } - .funktion { } + .script-size { + display: inline-flex; + background-color: #505050; + border-radius: 3px; + padding: 3px; + margin: 2px; + white-space: nowrap; + overflow: hidden; + text-decoration: none; + color: white; + } + .script-size.eval { + background-color: #ee6300fc; + } + .script-size.streaming { + background-color: #008aff; + } + .script-size.deserialized { + background-color: #1fad00fc; + } + + .script-details { + padding-right: 5px; + margin-right: 4px; + } + /* all but the last need a border */ + .script-details:nth-last-child(n+2) { + border-right: 1px white solid; + } + + .script-details.id { + min-width: 2em; + text-align: right; + } </style> <script src="./splaytree.js" type="text/javascript"></script> <script src="./codemap.js" type="text/javascript"></script> @@ -86,7 +119,6 @@ function $(query) { return document.querySelector(query); } - function loadFile() { let files = $('#uploadInput').files; @@ -149,19 +181,20 @@ function text(string) { } function delay(t) { - return new Promise(resolve = > setTimeout(resolve, t)); + return new Promise(resolve => setTimeout(resolve, t)); } function renderParseResults(parseProcessor) { let result = $('#result'); // clear out all existing result pages; result.innerHTML = ''; - const start = parseProcessor.firstEvent; - const end = parseProcessor.lastEvent; + const start = parseProcessor.firstEventTimestamp; + const end = parseProcessor.lastEventTimestamp; renderScript(result, parseProcessor.totalScript, start, end); // Build up the graphs lazily to keep the page responsive. parseProcessor.scripts.forEach( script => renderScript(result, script, start, end)); + renderScriptSizes(parseProcessor); // Install an intersection observer to lazily load the graphs when the script // div becomes visible for the first time. var io = new IntersectionObserver((entries, observer) => { @@ -172,11 +205,10 @@ function renderParseResults(parseProcessor) { appendGraph(target.script, target, start, end); observer.unobserve(entry.target); }); - }, {}); + }, {rootMargin: '400px'}); document.querySelectorAll('.script').forEach(div => io.observe(div)); } - const kTimeFactor = 10; const kHeight = 20; const kFunktionTopOffset = 50; @@ -189,32 +221,69 @@ function renderScript(result, script, start, end) { scriptDiv.script = script; let scriptTitle = h3(); - if (script.file) scriptTitle.appendChild(a(script.file, script.file)); - let anchor = a("", ' id=' + script.id); + let anchor = a("", 'Script #' + script.id); anchor.name = "script"+script.id scriptTitle.appendChild(anchor); scriptDiv.appendChild(scriptTitle); + if (script.file) scriptTitle.appendChild(a(script.file, script.file)); let summary = createNode('pre', 'script-details'); summary.appendChild(text(script.summary)); scriptDiv.appendChild(summary); result.appendChild(scriptDiv); - return scriptDiv; +} + +function renderScriptSizes(parseProcessor) { + let scriptsDiv = $('#scripts'); + parseProcessor.scripts.forEach( + script => { + let scriptDiv = a('#script'+script.id, '', 'script-size'); + let scriptId = div('script-details'); + scriptId.classList.add('id'); + scriptId.innerText = script.id; + scriptDiv.appendChild(scriptId); + let scriptSize = div('script-details'); + scriptSize.innerText = BYTES(script.bytesTotal); + scriptDiv.appendChild(scriptSize); + let scriptUrl = div('script-details'); + if (script.isEval) { + scriptUrl.innerText = "eval"; + scriptDiv.classList.add('eval'); + } else { + scriptUrl.innerText = script.file.split("/").pop(); + } + if (script.isStreamingCompiled ) { + scriptDiv.classList.add('streaming'); + } else if (script.deserializationTimestamp > 0) { + scriptDiv.classList.add('deserialized'); + } + scriptDiv.appendChild(scriptUrl); + scriptDiv.style.width = script.bytesTotal * 0.001; + scriptsDiv.appendChild(scriptDiv); + }); } const kMaxTime = 120 * kSecondsToMillis; // Resolution of the graphs const kTimeIncrement = 1; const kSelectionTimespan = 2; +// TODO(cbruni): support compilation cache hit. const series = [ -// ['firstParseEvent', 'Any Parse Event'], + ['firstParseEvent', 'Any Parse', 'area'], + ['execution', '1st Exec', 'area'], + ['firstCompileEvent', 'Any Compile', 'area'], + ['compile', 'Eager Compile'], + ['lazyCompile', 'Lazy Compile'], ['parse', 'Parsing'], -// ['preparse', 'Preparsing'], -// ['resolution', 'Preparsing with Var. Resolution'], - ['lazyCompile', 'Lazy Compilation'], - ['compile', 'Eager Compilation'], - ['execution', 'First Execution'], + ['preparse', 'Preparse'], + ['resolution', 'Preparse with Var. Resolution'], + ['deserialization', 'Deserialization'], + ['optimization', 'Optimize'], ]; const metricNames = series.map(each => each[0]); +// Display cumulative values (useuful for bytes). +const kCumulative = true; +// Include durations in the graphs. +const kUseDuration = false; function appendGraph(script, parentNode, start, end) { @@ -223,27 +292,34 @@ function appendGraph(script, parentNode, start, end) { console.time(timerLabel); let data = new google.visualization.DataTable(); - data.addColumn('number', 'Time'); + data.addColumn('number', 'Duration'); // The series are interleave bytes processed, time spent and thus have two // different vAxes. let seriesOptions = []; - series.forEach(each => { - let description = each[1]; + let colors = ['#4D4D4D', '#fff700', '#5DA5DA', '#FAA43A', '#60BD68', + '#F17CB0', '#B2912F', '#B276B2', '#DECF3F', '#F15854']; + series.forEach(([metric, description, type]) => { + let color = colors.shift(); // Add the bytes column. - data.addColumn('number', description + ' Bytes'); - seriesOptions.push({targetAxisIndex: 0}); + data.addColumn('number', description); + let options = {targetAxisIndex: 0, color: color}; + if (type == 'area') options.type = 'area'; + seriesOptions.push(options) // Add the time column. - data.addColumn('number', description + ' Time'); - seriesOptions.push({targetAxisIndex: 1, lineDashStyle: [3, 2]}); + if (kUseDuration) { + data.addColumn('number', description + ' Duration'); + seriesOptions.push( + {targetAxisIndex: 1, color: color, lineDashStyle: [3, 2]}); + } }); - // The first entry contains the total. - seriesOptions[0].type = 'area'; const maxTime = Math.min(kMaxTime, end); console.time('metrics'); let metricValues = - script.getAccumulatedTimeMetrics(metricNames , 0, maxTime, kTimeIncrement); + script.getAccumulatedTimeMetrics(metricNames , 0, maxTime, kTimeIncrement, + kCumulative, kUseDuration); console.timeEnd('metrics'); + // Make sure that the series added to the graph matches the returned values. console.assert(metricValues[0].length == seriesOptions.length + 1); data.addRows(metricValues); @@ -257,11 +333,11 @@ function appendGraph(script, parentNode, start, end) { }, vAxes: { 0: {title: 'Bytes Touched', format: 'short'}, - 1: {title: 'Time', format: '#,###ms'} + 1: {title: 'Duration', format: '#,###ms'} }, height: 400, width: 1000, - chartArea: {left: '5%', top: '15%', width: "85%", height: "75%"}, + chartArea: {left: 70, top: 0, right: 160, height: "90%"}, // The first series should be a area chart (total bytes touched), series: seriesOptions, // everthing else is a line. @@ -275,27 +351,29 @@ function appendGraph(script, parentNode, start, end) { google.visualization.events.addListener(chart, 'select', () => selectGraphPointHandler(chart, data, script, parentNode)); chart.draw(data, options); + // Add event listeners console.timeEnd(timerLabel); } - function selectGraphPointHandler(chart, data, script, parentNode) { let selection = chart.getSelection(); if (selection.length <= 0) return; // Display a list of funktions with events at the given time. let {row, column} = selection[0]; if (row === null|| column === null) return; - let name = series[((column-1)/2) | 0][0]; + const kEntrySize = kUseDuration ? 2 : 1; + let [metric, description] = series[((column-1)/ kEntrySize) | 0]; let time = data.getValue(row, 0); let funktions = script.getFunktionsAtTime( - time * kSecondsToMillis, kSelectionTimespan, name); + time * kSecondsToMillis, kSelectionTimespan, metric); let oldList = parentNode.querySelector('.funktion-list'); - parentNode.replaceChild(createFunktionList(name, time, funktions), oldList); + parentNode.replaceChild( + createFunktionList(metric, description, time, funktions), oldList); } -function createFunktionList(metric, time, funktions) { +function createFunktionList(metric, description, time, funktions) { let container = createNode('div', 'funktion-list'); - container.appendChild(h3('Changes of ' + metric + ' at ' + + container.appendChild(h3('Changes of "' + description + '" at ' + time + 's: ' + funktions.length)); let listNode = createNode('ul'); funktions.forEach(funktion => { @@ -311,8 +389,6 @@ function createFunktionList(metric, time, funktions) { container.appendChild(listNode); return container; } - - </script> </head> @@ -326,10 +402,14 @@ function createFunktionList(metric, time, funktions) { <h2>Data</h2> <form name="fileForm"> <p> - <input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace entries: <span id="count">0</span> + <input id="uploadInput" type="file" name="files" onchange="loadFile();" accept=".log"> trace entries: <span id="count">0</span> </p> </form> + + <h2>Scripts</h2> + <div id="scripts"></div> + <h2>Result</h2> <div id="result"></div> </body> |