mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-28 00:07:28 +00:00
bug 1096718 - - display time measured spent in each compartment r=billm,mossop
This commit is contained in:
parent
4f66eb5a78
commit
36b059df69
@ -51,11 +51,10 @@ static RedirEntry kRedirMap[] = {
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
||||
{ "compartments", "chrome://global/content/aboutCompartments.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT |
|
||||
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
|
||||
{ "memory", "chrome://global/content/aboutMemory.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "compartments", "chrome://global/content/aboutCompartments.xhtml",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "addons", "chrome://mozapps/content/extensions/extensions.xul",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "newaddon", "chrome://mozapps/content/extensions/newaddon.xul",
|
||||
|
@ -168,6 +168,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "neterror", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "compartments", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "memory", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "compartments", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "addons", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "newaddon", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
|
||||
|
@ -167,6 +167,30 @@ JS_GetEmptyString(JSRuntime *rt)
|
||||
return rt->emptyString;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_GetCompartmentStats(JSRuntime *rt, CompartmentStatsVector &stats)
|
||||
{
|
||||
if (!stats.resizeUninitialized(rt->numCompartments))
|
||||
return false;
|
||||
|
||||
size_t pos = 0;
|
||||
for (CompartmentsIter c(rt, WithAtoms); !c.done(); c.next()) {
|
||||
CompartmentTimeStats *stat = &stats[pos];
|
||||
stat->time = c.get()->totalTime;
|
||||
stat->compartment = c.get();
|
||||
stat->addonId = c.get()->addonId;
|
||||
if (rt->compartmentNameCallback) {
|
||||
(*rt->compartmentNameCallback)(rt, stat->compartment,
|
||||
stat->compartmentName,
|
||||
MOZ_ARRAY_LENGTH(stat->compartmentName));
|
||||
} else {
|
||||
strcpy(stat->compartmentName, "<unknown>");
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
void
|
||||
|
@ -1042,6 +1042,19 @@ JS_GetEmptyStringValue(JSContext *cx);
|
||||
extern JS_PUBLIC_API(JSString *)
|
||||
JS_GetEmptyString(JSRuntime *rt);
|
||||
|
||||
struct CompartmentTimeStats {
|
||||
char compartmentName[1024];
|
||||
JSAddonId *addonId;
|
||||
JSCompartment *compartment;
|
||||
uint64_t time; // microseconds
|
||||
uint64_t cpowTime; // microseconds
|
||||
};
|
||||
|
||||
typedef js::Vector<CompartmentTimeStats, 0, js::SystemAllocPolicy> CompartmentStatsVector;
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetCompartmentStats(JSRuntime *rt, CompartmentStatsVector &stats);
|
||||
|
||||
/*
|
||||
* Format is a string of the following characters (spaces are insignificant),
|
||||
* specifying the tabulated type conversions:
|
||||
|
@ -345,8 +345,16 @@ xpc::TraceXPCGlobal(JSTracer *trc, JSObject *obj)
|
||||
compartmentPrivate->scope->TraceInside(trc);
|
||||
}
|
||||
|
||||
|
||||
namespace xpc {
|
||||
|
||||
uint64_t
|
||||
GetCompartmentCPOWMicroseconds(JSCompartment *compartment)
|
||||
{
|
||||
xpc::CompartmentPrivate *compartmentPrivate = xpc::CompartmentPrivate::Get(compartment);
|
||||
return compartmentPrivate ? PR_IntervalToMicroseconds(compartmentPrivate->CPOWTime) : 0;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
|
||||
JS::CompartmentOptions& aOptions)
|
||||
|
@ -139,6 +139,9 @@ XrayAwareCalleeGlobal(JSObject *fun);
|
||||
void
|
||||
TraceXPCGlobal(JSTracer *trc, JSObject *obj);
|
||||
|
||||
uint64_t
|
||||
GetCompartmentCPOWMicroseconds(JSCompartment *compartment);
|
||||
|
||||
} /* namespace xpc */
|
||||
|
||||
namespace JS {
|
||||
|
@ -0,0 +1,75 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-*/
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
const { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
|
||||
function go() {
|
||||
let compartmentInfo = Cc["@mozilla.org/compartment-info;1"]
|
||||
.getService(Ci.nsICompartmentInfo);
|
||||
let compartments = compartmentInfo.getCompartments();
|
||||
let count = compartments.length;
|
||||
let addons = {};
|
||||
for (let i = 0; i < count; i++) {
|
||||
let compartment = compartments.queryElementAt(i, Ci.nsICompartment);
|
||||
if (addons[compartment.addonId]) {
|
||||
addons[compartment.addonId].time += compartment.time;
|
||||
addons[compartment.addonId].CPOWTime += compartment.CPOWTime;
|
||||
addons[compartment.addonId].compartments.push(compartment);
|
||||
} else {
|
||||
addons[compartment.addonId] = {
|
||||
time: compartment.time,
|
||||
CPOWTime: compartment.CPOWTime,
|
||||
compartments: [compartment]
|
||||
};
|
||||
}
|
||||
}
|
||||
let dataDiv = document.getElementById("data");
|
||||
for (let addon in addons) {
|
||||
let el = document.createElement("tr");
|
||||
let name = document.createElement("td");
|
||||
let time = document.createElement("td");
|
||||
let cpow = document.createElement("td");
|
||||
name.className = "addon";
|
||||
time.className = "time";
|
||||
cpow.className = "cpow";
|
||||
name.textContent = addon;
|
||||
AddonManager.getAddonByID(addon, function(a) {
|
||||
if (a) {
|
||||
name.textContent = a.name;
|
||||
}
|
||||
});
|
||||
time.textContent = addons[addon].time +"μs";
|
||||
cpow.textContent = addons[addon].CPOWTime +"μs";
|
||||
el.appendChild(time);
|
||||
el.appendChild(cpow);
|
||||
el.appendChild(name);
|
||||
let div = document.createElement("tr");
|
||||
for (let comp of addons[addon].compartments) {
|
||||
let c = document.createElement("tr");
|
||||
let name = document.createElement("td");
|
||||
let time = document.createElement("td");
|
||||
let cpow = document.createElement("td");
|
||||
name.className = "addon";
|
||||
time.className = "time";
|
||||
cpow.className = "cpow";
|
||||
name.textContent = comp.label;
|
||||
time.textContent = comp.time +"μs";
|
||||
cpow.textContent = comp.CPOWTime +"μs";
|
||||
c.appendChild(time);
|
||||
c.appendChild(cpow);
|
||||
c.appendChild(name);
|
||||
div.appendChild(c);
|
||||
div.className = "details";
|
||||
}
|
||||
el.addEventListener("click", function() { div.style.display = (div.style.display != "block" ? "block" : "none"); });
|
||||
el.appendChild(div);
|
||||
dataDiv.appendChild(el);
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>about:compartments</title>
|
||||
<script type="text/javascript;version=1.8" src="chrome://global/content/aboutCompartments.js"></script>
|
||||
<style>
|
||||
td.addon {
|
||||
display: inline-block;
|
||||
width: 400px;
|
||||
}
|
||||
td.time {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
}
|
||||
td.cpow {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
}
|
||||
.header {
|
||||
font-weight: bold;
|
||||
}
|
||||
tr.details {
|
||||
font-weight: lighter;
|
||||
color: gray;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="go()">
|
||||
<table id="data">
|
||||
<tr class="header">
|
||||
<td class="time">time</td>
|
||||
<td class="cpow">time in CPOWs</td>
|
||||
<td class="addon">name</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
7
toolkit/components/aboutcompartments/jar.mn
Normal file
7
toolkit/components/aboutcompartments/jar.mn
Normal file
@ -0,0 +1,7 @@
|
||||
# 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/.
|
||||
|
||||
toolkit.jar:
|
||||
+ content/global/aboutCompartments.xhtml (content/aboutCompartments.xhtml)
|
||||
+ content/global/aboutCompartments.js (content/aboutCompartments.js)
|
23
toolkit/components/aboutcompartments/moz.build
Normal file
23
toolkit/components/aboutcompartments/moz.build
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
XPIDL_MODULE = 'compartments'
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsICompartmentInfo.idl',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsCompartmentInfo.cpp'
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsCompartmentInfo.h'
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
94
toolkit/components/aboutcompartments/nsCompartmentInfo.cpp
Normal file
94
toolkit/components/aboutcompartments/nsCompartmentInfo.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsCompartmentInfo.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsLiteralString.h"
|
||||
#include "nsCRTGlue.h"
|
||||
#include "nsIJSRuntimeService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
class nsCompartment : public nsICompartment {
|
||||
public:
|
||||
nsCompartment(nsAString& aCompartmentName, nsAString& aAddonId,
|
||||
uint64_t aTime, uint64_t aCPOWTime)
|
||||
: mCompartmentName(aCompartmentName), mAddonId(aAddonId), mTime(aTime), mCPOWTime(aCPOWTime) {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
/* readonly attribute wstring compartmentName; */
|
||||
NS_IMETHOD GetCompartmentName(nsAString& aCompartmentName){
|
||||
aCompartmentName.Assign(mCompartmentName);
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
/* readonly attribute unsigned long time; */
|
||||
NS_IMETHOD GetTime(uint64_t* aTime) {
|
||||
*aTime = mTime;
|
||||
return NS_OK;
|
||||
}
|
||||
/* readonly attribute wstring addon id; */
|
||||
NS_IMETHOD GetAddonId(nsAString& aAddonId){
|
||||
aAddonId.Assign(mAddonId);
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
/* readonly attribute unsigned long CPOW time; */
|
||||
NS_IMETHOD GetCPOWTime(uint64_t* aCPOWTime) {
|
||||
*aCPOWTime = mCPOWTime;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsString mCompartmentName;
|
||||
nsString mAddonId;
|
||||
uint64_t mTime;
|
||||
uint64_t mCPOWTime;
|
||||
virtual ~nsCompartment() {}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsCompartment, nsICompartment)
|
||||
NS_IMPL_ISUPPORTS(nsCompartmentInfo, nsICompartmentInfo)
|
||||
|
||||
nsCompartmentInfo::nsCompartmentInfo()
|
||||
{
|
||||
}
|
||||
|
||||
nsCompartmentInfo::~nsCompartmentInfo()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCompartmentInfo::GetCompartments(nsIArray** aCompartments)
|
||||
{
|
||||
JSRuntime* rt;
|
||||
nsCOMPtr<nsIJSRuntimeService> svc(do_GetService("@mozilla.org/js/xpc/RuntimeService;1"));
|
||||
NS_ENSURE_TRUE(svc, NS_ERROR_FAILURE);
|
||||
svc->GetRuntime(&rt);
|
||||
nsCOMPtr<nsIMutableArray> compartments = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
CompartmentStatsVector stats;
|
||||
if (!JS_GetCompartmentStats(rt, stats))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
size_t num = stats.length();
|
||||
for (size_t pos = 0; pos < num; pos++) {
|
||||
nsString addonId;
|
||||
if (stats[pos].addonId) {
|
||||
AssignJSFlatString(addonId, (JSFlatString*)stats[pos].addonId);
|
||||
} else {
|
||||
addonId.AssignLiteral("<non-addon>");
|
||||
}
|
||||
|
||||
uint32_t cpowTime = xpc::GetCompartmentCPOWMicroseconds(stats[pos].compartment);
|
||||
nsCString compartmentName(stats[pos].compartmentName);
|
||||
NS_ConvertUTF8toUTF16 name(compartmentName);
|
||||
compartments->AppendElement(new nsCompartment(name, addonId, stats[pos].time, cpowTime), false);
|
||||
}
|
||||
compartments.forget(aCompartments);
|
||||
return NS_OK;
|
||||
}
|
25
toolkit/components/aboutcompartments/nsCompartmentInfo.h
Normal file
25
toolkit/components/aboutcompartments/nsCompartmentInfo.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsCompartmentInfo_h
|
||||
#define nsCompartmentInfo_h
|
||||
|
||||
#include "nsICompartmentInfo.h"
|
||||
|
||||
class nsCompartmentInfo : public nsICompartmentInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICOMPARTMENTINFO
|
||||
|
||||
nsCompartmentInfo();
|
||||
|
||||
private:
|
||||
virtual ~nsCompartmentInfo();
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif
|
31
toolkit/components/aboutcompartments/nsICompartmentInfo.idl
Normal file
31
toolkit/components/aboutcompartments/nsICompartmentInfo.idl
Normal file
@ -0,0 +1,31 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-*/
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIArray.idl"
|
||||
|
||||
[scriptable, uuid(13dd4c09-ff11-4943-8dc2-d96eb69c963b)]
|
||||
interface nsICompartment : nsISupports {
|
||||
/* name of compartment */
|
||||
readonly attribute AString compartmentName;
|
||||
/* time spent executing code in this compartment in microseconds */
|
||||
readonly attribute unsigned long long time;
|
||||
/* the id of the addon associated with this compartment, or null */
|
||||
readonly attribute AString addonId;
|
||||
/* time spent processing CPOWs in microseconds */
|
||||
readonly attribute unsigned long long CPOWTime;
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(5795113a-39a1-4087-ba09-98b7d07d025a)]
|
||||
interface nsICompartmentInfo : nsISupports {
|
||||
nsIArray getCompartments();
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_COMPARTMENT_INFO_CID \
|
||||
{ 0x2d3c2f2d, 0x698d, 0x471d, \
|
||||
{ 0xba, 0x3e, 0x14, 0x44, 0xdd, 0x52, 0x1e, 0x29 } }
|
||||
%}
|
@ -3,7 +3,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
toolkit.jar:
|
||||
+ content/global/aboutCompartments.xhtml (content/aboutCompartments.xhtml)
|
||||
+ content/global/aboutMemory.js (content/aboutMemory.js)
|
||||
+ content/global/aboutMemory.xhtml (content/aboutMemory.xhtml)
|
||||
+ content/global/aboutMemory.css (content/aboutMemory.css)
|
||||
|
@ -10,6 +10,7 @@ if CONFIG['MOZ_ENABLE_XREMOTE']:
|
||||
|
||||
DIRS += [
|
||||
'aboutcache',
|
||||
'aboutcompartments',
|
||||
'aboutmemory',
|
||||
'addoncompat',
|
||||
'alerts',
|
||||
|
@ -50,6 +50,8 @@
|
||||
#include "nsThreadManager.h"
|
||||
#include "nsThreadPool.h"
|
||||
|
||||
#include "nsCompartmentInfo.h"
|
||||
|
||||
#include "xptinfo.h"
|
||||
#include "nsIInterfaceInfoManager.h"
|
||||
#include "xptiprivate.h"
|
||||
@ -234,6 +236,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMemoryInfoDumper)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStatusReporterManager, Init)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCompartmentInfo)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIOUtil)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSecurityConsoleMessage)
|
||||
|
@ -82,3 +82,4 @@
|
||||
COMPONENT(CYCLE_COLLECTOR_LOGGER, nsCycleCollectorLoggerConstructor)
|
||||
COMPONENT(MESSAGE_LOOP, nsMessageLoopConstructor)
|
||||
COMPONENT(STATUS_REPORTER_MANAGER, nsStatusReporterManagerConstructor)
|
||||
COMPONENT(COMPARTMENT_INFO, nsCompartmentInfoConstructor)
|
@ -90,6 +90,8 @@
|
||||
*/
|
||||
#define NS_MESSAGE_LOOP_CONTRACTID "@mozilla.org/message-loop;1"
|
||||
|
||||
#define NS_COMPARTMENT_INFO_CONTRACTID "@mozilla.org/compartment-info;1"
|
||||
|
||||
/**
|
||||
* The following are the CIDs and Contract IDs of the nsISupports wrappers for
|
||||
* primative types.
|
||||
|
Loading…
x
Reference in New Issue
Block a user