mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1149486 - Regroup PerformanceStats by window. r=jandem, r=bholley
This commit is contained in:
parent
0eb761fdef
commit
b92e139ab0
@ -274,9 +274,10 @@ JS_GetEmptyString(JSRuntime* rt)
|
||||
namespace js {
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
GetPerformanceStats(JSRuntime* rt,
|
||||
PerformanceStatsVector& stats,
|
||||
PerformanceStats& processStats)
|
||||
IterPerformanceStats(JSContext* cx,
|
||||
PerformanceStatsWalker walker,
|
||||
PerformanceData* processStats,
|
||||
void* closure)
|
||||
{
|
||||
// As a PerformanceGroup is typically associated to several
|
||||
// compartments, use a HashSet to make sure that we only report
|
||||
@ -289,13 +290,16 @@ GetPerformanceStats(JSRuntime* rt,
|
||||
return false;
|
||||
}
|
||||
|
||||
JSRuntime* rt = JS_GetRuntime(cx);
|
||||
for (CompartmentsIter c(rt, WithAtoms); !c.done(); c.next()) {
|
||||
JSCompartment* compartment = c.get();
|
||||
if (!compartment->performanceMonitoring.isLinked()) {
|
||||
// Don't report compartments that do not even have a PerformanceGroup.
|
||||
continue;
|
||||
}
|
||||
PerformanceGroup* group = compartment->performanceMonitoring.getGroup();
|
||||
|
||||
js::AutoCompartment autoCompartment(cx, compartment);
|
||||
PerformanceGroup* group = compartment->performanceMonitoring.getGroup(cx);
|
||||
|
||||
if (group->data.ticks == 0) {
|
||||
// Don't report compartments that have never been used.
|
||||
@ -308,38 +312,16 @@ GetPerformanceStats(JSRuntime* rt,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!stats.growBy(1)) {
|
||||
// Memory issue
|
||||
if (!(*walker)(cx, group->data, closure)) {
|
||||
// Issue in callback
|
||||
return false;
|
||||
}
|
||||
PerformanceStats* stat = &stats.back();
|
||||
stat->isSystem = compartment->isSystem();
|
||||
if (compartment->addonId)
|
||||
stat->addonId = compartment->addonId;
|
||||
|
||||
if (compartment->addonId || !compartment->isSystem()) {
|
||||
if (rt->compartmentNameCallback) {
|
||||
(*rt->compartmentNameCallback)(rt, compartment,
|
||||
stat->name,
|
||||
mozilla::ArrayLength(stat->name));
|
||||
} else {
|
||||
strcpy(stat->name, "<unknown>");
|
||||
}
|
||||
} else {
|
||||
strcpy(stat->name, "<platform>");
|
||||
}
|
||||
stat->performance = group->data;
|
||||
if (!set.add(ptr, group)) {
|
||||
// Memory issue
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(processStats.name, "<process>");
|
||||
processStats.addonId = nullptr;
|
||||
processStats.isSystem = true;
|
||||
processStats.performance = rt->stopwatch.performance;
|
||||
|
||||
*processStats = rt->stopwatch.performance;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -929,6 +911,7 @@ JSAutoCompartment::JSAutoCompartment(JSContext* cx, JSScript* target
|
||||
cx_->enterCompartment(target->compartment());
|
||||
}
|
||||
|
||||
|
||||
JSAutoCompartment::~JSAutoCompartment()
|
||||
{
|
||||
cx_->leaveCompartment(oldCompartment_);
|
||||
|
@ -720,6 +720,18 @@ typedef void
|
||||
(* JSCompartmentNameCallback)(JSRuntime* rt, JSCompartment* compartment,
|
||||
char* buf, size_t bufsize);
|
||||
|
||||
/**
|
||||
* Callback used to ask the embedding to determine in which
|
||||
* Performance Group the current execution belongs. Typically, this is
|
||||
* used to regroup JSCompartments from several iframes from the same
|
||||
* page or from several compartments of the same addon into a single
|
||||
* Performance Group.
|
||||
*
|
||||
* Returns an opaque key.
|
||||
*/
|
||||
typedef void*
|
||||
(* JSCurrentPerfGroupCallback)(JSContext*);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
static MOZ_ALWAYS_INLINE jsval
|
||||
@ -5446,9 +5458,10 @@ struct PerformanceGroup {
|
||||
stopwatch_ = nullptr;
|
||||
}
|
||||
|
||||
PerformanceGroup()
|
||||
explicit PerformanceGroup(void* key)
|
||||
: stopwatch_(nullptr)
|
||||
, iteration_(0)
|
||||
, key_(key)
|
||||
, refCount_(0)
|
||||
{ }
|
||||
~PerformanceGroup()
|
||||
@ -5467,6 +5480,9 @@ struct PerformanceGroup {
|
||||
// may safely overflow.
|
||||
uint64_t iteration_;
|
||||
|
||||
// The hash key for this PerformanceGroup.
|
||||
void* const key_;
|
||||
|
||||
// Increment/decrement the refcounter, return the updated value.
|
||||
uint64_t incRefCount() {
|
||||
MOZ_ASSERT(refCount_ + 1 > 0);
|
||||
@ -5478,7 +5494,7 @@ struct PerformanceGroup {
|
||||
}
|
||||
friend struct PerformanceGroupHolder;
|
||||
|
||||
private:
|
||||
private:
|
||||
// A reference counter. Maintained by PerformanceGroupHolder.
|
||||
uint64_t refCount_;
|
||||
};
|
||||
@ -5491,7 +5507,7 @@ struct PerformanceGroupHolder {
|
||||
// Get the group.
|
||||
// On first call, this causes a single Hashtable lookup.
|
||||
// Successive calls do not require further lookups.
|
||||
js::PerformanceGroup* getGroup();
|
||||
js::PerformanceGroup* getGroup(JSContext*);
|
||||
|
||||
// `true` if the this holder is currently associated to a
|
||||
// PerformanceGroup, `false` otherwise. Use this method to avoid
|
||||
@ -5506,9 +5522,8 @@ struct PerformanceGroupHolder {
|
||||
// (new values of `isSystem()`, `principals()` or `addonId`).
|
||||
void unlink();
|
||||
|
||||
PerformanceGroupHolder(JSRuntime* runtime, JSCompartment* compartment)
|
||||
explicit PerformanceGroupHolder(JSRuntime* runtime)
|
||||
: runtime_(runtime)
|
||||
, compartment_(compartment)
|
||||
, group_(nullptr)
|
||||
{ }
|
||||
~PerformanceGroupHolder();
|
||||
@ -5516,10 +5531,9 @@ private:
|
||||
// Return the key representing this PerformanceGroup in
|
||||
// Runtime::Stopwatch.
|
||||
// Do not deallocate the key.
|
||||
void* getHashKey();
|
||||
void* getHashKey(JSContext* cx);
|
||||
|
||||
JSRuntime* runtime_;
|
||||
JSCompartment* compartment_;
|
||||
JSRuntime *runtime_;
|
||||
|
||||
// The PerformanceGroup held by this object.
|
||||
// Initially set to `nullptr` until the first cal to `getGroup`.
|
||||
@ -5552,56 +5566,30 @@ IsStopwatchActive(JSRuntime*);
|
||||
extern JS_PUBLIC_API(PerformanceData*)
|
||||
GetPerformanceData(JSRuntime*);
|
||||
|
||||
typedef bool
|
||||
(PerformanceStatsWalker)(JSContext* cx, const PerformanceData& stats, void* closure);
|
||||
|
||||
/**
|
||||
* Performance statistics for a performance group (a process, an
|
||||
* add-on, a webpage, the built-ins or a special compartment).
|
||||
*/
|
||||
struct PerformanceStats {
|
||||
/**
|
||||
* If this group represents an add-on, the ID of the addon,
|
||||
* otherwise `nullptr`.
|
||||
*/
|
||||
JSAddonId* addonId;
|
||||
|
||||
/**
|
||||
* If this group represents a webpage, the process itself or a special
|
||||
* compartment, a human-readable name. Unspecified for add-ons.
|
||||
*/
|
||||
char name[1024];
|
||||
|
||||
/**
|
||||
* `true` if the group represents in system compartments, `false`
|
||||
* otherwise. A group may never contain both system and non-system
|
||||
* compartments.
|
||||
*/
|
||||
bool isSystem;
|
||||
|
||||
/**
|
||||
* Performance information.
|
||||
*/
|
||||
js::PerformanceData performance;
|
||||
|
||||
PerformanceStats()
|
||||
: addonId(nullptr)
|
||||
, isSystem(false)
|
||||
{
|
||||
name[0] = '\0';
|
||||
}
|
||||
};
|
||||
|
||||
typedef js::Vector<PerformanceStats, 0, js::SystemAllocPolicy> PerformanceStatsVector;
|
||||
|
||||
/**
|
||||
* Extract the performance statistics.
|
||||
*
|
||||
* After a successful call, `stats` holds the `PerformanceStats` for
|
||||
* all performance groups, and `global` holds a `PerformanceStats`
|
||||
* representing the entire process.
|
||||
* Note that before calling `walker`, we enter the corresponding context.
|
||||
*/
|
||||
extern JS_PUBLIC_API(bool)
|
||||
GetPerformanceStats(JSRuntime* rt, js::PerformanceStatsVector& stats, js::PerformanceStats& global);
|
||||
IterPerformanceStats(JSContext* cx, PerformanceStatsWalker* walker, js::PerformanceData* process, void* closure);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/**
|
||||
* Callback used to ask the embedding to determine in which
|
||||
* Performance Group a compartment belongs. Typically, this is used to
|
||||
* regroup JSCompartments from several iframes from the same page or
|
||||
* from several compartments of the same addon into a single
|
||||
* Performance Group.
|
||||
*
|
||||
* Returns an opaque key.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_SetCurrentPerfGroupCallback(JSRuntime *rt, JSCurrentPerfGroupCallback cb);
|
||||
|
||||
|
||||
#endif /* jsapi_h */
|
||||
|
@ -53,7 +53,7 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
|
||||
#endif
|
||||
global_(nullptr),
|
||||
enterCompartmentDepth(0),
|
||||
performanceMonitoring(runtime_, this),
|
||||
performanceMonitoring(runtime_),
|
||||
data(nullptr),
|
||||
objectMetadataCallback(nullptr),
|
||||
lastAnimationTime(0),
|
||||
|
@ -409,8 +409,7 @@ struct AutoStopwatch final
|
||||
//
|
||||
// Previous owner is restored upon destruction.
|
||||
explicit inline AutoStopwatch(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||
: compartment_(nullptr)
|
||||
, runtime_(nullptr)
|
||||
: cx_(cx)
|
||||
, iteration_(0)
|
||||
, isActive_(false)
|
||||
, isTop_(false)
|
||||
@ -419,16 +418,17 @@ struct AutoStopwatch final
|
||||
, CPOWTimeStart_(0)
|
||||
{
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
runtime_ = cx->runtime();
|
||||
if (!runtime_->stopwatch.isActive())
|
||||
return;
|
||||
compartment_ = cx->compartment();
|
||||
MOZ_ASSERT(compartment_);
|
||||
if (compartment_->scheduledForDestruction)
|
||||
return;
|
||||
iteration_ = runtime_->stopwatch.iteration;
|
||||
|
||||
PerformanceGroup* group = compartment_->performanceMonitoring.getGroup();
|
||||
JSRuntime* runtime = JS_GetRuntime(cx_);
|
||||
if (!runtime->stopwatch.isActive())
|
||||
return;
|
||||
|
||||
JSCompartment* compartment = cx_->compartment();
|
||||
if (compartment->scheduledForDestruction)
|
||||
return;
|
||||
iteration_ = runtime->stopwatch.iteration;
|
||||
|
||||
PerformanceGroup *group = compartment->performanceMonitoring.getGroup(cx);
|
||||
MOZ_ASSERT(group);
|
||||
|
||||
if (group->hasStopwatch(iteration_)) {
|
||||
@ -438,22 +438,22 @@ struct AutoStopwatch final
|
||||
}
|
||||
|
||||
// Start the stopwatch.
|
||||
if (!this->getTimes(&userTimeStart_, &systemTimeStart_))
|
||||
if (!this->getTimes(runtime, &userTimeStart_, &systemTimeStart_))
|
||||
return;
|
||||
isActive_ = true;
|
||||
CPOWTimeStart_ = runtime_->stopwatch.performance.totalCPOWTime;
|
||||
CPOWTimeStart_ = runtime->stopwatch.performance.totalCPOWTime;
|
||||
|
||||
// We are now in charge of monitoring this group for the tick,
|
||||
// until destruction of `this` or until we enter a nested event
|
||||
// loop and `iteration_` is incremented.
|
||||
group->acquireStopwatch(iteration_, this);
|
||||
|
||||
if (runtime_->stopwatch.isEmpty) {
|
||||
if (runtime->stopwatch.isEmpty) {
|
||||
// This is the topmost stopwatch on the stack.
|
||||
// It will be in charge of updating the per-process
|
||||
// performance data.
|
||||
runtime_->stopwatch.isEmpty = false;
|
||||
runtime_->stopwatch.performance.ticks++;
|
||||
runtime->stopwatch.isEmpty = false;
|
||||
runtime->stopwatch.performance.ticks++;
|
||||
isTop_ = true;
|
||||
}
|
||||
}
|
||||
@ -463,32 +463,35 @@ struct AutoStopwatch final
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!compartment_->scheduledForDestruction);
|
||||
JSRuntime* runtime = JS_GetRuntime(cx_);
|
||||
JSCompartment* compartment = cx_->compartment();
|
||||
|
||||
if (!runtime_->stopwatch.isActive()) {
|
||||
MOZ_ASSERT(!compartment->scheduledForDestruction);
|
||||
|
||||
if (!runtime->stopwatch.isActive()) {
|
||||
// Monitoring has been stopped while we were
|
||||
// executing the code. Drop everything.
|
||||
return;
|
||||
}
|
||||
|
||||
if (iteration_ != runtime_->stopwatch.iteration) {
|
||||
if (iteration_ != runtime->stopwatch.iteration) {
|
||||
// We have entered a nested event loop at some point.
|
||||
// Any information we may have is obsolete.
|
||||
return;
|
||||
}
|
||||
|
||||
PerformanceGroup* group = compartment_->performanceMonitoring.getGroup();
|
||||
PerformanceGroup *group = compartment->performanceMonitoring.getGroup(cx_);
|
||||
MOZ_ASSERT(group);
|
||||
|
||||
// Compute time spent.
|
||||
group->releaseStopwatch(iteration_, this);
|
||||
uint64_t userTimeEnd, systemTimeEnd;
|
||||
if (!this->getTimes(&userTimeEnd, &systemTimeEnd))
|
||||
if (!this->getTimes(runtime, &userTimeEnd, &systemTimeEnd))
|
||||
return;
|
||||
|
||||
uint64_t userTimeDelta = userTimeEnd - userTimeStart_;
|
||||
uint64_t systemTimeDelta = systemTimeEnd - systemTimeStart_;
|
||||
uint64_t CPOWTimeDelta = runtime_->stopwatch.performance.totalCPOWTime - CPOWTimeStart_;
|
||||
uint64_t CPOWTimeDelta = runtime->stopwatch.performance.totalCPOWTime - CPOWTimeStart_;
|
||||
group->data.totalUserTime += userTimeDelta;
|
||||
group->data.totalSystemTime += systemTimeDelta;
|
||||
group->data.totalCPOWTime += CPOWTimeDelta;
|
||||
@ -500,10 +503,10 @@ struct AutoStopwatch final
|
||||
if (isTop_) {
|
||||
// This is the topmost stopwatch on the stack.
|
||||
// Record the timing information.
|
||||
runtime_->stopwatch.performance.totalUserTime = userTimeEnd;
|
||||
runtime_->stopwatch.performance.totalSystemTime = systemTimeEnd;
|
||||
updateDurations(totalTimeDelta, runtime_->stopwatch.performance.durations);
|
||||
runtime_->stopwatch.isEmpty = true;
|
||||
runtime->stopwatch.performance.totalUserTime = userTimeEnd;
|
||||
runtime->stopwatch.performance.totalSystemTime = systemTimeEnd;
|
||||
updateDurations(totalTimeDelta, runtime->stopwatch.performance.durations);
|
||||
runtime->stopwatch.isEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -527,7 +530,7 @@ struct AutoStopwatch final
|
||||
// Get the OS-reported time spent in userland/systemland, in
|
||||
// microseconds. On most platforms, this data is per-thread,
|
||||
// but on some platforms we need to fall back to per-process.
|
||||
bool getTimes(uint64_t* userTime, uint64_t* systemTime) const {
|
||||
bool getTimes(JSRuntime* runtime, uint64_t* userTime, uint64_t* systemTime) const {
|
||||
MOZ_ASSERT(userTime);
|
||||
MOZ_ASSERT(systemTime);
|
||||
|
||||
@ -591,12 +594,12 @@ struct AutoStopwatch final
|
||||
kernelTimeInt.LowPart = kernelFileTime.dwLowDateTime;
|
||||
kernelTimeInt.HighPart = kernelFileTime.dwHighDateTime;
|
||||
// Convert 100 ns to 1 us, make sure that the result is monotonic
|
||||
*systemTime = runtime_-> stopwatch.systemTimeFix.monotonize(kernelTimeInt.QuadPart / 10);
|
||||
*systemTime = runtime->stopwatch.systemTimeFix.monotonize(kernelTimeInt.QuadPart / 10);
|
||||
|
||||
userTimeInt.LowPart = userFileTime.dwLowDateTime;
|
||||
userTimeInt.HighPart = userFileTime.dwHighDateTime;
|
||||
// Convert 100 ns to 1 us, make sure that the result is monotonic
|
||||
*userTime = runtime_-> stopwatch.userTimeFix.monotonize(userTimeInt.QuadPart / 10);
|
||||
*userTime = runtime->stopwatch.userTimeFix.monotonize(userTimeInt.QuadPart / 10);
|
||||
|
||||
#endif // defined(XP_MACOSX) || defined(XP_UNIX) || defined(XP_WIN)
|
||||
|
||||
@ -604,13 +607,9 @@ struct AutoStopwatch final
|
||||
}
|
||||
|
||||
private:
|
||||
// The compartment with which this object was initialized.
|
||||
// The context with which this object was initialized.
|
||||
// Non-null.
|
||||
JSCompartment* compartment_;
|
||||
|
||||
// The runtime with which this object was initialized.
|
||||
// Non-null.
|
||||
JSRuntime* runtime_;
|
||||
JSContext* const cx_;
|
||||
|
||||
// An indication of the number of times we have entered the event
|
||||
// loop. Used only for comparison.
|
||||
|
@ -898,15 +898,14 @@ js::PerformanceGroupHolder::~PerformanceGroupHolder()
|
||||
}
|
||||
|
||||
void*
|
||||
js::PerformanceGroupHolder::getHashKey()
|
||||
js::PerformanceGroupHolder::getHashKey(JSContext* cx)
|
||||
{
|
||||
return compartment_->isSystem() ?
|
||||
(void*)compartment_->addonId :
|
||||
(void*)JS_GetCompartmentPrincipals(compartment_);
|
||||
// This key may be `nullptr` if we have `isSystem() == true`
|
||||
// and `compartment_->addonId`. This is absolutely correct,
|
||||
// and this represents the `PerformanceGroup` used to track
|
||||
// the performance of the the platform compartments.
|
||||
if (runtime_->stopwatch.currentPerfGroupCallback) {
|
||||
return (*runtime_->stopwatch.currentPerfGroupCallback)(cx);
|
||||
}
|
||||
|
||||
// As a fallback, put everything in the same PerformanceGroup.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@ -927,26 +926,26 @@ js::PerformanceGroupHolder::unlink()
|
||||
|
||||
|
||||
JSRuntime::Stopwatch::Groups::Ptr ptr =
|
||||
runtime_->stopwatch.groups_.lookup(getHashKey());
|
||||
runtime_->stopwatch.groups_.lookup(group->key_);
|
||||
MOZ_ASSERT(ptr);
|
||||
runtime_->stopwatch.groups_.remove(ptr);
|
||||
js_delete(group);
|
||||
}
|
||||
|
||||
PerformanceGroup*
|
||||
js::PerformanceGroupHolder::getGroup()
|
||||
js::PerformanceGroupHolder::getGroup(JSContext* cx)
|
||||
{
|
||||
if (group_)
|
||||
return group_;
|
||||
|
||||
void* key = getHashKey();
|
||||
void* key = getHashKey(cx);
|
||||
JSRuntime::Stopwatch::Groups::AddPtr ptr =
|
||||
runtime_->stopwatch.groups_.lookupForAdd(key);
|
||||
if (ptr) {
|
||||
group_ = ptr->value();
|
||||
MOZ_ASSERT(group_);
|
||||
} else {
|
||||
group_ = runtime_->new_<PerformanceGroup>();
|
||||
group_ = runtime_->new_<PerformanceGroup>(key);
|
||||
runtime_->stopwatch.groups_.add(ptr, key, group_);
|
||||
}
|
||||
|
||||
@ -960,3 +959,9 @@ js::GetPerformanceData(JSRuntime* rt)
|
||||
{
|
||||
return &rt->stopwatch.performance;
|
||||
}
|
||||
|
||||
void
|
||||
JS_SetCurrentPerfGroupCallback(JSRuntime *rt, JSCurrentPerfGroupCallback cb)
|
||||
{
|
||||
rt->stopwatch.currentPerfGroupCallback = cb;
|
||||
}
|
||||
|
@ -1492,9 +1492,22 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||
*/
|
||||
js::PerformanceData performance;
|
||||
|
||||
/**
|
||||
* Callback used to ask the embedding to determine in which
|
||||
* Performance Group the current execution belongs. Typically, this is
|
||||
* used to regroup JSCompartments from several iframes from the same
|
||||
* page or from several compartments of the same addon into a single
|
||||
* Performance Group.
|
||||
*
|
||||
* May be `nullptr`, in which case we put all the JSCompartments
|
||||
* in the same PerformanceGroup.
|
||||
*/
|
||||
JSCurrentPerfGroupCallback currentPerfGroupCallback;
|
||||
|
||||
Stopwatch()
|
||||
: iteration(0)
|
||||
, isEmpty(true)
|
||||
, currentPerfGroupCallback(nullptr)
|
||||
, isActive_(false)
|
||||
{ }
|
||||
|
||||
|
@ -1779,6 +1779,20 @@ GetCompartmentName(JSCompartment* c, nsCString& name, int* anonymizeID,
|
||||
}
|
||||
}
|
||||
|
||||
extern void
|
||||
xpc::GetCurrentCompartmentName(JSContext* cx, nsCString& name)
|
||||
{
|
||||
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
|
||||
if (!global) {
|
||||
name.AssignLiteral("no global");
|
||||
return;
|
||||
}
|
||||
|
||||
JSCompartment* compartment = GetObjectCompartment(global);
|
||||
int anonymizeID = 0;
|
||||
GetCompartmentName(compartment, name, &anonymizeID, false);
|
||||
}
|
||||
|
||||
static int64_t
|
||||
JSMainRuntimeGCHeapDistinguishedAmount()
|
||||
{
|
||||
@ -3302,6 +3316,47 @@ static const JSWrapObjectCallbacks WrapObjectCallbacks = {
|
||||
xpc::WrapperFactory::PrepareForWrapping
|
||||
};
|
||||
|
||||
/**
|
||||
* Group JSCompartments into PerformanceGroups.
|
||||
*
|
||||
* - All JSCompartments from the same add-on belong to the same
|
||||
* PerformanceGroup.
|
||||
* - All JSCompartments from the same same webpage (including
|
||||
* frames) belong to the same PerformanceGroup.
|
||||
* - All other JSCompartments (normally, system add-ons)
|
||||
* belong to to a big uncategorized PerformanceGroup.
|
||||
*/
|
||||
static void*
|
||||
GetCurrentPerfGroupCallback(JSContext* cx) {
|
||||
RootedObject global(cx, CurrentGlobalOrNull(cx));
|
||||
if (!global) {
|
||||
// This can happen for the atom compartments, which is system
|
||||
// code.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSAddonId* addonId = AddonIdOfObject(global);
|
||||
if (addonId) {
|
||||
// If this is an add-on, use the id as key.
|
||||
return addonId;
|
||||
}
|
||||
|
||||
// If the compartment belongs to a webpage, use the address of the
|
||||
// topmost scriptable window, hence regrouping all frames of a
|
||||
// window.
|
||||
nsRefPtr<nsGlobalWindow> win = WindowOrNull(global);
|
||||
if (win) {
|
||||
nsCOMPtr<nsIDOMWindow> top;
|
||||
nsresult rv = win->GetScriptableTop(getter_AddRefs(top));
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
return top.get();
|
||||
}
|
||||
|
||||
// Otherwise, this is platform code, use `nullptr` as key.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
: CycleCollectedJSRuntime(nullptr, JS::DefaultHeapMaxBytes, JS::DefaultNurseryBytes),
|
||||
mJSContextStack(new XPCJSContextStack(this)),
|
||||
@ -3481,6 +3536,8 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
// Watch for the JS boolean options.
|
||||
ReloadPrefsCallback(nullptr, this);
|
||||
Preferences::RegisterCallback(ReloadPrefsCallback, JS_OPTIONS_DOT_STR, this);
|
||||
|
||||
JS_SetCurrentPerfGroupCallback(runtime, ::GetCurrentPerfGroupCallback);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -139,9 +139,6 @@ XrayAwareCalleeGlobal(JSObject* fun);
|
||||
void
|
||||
TraceXPCGlobal(JSTracer* trc, JSObject* obj);
|
||||
|
||||
uint64_t
|
||||
GetCompartmentCPOWMicroseconds(JSCompartment* compartment);
|
||||
|
||||
} /* namespace xpc */
|
||||
|
||||
namespace JS {
|
||||
@ -532,6 +529,12 @@ void
|
||||
DispatchScriptErrorEvent(nsPIDOMWindow* win, JSRuntime* rt, xpc::ErrorReport* xpcReport,
|
||||
JS::Handle<JS::Value> exception);
|
||||
|
||||
// Return a name for the compartment.
|
||||
// This function makes reasonable efforts to make this name both mostly human-readable
|
||||
// and unique. However, there are no guarantees of either property.
|
||||
extern void
|
||||
GetCurrentCompartmentName(JSContext*, nsCString& name);
|
||||
|
||||
} // namespace xpc
|
||||
|
||||
namespace mozilla {
|
||||
|
Loading…
Reference in New Issue
Block a user