Bug 1123237 - Part 9. Interface to memory-profiler add-ons. r=jimb

Based on patch from Ting-Yuan Huang <laszio.bugzilla@gmail.com>
This commit is contained in:
Kan-Ru Chen 2015-05-08 11:24:12 +08:00
parent 150d9dd765
commit c6fa37762e
6 changed files with 199 additions and 0 deletions

View File

@ -0,0 +1,66 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Cc, Ci, Cu } = require("chrome");
let protocol = require("devtools/server/protocol");
let { method, RetVal, Arg, types } = protocol;
const { reportException } = require("devtools/toolkit/DevToolsUtils");
loader.lazyRequireGetter(this, "events", "sdk/event/core");
let MemprofActor = protocol.ActorClass({
typeName: "memprof",
initialize: function(conn) {
protocol.Actor.prototype.initialize.call(this, conn);
this._profiler = Cc["@mozilla.org/tools/memory-profiler;1"]
.getService(Ci.nsIMemoryProfiler);
},
destroy: function() {
this._profiler = null;
protocol.Actor.prototype.destroy.call(this);
},
startProfiler: method(function() {
this._profiler.startProfiler();
}, {
request: {},
response: {}
}),
stopProfiler: method(function() {
this._profiler.stopProfiler();
}, {
request: {},
response: {}
}),
resetProfiler: method(function() {
this._profiler.resetProfiler();
}, {
request: {},
response: {}
}),
getResults: method(function() {
return this._profiler.getResults();
}, {
request: {},
response: {
ret: RetVal("json")
}
})
});
exports.MemprofActor = MemprofActor;
exports.MemprofFront = protocol.FrontClass(MemprofActor, {
initialize: function(client, form) {
protocol.Front.prototype.initialize.call(this, client, form);
this.actorID = form.memprofActor;
this.manage(this);
}
});

View File

@ -493,6 +493,11 @@ var DebuggerServer = {
constructor: "MemoryActor",
type: { tab: true }
});
this.registerModule("devtools/server/actors/memprof", {
prefix: "memprof",
constructor: "MemprofActor",
type: { global: true, tab: true }
});
this.registerModule("devtools/server/actors/framerate", {
prefix: "framerate",
constructor: "FramerateActor",

View File

@ -54,6 +54,7 @@ EXTRA_JS_MODULES.devtools.server.actors += [
'actors/inspector.js',
'actors/layout.js',
'actors/memory.js',
'actors/memprof.js',
'actors/monitor.js',
'actors/object.js',
'actors/performance-entries.js',

View File

@ -15,6 +15,7 @@ support-files =
inspector-traversal-data.html
large-image.jpg
memory-helpers.js
memprof-helpers.js
nonchrome_unsafeDereference.html
small-image.gif
setup-in-child.js
@ -91,6 +92,7 @@ skip-if = buildapp == 'mulet'
[test_memory_census.html]
[test_memory_gc_01.html]
[test_memory_gc_events.html]
[test_memprof.html]
[test_preference.html]
[test_registerActor.html]
[test_settings.html]

View File

@ -0,0 +1,54 @@
let Cu = Components.utils;
let Cc = Components.classes;
let Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
// Always log packets when running tests.
Services.prefs.setBoolPref("devtools.debugger.log", true);
SimpleTest.registerCleanupFunction(function() {
Services.prefs.clearUserPref("devtools.debugger.log");
});
Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/devtools/Loader.jsm");
let { require } = devtools;
let { MemprofFront } = require("devtools/server/actors/memprof");
function startServerAndGetSelectedTabMemprof() {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
var client = new DebuggerClient(DebuggerServer.connectPipe());
return new Promise((resolve, reject) => {
client.connect(response => {
if (response.error) {
reject(new Error(response.error + ": " + response.message));
return;
}
client.listTabs(response => {
if (response.error) {
reject(new Error(response.error + ": " + response.message));
return;
}
var form = response.tabs[response.selected];
var memprof = MemprofFront(client, form);
resolve({ memprof, client });
});
});
});
}
function destroyServerAndFinish(client) {
client.close(() => {
DebuggerServer.destroy();
SimpleTest.finish();
});
}

View File

@ -0,0 +1,71 @@
<!DOCTYPE HTML>
<html>
<!--
Bug 1123237 - Test profiling memory allocations.
-->
<head>
<meta charset="utf-8">
<title>Memory profiler actor test</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<pre id="test">
<script src="memprof-helpers.js" type="application/javascript;version=1.8"></script>
<script>
window.onload = function() {
SimpleTest.waitForExplicitFinish();
Task.spawn(function* () {
var { memprof, client } = yield startServerAndGetSelectedTabMemprof();
yield memprof.startProfiler();
ok(true, "Can start profiling allocations");
// Allocate some objects.
var alloc;
(function memprof_test_outer() {
(function memprof_test_middle() {
(function memprof_test_inner() {
for (i = 0; i < 65535; ++i) {
alloc = {};
}
}());
}());
}());
yield memprof.stopProfiler();
ok(true, "Can stop profiling allocations");
var results = yield memprof.getResults();
ok(true, "Can get results");
function isTestAllocation(name) {
return /memprof_test_inner/.test(name)
|| /memprof_test_middle/.test(name)
|| /memprof_test_outer/.test(name)
}
var testAllocations = results.names.filter(isTestAllocation);
ok(testAllocations.length >= 3, "Should find our 3 test allocations");
// Ensure the allocation traces has the correct index
var inner = results.traces.find(
trace => /memprof_test_inner/.test(results.names[trace.nameIdx]));
ok(inner, "Find the inner most frame");
var middle = results.traces[inner.parentIdx];
ok(/memprof_test_middle/.test(results.names[middle.nameIdx]),
"Find the middle frame");
var outer = results.traces[middle.parentIdx];
ok(/memprof_test_outer/.test(results.names[outer.nameIdx]),
"Find the outer frame");
yield memprof.resetProfiler();
destroyServerAndFinish(client);
});
};
</script>
</pre>
</body>
</html>