1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5'use strict'; 6 7base.requireStylesheet('tcmalloc.tcmalloc_instance_view'); 8 9base.require('tracing.analysis.object_instance_view'); 10base.require('tracing.analysis.util'); 11 12base.exportTo('tcmalloc', function() { 13 14 var tsRound = tracing.analysis.tsRound; 15 16 /** 17 * Displays tcmalloc heap memory information over time. A tcmalloc instance 18 * has multiple snapshots. 19 * @constructor 20 */ 21 var TcmallocInstanceView = ui.define( 22 'tcmalloc-instance-view', tracing.analysis.ObjectInstanceView); 23 24 TcmallocInstanceView.prototype = { 25 __proto__: tracing.analysis.ObjectInstanceView.prototype, 26 27 decorate: function() { 28 tracing.analysis.ObjectInstanceView.prototype.decoreate.apply(this); 29 this.classList.add('tcmalloc-instance-view'); 30 }, 31 32 updateContents: function() { 33 var instance = this.objectInstance_; 34 if (!instance || !instance.snapshots || instance.snapshots.length == 0) { 35 this.textContent = 'No data found.'; 36 return; 37 } 38 // Clear old view. 39 this.textContent = ''; 40 41 // First, grab the largest N traces from the first snapshot. 42 var snapshot = instance.snapshots[0]; 43 var heapEntry = snapshot.heap_; 44 var traceNames = Object.keys(heapEntry.children); 45 traceNames.sort(function(a, b) { 46 // Sort from large to small. 47 return heapEntry.children[b].currentBytes - 48 heapEntry.children[a].currentBytes; 49 }); 50 // Only use the largest 5 traces to start 51 traceNames = traceNames.slice(0, 5); 52 53 var table = document.createElement('table'); 54 var titles = ['Total']; 55 titles = titles.concat(traceNames); 56 table.appendChild(this.buildRow_(null, titles)); 57 58 // One array per trace name. 59 var chartArrays = [[], [], [], [], []]; 60 for (var i = 0; i < instance.snapshots.length; i++) { 61 var snapshot = instance.snapshots[i]; 62 var rowData = [snapshot.total_.currentBytes]; 63 for (var j = 0; j < 5; j++) { 64 var bytes = snapshot.heap_.children[traceNames[j]].currentBytes; 65 rowData.push(bytes); 66 // Associate a megabyte count with a time in seconds. 67 chartArrays[j].push( 68 [Math.round(snapshot.ts / 1000), bytes / 1024 / 1024]); 69 } 70 var row = this.buildRow_(snapshot, rowData); 71 table.appendChild(row); 72 } 73 this.appendChild(table); 74 }, 75 76 buildRow_: function(snapshot, items) { 77 var row = document.createElement('tr'); 78 var td = document.createElement('td'); 79 if (snapshot) { 80 var snapshotLink = new tracing.analysis.ObjectSnapshotLink(); 81 snapshotLink.objectSnapshot = snapshot; 82 td.appendChild(snapshotLink); 83 } 84 row.appendChild(td); 85 for (var i = 0; i < items.length; i++) { 86 var data = document.createElement('td'); 87 data.textContent = items[i]; 88 row.appendChild(data); 89 } 90 return row; 91 }, 92 93 /* 94 * Returns a human readable string for a size in bytes. 95 */ 96 getByteString_: function(bytes) { 97 var mb = bytes / 1024 / 1024; 98 return mb.toFixed(1) + ' MB'; 99 } 100 }; 101 102 tracing.analysis.ObjectInstanceView.register( 103 'memory::Heap', TcmallocInstanceView); 104 105 return { 106 TcmallocInstanceView: TcmallocInstanceView 107 }; 108 109}); 110