зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 00726df4997c (bug 1190074) for bustage on a CLOSED TREE
This commit is contained in:
Родитель
47e3ab6e7c
Коммит
9a0fd3701a
|
@ -368,12 +368,12 @@ IterPerformanceStats(JSContext* cx,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
js::AutoCompartment autoCompartment(cx, compartment);
|
js::AutoCompartment autoCompartment(cx, compartment);
|
||||||
mozilla::RefPtr<PerformanceGroup> ownGroup = compartment->performanceMonitoring.getOwnGroup();
|
PerformanceGroup* ownGroup = compartment->performanceMonitoring.getOwnGroup(cx);
|
||||||
if (ownGroup->data.ticks == 0) {
|
if (ownGroup->data.ticks == 0) {
|
||||||
// Don't report compartments that have never been used.
|
// Don't report compartments that have never been used.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mozilla::RefPtr<PerformanceGroup> sharedGroup = compartment->performanceMonitoring.getSharedGroup(cx);
|
PerformanceGroup* sharedGroup = compartment->performanceMonitoring.getSharedGroup(cx);
|
||||||
if (!(*walker)(cx,
|
if (!(*walker)(cx,
|
||||||
ownGroup->data, ownGroup->uid, &sharedGroup->uid,
|
ownGroup->data, ownGroup->uid, &sharedGroup->uid,
|
||||||
closure)) {
|
closure)) {
|
||||||
|
@ -383,7 +383,7 @@ IterPerformanceStats(JSContext* cx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, report the process stats
|
// Finally, report the process stats
|
||||||
*processStats = rt->stopwatch.performance.getOwnGroup()->data;
|
*processStats = rt->stopwatch.performance;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/Range.h"
|
#include "mozilla/Range.h"
|
||||||
#include "mozilla/RangedPtr.h"
|
#include "mozilla/RangedPtr.h"
|
||||||
#include "mozilla/RefPtr.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
@ -5515,22 +5514,15 @@ struct PerformanceGroup {
|
||||||
stopwatch_ = nullptr;
|
stopwatch_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refcounting. For use with mozilla::RefPtr.
|
explicit PerformanceGroup(JSContext* cx, void* key);
|
||||||
void AddRef();
|
~PerformanceGroup()
|
||||||
void Release();
|
{
|
||||||
|
MOZ_ASSERT(refCount_ == 0);
|
||||||
// Construct a PerformanceGroup for a single compartment.
|
}
|
||||||
explicit PerformanceGroup(JSRuntime* rt);
|
private:
|
||||||
|
|
||||||
// Construct a PerformanceGroup for a group of compartments.
|
|
||||||
explicit PerformanceGroup(JSContext* rt, void* key);
|
|
||||||
|
|
||||||
private:
|
|
||||||
PerformanceGroup& operator=(const PerformanceGroup&) = delete;
|
PerformanceGroup& operator=(const PerformanceGroup&) = delete;
|
||||||
PerformanceGroup(const PerformanceGroup&) = delete;
|
PerformanceGroup(const PerformanceGroup&) = delete;
|
||||||
|
|
||||||
JSRuntime* runtime_;
|
|
||||||
|
|
||||||
// The stopwatch currently monitoring the group,
|
// The stopwatch currently monitoring the group,
|
||||||
// or `nullptr` if none. Used ony for comparison.
|
// or `nullptr` if none. Used ony for comparison.
|
||||||
const AutoStopwatch* stopwatch_;
|
const AutoStopwatch* stopwatch_;
|
||||||
|
@ -5542,14 +5534,20 @@ private:
|
||||||
// The hash key for this PerformanceGroup.
|
// The hash key for this PerformanceGroup.
|
||||||
void* const key_;
|
void* const key_;
|
||||||
|
|
||||||
// A reference counter.
|
// Increment/decrement the refcounter, return the updated value.
|
||||||
|
uint64_t incRefCount() {
|
||||||
|
MOZ_ASSERT(refCount_ + 1 > 0);
|
||||||
|
return ++refCount_;
|
||||||
|
}
|
||||||
|
uint64_t decRefCount() {
|
||||||
|
MOZ_ASSERT(refCount_ > 0);
|
||||||
|
return --refCount_;
|
||||||
|
}
|
||||||
|
friend struct PerformanceGroupHolder;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// A reference counter. Maintained by PerformanceGroupHolder.
|
||||||
uint64_t refCount_;
|
uint64_t refCount_;
|
||||||
|
|
||||||
|
|
||||||
// `true` if this PerformanceGroup may be shared by several
|
|
||||||
// compartments, `false` if it is dedicated to a single
|
|
||||||
// compartment.
|
|
||||||
const bool isSharedGroup_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -5566,7 +5564,7 @@ struct PerformanceGroupHolder {
|
||||||
js::PerformanceGroup* getSharedGroup(JSContext*);
|
js::PerformanceGroup* getSharedGroup(JSContext*);
|
||||||
|
|
||||||
// Get the own group.
|
// Get the own group.
|
||||||
js::PerformanceGroup* getOwnGroup();
|
js::PerformanceGroup* getOwnGroup(JSContext*);
|
||||||
|
|
||||||
// `true` if the this holder is currently associated to a shared
|
// `true` if the this holder is currently associated to a shared
|
||||||
// PerformanceGroup, `false` otherwise. Use this method to avoid
|
// PerformanceGroup, `false` otherwise. Use this method to avoid
|
||||||
|
@ -5586,6 +5584,8 @@ struct PerformanceGroupHolder {
|
||||||
|
|
||||||
explicit PerformanceGroupHolder(JSRuntime* runtime)
|
explicit PerformanceGroupHolder(JSRuntime* runtime)
|
||||||
: runtime_(runtime)
|
: runtime_(runtime)
|
||||||
|
, sharedGroup_(nullptr)
|
||||||
|
, ownGroup_(nullptr)
|
||||||
{ }
|
{ }
|
||||||
~PerformanceGroupHolder();
|
~PerformanceGroupHolder();
|
||||||
|
|
||||||
|
@ -5600,8 +5600,8 @@ struct PerformanceGroupHolder {
|
||||||
// The PerformanceGroups held by this object.
|
// The PerformanceGroups held by this object.
|
||||||
// Initially set to `nullptr` until the first call to `getGroup`.
|
// Initially set to `nullptr` until the first call to `getGroup`.
|
||||||
// May be reset to `nullptr` by a call to `unlink`.
|
// May be reset to `nullptr` by a call to `unlink`.
|
||||||
mozilla::RefPtr<js::PerformanceGroup> sharedGroup_;
|
js::PerformanceGroup* sharedGroup_;
|
||||||
mozilla::RefPtr<js::PerformanceGroup> ownGroup_;
|
js::PerformanceGroup* ownGroup_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -389,6 +389,22 @@ class AutoStopwatch final
|
||||||
// loop. Used only for comparison.
|
// loop. Used only for comparison.
|
||||||
uint64_t iteration_;
|
uint64_t iteration_;
|
||||||
|
|
||||||
|
// `true` if this object is currently used to monitor performance
|
||||||
|
// for a shared PerformanceGroup, `false` otherwise, i.e. if the
|
||||||
|
// stopwatch mechanism is off or if another stopwatch is already
|
||||||
|
// in charge of monitoring for the same PerformanceGroup.
|
||||||
|
bool isMonitoringForGroup_;
|
||||||
|
|
||||||
|
// `true` if this object is currently used to monitor performance
|
||||||
|
// for a single compartment, `false` otherwise, i.e. if the
|
||||||
|
// stopwatch mechanism is off or if another stopwatch is already
|
||||||
|
// in charge of monitoring for the same PerformanceGroup.
|
||||||
|
bool isMonitoringForSelf_;
|
||||||
|
|
||||||
|
// `true` if this stopwatch is the topmost stopwatch on the stack
|
||||||
|
// for this event, `false` otherwise.
|
||||||
|
bool isMonitoringForTop_;
|
||||||
|
|
||||||
// `true` if we are monitoring jank, `false` otherwise.
|
// `true` if we are monitoring jank, `false` otherwise.
|
||||||
bool isMonitoringJank_;
|
bool isMonitoringJank_;
|
||||||
// `true` if we are monitoring CPOW, `false` otherwise.
|
// `true` if we are monitoring CPOW, `false` otherwise.
|
||||||
|
@ -399,20 +415,6 @@ class AutoStopwatch final
|
||||||
uint64_t systemTimeStart_;
|
uint64_t systemTimeStart_;
|
||||||
uint64_t CPOWTimeStart_;
|
uint64_t CPOWTimeStart_;
|
||||||
|
|
||||||
// The performance group shared by this compartment and possibly
|
|
||||||
// others, or `nullptr` if another AutoStopwatch is already in
|
|
||||||
// charge of monitoring that group.
|
|
||||||
mozilla::RefPtr<js::PerformanceGroup> sharedGroup_;
|
|
||||||
|
|
||||||
// The toplevel group, representing the entire process, or `nullptr`
|
|
||||||
// if another AutoStopwatch is already in charge of monitoring that group.
|
|
||||||
mozilla::RefPtr<js::PerformanceGroup> topGroup_;
|
|
||||||
|
|
||||||
// The performance group specific to this compartment, or
|
|
||||||
// `nullptr` if another AutoStopwatch is already in charge of
|
|
||||||
// monitoring that group.
|
|
||||||
mozilla::RefPtr<js::PerformanceGroup> ownGroup_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// If the stopwatch is active, constructing an instance of
|
// If the stopwatch is active, constructing an instance of
|
||||||
// AutoStopwatch causes it to become the current owner of the
|
// AutoStopwatch causes it to become the current owner of the
|
||||||
|
@ -422,6 +424,9 @@ class AutoStopwatch final
|
||||||
explicit inline AutoStopwatch(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
explicit inline AutoStopwatch(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: cx_(cx)
|
: cx_(cx)
|
||||||
, iteration_(0)
|
, iteration_(0)
|
||||||
|
, isMonitoringForGroup_(false)
|
||||||
|
, isMonitoringForSelf_(false)
|
||||||
|
, isMonitoringForTop_(false)
|
||||||
, isMonitoringJank_(false)
|
, isMonitoringJank_(false)
|
||||||
, isMonitoringCPOW_(false)
|
, isMonitoringCPOW_(false)
|
||||||
, userTimeStart_(0)
|
, userTimeStart_(0)
|
||||||
|
@ -437,23 +442,52 @@ class AutoStopwatch final
|
||||||
JSRuntime* runtime = cx_->runtime();
|
JSRuntime* runtime = cx_->runtime();
|
||||||
iteration_ = runtime->stopwatch.iteration;
|
iteration_ = runtime->stopwatch.iteration;
|
||||||
|
|
||||||
sharedGroup_ = acquireGroup(compartment->performanceMonitoring.getSharedGroup(cx));
|
PerformanceGroup* sharedGroup = compartment->performanceMonitoring.getSharedGroup(cx);
|
||||||
if (sharedGroup_)
|
if (!sharedGroup) {
|
||||||
topGroup_ = acquireGroup(runtime->stopwatch.performance.getOwnGroup());
|
// Either this Runtime is not configured for Performance Monitoring, or we couldn't
|
||||||
|
// allocate the group, or there was a problem with the hashtable.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (runtime->stopwatch.isMonitoringPerCompartment())
|
if (!sharedGroup->hasStopwatch(iteration_)) {
|
||||||
ownGroup_ = acquireGroup(compartment->performanceMonitoring.getOwnGroup());
|
// 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.
|
||||||
|
sharedGroup->acquireStopwatch(iteration_, this);
|
||||||
|
isMonitoringForGroup_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sharedGroup_ && !ownGroup_) {
|
PerformanceGroup* ownGroup = nullptr;
|
||||||
|
if (runtime->stopwatch.isMonitoringPerCompartment()) {
|
||||||
|
// As above, but for the group representing just this compartment.
|
||||||
|
ownGroup = compartment->performanceMonitoring.getOwnGroup(cx);
|
||||||
|
if (!ownGroup->hasStopwatch(iteration_)) {
|
||||||
|
ownGroup->acquireStopwatch(iteration_, this);
|
||||||
|
isMonitoringForSelf_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
isMonitoringForTop_ = true;
|
||||||
|
|
||||||
|
MOZ_ASSERT(isMonitoringForGroup_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isMonitoringForGroup_ && !isMonitoringForSelf_) {
|
||||||
// We are not in charge of monitoring anything.
|
// We are not in charge of monitoring anything.
|
||||||
|
// (isMonitoringForTop_ implies isMonitoringForGroup_,
|
||||||
|
// so we do not need to check it)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enter();
|
enter();
|
||||||
}
|
}
|
||||||
~AutoStopwatch()
|
~AutoStopwatch() {
|
||||||
{
|
if (!isMonitoringForGroup_ && !isMonitoringForSelf_) {
|
||||||
if (!sharedGroup_ && !ownGroup_) {
|
|
||||||
// We are not in charge of monitoring anything.
|
// We are not in charge of monitoring anything.
|
||||||
// (isMonitoringForTop_ implies isMonitoringForGroup_,
|
// (isMonitoringForTop_ implies isMonitoringForGroup_,
|
||||||
// so we do not need to check it)
|
// so we do not need to check it)
|
||||||
|
@ -471,19 +505,31 @@ class AutoStopwatch final
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseGroup(sharedGroup_);
|
|
||||||
releaseGroup(topGroup_);
|
|
||||||
releaseGroup(ownGroup_);
|
|
||||||
|
|
||||||
// Finish and commit measures
|
// Finish and commit measures
|
||||||
exit();
|
exit();
|
||||||
|
|
||||||
|
// Now release groups.
|
||||||
|
if (isMonitoringForGroup_) {
|
||||||
|
PerformanceGroup* sharedGroup = compartment->performanceMonitoring.getSharedGroup(cx_);
|
||||||
|
MOZ_ASSERT(sharedGroup);
|
||||||
|
sharedGroup->releaseStopwatch(iteration_, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMonitoringForSelf_) {
|
||||||
|
PerformanceGroup* ownGroup = compartment->performanceMonitoring.getOwnGroup(cx_);
|
||||||
|
MOZ_ASSERT(ownGroup);
|
||||||
|
ownGroup->releaseStopwatch(iteration_, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMonitoringForTop_)
|
||||||
|
runtime->stopwatch.isEmpty = true;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void enter() {
|
void enter() {
|
||||||
JSRuntime* runtime = cx_->runtime();
|
JSRuntime* runtime = cx_->runtime();
|
||||||
|
|
||||||
if (runtime->stopwatch.isMonitoringCPOW()) {
|
if (runtime->stopwatch.isMonitoringCPOW()) {
|
||||||
CPOWTimeStart_ = runtime->stopwatch.performance.getOwnGroup()->data.totalCPOWTime;
|
CPOWTimeStart_ = runtime->stopwatch.performance.totalCPOWTime;
|
||||||
isMonitoringCPOW_ = true;
|
isMonitoringCPOW_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,54 +563,46 @@ class AutoStopwatch final
|
||||||
uint64_t CPOWTimeDelta = 0;
|
uint64_t CPOWTimeDelta = 0;
|
||||||
if (isMonitoringCPOW_ && runtime->stopwatch.isMonitoringCPOW()) {
|
if (isMonitoringCPOW_ && runtime->stopwatch.isMonitoringCPOW()) {
|
||||||
// We were monitoring CPOW when we entered and we still are.
|
// We were monitoring CPOW when we entered and we still are.
|
||||||
CPOWTimeDelta = runtime->stopwatch.performance.getOwnGroup()->data.totalCPOWTime - CPOWTimeStart_;
|
CPOWTimeDelta = runtime->stopwatch.performance.totalCPOWTime - CPOWTimeStart_;
|
||||||
|
|
||||||
}
|
}
|
||||||
commitDeltasToGroups(userTimeDelta, systemTimeDelta, CPOWTimeDelta);
|
commitDeltasToGroups(userTimeDelta, systemTimeDelta, CPOWTimeDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to acquire a group
|
void commitDeltasToGroups(uint64_t userTimeDelta,
|
||||||
// If the group is `null` or if the group already has a stopwatch,
|
uint64_t systemTimeDelta,
|
||||||
// do nothing and return `null`.
|
uint64_t CPOWTimeDelta)
|
||||||
// Otherwise, bind the group to `this` for the current iteration
|
{
|
||||||
// and return `group`.
|
JSCompartment* compartment = cx_->compartment();
|
||||||
PerformanceGroup* acquireGroup(PerformanceGroup* group) {
|
|
||||||
if (!group)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
if (group->hasStopwatch(iteration_))
|
PerformanceGroup* sharedGroup = compartment->performanceMonitoring.getSharedGroup(cx_);
|
||||||
return nullptr;
|
MOZ_ASSERT(sharedGroup);
|
||||||
|
applyDeltas(userTimeDelta, systemTimeDelta, CPOWTimeDelta, sharedGroup->data);
|
||||||
|
|
||||||
group->acquireStopwatch(iteration_, this);
|
if (isMonitoringForSelf_) {
|
||||||
return group;
|
PerformanceGroup* ownGroup = compartment->performanceMonitoring.getOwnGroup(cx_);
|
||||||
|
MOZ_ASSERT(ownGroup);
|
||||||
|
applyDeltas(userTimeDelta, systemTimeDelta, CPOWTimeDelta, ownGroup->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMonitoringForTop_) {
|
||||||
|
JSRuntime* runtime = cx_->runtime();
|
||||||
|
applyDeltas(userTimeDelta, systemTimeDelta, CPOWTimeDelta, runtime->stopwatch.performance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release a group.
|
|
||||||
// Noop if `group` is null or if `this` is not the stopwatch
|
|
||||||
// of `group` for the current iteration.
|
|
||||||
void releaseGroup(PerformanceGroup* group) {
|
|
||||||
if (group)
|
|
||||||
group->releaseStopwatch(iteration_, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void commitDeltasToGroups(uint64_t userTimeDelta, uint64_t systemTimeDelta,
|
void applyDeltas(uint64_t userTimeDelta,
|
||||||
uint64_t CPOWTimeDelta) const {
|
uint64_t systemTimeDelta,
|
||||||
applyDeltas(userTimeDelta, systemTimeDelta, CPOWTimeDelta, sharedGroup_);
|
uint64_t CPOWTimeDelta,
|
||||||
applyDeltas(userTimeDelta, systemTimeDelta, CPOWTimeDelta, topGroup_);
|
PerformanceData& data) const {
|
||||||
applyDeltas(userTimeDelta, systemTimeDelta, CPOWTimeDelta, ownGroup_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void applyDeltas(uint64_t userTimeDelta, uint64_t systemTimeDelta,
|
data.ticks++;
|
||||||
uint64_t CPOWTimeDelta, PerformanceGroup* group) const {
|
|
||||||
if (!group)
|
|
||||||
return;
|
|
||||||
|
|
||||||
group->data.ticks++;
|
|
||||||
|
|
||||||
uint64_t totalTimeDelta = userTimeDelta + systemTimeDelta;
|
uint64_t totalTimeDelta = userTimeDelta + systemTimeDelta;
|
||||||
group->data.totalUserTime += userTimeDelta;
|
data.totalUserTime += userTimeDelta;
|
||||||
group->data.totalSystemTime += systemTimeDelta;
|
data.totalSystemTime += systemTimeDelta;
|
||||||
group->data.totalCPOWTime += CPOWTimeDelta;
|
data.totalCPOWTime += CPOWTimeDelta;
|
||||||
|
|
||||||
// Update an array containing the number of times we have missed
|
// Update an array containing the number of times we have missed
|
||||||
// at least 2^0 successive ms, 2^1 successive ms, ...
|
// at least 2^0 successive ms, 2^1 successive ms, ...
|
||||||
|
@ -574,10 +612,10 @@ class AutoStopwatch final
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
uint64_t duration = 1000;
|
uint64_t duration = 1000;
|
||||||
for (i = 0, duration = 1000;
|
for (i = 0, duration = 1000;
|
||||||
i < ArrayLength(group->data.durations) && duration < totalTimeDelta;
|
i < ArrayLength(data.durations) && duration < totalTimeDelta;
|
||||||
++i, duration *= 2)
|
++i, duration *= 2)
|
||||||
{
|
{
|
||||||
group->data.durations[i]++;
|
data.durations[i]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -222,8 +222,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
||||||
largeAllocationFailureCallback(nullptr),
|
largeAllocationFailureCallback(nullptr),
|
||||||
oomCallback(nullptr),
|
oomCallback(nullptr),
|
||||||
debuggerMallocSizeOf(ReturnZeroSize),
|
debuggerMallocSizeOf(ReturnZeroSize),
|
||||||
lastAnimationTime(0),
|
lastAnimationTime(0)
|
||||||
stopwatch(thisFromCtor())
|
|
||||||
{
|
{
|
||||||
setGCStoreBufferPtr(&gc.storeBuffer);
|
setGCStoreBufferPtr(&gc.storeBuffer);
|
||||||
|
|
||||||
|
@ -931,17 +930,40 @@ js::PerformanceGroupHolder::getHashKey(JSContext* cx)
|
||||||
void
|
void
|
||||||
js::PerformanceGroupHolder::unlink()
|
js::PerformanceGroupHolder::unlink()
|
||||||
{
|
{
|
||||||
ownGroup_ = nullptr;
|
if (ownGroup_) {
|
||||||
|
js_delete(ownGroup_);
|
||||||
|
ownGroup_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sharedGroup_) {
|
||||||
|
// The group has never been instantiated.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
js::PerformanceGroup* group = sharedGroup_;
|
||||||
sharedGroup_ = nullptr;
|
sharedGroup_ = nullptr;
|
||||||
|
|
||||||
|
if (group->decRefCount() > 0) {
|
||||||
|
// The group has at least another owner.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JSRuntime::Stopwatch::Groups::Ptr ptr =
|
||||||
|
runtime_->stopwatch.groups().lookup(group->key_);
|
||||||
|
MOZ_ASSERT(ptr);
|
||||||
|
runtime_->stopwatch.groups().remove(ptr);
|
||||||
|
js_delete(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceGroup*
|
PerformanceGroup*
|
||||||
js::PerformanceGroupHolder::getOwnGroup()
|
js::PerformanceGroupHolder::getOwnGroup(JSContext* cx)
|
||||||
{
|
{
|
||||||
if (ownGroup_)
|
if (ownGroup_)
|
||||||
return ownGroup_;
|
return ownGroup_;
|
||||||
|
|
||||||
return ownGroup_ = runtime_->new_<PerformanceGroup>(runtime_);
|
ownGroup_ = runtime_->new_<PerformanceGroup>(cx, nullptr);
|
||||||
|
return ownGroup_;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceGroup*
|
PerformanceGroup*
|
||||||
|
@ -963,58 +985,31 @@ js::PerformanceGroupHolder::getSharedGroup(JSContext* cx)
|
||||||
if (!sharedGroup_)
|
if (!sharedGroup_)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
runtime_->stopwatch.groups().add(ptr, key, sharedGroup_);
|
if (!runtime_->stopwatch.groups().add(ptr, key, sharedGroup_)) {
|
||||||
|
js_delete(sharedGroup_);
|
||||||
|
sharedGroup_ = nullptr;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sharedGroup_->incRefCount();
|
||||||
|
|
||||||
return sharedGroup_;
|
return sharedGroup_;
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceData*
|
PerformanceData*
|
||||||
js::GetPerformanceData(JSRuntime* rt)
|
js::GetPerformanceData(JSRuntime* rt)
|
||||||
{
|
{
|
||||||
return &rt->stopwatch.performance.getOwnGroup()->data;
|
return &rt->stopwatch.performance;
|
||||||
}
|
}
|
||||||
|
|
||||||
js::PerformanceGroup::PerformanceGroup(JSRuntime* rt)
|
js::PerformanceGroup::PerformanceGroup(JSContext* cx, void* key)
|
||||||
: uid(rt->stopwatch.uniqueId()),
|
: uid(cx->runtime()->stopwatch.uniqueId())
|
||||||
runtime_(rt),
|
, stopwatch_(nullptr)
|
||||||
stopwatch_(nullptr),
|
, iteration_(0)
|
||||||
iteration_(0),
|
, key_(key)
|
||||||
key_(nullptr),
|
, refCount_(0)
|
||||||
refCount_(0),
|
|
||||||
isSharedGroup_(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
js::PerformanceGroup::PerformanceGroup(JSContext* cx, void* key)
|
|
||||||
: uid(cx->runtime()->stopwatch.uniqueId()),
|
|
||||||
runtime_(cx->runtime()),
|
|
||||||
stopwatch_(nullptr),
|
|
||||||
iteration_(0),
|
|
||||||
key_(key),
|
|
||||||
refCount_(0),
|
|
||||||
isSharedGroup_(true)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
void
|
|
||||||
js::PerformanceGroup::AddRef()
|
|
||||||
{
|
{
|
||||||
++refCount_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
js::PerformanceGroup::Release()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(refCount_ > 0);
|
|
||||||
--refCount_;
|
|
||||||
if (refCount_ > 0)
|
|
||||||
return;
|
|
||||||
if (!isSharedGroup_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
JSRuntime::Stopwatch::Groups::Ptr ptr = runtime_->stopwatch.groups().lookup(key_);
|
|
||||||
MOZ_ASSERT(ptr);
|
|
||||||
runtime_->stopwatch.groups().remove(ptr);
|
|
||||||
js_delete(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1512,11 +1512,6 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
return groups_;
|
return groups_;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Performance data on the entire runtime.
|
|
||||||
*/
|
|
||||||
js::PerformanceGroupHolder performance;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of times we have entered the event loop.
|
* The number of times we have entered the event loop.
|
||||||
* Used to reset counters whenever we enter the loop,
|
* Used to reset counters whenever we enter the loop,
|
||||||
|
@ -1528,6 +1523,17 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
*/
|
*/
|
||||||
uint64_t iteration;
|
uint64_t iteration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `true` if no stopwatch has been registered for the
|
||||||
|
* current run of the event loop, `false` until then.
|
||||||
|
*/
|
||||||
|
bool isEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performance data on the entire runtime.
|
||||||
|
*/
|
||||||
|
js::PerformanceData performance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback used to ask the embedding to determine in which
|
* Callback used to ask the embedding to determine in which
|
||||||
* Performance Group the current execution belongs. Typically, this is
|
* Performance Group the current execution belongs. Typically, this is
|
||||||
|
@ -1540,9 +1546,9 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
*/
|
*/
|
||||||
JSCurrentPerfGroupCallback currentPerfGroupCallback;
|
JSCurrentPerfGroupCallback currentPerfGroupCallback;
|
||||||
|
|
||||||
Stopwatch(JSRuntime* runtime)
|
Stopwatch()
|
||||||
: performance(runtime)
|
: iteration(0)
|
||||||
, iteration(0)
|
, isEmpty(true)
|
||||||
, currentPerfGroupCallback(nullptr)
|
, currentPerfGroupCallback(nullptr)
|
||||||
, isMonitoringJank_(false)
|
, isMonitoringJank_(false)
|
||||||
, isMonitoringCPOW_(false)
|
, isMonitoringCPOW_(false)
|
||||||
|
@ -1559,6 +1565,7 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
*/
|
*/
|
||||||
void reset() {
|
void reset() {
|
||||||
++iteration;
|
++iteration;
|
||||||
|
isEmpty = true;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Activate/deactivate stopwatch measurement of jank.
|
* Activate/deactivate stopwatch measurement of jank.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче