storage.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 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 5storage = new (function() { 6 7this.table_ = null; 8this.tableData_ = null; 9this.profileMenu_ = null; 10 11this.onDomReady_ = function() { 12 // Create the menus for mmap and nheap profiling. 13 this.profileMenu_ = $('#storage-profile-menu'); 14 this.profileMenu_ 15 .mouseleave(this.profileMenu_.hide.bind( 16 this.profileMenu_, {duration: 0})) 17 .hide(); 18 19 // Initialize the toolbar. 20 $('#storage-profile').button({icons:{primary: 'ui-icon-image'}}) 21 .click(this.profileMmapForSelectedSnapshots.bind(this, null)) 22 .mouseenter(this.showProfileMenu_.bind(this)); 23 24 $('#storage-dump-mmaps').button({icons:{primary: 'ui-icon-calculator'}}) 25 .click(this.dumpMmapForSelectedSnapshot_.bind(this)); 26 $('#storage-dump-nheap').button({icons:{primary: 'ui-icon-calculator'}}) 27 .click(this.dumpNheapForSelectedSnapshot_.bind(this)); 28 29 // Create the table. 30 this.table_ = new google.visualization.Table($('#storage-table')[0]); 31 $('#storage-table').on('contextmenu', this.showProfileMenu_.bind(this)); 32}; 33 34this.reload = function() { 35 webservice.ajaxRequest('/storage/list', this.onListAjaxResponse_.bind(this)); 36} 37 38this.onListAjaxResponse_ = function(data) { 39 this.tableData_ = new google.visualization.DataTable(data); 40 this.redraw(); 41}; 42 43this.profileMmapForSelectedSnapshots = function(ruleset) { 44 // Generates a mmap profile for the selected snapshots. 45 var sel = this.table_.getSelection(); 46 if (!sel.length || !this.tableData_) { 47 alert('No snapshots selected!'); 48 return; 49 } 50 var archiveName = null; 51 var snapshots = []; 52 53 for (var i = 0; i < sel.length; ++i) { 54 var row = sel[i].row; 55 var curArchive = this.tableData_.getValue(row, 0); 56 if (archiveName && curArchive != archiveName) { 57 alert('All the selected snapshots must belong to the same archive!'); 58 return; 59 } 60 archiveName = curArchive; 61 snapshots.push(this.tableData_.getValue(row, 1)); 62 } 63 profiler.profileArchivedMmaps(archiveName, snapshots, ruleset); 64 rootUi.showTab('prof'); 65}; 66 67this.dumpMmapForSelectedSnapshot_ = function() { 68 var sel = this.table_.getSelection(); 69 if (sel.length != 1) { 70 alert('Please select only one snapshot.') 71 return; 72 } 73 74 var row = sel[0].row; 75 mmap.dumpMmapsFromStorage(this.tableData_.getValue(row, 0), 76 this.tableData_.getValue(row, 1)) 77 rootUi.showTab('mm'); 78}; 79 80this.dumpNheapForSelectedSnapshot_ = function() { 81 var sel = this.table_.getSelection(); 82 if (sel.length != 1) { 83 alert('Please select only one snapshot.') 84 return; 85 } 86 87 var row = sel[0].row; 88 if (!this.checkHasNativeHapDump_(row)) 89 return; 90 nheap.dumpNheapFromStorage(this.tableData_.getValue(row, 0), 91 this.tableData_.getValue(row, 1)) 92 rootUi.showTab('nheap'); 93}; 94 95this.profileNativeForSelectedSnapshots = function(ruleset) { 96 // Generates a native heap profile for the selected snapshots. 97 var sel = this.table_.getSelection(); 98 if (!sel.length || !this.tableData_) { 99 alert('No snapshots selected!'); 100 return; 101 } 102 var archiveName = null; 103 var snapshots = []; 104 105 for (var i = 0; i < sel.length; ++i) { 106 var row = sel[i].row; 107 var curArchive = this.tableData_.getValue(row, 0); 108 if (archiveName && curArchive != archiveName) { 109 alert('All the selected snapshots must belong to the same archive!'); 110 return; 111 } 112 if (!this.checkHasNativeHapDump_(row)) 113 return; 114 archiveName = curArchive; 115 snapshots.push(this.tableData_.getValue(row, 1)); 116 } 117 profiler.profileArchivedNHeaps(archiveName, snapshots, ruleset); 118 rootUi.showTab('prof'); 119}; 120 121this.checkHasNativeHapDump_ = function(row) { 122 if (!this.tableData_.getValue(row, 3)) { 123 alert('The selected snapshot doesn\'t have a heap dump!'); 124 return false; 125 } 126 return true; 127} 128 129this.rebuildMenu_ = function() { 130 this.profileMenu_.empty(); 131 132 this.profileMenu_.append( 133 $('<li/>').addClass('header').text('Memory map rules')); 134 profiler.rulesets['mmap'].forEach(function(rule) { 135 this.profileMenu_.append( 136 $('<li/>').text(rule).click( 137 this.profileMmapForSelectedSnapshots.bind(this, rule))); 138 }, this); 139 140 this.profileMenu_.append( 141 $('<li/>').addClass('header').text('Native heap rules')); 142 profiler.rulesets['nheap'].forEach(function(rule) { 143 this.profileMenu_.append( 144 $('<li/>').text(rule).click( 145 this.profileNativeForSelectedSnapshots.bind(this, rule))); 146 }, this); 147 148 this.profileMenu_.menu(); 149}; 150 151this.showProfileMenu_ = function(evt) { 152 console.log(evt); 153 var pos; 154 if (evt.type == 'contextmenu') 155 pos = {my: "left top", at: "left bottom", of: evt}; 156 else 157 pos = {my: "left top", at: "left bottom", of: evt.target}; 158 this.profileMenu_.show({duration: 0}).position(pos); 159 evt.preventDefault(); 160} 161 162this.redraw = function() { 163 this.rebuildMenu_(); 164 if (!this.tableData_) 165 return; 166 this.table_.draw(this.tableData_); 167}; 168 169$(document).ready(this.onDomReady_.bind(this)); 170 171})();