blob: a3b5be3870fa32588a0f12b2958831e7362c609a [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<link rel="import" href="/tracing/extras/v8/v8_thread_slice.html">
<link rel="import" href="/tracing/ui/base/table.html">
<dom-module id='tr-ui-e-v8-runtime-call-stats-table'>
<template>
<style>
#table {
flex: 0 0 auto;
align-self: stretch;
margin-top: 1em;
}
</style>
<tr-ui-b-table id="table"></tr-ui-b-table>
</template>
</dom-module>
<script>
'use strict';
tr.exportTo('tr.ui.e.v8', function() {
function handleCodeSearch_(event) {
if (event.target.parentNode === undefined) return;
var name = event.target.parentNode.entryName;
var url = 'https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=';
if (name.startsWith('API_')) name = name.substring(4);
url += encodeURIComponent(name) + '+file:src/v8/src';
window.open(url, '_blank');
}
var Entry = function(name, count, time) {
this.name_ = name;
this.count_ = count;
this.time_ = time;
};
Entry.prototype = {
__proto__: Object.prototype,
get name() {
return this.name_;
},
get count() {
return this.count_;
},
get time() {
return this.time_;
},
accumulate: function(count, time) {
this.count_ += count;
this.time_ += time;
},
reset: function() {
this.count_ = 0;
this.time_ = 0;
}
};
var GroupedEntry = function(name, match_regex) {
Entry.call(this, name, 0, 0);
this.regex_ = match_regex;
this.entries_ = new Map();
};
GroupedEntry.prototype = {
__proto__: Entry.prototype,
match: function(name) {
return this.regex_ && !(!name.match(this.regex_));
},
add: function(entry) {
var value = this.entries_.get(entry.name);
if (value !== undefined)
value.accumulate(entry.count, entry.time);
else
this.entries_.set(entry.name, entry);
this.count_ += entry.count;
this.time_ += entry.time;
},
get subRows() {
return Array.from(this.entries_.values());
},
reset: function(entry) {
this.time_ = 0;
this.count_ = 0;
this.entries_.clear();
}
};
Polymer({
is: 'tr-ui-e-v8-runtime-call-stats-table',
ready: function() {
this.table_ = this.$.table;
this.totalTime_ = 0;
},
constructTable_: function() {
var totalTime = this.totalTime_;
this.table_.selectionMode = tr.ui.b.TableFormat.SelectionMode.ROW;
this.table_.tableColumns = [
{
title: 'Name',
value: function(row) {
var typeEl = document.createElement('span');
typeEl.innerText = row.name;
if (!(row instanceof GroupedEntry)) {
typeEl.title = 'click ? for code search';
typeEl.entryName = row.name;
var codeSearchEl = document.createElement('span');
codeSearchEl.innerText = '?';
codeSearchEl.style.float = 'right';
codeSearchEl.style.borderRadius = '5px';
codeSearchEl.style.backgroundColor = '#EEE';
codeSearchEl.addEventListener('click',
handleCodeSearch_.bind(this));
typeEl.appendChild(codeSearchEl);
}
return typeEl;
},
width: '200px',
showExpandButtons: true
},
{
title: 'Time',
value: function(row) {
var typeEl = document.createElement('span');
typeEl.innerText = (row.time / 1000.0).toFixed(3) + ' ms';
return typeEl;
},
width: '100px',
cmp: function(a, b) {
return a.time - b.time;
}
},
{
title: 'Count',
value: function(row) {
var typeEl = document.createElement('span');
typeEl.innerText = row.count;
return typeEl;
},
width: '100px',
cmp: function(a, b) {
return a.count - b.count;
}
},
{
title: 'Percent',
value: function(row) {
var typeEl = document.createElement('span');
typeEl.innerText = (row.time / totalTime * 100).toFixed(3) + '%';
return typeEl;
},
width: '100px',
cmp: function(a, b) {
return a.time - b.time;
}
}
];
this.table_.sortColumnIndex = 1;
this.table_.sortDescending = true;
},
set slices(slices) {
var groups = new Array(
new GroupedEntry('Total'),
new GroupedEntry('IC', /.*IC.*/),
new GroupedEntry('Optimize',
/StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/),
new GroupedEntry('Compile', /.*Compile.*/),
new GroupedEntry('Parse', /.*Parse.*/),
new GroupedEntry('Callback', /.*Callback$/),
new GroupedEntry('API', /.*API.*/),
new GroupedEntry('GC', /GC|AllocateInTargetSpace/),
new GroupedEntry('JavaScript', /JS_Execution/),
new GroupedEntry('Runtime', /.*/)
);
slices.forEach(function(slice) {
if (!(slice instanceof tr.e.v8.V8ThreadSlice)) return;
try {
var runtimeCallStats = JSON.parse(slice.runtimeCallStats);
} catch (e) {
var runtimeCallStats = slice.runtimeCallStats;
}
if (runtimeCallStats !== undefined) {
Object.getOwnPropertyNames(runtimeCallStats).forEach(
function(runtimeCallStatName) {
for (var i = 1; i < groups.length; ++i) {
if (groups[i].match(runtimeCallStatName)) {
var runtimeCallStat = runtimeCallStats[runtimeCallStatName];
if (runtimeCallStat.length !== 2) break;
var entry = new Entry(runtimeCallStatName, runtimeCallStat[0],
runtimeCallStat[1]);
groups[0].accumulate(runtimeCallStat[0], runtimeCallStat[1]);
groups[i].add(entry);
break;
}
}
}, this);
}
}, this);
this.totalTime_ = groups[0].time;
if (this.totalTime_ > 0) {
this.constructTable_();
this.table_.tableRows = groups;
this.table_.rebuild();
}
}
});
return {};
});
</script>