// Copyright (c) 2013 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. 'use strict'; base.requireStylesheet('tcmalloc.tcmalloc_instance_view'); base.require('tracing.analysis.object_instance_view'); base.require('tracing.analysis.util'); base.exportTo('tcmalloc', function() { var tsRound = tracing.analysis.tsRound; /** * Displays tcmalloc heap memory information over time. A tcmalloc instance * has multiple snapshots. * @constructor */ var TcmallocInstanceView = ui.define( 'tcmalloc-instance-view', tracing.analysis.ObjectInstanceView); TcmallocInstanceView.prototype = { __proto__: tracing.analysis.ObjectInstanceView.prototype, decorate: function() { tracing.analysis.ObjectInstanceView.prototype.decoreate.apply(this); this.classList.add('tcmalloc-instance-view'); }, updateContents: function() { var instance = this.objectInstance_; if (!instance || !instance.snapshots || instance.snapshots.length == 0) { this.textContent = 'No data found.'; return; } // Clear old view. this.textContent = ''; // First, grab the largest N traces from the first snapshot. var snapshot = instance.snapshots[0]; var heapEntry = snapshot.heap_; var traceNames = Object.keys(heapEntry.children); traceNames.sort(function(a, b) { // Sort from large to small. return heapEntry.children[b].currentBytes - heapEntry.children[a].currentBytes; }); // Only use the largest 5 traces to start traceNames = traceNames.slice(0, 5); var table = document.createElement('table'); var titles = ['Total']; titles = titles.concat(traceNames); table.appendChild(this.buildRow_(null, titles)); // One array per trace name. var chartArrays = [[], [], [], [], []]; for (var i = 0; i < instance.snapshots.length; i++) { var snapshot = instance.snapshots[i]; var rowData = [snapshot.total_.currentBytes]; for (var j = 0; j < 5; j++) { var bytes = snapshot.heap_.children[traceNames[j]].currentBytes; rowData.push(bytes); // Associate a megabyte count with a time in seconds. chartArrays[j].push( [Math.round(snapshot.ts / 1000), bytes / 1024 / 1024]); } var row = this.buildRow_(snapshot, rowData); table.appendChild(row); } this.appendChild(table); }, buildRow_: function(snapshot, items) { var row = document.createElement('tr'); var td = document.createElement('td'); if (snapshot) { var snapshotLink = new tracing.analysis.ObjectSnapshotLink(); snapshotLink.objectSnapshot = snapshot; td.appendChild(snapshotLink); } row.appendChild(td); for (var i = 0; i < items.length; i++) { var data = document.createElement('td'); data.textContent = items[i]; row.appendChild(data); } return row; }, /* * Returns a human readable string for a size in bytes. */ getByteString_: function(bytes) { var mb = bytes / 1024 / 1024; return mb.toFixed(1) + ' MB'; } }; tracing.analysis.ObjectInstanceView.register( 'memory::Heap', TcmallocInstanceView); return { TcmallocInstanceView: TcmallocInstanceView }; });