blob: 6bd570eeb91bfd0329619041b0b4d9e401315bfe [file] [log] [blame]
<!DOCTYPE html>
<!--
Copyright (c) 2015 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="/base/ui/color_legend.html">
<link rel="import"
href="/core/analysis/memory_dump_allocator_details_pane.html">
<link rel="import"
href="/core/analysis/memory_dump_vm_regions_details_pane.html">
<link rel="import" href="/core/analysis/memory_dump_sub_view_util.html">
<link rel="import" href="/base/units/size_in_bytes_span.html">
<link rel="import" href="/base/ui/table.html">
<link rel="import" href="/model/attribute.html">
<polymer-element name="tr-c-a-memory-dump-overview-pane">
<template>
<style>
:host {
display: flex;
flex-direction: column;
}
#label {
flex: 0 0 auto;
padding: 8px;
background-color: #eee;
border-bottom: 1px solid #8e8e8e;
border-top: 1px solid white;
font-size: 15px;
font-weight: bold;
}
#table {
flex: 1 0 auto;
align-self: stretch;
}
</style>
<div id="label">Overview</div>
<tr-b-ui-table id="table">
</tr-b-ui-table>
</template>
<script>
'use strict';
(function() {
var IMPORTANCE_RULES = [
{
condition: 'tracing',
importance: 0
},
{
importance: 1
}
];
Polymer({
// TODO(petrcermak): Consider sharing more code between
// tr-c-a-memory-dump-overview-pane and tr-c-memory-dump-process pane
// (e.g. by defining a common base class tr-c-memory-dump-pane).
created: function() {
this.processMemoryDumps_ = undefined;
},
ready: function() {
this.$.table.supportsSelection = true;
this.$.table.cellSelectionMode = true;
this.$.table.addEventListener('selection-changed',
function(tableEvent) {
tableEvent.stopPropagation();
var paneEvent = new Event('selected-memory-cell-changed');
this.dispatchEvent(paneEvent);
}.bind(this));
},
set processMemoryDumps(processMemoryDumps) {
this.processMemoryDumps_ = processMemoryDumps;
this.updateContents_();
},
get processMemoryDumps() {
return this.processMemoryDumps_;
},
get selectedMemoryCell() {
var selectedTableRow = this.$.table.selectedTableRow;
if (!selectedTableRow)
return undefined;
var selectedColumnIndex = this.$.table.selectedColumnIndex;
if (selectedColumnIndex === undefined)
return undefined;
var selectedColumn = this.$.table.tableColumns[selectedColumnIndex];
var selectedMemoryCell = selectedColumn.cell(selectedTableRow);
return selectedMemoryCell;
},
updateContents_: function() {
var processMemoryDumps = this.processMemoryDumps_ || [];
var rows = processMemoryDumps.map(function(processMemoryDump) {
function buildVMRegionsPane() {
var pane = document.createElement(
'tr-c-a-memory-dump-vm-regions-details-pane');
pane.vmRegions = processMemoryDump.mostRecentVmRegions;
return pane;
}
// Used memory (total resident, PSS, ...).
var usedMemorySizes = {};
var totalResident = processMemoryDump.totalResidentBytes;
if (totalResident !== undefined) {
var cell = new tr.c.analysis.MemoryCell(
new tr.model.ScalarAttribute('bytes', totalResident));
cell.buildDetailsPane = buildVMRegionsPane;
usedMemorySizes['Total resident'] = cell;
}
function addByteStatCell(byteStatName, columnTitle) {
var byteStat =
processMemoryDump.getMostRecentTotalVmRegionStat(byteStatName);
if (byteStat !== undefined) {
var cell = new tr.c.analysis.MemoryCell(
new tr.model.ScalarAttribute('bytes', byteStat));
cell.buildDetailsPane = buildVMRegionsPane;
usedMemorySizes[columnTitle] = cell;
}
}
addByteStatCell('proportionalResident', 'PSS');
addByteStatCell('privateDirtyResident', 'Private dirty');
addByteStatCell('swapped', 'Swapped');
// Allocator memory (v8, oilpan, ...).
var allocatorSizes = {};
if (processMemoryDump.memoryAllocatorDumps !== undefined) {
processMemoryDump.memoryAllocatorDumps.forEach(function(dump) {
var attr = dump.attributes['size'];
// TODO(petrcermak): Remove support for the old default attribute
// name once the correspoding change lands in Chromium.
if (attr === undefined)
attr = dump.attributes['outer_size'];
var cell = new tr.c.analysis.MemoryCell(attr);
cell.buildDetailsPane = function() {
var pane = document.createElement(
'tr-c-a-memory-dump-allocator-details-pane');
pane.memoryAllocatorDump = dump;
return pane;
};
allocatorSizes[dump.fullName] = cell;
}, this);
}
return {
title: processMemoryDump.process.userFriendlyName,
usedMemorySizes: usedMemorySizes,
allocatorSizes: allocatorSizes
};
}, this);
this.$.table.tableRows = rows;
this.updateColumns_(rows);
this.$.table.rebuild();
},
updateColumns_: function(rows) {
var titleColumn = {
title: 'Process',
value: function(row) {
var titleEl = document.createElement('tr-b-ui-color-legend');
titleEl.label = row.title;
return titleEl;
},
width: '200px',
cmp: function(rowA, rowB) {
return rowA.title.localeCompare(rowB.title);
},
supportsCellSelection: false
};
var usedMemorySizeColumns = tr.c.analysis.MemoryColumn.fromRows(
rows, 'usedMemorySizes');
var allocatorSizeColumns = tr.c.analysis.MemoryColumn.fromRows(
rows, 'allocatorSizes', function(allocatorName) {
var titleEl = document.createElement('tr-b-ui-color-legend');
titleEl.label = allocatorName;
return titleEl;
});
tr.c.analysis.MemoryColumn.sortByImportance(
allocatorSizeColumns, IMPORTANCE_RULES);
// Grey the 'tracing' column out (if present).
// TODO(petrcermak): Find a less hacky way to do this.
var tracingColumn = tr.b.findFirstInArray(allocatorSizeColumns,
function(column) {
return column.name === 'tracing';
});
if (tracingColumn !== undefined) {
var titleEl = document.createElement('span');
titleEl.style.color = '#999';
titleEl.textContent = 'tracing';
tracingColumn.title = titleEl;
var oldValueCallback = tracingColumn.value;
tracingColumn.value = function(row) {
var oldValue = oldValueCallback.call(this, row);
if (!(oldValue instanceof HTMLElement))
oldValue = document.createTextNode(oldValue);
var valueEl = document.createElement('span');
valueEl.style.color = '#999';
valueEl.appendChild(oldValue);
return valueEl;
};
}
var sizeColumns = usedMemorySizeColumns.concat(allocatorSizeColumns);
tr.c.analysis.MemoryColumn.spaceEqually(sizeColumns);
var columns = [titleColumn].concat(sizeColumns);
this.$.table.tableColumns = columns;
}
});
})();
</script>
</polymer-element>