зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1245954 - Console StartTimer/StopTimer and IncrementCounter should run in the owning thread, r=bz
This commit is contained in:
Родитель
22cf864d75
Коммит
e20d589c0b
|
@ -84,6 +84,11 @@ public:
|
|||
: mMethodName(Console::MethodLog)
|
||||
, mPrivate(false)
|
||||
, mTimeStamp(JS_Now() / PR_USEC_PER_MSEC)
|
||||
, mStartTimerValue(0)
|
||||
, mStartTimerStatus(false)
|
||||
, mStopTimerDuration(0)
|
||||
, mStopTimerStatus(false)
|
||||
, mCountValue(MAX_PAGE_COUNTERS)
|
||||
, mIDType(eUnknown)
|
||||
, mOuterIDNumber(0)
|
||||
, mInnerIDNumber(0)
|
||||
|
@ -172,7 +177,34 @@ public:
|
|||
Console::MethodName mMethodName;
|
||||
bool mPrivate;
|
||||
int64_t mTimeStamp;
|
||||
DOMHighResTimeStamp mMonotonicTimer;
|
||||
|
||||
// These values are set in the owning thread and they contain the timestamp of
|
||||
// when the new timer has started, the name of it and the status of the
|
||||
// creation of it. If status is false, something went wrong. User
|
||||
// DOMHighResTimeStamp instead mozilla::TimeStamp because we use
|
||||
// monotonicTimer from Performance.now();
|
||||
// They will be set on the owning thread and never touched again on that
|
||||
// thread. They will be used on the main-thread in order to create a
|
||||
// ConsoleTimerStart dictionary when console.time() is used.
|
||||
DOMHighResTimeStamp mStartTimerValue;
|
||||
nsString mStartTimerLabel;
|
||||
bool mStartTimerStatus;
|
||||
|
||||
// These values are set in the owning thread and they contain the duration,
|
||||
// the name and the status of the StopTimer method. If status is false,
|
||||
// something went wrong. They will be set on the owning thread and never
|
||||
// touched again on that thread. They will be used on the main-thread in order
|
||||
// to create a ConsoleTimerEnd dictionary. This members are set when
|
||||
// console.timeEnd() is called.
|
||||
double mStopTimerDuration;
|
||||
nsString mStopTimerLabel;
|
||||
bool mStopTimerStatus;
|
||||
|
||||
// These 2 values are set by IncreaseCounter on the owning thread and they are
|
||||
// used on the main-thread by CreateCounterValue. These members are set when
|
||||
// console.count() is called.
|
||||
nsString mCountLabel;
|
||||
uint32_t mCountValue;
|
||||
|
||||
// The concept of outerID and innerID is misleading because when a
|
||||
// ConsoleCallData is created from a window, these are the window IDs, but
|
||||
|
@ -345,7 +377,7 @@ private:
|
|||
void
|
||||
RunWithWindow(nsPIDOMWindowInner* aWindow)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
AutoJSAPI jsapi;
|
||||
MOZ_ASSERT(aWindow);
|
||||
|
@ -367,7 +399,7 @@ private:
|
|||
void
|
||||
RunWindowless()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
WorkerPrivate* wp = mWorkerPrivate;
|
||||
while (wp->GetParent()) {
|
||||
|
@ -517,7 +549,7 @@ private:
|
|||
RunConsole(JSContext* aCx, nsPIDOMWindowOuter* aOuterWindow,
|
||||
nsPIDOMWindowInner* aInnerWindow) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
MOZ_ASSERT(mCallData->mCopiedArguments.IsEmpty());
|
||||
|
||||
// The windows have to run in parallel.
|
||||
|
@ -564,6 +596,8 @@ private:
|
|||
void
|
||||
ProcessCallData(JSContext* aCx)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
|
||||
JS::Rooted<JS::Value> argumentsValue(aCx);
|
||||
|
@ -658,7 +692,7 @@ private:
|
|||
RunConsole(JSContext* aCx, nsPIDOMWindowOuter* aOuterWindow,
|
||||
nsPIDOMWindowInner* aInnerWindow) override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
|
||||
|
@ -793,7 +827,7 @@ NS_IMETHODIMP
|
|||
Console::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
const char16_t* aData)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (strcmp(aTopic, "inner-window-destroyed")) {
|
||||
return NS_OK;
|
||||
|
@ -1120,6 +1154,8 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
|||
}
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp monotonicTimer;
|
||||
|
||||
// Monotonic timer for 'time' and 'timeEnd'
|
||||
if (aMethodName == MethodTime ||
|
||||
aMethodName == MethodTimeEnd ||
|
||||
|
@ -1133,7 +1169,7 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
|||
return;
|
||||
}
|
||||
|
||||
callData->mMonotonicTimer = performance->Now();
|
||||
monotonicTimer = performance->Now();
|
||||
|
||||
nsDocShell* docShell = static_cast<nsDocShell*>(mWindow->GetDocShell());
|
||||
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
|
||||
|
@ -1175,12 +1211,36 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
|||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
TimeDuration duration =
|
||||
mozilla::TimeStamp::Now() - workerPrivate->CreationTimeStamp();
|
||||
mozilla::TimeStamp::Now() - workerPrivate->NowBaseTimeStamp();
|
||||
|
||||
callData->mMonotonicTimer = duration.ToMilliseconds();
|
||||
monotonicTimer = duration.ToMilliseconds();
|
||||
}
|
||||
}
|
||||
|
||||
if (aMethodName == MethodTime && !aData.IsEmpty()) {
|
||||
callData->mStartTimerStatus = StartTimer(aCx, aData[0],
|
||||
monotonicTimer,
|
||||
callData->mStartTimerLabel,
|
||||
&callData->mStartTimerValue);
|
||||
}
|
||||
|
||||
else if (aMethodName == MethodTimeEnd && !aData.IsEmpty()) {
|
||||
callData->mStopTimerStatus = StopTimer(aCx, aData[0],
|
||||
monotonicTimer,
|
||||
callData->mStopTimerLabel,
|
||||
&callData->mStopTimerDuration);
|
||||
}
|
||||
|
||||
else if (aMethodName == MethodCount) {
|
||||
ConsoleStackEntry frame;
|
||||
if (callData->mTopStackFrame) {
|
||||
frame = *callData->mTopStackFrame;
|
||||
}
|
||||
|
||||
callData->mCountValue = IncreaseCounter(aCx, frame, aData,
|
||||
callData->mCountLabel);
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
|
@ -1244,7 +1304,7 @@ Console::ProcessCallData(ConsoleCallData* aData, JS::Handle<JSObject*> aGlobal,
|
|||
const Sequence<JS::Value>& aArguments)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ConsoleStackEntry frame;
|
||||
if (aData->mTopStackFrame) {
|
||||
|
@ -1322,15 +1382,20 @@ Console::ProcessCallData(ConsoleCallData* aData, JS::Handle<JSObject*> aGlobal,
|
|||
}
|
||||
|
||||
else if (aData->mMethodName == MethodTime && !aArguments.IsEmpty()) {
|
||||
event.mTimer = StartTimer(cx, aArguments[0], aData->mMonotonicTimer);
|
||||
event.mTimer = CreateStartTimerValue(cx, aData->mStartTimerLabel,
|
||||
aData->mStartTimerValue,
|
||||
aData->mStartTimerStatus);
|
||||
}
|
||||
|
||||
else if (aData->mMethodName == MethodTimeEnd && !aArguments.IsEmpty()) {
|
||||
event.mTimer = StopTimer(cx, aArguments[0], aData->mMonotonicTimer);
|
||||
event.mTimer = CreateStopTimerValue(cx, aData->mStopTimerLabel,
|
||||
aData->mStopTimerDuration,
|
||||
aData->mStopTimerStatus);
|
||||
}
|
||||
|
||||
else if (aData->mMethodName == MethodCount) {
|
||||
event.mCounter = IncreaseCounter(cx, frame, aArguments);
|
||||
event.mCounter = CreateCounterValue(cx, aData->mCountLabel,
|
||||
aData->mCountValue);
|
||||
}
|
||||
|
||||
// We want to create a console event object and pass it to our
|
||||
|
@ -1460,6 +1525,8 @@ Console::ProcessArguments(JSContext* aCx,
|
|||
Sequence<JS::Value>& aSequence,
|
||||
Sequence<JS::Value>& aStyles) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (aData.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1697,7 +1764,7 @@ void
|
|||
Console::MakeFormatString(nsCString& aFormat, int32_t aInteger,
|
||||
int32_t aMantissa, char aCh) const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
aFormat.Append('%');
|
||||
if (aInteger >= 0) {
|
||||
|
@ -1717,6 +1784,8 @@ Console::ComposeGroupName(JSContext* aCx,
|
|||
const Sequence<JS::Value>& aData,
|
||||
nsAString& aName) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
for (uint32_t i = 0; i < aData.Length(); ++i) {
|
||||
if (i != 0) {
|
||||
aName.AppendASCII(" ");
|
||||
|
@ -1737,13 +1806,50 @@ Console::ComposeGroupName(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
JS::Value
|
||||
bool
|
||||
Console::StartTimer(JSContext* aCx, const JS::Value& aName,
|
||||
DOMHighResTimeStamp aTimestamp)
|
||||
DOMHighResTimeStamp aTimestamp,
|
||||
nsAString& aTimerLabel,
|
||||
DOMHighResTimeStamp* aTimerValue)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aTimerValue);
|
||||
*aTimerValue = 0;
|
||||
|
||||
if (mTimerRegistry.Count() >= MAX_PAGE_TIMERS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> name(aCx, aName);
|
||||
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name));
|
||||
if (!jsString) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoJSString label;
|
||||
if (!label.init(aCx, jsString)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp entry;
|
||||
if (!mTimerRegistry.Get(label, &entry)) {
|
||||
mTimerRegistry.Put(label, aTimestamp);
|
||||
} else {
|
||||
aTimestamp = entry;
|
||||
}
|
||||
|
||||
aTimerLabel = label;
|
||||
*aTimerValue = aTimestamp;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Value
|
||||
Console::CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
||||
DOMHighResTimeStamp aTimerValue,
|
||||
bool aTimerStatus) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!aTimerStatus) {
|
||||
RootedDictionary<ConsoleTimerError> error(aCx);
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
|
@ -1756,27 +1862,8 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
|
|||
|
||||
RootedDictionary<ConsoleTimerStart> timer(aCx);
|
||||
|
||||
JS::Rooted<JS::Value> name(aCx, aName);
|
||||
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name));
|
||||
if (!jsString) {
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
nsAutoJSString key;
|
||||
if (!key.init(aCx, jsString)) {
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
timer.mName = key;
|
||||
|
||||
DOMHighResTimeStamp entry;
|
||||
if (!mTimerRegistry.Get(key, &entry)) {
|
||||
mTimerRegistry.Put(key, aTimestamp);
|
||||
} else {
|
||||
aTimestamp = entry;
|
||||
}
|
||||
|
||||
timer.mStarted = aTimestamp;
|
||||
timer.mName = aTimerLabel;
|
||||
timer.mStarted = aTimerValue;
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!ToJSValue(aCx, timer, &value)) {
|
||||
|
@ -1786,33 +1873,51 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
|
|||
return value;
|
||||
}
|
||||
|
||||
JS::Value
|
||||
bool
|
||||
Console::StopTimer(JSContext* aCx, const JS::Value& aName,
|
||||
DOMHighResTimeStamp aTimestamp)
|
||||
DOMHighResTimeStamp aTimestamp,
|
||||
nsAString& aTimerLabel,
|
||||
double* aTimerDuration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aTimerDuration);
|
||||
*aTimerDuration = 0;
|
||||
|
||||
JS::Rooted<JS::Value> name(aCx, aName);
|
||||
JS::Rooted<JSString*> jsString(aCx, JS::ToString(aCx, name));
|
||||
if (!jsString) {
|
||||
return JS::UndefinedValue();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoJSString key;
|
||||
if (!key.init(aCx, jsString)) {
|
||||
return JS::UndefinedValue();
|
||||
return false;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp entry;
|
||||
if (!mTimerRegistry.Get(key, &entry)) {
|
||||
return JS::UndefinedValue();
|
||||
return false;
|
||||
}
|
||||
|
||||
mTimerRegistry.Remove(key);
|
||||
|
||||
aTimerLabel = key;
|
||||
*aTimerDuration = aTimestamp - entry;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Value
|
||||
Console::CreateStopTimerValue(JSContext* aCx, const nsAString& aLabel,
|
||||
double aDuration, bool aStatus) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!aStatus) {
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
RootedDictionary<ConsoleTimerEnd> timer(aCx);
|
||||
timer.mName = key;
|
||||
timer.mDuration = aTimestamp - entry;
|
||||
timer.mName = aLabel;
|
||||
timer.mDuration = aDuration;
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!ToJSValue(aCx, timer, &value)) {
|
||||
|
@ -1826,6 +1931,8 @@ bool
|
|||
Console::ArgumentsToValueList(const Sequence<JS::Value>& aData,
|
||||
Sequence<JS::Value>& aSequence) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
for (uint32_t i = 0; i < aData.Length(); ++i) {
|
||||
if (!aSequence.AppendElement(aData[i], fallible)) {
|
||||
return false;
|
||||
|
@ -1835,12 +1942,11 @@ Console::ArgumentsToValueList(const Sequence<JS::Value>& aData,
|
|||
return true;
|
||||
}
|
||||
|
||||
JS::Value
|
||||
uint32_t
|
||||
Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
|
||||
const Sequence<JS::Value>& aArguments)
|
||||
const Sequence<JS::Value>& aArguments,
|
||||
nsAString& aCountLabel)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ClearException ce(aCx);
|
||||
|
||||
nsAutoString key;
|
||||
|
@ -1864,25 +1970,40 @@ Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
|
|||
}
|
||||
|
||||
uint32_t count = 0;
|
||||
if (!mCounterRegistry.Get(key, &count)) {
|
||||
if (mCounterRegistry.Count() >= MAX_PAGE_COUNTERS) {
|
||||
RootedDictionary<ConsoleCounterError> error(aCx);
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!ToJSValue(aCx, error, &value)) {
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
if (!mCounterRegistry.Get(key, &count) &&
|
||||
mCounterRegistry.Count() >= MAX_PAGE_COUNTERS) {
|
||||
return MAX_PAGE_COUNTERS;
|
||||
}
|
||||
|
||||
++count;
|
||||
mCounterRegistry.Put(key, count);
|
||||
|
||||
aCountLabel = label;
|
||||
return count;
|
||||
}
|
||||
|
||||
JS::Value
|
||||
Console::CreateCounterValue(JSContext* aCx, const nsAString& aCountLabel,
|
||||
uint32_t aCountValue) const
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
ClearException ce(aCx);
|
||||
|
||||
if (aCountValue == MAX_PAGE_COUNTERS) {
|
||||
RootedDictionary<ConsoleCounterError> error(aCx);
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!ToJSValue(aCx, error, &value)) {
|
||||
return JS::UndefinedValue();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
RootedDictionary<ConsoleCounter> data(aCx);
|
||||
data.mLabel = label;
|
||||
data.mCount = count;
|
||||
data.mLabel = aCountLabel;
|
||||
data.mCount = aCountValue;
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!ToJSValue(aCx, data, &value)) {
|
||||
|
@ -1909,7 +2030,7 @@ Console::ShouldIncludeStackTrace(MethodName aMethodName) const
|
|||
JSObject*
|
||||
Console::GetOrCreateSandbox(JSContext* aCx, nsIPrincipal* aPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (!mSandbox) {
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
|
|
|
@ -181,13 +181,67 @@ private:
|
|||
ComposeGroupName(JSContext* aCx, const Sequence<JS::Value>& aData,
|
||||
nsAString& aName) const;
|
||||
|
||||
JS::Value
|
||||
// StartTimer is called on the owning thread and populates aTimerLabel and
|
||||
// aTimerValue. It returns false if a JS exception is thrown or if
|
||||
// the max number of timers is reached.
|
||||
// * aCx - the JSContext rooting aName.
|
||||
// * aName - this is (should be) the name of the timer as JS::Value.
|
||||
// * aTimestamp - the monotonicTimer for this context (taken from
|
||||
// window->performance.now() or from Now() -
|
||||
// workerPrivate->NowBaseTimeStamp() in workers.
|
||||
// * aTimerLabel - This label will be populated with the aName converted to a
|
||||
// string.
|
||||
// * aTimerValue - the StartTimer value stored into (or taken from)
|
||||
// mTimerRegistry.
|
||||
bool
|
||||
StartTimer(JSContext* aCx, const JS::Value& aName,
|
||||
DOMHighResTimeStamp aTimestamp);
|
||||
DOMHighResTimeStamp aTimestamp,
|
||||
nsAString& aTimerLabel,
|
||||
DOMHighResTimeStamp* aTimerValue);
|
||||
|
||||
// CreateStartTimerValue is called on the main thread only and generates a
|
||||
// ConsoleTimerStart dictionary exposed as JS::Value. If aTimerStatus is
|
||||
// false, it generates a ConsoleTimerError instead. It's called only after
|
||||
// the execution StartTimer on the owning thread.
|
||||
// * aCx - this is the context that will root the returned value.
|
||||
// * aTimerLabel - this label must be what StartTimer received as aTimerLabel.
|
||||
// * aTimerValue - this is what StartTimer received as aTimerValue
|
||||
// * aTimerStatus - the return value of StartTimer.
|
||||
JS::Value
|
||||
CreateStartTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
||||
DOMHighResTimeStamp aTimerValue,
|
||||
bool aTimerStatus) const;
|
||||
|
||||
// StopTimer follows the same pattern as StartTimer: it runs on the
|
||||
// owning thread and populates aTimerLabel and aTimerDuration, used by
|
||||
// CreateStopTimerValue on the main thread. It returns false if a JS
|
||||
// exception is thrown or if the aName timer doesn't exist in mTimerRegistry.
|
||||
// * aCx - the JSContext rooting aName.
|
||||
// * aName - this is (should be) the name of the timer as JS::Value.
|
||||
// * aTimestamp - the monotonicTimer for this context (taken from
|
||||
// window->performance.now() or from Now() -
|
||||
// workerPrivate->NowBaseTimeStamp() in workers.
|
||||
// * aTimerLabel - This label will be populated with the aName converted to a
|
||||
// string.
|
||||
// * aTimerDuration - the difference between aTimestamp and when the timer
|
||||
// started (see StartTimer).
|
||||
bool
|
||||
StopTimer(JSContext* aCx, const JS::Value& aName,
|
||||
DOMHighResTimeStamp aTimestamp);
|
||||
DOMHighResTimeStamp aTimestamp,
|
||||
nsAString& aTimerLabel,
|
||||
double* aTimerDuration);
|
||||
|
||||
// Executed on the main thread and generates a ConsoleTimerEnd dictionary
|
||||
// exposed as JS::Value, or a ConsoleTimerError dictionary if aTimerStatus is
|
||||
// false. See StopTimer.
|
||||
// * aCx - this is the context that will root the returned value.
|
||||
// * aTimerLabel - this label must be what StopTimer received as aTimerLabel.
|
||||
// * aTimerDuration - this is what StopTimer received as aTimerDuration
|
||||
// * aTimerStatus - the return value of StopTimer.
|
||||
JS::Value
|
||||
CreateStopTimerValue(JSContext* aCx, const nsAString& aTimerLabel,
|
||||
double aTimerDuration,
|
||||
bool aTimerStatus) const;
|
||||
|
||||
// The method populates a Sequence from an array of JS::Value.
|
||||
bool
|
||||
|
@ -198,9 +252,29 @@ private:
|
|||
ProfileMethod(JSContext* aCx, const nsAString& aAction,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
JS::Value
|
||||
// This method follows the same pattern as StartTimer: its runs on the owning
|
||||
// thread and populates aCountLabel, used by CreateCounterValue on the
|
||||
// main thread. Returns MAX_PAGE_COUNTERS in case of error otherwise the
|
||||
// incremented counter value.
|
||||
// * aCx - the JSContext rooting aData.
|
||||
// * aFrame - the first frame of ConsoleCallData.
|
||||
// * aData - the arguments received by the console.count() method.
|
||||
// * aCountLabel - the label that will be populated by this method.
|
||||
uint32_t
|
||||
IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
|
||||
const Sequence<JS::Value>& aArguments);
|
||||
const Sequence<JS::Value>& aData,
|
||||
nsAString& aCountLabel);
|
||||
|
||||
// Executed on the main thread and generates a ConsoleCounter dictionary as
|
||||
// JS::Value. If aCountValue is == MAX_PAGE_COUNTERS it generates a
|
||||
// ConsoleCounterError instead. See IncreaseCounter.
|
||||
// * aCx - this is the context that will root the returned value.
|
||||
// * aCountLabel - this label must be what IncreaseCounter received as
|
||||
// aTimerLabel.
|
||||
// * aCountValue - the return value of IncreaseCounter.
|
||||
JS::Value
|
||||
CreateCounterValue(JSContext* aCx, const nsAString& aCountLabel,
|
||||
uint32_t aCountValue) const;
|
||||
|
||||
bool
|
||||
ShouldIncludeStackTrace(MethodName aMethodName) const;
|
||||
|
@ -214,15 +288,13 @@ private:
|
|||
void
|
||||
UnregisterConsoleCallData(ConsoleCallData* aData);
|
||||
|
||||
// All these nsCOMPtr are touched on main-thread only.
|
||||
// All these nsCOMPtr are touched on main thread only.
|
||||
nsCOMPtr<nsPIDOMWindowInner> mWindow;
|
||||
nsCOMPtr<nsIConsoleAPIStorage> mStorage;
|
||||
RefPtr<JSObjectHolder> mSandbox;
|
||||
|
||||
// Touched on main-thread only.
|
||||
// Touched on the owner thread.
|
||||
nsDataHashtable<nsStringHashKey, DOMHighResTimeStamp> mTimerRegistry;
|
||||
|
||||
// Touched on main-thread only.
|
||||
nsDataHashtable<nsStringHashKey, uint32_t> mCounterRegistry;
|
||||
|
||||
// Raw pointers because ConsoleCallData manages its own
|
||||
|
|
Загрузка…
Ссылка в новой задаче