summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js')
-rw-r--r--Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js204
1 files changed, 200 insertions, 4 deletions
diff --git a/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js b/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js
index 2f709fe23..1dfb21aa4 100644
--- a/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js
+++ b/Source/WebCore/inspector/front-end/NativeMemorySnapshotView.js
@@ -35,9 +35,13 @@
WebInspector.NativeMemorySnapshotView = function(profile)
{
WebInspector.View.call(this);
- this.element.addStyleClass("memory-chart-view");
- this.element.createChild("div").textContent = "Memory chart";
+ this.registerRequiredCSS("nativeMemoryProfiler.css");
this._profile = profile;
+ this.element.addStyleClass("memory-chart-view");
+
+ var pieChart = new WebInspector.NativeMemoryPieChart(profile._memoryBlock);
+ pieChart.element.addStyleClass("fill");
+ pieChart.show(this.element);
}
WebInspector.NativeMemorySnapshotView.prototype = {
@@ -65,7 +69,7 @@ WebInspector.NativeMemorySnapshotView.prototype.__proto__ = WebInspector.View.pr
WebInspector.NativeMemoryProfileType = function()
{
WebInspector.ProfileType.call(this, WebInspector.NativeMemoryProfileType.TypeId, WebInspector.UIString("Take Native Memory Snapshot"));
- this._profileIndex = 1;
+ this._nextProfileUid = 1;
}
WebInspector.NativeMemoryProfileType.TypeId = "NATIVE_MEMORY";
@@ -83,8 +87,16 @@ WebInspector.NativeMemoryProfileType.prototype = {
buttonClicked: function()
{
var profilesPanel = WebInspector.panels.profiles;
- var profileHeader = new WebInspector.NativeMemoryProfileHeader(this, WebInspector.UIString("Snapshot %d", this._profileIndex++), -1);
+ var profileHeader = new WebInspector.NativeMemoryProfileHeader(this, WebInspector.UIString("Snapshot %d", this._nextProfileUid), this._nextProfileUid);
+ ++this._nextProfileUid;
+ profileHeader.isTemporary = true;
profilesPanel.addProfileHeader(profileHeader);
+ function didReceiveMemorySnapshot(error, memoryBlock)
+ {
+ profileHeader._memoryBlock = memoryBlock;
+ profileHeader.isTemporary = false;
+ }
+ MemoryAgent.getProcessMemoryDistribution(didReceiveMemorySnapshot.bind(this));
return false;
},
@@ -132,6 +144,11 @@ WebInspector.NativeMemoryProfileType.prototype.__proto__ = WebInspector.ProfileT
WebInspector.NativeMemoryProfileHeader = function(type, title, uid)
{
WebInspector.ProfileHeader.call(this, type, title, uid);
+
+ /**
+ * @type {MemoryAgent.MemoryBlock}
+ */
+ this._memoryBlock = null;
}
WebInspector.NativeMemoryProfileHeader.prototype = {
@@ -153,3 +170,182 @@ WebInspector.NativeMemoryProfileHeader.prototype = {
}
WebInspector.NativeMemoryProfileHeader.prototype.__proto__ = WebInspector.ProfileHeader.prototype;
+
+/**
+ * @constructor
+ * @param {string} fillStyle
+ * @param {string} name
+ * @param {string} description
+ */
+WebInspector.MemoryBlockViewProperties = function(fillStyle, name, description)
+{
+ this._fillStyle = fillStyle;
+ this._name = name;
+ this._description = description;
+}
+
+/**
+ * @type {Object.<string, WebInspector.MemoryBlockViewProperties>}
+ */
+WebInspector.MemoryBlockViewProperties._standardBlocks = null;
+
+WebInspector.MemoryBlockViewProperties._initialize = function()
+{
+ if (WebInspector.MemoryBlockViewProperties._standardBlocks)
+ return;
+ WebInspector.MemoryBlockViewProperties._standardBlocks = {};
+ function addBlock(fillStyle, name, description)
+ {
+ WebInspector.MemoryBlockViewProperties._standardBlocks[name] = new WebInspector.MemoryBlockViewProperties(fillStyle, name, WebInspector.UIString(description));
+ }
+ addBlock("rgba(240, 240, 250, 0.8)", "ProcessPrivateMemory", "Total");
+ addBlock("rgba(250, 200, 200, 0.8)", "JSHeapAllocated", "JavaScript heap");
+ addBlock("rgba(200, 250, 200, 0.8)", "JSHeapUsed", "Used JavaScript heap");
+}
+
+WebInspector.MemoryBlockViewProperties._forMemoryBlock = function(memoryBlock)
+{
+ WebInspector.MemoryBlockViewProperties._initialize();
+ var result = WebInspector.MemoryBlockViewProperties._standardBlocks[memoryBlock.name];
+ if (result)
+ return result;
+ return new WebInspector.MemoryBlockViewProperties("rgba(20, 200, 20, 0.8)", memoryBlock.name, memoryBlock.name);
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.View}
+ * @param {MemoryAgent.MemoryBlock} memorySnapshot
+ */
+WebInspector.NativeMemoryPieChart = function(memorySnapshot)
+{
+ WebInspector.View.call(this);
+ this._memorySnapshot = memorySnapshot;
+ this.element = document.createElement("div");
+ this.element.addStyleClass("memory-pie-chart-container");
+ this._memoryBlockList = this.element.createChild("div", "memory-blocks-list");
+
+ this._canvasContainer = this.element.createChild("div", "memory-pie-chart");
+ this._canvas = this._canvasContainer.createChild("canvas");
+ this._addBlockLabels(memorySnapshot, true);
+}
+
+WebInspector.NativeMemoryPieChart.prototype = {
+ /**
+ * @override
+ */
+ onResize: function()
+ {
+ this._updateSize();
+ this._paint();
+ },
+
+ _updateSize: function()
+ {
+ var width = this._canvasContainer.clientWidth - 5;
+ var height = this._canvasContainer.clientHeight - 5;
+ this._canvas.width = width;
+ this._canvas.height = height;
+ },
+
+ _addBlockLabels: function(memoryBlock, includeChildren)
+ {
+ var viewProperties = WebInspector.MemoryBlockViewProperties._forMemoryBlock(memoryBlock);
+ var title = viewProperties._description + ": " + Number.bytesToString(memoryBlock.size);
+
+ var swatchElement = this._memoryBlockList.createChild("div", "item");
+ swatchElement.createChild("div", "swatch").style.backgroundColor = viewProperties._fillStyle;
+ swatchElement.createChild("span", "title").textContent = WebInspector.UIString(title);
+
+ if (!memoryBlock.children || !includeChildren)
+ return;
+ for (var i = 0; i < memoryBlock.children.length; i++)
+ this._addBlockLabels(memoryBlock.children[i], false);
+ },
+
+ _paint: function()
+ {
+ this._clear();
+ var width = this._canvas.width;
+ var height = this._canvas.height;
+
+ var x = width / 2;
+ var y = height / 2;
+ var radius = 200;
+
+ var ctx = this._canvas.getContext("2d");
+ ctx.beginPath();
+ ctx.arc(x, y, radius, 0, Math.PI*2, false);
+ ctx.lineWidth = 1;
+ ctx.fillStyle = WebInspector.MemoryBlockViewProperties._forMemoryBlock(this._memorySnapshot)._fillStyle;
+ ctx.strokeStyle = "rgba(130, 130, 130, 0.8)";
+ ctx.fill();
+ ctx.stroke();
+ ctx.closePath();
+
+ var startAngle = - Math.PI / 2;
+ var currentAngle = startAngle;
+ var memoryBlock = this._memorySnapshot;
+
+ function paintPercentAndLabel(fraction, title, midAngle)
+ {
+ ctx.beginPath();
+ ctx.font = "14px Arial";
+ ctx.fillStyle = "rgba(10, 10, 10, 0.8)";
+
+ var textX = x + radius * Math.cos(midAngle) / 2;
+ var textY = y + radius * Math.sin(midAngle) / 2;
+ ctx.fillText((100 * fraction).toFixed(0) + "%", textX, textY);
+
+ textX = x + radius * Math.cos(midAngle);
+ textY = y + radius * Math.sin(midAngle);
+ if (midAngle <= startAngle + Math.PI) {
+ textX += 10;
+ textY += 10;
+ } else {
+ var metrics = ctx.measureText(title);
+ textX -= metrics.width + 10;
+ }
+ ctx.fillText(title, textX, textY);
+ ctx.closePath();
+ }
+
+ if (memoryBlock.children) {
+ var total = memoryBlock.size;
+ for (var i = 0; i < memoryBlock.children.length; i++) {
+ var child = memoryBlock.children[i];
+ if (!child.size)
+ continue;
+ var viewProperties = WebInspector.MemoryBlockViewProperties._forMemoryBlock(child);
+ var angleSpan = Math.PI * 2 * (child.size / total);
+ ctx.beginPath();
+ ctx.moveTo(x, y);
+ ctx.lineTo(x + radius * Math.cos(currentAngle), y + radius * Math.sin(currentAngle));
+ ctx.arc(x, y, radius, currentAngle, currentAngle + angleSpan, false);
+ ctx.lineWidth = 0.5;
+ ctx.lineTo(x, y);
+ ctx.fillStyle = viewProperties._fillStyle;
+ ctx.strokeStyle = "rgba(100, 100, 100, 0.8)";
+ ctx.fill();
+ ctx.stroke();
+ ctx.closePath();
+
+ paintPercentAndLabel(child.size / total, viewProperties._description, currentAngle + angleSpan / 2);
+
+ currentAngle += angleSpan;
+ }
+ }
+
+ var fraction = 1 - (currentAngle - startAngle) / (2 * Math.PI);
+ var midAngle = (currentAngle + startAngle + 2 * Math.PI) / 2;
+ paintPercentAndLabel(fraction, WebInspector.UIString("Unknown"), midAngle);
+ },
+
+ _clear: function() {
+ var ctx = this._canvas.getContext("2d");
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ }
+}
+
+WebInspector.NativeMemoryPieChart.prototype.__proto__ = WebInspector.View.prototype;