diff options
author | junjianx@chromium.org <junjianx@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-14 02:30:36 +0000 |
---|---|---|
committer | junjianx@chromium.org <junjianx@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-14 02:30:36 +0000 |
commit | feceb564cfd997b9a0fd69803f7d01d6ed41053f (patch) | |
tree | 3414a7f322dd2c6ea5acc230a559e9ed9639d47b /tools/deep_memory_profiler | |
parent | 5e91599a896a0b82d37a39ab888a4203421cf2a6 (diff) | |
download | chromium_src-feceb564cfd997b9a0fd69803f7d01d6ed41053f.zip chromium_src-feceb564cfd997b9a0fd69803f7d01d6ed41053f.tar.gz chromium_src-feceb564cfd997b9a0fd69803f7d01d6ed41053f.tar.bz2 |
Initial version of graph visualizer for dmprof
BUG=259206
NOTRY=True
Review URL: https://chromiumcodereview.appspot.com/22440003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217450 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/deep_memory_profiler')
-rw-r--r-- | tools/deep_memory_profiler/visualizer/main.css | 9 | ||||
-rw-r--r-- | tools/deep_memory_profiler/visualizer/main.html | 17 | ||||
-rw-r--r-- | tools/deep_memory_profiler/visualizer/main.js | 160 |
3 files changed, 186 insertions, 0 deletions
diff --git a/tools/deep_memory_profiler/visualizer/main.css b/tools/deep_memory_profiler/visualizer/main.css new file mode 100644 index 0000000..5d9ed53 --- /dev/null +++ b/tools/deep_memory_profiler/visualizer/main.css @@ -0,0 +1,9 @@ +/* Copyright 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. */ + +.plot-container { + width: 1240px; + height: 720px; + margin: 30px auto 30px auto; +}
\ No newline at end of file diff --git a/tools/deep_memory_profiler/visualizer/main.html b/tools/deep_memory_profiler/visualizer/main.html new file mode 100644 index 0000000..fdd7874 --- /dev/null +++ b/tools/deep_memory_profiler/visualizer/main.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<!-- +Copyright 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. +--> +<meta charset="utf-8"> +<link rel="stylesheet" href="main.css"> +<script src="../../../third_party/flot/jquery.min.js"></script> +<script src="../../../third_party/flot/jquery.flot.min.js"></script> +<script src="../../../third_party/flot/jquery.flot.stack.min.js"></script> +<script src="main.js"></script> + +<body> + <h2>Deep Memory Profiler Visulaizer</h2> + <div id="plot" class="plot-container"></div> +</body> diff --git a/tools/deep_memory_profiler/visualizer/main.js b/tools/deep_memory_profiler/visualizer/main.js new file mode 100644 index 0000000..8c4dff8 --- /dev/null +++ b/tools/deep_memory_profiler/visualizer/main.js @@ -0,0 +1,160 @@ +// Copyright 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. + +/** + * This class provides data access interface for dump file profiler + * @constructor + */ +var Profiler = function(jsonData) { + this._jsonData = jsonData; +}; + +/** + * Get units of a snapshot in a world. + * Exception will be thrown when no world of given name exists. + * @param {string} worldName + * @param {number} snapshotIndex + * @return {Object.<string, number>} + */ +Profiler.prototype.getUnits = function(worldName, snapshotIndex) { + var snapshot = this._jsonData.snapshots[snapshotIndex]; + if (!snapshot.worlds[worldName]) + throw 'no world ' + worldName + ' in snapshot ' + index; + + // Return units. + var world = snapshot.worlds[worldName]; + var units = {}; + for (var unitName in world.units) + units[unitName] = world.units[unitName][0]; + return units; +}; + +/** + * Get first-level breakdowns of a snapshot in a world. + * Exception will be thrown when no world of given name exists. + * @param {string} worldName + * @param {number} snapshotIndex + * @return {Object.<string, Object>} + */ +Profiler.prototype.getBreakdowns = function(worldName, snapshotIndex) { + var snapshot = this._jsonData.snapshots[snapshotIndex]; + if (!snapshot.worlds[worldName]) + throw 'no world ' + worldName + ' in snapshot ' + index; + + // Return breakdowns. + // TODO(junjianx): handle breakdown with arbitrary-level structure. + return snapshot.worlds[worldName].breakdown; +}; + +/** + * Get categories from fixed hard-coded worlds and breakdowns temporarily. + * TODO(junjianx): remove the hard-code and support general cases. + * @return {Array.<Object>} + */ +Profiler.prototype.getCategories = function() { + var categories = []; + var snapshotNum = this._jsonData.snapshots.length; + + for (var snapshotIndex = 0; snapshotIndex < snapshotNum; ++snapshotIndex) { + // Initial categories object for one snapshot. + categories.push({}); + + // Handle breakdowns in malloc world. + var mallocBreakdown = this.getBreakdowns('malloc', snapshotIndex); + var mallocUnits = this.getUnits('malloc', snapshotIndex); + if (!mallocBreakdown['component']) + throw 'no breakdown ' + 'component' + ' in snapshot ' + snapshotIndex; + + var componentBreakdown = mallocBreakdown['component']; + var componentMemory = 0; + Object.keys(componentBreakdown).forEach(function(breakdownName) { + var breakdown = componentBreakdown[breakdownName]; + var memory = breakdown.units.reduce(function(previous, current) { + return previous + mallocUnits[current]; + }, 0); + componentMemory += memory; + + if (componentBreakdown['hidden'] === true) + return; + else + categories[snapshotIndex][breakdownName] = memory; + }); + + // Handle breakdowns in vm world. + var vmBreakdown = this.getBreakdowns('vm', snapshotIndex); + var vmUnits = this.getUnits('vm', snapshotIndex); + if (!vmBreakdown['map']) + throw 'no breakdown ' + 'map' + ' in snapshot ' + snapshotIndex; + + var mapBreakdown = vmBreakdown['map']; + + Object.keys(mapBreakdown).forEach(function(breakdownName) { + var breakdown = mapBreakdown[breakdownName]; + var memory = breakdown.units.reduce(function(previous, current) { + return previous + vmUnits[current]; + }, 0); + + if (vmBreakdown['hidden'] === true) + return; + else if (breakdownName === 'mmap-tcmalloc') + categories[snapshotIndex]['tc-unused'] = memory - componentMemory; + else + categories[snapshotIndex][breakdownName] = memory; + }); + } + + return categories; +}; + +/** + * Generate lines for flot plotting. + * @param {Array.<Object>} categories + * @return {Array.<Object>} + */ +var generateLines = function(categories) { + var lines = {}; + var snapshotNum = categories.length; + + // Initialize lines with all zero. + categories.forEach(function(categories) { + Object.keys(categories).forEach(function(breakdownName) { + if (lines[breakdownName]) + return; + lines[breakdownName] = []; + for (var i = 0; i < snapshotNum; ++i) + lines[breakdownName].push([i, 0]); + }); + }); + + // Assignment lines with values of categories. + categories.forEach(function(categories, index) { + Object.keys(categories).forEach(function(breakdownName) { + lines[breakdownName][index] = [index, categories[breakdownName]]; + }); + }); + + return Object.keys(lines).map(function(breakdownName) { + return { + label: breakdownName, + data: lines[breakdownName] + }; + }); +}; + +$(function() { + // Read original data and plot. + $.getJSON('data/result.json', function(jsonData) { + var profiler = new Profiler(jsonData); + var categories = profiler.getCategories(); + var lines = generateLines(categories); + + // Plot stack graph. + $.plot('#plot', lines, { + series: { + stack: true, + lines: { show: true, fill: true } + } + }); + }); +});
\ No newline at end of file |