Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial extension attempt; this is all derived from about:gc
Our upstream about:gc was originally https://bitbucket.org/burg/aboutgc
- Loading branch information
0 parents
commit d34ac58
Showing
7 changed files
with
333 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
FILES := bootstrap.js install.rdf stylesheet.css about-jsprobes.html about-jsprobes.js lib/*.js | ||
|
||
about-jsprobes.xpi: $(FILES) | ||
zip -9 $@ $+ | ||
|
||
clean: | ||
rm -f about-jsprobes.xpi *[~#] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
This is intended to be a super simple playground for JSProbes. It is a simple | ||
restartless add-on that adds an "about:jsprobes" URL that displays/runs | ||
about-jsprobes.html and about-jsprobes.js with chrome privileges. The probes | ||
will not be active until you create the page. The probes will ideally stop | ||
once you close the page. | ||
|
||
Your stock Firefox does not include jsprobes support. To get said support, you | ||
need to apply the patch queue from: https://bitbucket.org/asuth/jsprobes-patches | ||
and modify your .mozconfig to include: | ||
|
||
ac_add_options --enable-jsprobes | ||
|
||
You can also try and use a build spun by someone else. | ||
|
||
This add-on is derived from about:gc by Steve Fink (and later amended by Brian | ||
Burg to support JSProbes.) | ||
|
||
If you want to learn about JSProbes, you want to see: | ||
|
||
- http://brrian.tumblr.com/post/10571624125/jsprobes | ||
- http://blog.mozilla.com/sfink/2011/09/21/js-probes/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<base href="resource://aboutjsprobes/" /> | ||
<title>About JSProbes</title> | ||
<script type="text/javascript" src="about-jsprobes.js"></script> | ||
<link rel="stylesheet" href="stylesheet.css" /> | ||
</head> | ||
<body> | ||
<h2>Probe Results:</h2> | ||
<pre id="oot"> | ||
</pre> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
const Ci = Components.interfaces; | ||
const Cc = Components.classes; | ||
|
||
const wm = Cc["@mozilla.org/appshell/window-mediator;1"] | ||
.getService(Ci.nsIWindowMediator); | ||
|
||
try { | ||
const probes = Cc["@mozilla.org/base/probes;1"] | ||
.getService(Ci.nsIProbeService); | ||
} catch(e) { | ||
console.error("Could not load nsIProbeService"); | ||
throw new Error("I can't go on without my probes."); | ||
} | ||
|
||
var mainWindow = wm.getMostRecentWindow("navigator:browser"); | ||
var gBrowser = mainWindow.gBrowser; | ||
|
||
var urlListener = { | ||
QueryInterface: function(aIID) { | ||
if (aIID.equals(Ci.nsIWebProgressListener) || | ||
aIID.equals(Ci.nsISupportsWeakReference) || | ||
aIID.equals(Ci.nsISupports)) | ||
return this; | ||
throw Components.results.NS_NOINTERFACE; | ||
}, | ||
|
||
onLocationChange: function(aProgress, aRequest, aURI) { | ||
window.console.log("new URI: " + aURI.spec); | ||
} | ||
}; | ||
|
||
window.console.log("added listener"); | ||
|
||
window.addEventListener('unload', function() { | ||
gBrowser.removeProgressListener(urlListener); | ||
stopProbes(); | ||
}); | ||
|
||
gBrowser.addProgressListener(urlListener); | ||
|
||
// If scrolling through real-time data, advance this whenever dropping off | ||
// data points. | ||
var firstGCIndex = 0; | ||
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); | ||
const TYPE_REPEATING_SLACK = Ci.nsITimer.TYPE_REPEATING_SLACK; | ||
var activeHandlers = []; | ||
|
||
const BYTES_PER_KB = Math.pow(2, 10); | ||
const BYTES_PER_MB = Math.pow(2, 20); | ||
const BYTES_PER_GB = Math.pow(2, 30); | ||
|
||
const MS_PER_SECOND = 1000; | ||
const MS_PER_MINUTE = MS_PER_SECOND * 1000; | ||
const MS_PER_HOUR = MS_PER_MINUTE * 60; | ||
|
||
results = []; | ||
|
||
timerCb = {}; | ||
|
||
function stopProbes() { | ||
if (!probes) return; | ||
|
||
while (activeHandlers.length) { | ||
probes.removeHandler(activeHandlers.pop()); | ||
} | ||
|
||
timer.cancel(); | ||
timer = null; | ||
probes = null; | ||
} | ||
|
||
function execOnProbeThread(func, callback) { | ||
var execStr = func.toString(); | ||
execStr = execStr.substring(execStr.indexOf("{") + 1, | ||
execStr.lastIndexOf("}")); | ||
probes.asyncQuery(execStr, callback); | ||
} | ||
|
||
function registerProbe(probepoint, captureArgs, func) { | ||
var usingStr = "using(" + captureArgs.join(");using(") + ");"; | ||
var execStr = func.toString(); | ||
execStr = execStr.substring(execStr.indexOf("{") + 1, | ||
execStr.lastIndexOf("}")); | ||
var cookie = probes.addHandler(probepoint, usingStr, execStr); | ||
activeHandlers.push(cookie); | ||
} | ||
|
||
function gatherDataFromProbeThreadPeriodically(intervalMS, | ||
probeThreadFunc, | ||
thisThreadProcessFunc) { | ||
timerCb = { | ||
observe: function(subject, topic, data) { | ||
execOnProbeThread(probeThreadFunc, thisThreadProcessFunc); | ||
} | ||
}; | ||
|
||
timer.init(timerCb, intervalMS, TYPE_REPEATING_SLACK); | ||
} | ||
|
||
var outputDomNode = document.getElementById("oot"); | ||
function prettyPrint(obj) { | ||
var s = JSON.stringify(obj, 0, 2), | ||
tn = document.createTextNode(s); | ||
outputDomNode.appendChild(tn); | ||
} | ||
|
||
/** | ||
* These are the GC probes from about:gc, re-written to use the registerProbe | ||
* idiom above that scrapes source out of functions and tries to look pretty. | ||
* | ||
* Their general goal is to produce a list of GC info where the items look like: | ||
* [GC start timestamp, GC end timestamp, before bytes, after bytes]. There | ||
* are also heap resize events of the form [timestamp, old bytes, new bytes]. | ||
* These all end up living in tagged objects, and compartment and global GCs | ||
* are distinguished from each other. | ||
*/ | ||
function activateGCProbes() { | ||
execOnProbeThread(function() { | ||
var pendingData = [], | ||
HEAP_RESIZE_INTERVAL = 500.0, // minimum MS between posted events | ||
lastRecTime = 0, | ||
current; | ||
}); | ||
|
||
registerProbe( | ||
probes.COMPARTMENT_GC_DID_START, | ||
["env.currentTimeMS", "runtime.gcBytes"], | ||
function() { | ||
current = { | ||
type: 'GC_COMPARTMENT', | ||
data: [env.currentTimeMS, 0, runtime.gcBytes, 0], | ||
sortValue: env.currentTimeMS }; | ||
}); | ||
|
||
registerProbe( | ||
probes.GLOBAL_GC_DID_START, | ||
["env.currentTimeMS", "runtime.gcBytes"], | ||
function() { | ||
current = { | ||
type: 'GC_GLOBAL', | ||
data: [env.currentTimeMS, 0, runtime.gcBytes, 0], | ||
sortValue: env.currentTimeMS | ||
}; | ||
}); | ||
|
||
registerProbe( | ||
probes.JS_WILL_RESIZE_HEAP, | ||
["env.currentTimeMS", "oldSize", "newSize"], | ||
function() { | ||
if ((env.currentTimeMS - lastRecTime) > HEAP_RESIZE_INTERVAL) { | ||
lastRecTime = env.currentTimeMS; | ||
pendingData.push({ | ||
type: 'HEAP_RESIZE', | ||
sortValue: env.currentTimeMS, | ||
data: [env.currentTimeMS, oldSize, newSize] | ||
}); | ||
} | ||
}); | ||
|
||
registerProbe( | ||
probes.COMPARTMENT_GC_WILL_END, | ||
["env.currentTimeMS", "runtime.gcBytes"], | ||
function() { | ||
current.data[1] = env.currentTimeMS; | ||
current.data[3] = runtime.gcBytes; | ||
pendingData.push(current); | ||
}); | ||
|
||
registerProbe( | ||
probes.GLOBAL_GC_WILL_END, | ||
["env.currentTimeMS", "runtime.gcBytes"], | ||
function() { | ||
current.data[1] = env.currentTimeMS; | ||
current.data[3] = runtime.gcBytes; | ||
pendingData.push(current); | ||
}); | ||
|
||
gatherDataFromProbeThreadPeriodically( | ||
1000, | ||
function onProbeThread() { | ||
postMessage(pendingData); | ||
pendingData = []; | ||
}, | ||
function onOurThread(e) { | ||
prettyPrint(e.value); | ||
}); | ||
} | ||
|
||
activateGCProbes(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
const Cc = Components.classes; | ||
const Ci = Components.interfaces; | ||
const Cm = Components.manager; | ||
|
||
var testing = false; | ||
|
||
Cm.QueryInterface(Ci.nsIComponentRegistrar); | ||
|
||
Components.utils.import('resource://gre/modules/XPCOMUtils.jsm'); | ||
Components.utils.import('resource://gre/modules/Services.jsm'); | ||
|
||
function AboutJSProbes() {} | ||
|
||
AboutJSProbes.prototype = { | ||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]), | ||
classDescription: 'about:jsprobes', | ||
classID: Components.ID('{ced45ce8-a0ee-4dbd-8099-1a27f60e83c6}'), | ||
contractID: '@mozilla.org/network/protocol/about;1?what=jsprobes', | ||
|
||
newChannel: function(uri) | ||
{ | ||
var channel = Services.io.newChannel( | ||
'resource://aboutjsprobes/about-jsprobes.html', null, null); | ||
var securityManager = Cc['@mozilla.org/scriptsecuritymanager;1'] | ||
.getService(Ci.nsIScriptSecurityManager); | ||
var principal = securityManager.getSystemPrincipal(uri); | ||
channel.originalURI = uri; | ||
channel.owner = principal; | ||
|
||
// var c= Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService); | ||
// c.logStringMessage("uri = " + uri.toString()); | ||
|
||
return channel; | ||
}, | ||
|
||
getURIFlags: function(uri) | ||
{ | ||
return Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT | | ||
Ci.nsIAboutModule.ALLOW_SCRIPT; | ||
} | ||
}; | ||
|
||
const AboutJSProbesFactory = | ||
XPCOMUtils.generateNSGetFactory([AboutJSProbes])( | ||
AboutJSProbes.prototype.classID); | ||
|
||
const APP_STARTUP = 1; | ||
const ADDON_ENABLE = 3; | ||
const ADDON_UPGRADE = 7; | ||
|
||
function startup(aData, aReason) { | ||
Cm.registerFactory(AboutJSProbes.prototype.classID, | ||
AboutJSProbes.prototype.classDescription, | ||
AboutJSProbes.prototype.contractID, | ||
AboutJSProbesFactory); | ||
var fileuri = Services.io.newFileURI(aData.installPath); | ||
if (!aData.installPath.isDirectory()) | ||
fileuri = Services.io.newURI('jar:' + fileuri.spec + '!/', null, null); | ||
Services.io.getProtocolHandler('resource').QueryInterface(Ci.nsIResProtocolHandler).setSubstitution('aboutjsprobes', fileuri); | ||
} | ||
|
||
function shutdown(aData, aReason) { | ||
Services.io.getProtocolHandler('resource').QueryInterface(Ci.nsIResProtocolHandler).setSubstitution('aboutjsprobes', null); | ||
Cm.unregisterFactory(AboutJSProbes.prototype.classID, AboutJSProbesFactory); | ||
} | ||
function install(aData, aReason) { } | ||
function uninstall(aData, aReason) { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?xml version="1.0" encoding="utf-8"?><RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#"> | ||
<Description about="urn:mozilla:install-manifest"> | ||
<em:id>about-jsprobes@mozilla.org</em:id> | ||
<em:version>0.1</em:version> | ||
<em:type>2</em:type> | ||
<em:bootstrap>true</em:bootstrap> | ||
|
||
<!-- Firefox --> | ||
<em:targetApplication> | ||
<Description> | ||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> | ||
<em:minVersion>12.0</em:minVersion> | ||
<em:maxVersion>14.0</em:maxVersion> | ||
</Description> | ||
</em:targetApplication> | ||
|
||
<!-- Fennec --> | ||
<em:targetApplication> | ||
<Description> | ||
<em:id>{a23983c0-fd0e-11dc-95ff-0800200c9a66}</em:id> | ||
<em:minVersion>12.0</em:minVersion> | ||
<em:maxVersion>14.0</em:maxVersion> | ||
</Description> | ||
</em:targetApplication> | ||
|
||
<!-- Front End MetaData --> | ||
<em:name>About JSProbes</em:name> | ||
<em:description>JS Probes Experimentation Template</em:description> | ||
<em:creator>Team Mozilla</em:creator> | ||
<em:iconURL/> | ||
|
||
<em:optionsURL/> | ||
|
||
</Description> | ||
</RDF> |
Empty file.