Bug 1156264 - Activate/deactivate jank and CPOW monitoring separately (low-level). r=jandem

This commit is contained in:
David Rajchenbach-Teller 2015-06-04 13:12:07 +02:00
parent abf85e366c
commit 1ef717a2ba
7 changed files with 81 additions and 36 deletions

View File

@ -9,17 +9,31 @@
#include "nsContentUtils.h"
#include "CPOWTimer.h"
CPOWTimer::CPOWTimer(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: cx_(nullptr)
, startInterval_(0)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
JSRuntime* runtime = JS_GetRuntime(cx);
if (!js::GetStopwatchIsMonitoringCPOW(runtime))
return;
cx_ = cx;
startInterval_ = PR_IntervalNow();
}
CPOWTimer::~CPOWTimer()
{
JSContext* cx = nsContentUtils::GetCurrentJSContextForThread();
if (!cx)
if (!cx_) {
// Monitoring was off when we started the timer.
return;
}
JSRuntime* runtime = JS_GetRuntime(cx);
if (!js::IsStopwatchActive(runtime))
JSRuntime* runtime = JS_GetRuntime(cx_);
if (!js::GetStopwatchIsMonitoringCPOW(runtime)) {
// Monitoring has been deactivated while we were in the timer.
return;
}
js::PerformanceData* performance = js::GetPerformanceData(runtime);
uint64_t duration = PR_IntervalToMicroseconds(PR_IntervalNow() - startInterval);
uint64_t duration = PR_IntervalToMicroseconds(PR_IntervalNow() - startInterval_);
performance->totalCPOWTime += duration;
}

View File

@ -9,6 +9,7 @@
#define CPOWTIMER_H
#include "prinrval.h"
#include "jsapi.h"
/**
* A stopwatch measuring the duration of a CPOW call.
@ -21,20 +22,23 @@
*/
class MOZ_STACK_CLASS CPOWTimer final {
public:
explicit inline CPOWTimer(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
: startInterval(PR_IntervalNow())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
explicit inline CPOWTimer(JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
~CPOWTimer();
private:
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
/**
* The instant at which the stopwatch was started.
* The context in which this timer was created, or `nullptr` if
* CPOW monitoring was off when the timer was created.
*/
PRIntervalTime startInterval;
JSContext* cx_;
/**
* The instant at which the stopwatch was started. Undefined
* if CPOW monitoring was off when the timer was created.
*/
PRIntervalTime startInterval_;
};
#endif

View File

@ -149,7 +149,7 @@ const CPOWProxyHandler CPOWProxyHandler::singleton;
return false; \
} \
{ \
CPOWTimer timer; \
CPOWTimer timer(cx); \
return owner->call args; \
}

View File

@ -5561,11 +5561,19 @@ ResetStopwatches(JSRuntime*);
/**
* Turn on/off stopwatch-based CPU monitoring.
*
* `SetStopwatchActive` may return `false` if monitoring could not be
* activated, which may happen if we are out of memory.
* `SetStopwatchIsMonitoringCPOW` or `SetStopwatchIsMonitoringJank`
* may return `false` if monitoring could not be activated, which may
* happen if we are out of memory.
*/
extern JS_PUBLIC_API(bool)
SetStopwatchActive(JSRuntime*, bool);
SetStopwatchIsMonitoringCPOW(JSRuntime*, bool);
extern JS_PUBLIC_API(bool)
GetStopwatchIsMonitoringCPOW(JSRuntime*);
extern JS_PUBLIC_API(bool)
SetStopwatchIsMonitoringJank(JSRuntime*, bool);
extern JS_PUBLIC_API(bool)
GetStopwatchIsMonitoringJank(JSRuntime*);
extern JS_PUBLIC_API(bool)
IsStopwatchActive(JSRuntime*);

View File

@ -396,12 +396,13 @@ struct AutoStopwatch final
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
JSRuntime* runtime = JS_GetRuntime(cx_);
if (!runtime->stopwatch.isActive())
if (!runtime->stopwatch.isMonitoringJank())
return;
JSCompartment* compartment = cx_->compartment();
if (compartment->scheduledForDestruction)
return;
iteration_ = runtime->stopwatch.iteration;
PerformanceGroup *group = compartment->performanceMonitoring.getGroup(cx);
@ -444,7 +445,7 @@ struct AutoStopwatch final
MOZ_ASSERT(!compartment->scheduledForDestruction);
if (!runtime->stopwatch.isActive()) {
if (!runtime->stopwatch.isMonitoringJank()) {
// Monitoring has been stopped while we were
// executing the code. Drop everything.
return;

View File

@ -879,17 +879,25 @@ js::ResetStopwatches(JSRuntime* rt)
}
bool
js::SetStopwatchActive(JSRuntime* rt, bool isActive)
js::SetStopwatchIsMonitoringJank(JSRuntime* rt, bool value)
{
MOZ_ASSERT(rt);
return rt->stopwatch.setIsActive(isActive);
return rt->stopwatch.setIsMonitoringJank(value);
}
bool
js::GetStopwatchIsMonitoringJank(JSRuntime* rt)
{
return rt->stopwatch.isMonitoringJank();
}
bool
js::IsStopwatchActive(JSRuntime* rt)
js::SetStopwatchIsMonitoringCPOW(JSRuntime* rt, bool value)
{
MOZ_ASSERT(rt);
return rt->stopwatch.isActive();
return rt->stopwatch.setIsMonitoringCPOW(value);
}
bool
js::GetStopwatchIsMonitoringCPOW(JSRuntime* rt)
{
return rt->stopwatch.isMonitoringCPOW();
}
js::PerformanceGroupHolder::~PerformanceGroupHolder()

View File

@ -1502,7 +1502,8 @@ struct JSRuntime : public JS::shadow::Runtime,
: iteration(0)
, isEmpty(true)
, currentPerfGroupCallback(nullptr)
, isActive_(false)
, isMonitoringJank_(false)
, isMonitoringCPOW_(false)
{ }
/**
@ -1516,9 +1517,8 @@ struct JSRuntime : public JS::shadow::Runtime,
++iteration;
isEmpty = true;
}
/**
* Activate/deactivate stopwatch measurement.
* Activate/deactivate stopwatch measurement of jank.
*
* Noop if `value` is `true` and the stopwatch is already active,
* or if `value` is `false` and the stopwatch is already inactive.
@ -1528,8 +1528,8 @@ struct JSRuntime : public JS::shadow::Runtime,
*
* May return `false` if the underlying hashtable cannot be allocated.
*/
bool setIsActive(bool value) {
if (isActive_ != value)
bool setIsMonitoringJank(bool value) {
if (isMonitoringJank_ != value)
reset();
if (value && !groups_.initialized()) {
@ -1537,15 +1537,24 @@ struct JSRuntime : public JS::shadow::Runtime,
return false;
}
isActive_ = value;
isMonitoringJank_ = value;
return true;
}
bool isMonitoringJank() const {
return isMonitoringJank_;
}
/**
* Activate/deactivate stopwatch measurement of CPOW.
*/
bool setIsMonitoringCPOW(bool value) {
isMonitoringCPOW_ = value;
return true;
}
/**
* `true` if the stopwatch is currently monitoring, `false` otherwise.
*/
bool isActive() const {
return isActive_;
bool isMonitoringCPOW() const {
return isMonitoringCPOW_;
}
// Some systems have non-monotonic clocks. While we cannot
@ -1596,7 +1605,8 @@ struct JSRuntime : public JS::shadow::Runtime,
/**
* `true` if stopwatch monitoring is active, `false` otherwise.
*/
bool isActive_;
bool isMonitoringJank_;
bool isMonitoringCPOW_;
};
Stopwatch stopwatch;
};