Merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Razvan Maries 2019-01-21 19:50:56 +02:00
Родитель 599c8191cc d86ab4b794
Коммит 299b5e79f7
82 изменённых файлов: 480 добавлений и 455 удалений

Просмотреть файл

@ -10381,7 +10381,7 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel* aChannel,
// We're about to load a new page and it may take time before necko // We're about to load a new page and it may take time before necko
// gives back any data, so main thread might have a chance to process a // gives back any data, so main thread might have a chance to process a
// collector slice // collector slice
nsJSContext::MaybeRunNextCollectorSlice(this, JS::gcreason::DOCSHELL); nsJSContext::MaybeRunNextCollectorSlice(this, JS::GCReason::DOCSHELL);
// Success. Keep the initial ClientSource if it exists. // Success. Keep the initial ClientSource if it exists.
cleanupInitialClient.release(); cleanupInitialClient.release();

Просмотреть файл

@ -22,7 +22,7 @@ namespace mozilla {
namespace dom { namespace dom {
/* static */ void FuzzingFunctions::GarbageCollect(const GlobalObject&) { /* static */ void FuzzingFunctions::GarbageCollect(const GlobalObject&) {
nsJSContext::GarbageCollectNow(JS::gcreason::COMPONENT_UTILS, nsJSContext::GarbageCollectNow(JS::GCReason::COMPONENT_UTILS,
nsJSContext::NonIncrementalGC, nsJSContext::NonIncrementalGC,
nsJSContext::NonShrinkingGC); nsJSContext::NonShrinkingGC);
} }

Просмотреть файл

@ -1037,7 +1037,7 @@ NS_IMETHODIMP
nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener* aListener) { nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener* aListener) {
AUTO_PROFILER_LABEL("nsDOMWindowUtils::GarbageCollect", GCCC); AUTO_PROFILER_LABEL("nsDOMWindowUtils::GarbageCollect", GCCC);
nsJSContext::GarbageCollectNow(JS::gcreason::DOM_UTILS); nsJSContext::GarbageCollectNow(JS::GCReason::DOM_UTILS);
nsJSContext::CycleCollectNow(aListener); nsJSContext::CycleCollectNow(aListener);
return NS_OK; return NS_OK;
@ -1051,7 +1051,7 @@ nsDOMWindowUtils::CycleCollect(nsICycleCollectorListener* aListener) {
NS_IMETHODIMP NS_IMETHODIMP
nsDOMWindowUtils::RunNextCollectorTimer() { nsDOMWindowUtils::RunNextCollectorTimer() {
nsJSContext::RunNextCollectorTimer(JS::gcreason::DOM_WINDOW_UTILS); nsJSContext::RunNextCollectorTimer(JS::GCReason::DOM_WINDOW_UTILS);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -6006,10 +6006,11 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout,
nsJSUtils::ExecutionContext exec(aes.cx(), global); nsJSUtils::ExecutionContext exec(aes.cx(), global);
rv = exec.Compile(options, handler->GetHandlerText()); rv = exec.Compile(options, handler->GetHandlerText());
if (rv == NS_OK) { JS::Rooted<JSScript*> script(aes.cx(), exec.MaybeGetScript());
if (script) {
LoadedScript* initiatingScript = handler->GetInitiatingScript(); LoadedScript* initiatingScript = handler->GetInitiatingScript();
if (initiatingScript) { if (initiatingScript) {
initiatingScript->AssociateWithScript(exec.GetScript()); initiatingScript->AssociateWithScript(script);
} }
rv = exec.ExecScript(); rv = exec.ExecScript();

Просмотреть файл

@ -2495,7 +2495,7 @@ void nsGlobalWindowOuter::DetachFromDocShell() {
// When we're about to destroy a top level content window // When we're about to destroy a top level content window
// (for example a tab), we trigger a full GC by passing null as the last // (for example a tab), we trigger a full GC by passing null as the last
// param. We also trigger a full GC for chrome windows. // param. We also trigger a full GC for chrome windows.
nsJSContext::PokeGC(JS::gcreason::SET_DOC_SHELL, nsJSContext::PokeGC(JS::GCReason::SET_DOC_SHELL,
(mTopLevelOuterContentWindow || mIsChrome) (mTopLevelOuterContentWindow || mIsChrome)
? nullptr ? nullptr
: GetWrapperPreserveColor()); : GetWrapperPreserveColor());

Просмотреть файл

@ -324,12 +324,12 @@ nsJSEnvironmentObserver::Observe(nsISupports* aSubject, const char* aTopic,
// slow and it likely won't help us anyway. // slow and it likely won't help us anyway.
return NS_OK; return NS_OK;
} }
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE, nsJSContext::GarbageCollectNow(JS::GCReason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC, nsJSContext::NonIncrementalGC,
nsJSContext::ShrinkingGC); nsJSContext::ShrinkingGC);
nsJSContext::CycleCollectNow(); nsJSContext::CycleCollectNow();
if (NeedsGCAfterCC()) { if (NeedsGCAfterCC()) {
nsJSContext::GarbageCollectNow(JS::gcreason::MEM_PRESSURE, nsJSContext::GarbageCollectNow(JS::GCReason::MEM_PRESSURE,
nsJSContext::NonIncrementalGC, nsJSContext::NonIncrementalGC,
nsJSContext::ShrinkingGC); nsJSContext::ShrinkingGC);
} }
@ -577,7 +577,7 @@ nsJSContext::~nsJSContext() {
void nsJSContext::Destroy() { void nsJSContext::Destroy() {
if (mGCOnDestruction) { if (mGCOnDestruction) {
PokeGC(JS::gcreason::NSJSCONTEXT_DESTROY, mWindowProxy); PokeGC(JS::GCReason::NSJSCONTEXT_DESTROY, mWindowProxy);
} }
DropJSObjects(this); DropJSObjects(this);
@ -1079,17 +1079,17 @@ void nsJSContext::SetProcessingScriptTag(bool aFlag) {
void FullGCTimerFired(nsITimer* aTimer, void* aClosure) { void FullGCTimerFired(nsITimer* aTimer, void* aClosure) {
nsJSContext::KillFullGCTimer(); nsJSContext::KillFullGCTimer();
MOZ_ASSERT(!aClosure, "Don't pass a closure to FullGCTimerFired"); MOZ_ASSERT(!aClosure, "Don't pass a closure to FullGCTimerFired");
nsJSContext::GarbageCollectNow(JS::gcreason::FULL_GC_TIMER, nsJSContext::GarbageCollectNow(JS::GCReason::FULL_GC_TIMER,
nsJSContext::IncrementalGC); nsJSContext::IncrementalGC);
} }
// static // static
void nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason, void nsJSContext::GarbageCollectNow(JS::GCReason aReason,
IsIncremental aIncremental, IsIncremental aIncremental,
IsShrinking aShrinking, IsShrinking aShrinking,
int64_t aSliceMillis) { int64_t aSliceMillis) {
AUTO_PROFILER_LABEL_DYNAMIC_CSTR("nsJSContext::GarbageCollectNow", GCCC, AUTO_PROFILER_LABEL_DYNAMIC_CSTR("nsJSContext::GarbageCollectNow", GCCC,
JS::gcreason::ExplainReason(aReason)); JS::ExplainGCReason(aReason));
MOZ_ASSERT_IF(aSliceMillis, aIncremental == IncrementalGC); MOZ_ASSERT_IF(aSliceMillis, aIncremental == IncrementalGC);
@ -1113,7 +1113,7 @@ void nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL; JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL;
if (aIncremental == NonIncrementalGC || if (aIncremental == NonIncrementalGC ||
aReason == JS::gcreason::FULL_GC_TIMER) { aReason == JS::GCReason::FULL_GC_TIMER) {
sNeedsFullGC = true; sNeedsFullGC = true;
} }
@ -1139,7 +1139,7 @@ static void FinishAnyIncrementalGC() {
// We're in the middle of an incremental GC, so finish it. // We're in the middle of an incremental GC, so finish it.
JS::PrepareForIncrementalGC(jsapi.cx()); JS::PrepareForIncrementalGC(jsapi.cx());
JS::FinishIncrementalGC(jsapi.cx(), JS::gcreason::CC_FORCED); JS::FinishIncrementalGC(jsapi.cx(), JS::GCReason::CC_FORCED);
} }
} }
@ -1573,7 +1573,7 @@ void nsJSContext::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp); uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
if (NeedsGCAfterCC()) { if (NeedsGCAfterCC()) {
PokeGC(JS::gcreason::CC_WAITING, nullptr, PokeGC(JS::GCReason::CC_WAITING, nullptr,
NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration)); NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration));
} }
@ -1730,8 +1730,7 @@ bool InterSliceGCRunnerFired(TimeStamp aDeadline, void* aData) {
TimeDuration duration = sGCUnnotifiedTotalTime; TimeDuration duration = sGCUnnotifiedTotalTime;
uintptr_t reason = reinterpret_cast<uintptr_t>(aData); uintptr_t reason = reinterpret_cast<uintptr_t>(aData);
nsJSContext::GarbageCollectNow( nsJSContext::GarbageCollectNow(
aData ? static_cast<JS::gcreason::Reason>(reason) aData ? static_cast<JS::GCReason>(reason) : JS::GCReason::INTER_SLICE_GC,
: JS::gcreason::INTER_SLICE_GC,
nsJSContext::IncrementalGC, nsJSContext::NonShrinkingGC, budget); nsJSContext::IncrementalGC, nsJSContext::NonShrinkingGC, budget);
sGCUnnotifiedTotalTime = TimeDuration(); sGCUnnotifiedTotalTime = TimeDuration();
@ -1780,7 +1779,7 @@ void GCTimerFired(nsITimer* aTimer, void* aClosure) {
void ShrinkingGCTimerFired(nsITimer* aTimer, void* aClosure) { void ShrinkingGCTimerFired(nsITimer* aTimer, void* aClosure) {
nsJSContext::KillShrinkingGCTimer(); nsJSContext::KillShrinkingGCTimer();
sIsCompactingOnUserInactive = true; sIsCompactingOnUserInactive = true;
nsJSContext::GarbageCollectNow(JS::gcreason::USER_INACTIVE, nsJSContext::GarbageCollectNow(JS::GCReason::USER_INACTIVE,
nsJSContext::IncrementalGC, nsJSContext::IncrementalGC,
nsJSContext::ShrinkingGC); nsJSContext::ShrinkingGC);
} }
@ -1886,7 +1885,7 @@ uint32_t nsJSContext::CleanupsSinceLastGC() { return sCleanupsSinceLastGC; }
// collection we run on a long timer. // collection we run on a long timer.
// static // static
void nsJSContext::RunNextCollectorTimer(JS::gcreason::Reason aReason, void nsJSContext::RunNextCollectorTimer(JS::GCReason aReason,
mozilla::TimeStamp aDeadline) { mozilla::TimeStamp aDeadline) {
if (sShuttingDown) { if (sShuttingDown) {
return; return;
@ -1925,7 +1924,7 @@ void nsJSContext::RunNextCollectorTimer(JS::gcreason::Reason aReason,
// static // static
void nsJSContext::MaybeRunNextCollectorSlice(nsIDocShell* aDocShell, void nsJSContext::MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
JS::gcreason::Reason aReason) { JS::GCReason aReason) {
if (!aDocShell || !XRE_IsContentProcess()) { if (!aDocShell || !XRE_IsContentProcess()) {
return; return;
} }
@ -1972,8 +1971,7 @@ void nsJSContext::MaybeRunNextCollectorSlice(nsIDocShell* aDocShell,
} }
// static // static
void nsJSContext::PokeGC(JS::gcreason::Reason aReason, JSObject* aObj, void nsJSContext::PokeGC(JS::GCReason aReason, JSObject* aObj, int aDelay) {
int aDelay) {
if (sShuttingDown) { if (sShuttingDown) {
return; return;
} }
@ -1981,7 +1979,7 @@ void nsJSContext::PokeGC(JS::gcreason::Reason aReason, JSObject* aObj,
if (aObj) { if (aObj) {
JS::Zone* zone = JS::GetObjectZone(aObj); JS::Zone* zone = JS::GetObjectZone(aObj);
CycleCollectedJSRuntime::Get()->AddZoneWaitingForGC(zone); CycleCollectedJSRuntime::Get()->AddZoneWaitingForGC(zone);
} else if (aReason != JS::gcreason::CC_WAITING) { } else if (aReason != JS::GCReason::CC_WAITING) {
sNeedsFullGC = true; sNeedsFullGC = true;
} }

Просмотреть файл

@ -72,7 +72,7 @@ class nsJSContext : public nsIScriptContext {
// Setup all the statics etc - safe to call multiple times after Startup(). // Setup all the statics etc - safe to call multiple times after Startup().
static void EnsureStatics(); static void EnsureStatics();
static void GarbageCollectNow(JS::gcreason::Reason reason, static void GarbageCollectNow(JS::GCReason reason,
IsIncremental aIncremental = NonIncrementalGC, IsIncremental aIncremental = NonIncrementalGC,
IsShrinking aShrinking = NonShrinkingGC, IsShrinking aShrinking = NonShrinkingGC,
int64_t aSliceMillis = 0); int64_t aSliceMillis = 0);
@ -97,17 +97,16 @@ class nsJSContext : public nsIScriptContext {
// If there is some pending CC or GC timer/runner, this will run it. // If there is some pending CC or GC timer/runner, this will run it.
static void RunNextCollectorTimer( static void RunNextCollectorTimer(
JS::gcreason::Reason aReason, JS::GCReason aReason,
mozilla::TimeStamp aDeadline = mozilla::TimeStamp()); mozilla::TimeStamp aDeadline = mozilla::TimeStamp());
// If user has been idle and aDocShell is for an iframe being loaded in an // If user has been idle and aDocShell is for an iframe being loaded in an
// already loaded top level docshell, this will run a CC or GC // already loaded top level docshell, this will run a CC or GC
// timer/runner if there is such pending. // timer/runner if there is such pending.
static void MaybeRunNextCollectorSlice(nsIDocShell *aDocShell, static void MaybeRunNextCollectorSlice(nsIDocShell *aDocShell,
JS::gcreason::Reason aReason); JS::GCReason aReason);
// The GC should probably run soon, in the zone of object aObj (if given). // The GC should probably run soon, in the zone of object aObj (if given).
static void PokeGC(JS::gcreason::Reason aReason, JSObject *aObj, static void PokeGC(JS::GCReason aReason, JSObject *aObj, int aDelay = 0);
int aDelay = 0);
static void KillGCTimer(); static void KillGCTimer();
static void PokeShrinkingGC(); static void PokeShrinkingGC();

Просмотреть файл

@ -374,6 +374,10 @@ JSScript* nsJSUtils::ExecutionContext::GetScript() {
mScriptUsed = true; mScriptUsed = true;
#endif #endif
return MaybeGetScript();
}
JSScript* nsJSUtils::ExecutionContext::MaybeGetScript() {
return mScript; return mScript;
} }

Просмотреть файл

@ -175,6 +175,9 @@ class nsJSUtils {
// Get a successfully compiled script. // Get a successfully compiled script.
JSScript* GetScript(); JSScript* GetScript();
// Get the compiled script if present, or nullptr.
JSScript* MaybeGetScript();
// Execute the compiled script and ignore the return value. // Execute the compiled script and ignore the return value.
MOZ_MUST_USE nsresult ExecScript(); MOZ_MUST_USE nsresult ExecScript();

Просмотреть файл

@ -129,7 +129,7 @@ void MaybeCollectGarbageOnIPCMessage() {
return; return;
} }
nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC); nsJSContext::GarbageCollectNow(JS::GCReason::DOM_IPC);
nsJSContext::CycleCollectNow(); nsJSContext::CycleCollectNow();
#endif // BUILD_GC_ON_IPC_MESSAGES #endif // BUILD_GC_ON_IPC_MESSAGES
} }

Просмотреть файл

@ -2472,7 +2472,7 @@ mozilla::ipc::IPCResult ContentChild::RecvGarbageCollect() {
if (obs) { if (obs) {
obs->NotifyObservers(nullptr, "child-gc-request", nullptr); obs->NotifyObservers(nullptr, "child-gc-request", nullptr);
} }
nsJSContext::GarbageCollectNow(JS::gcreason::DOM_IPC); nsJSContext::GarbageCollectNow(JS::GCReason::DOM_IPC);
return IPC_OK(); return IPC_OK();
} }

Просмотреть файл

@ -2444,7 +2444,7 @@ class MOZ_RAII AutoSetProcessingScriptTag {
static nsresult ExecuteCompiledScript(JSContext* aCx, static nsresult ExecuteCompiledScript(JSContext* aCx,
ScriptLoadRequest* aRequest, ScriptLoadRequest* aRequest,
nsJSUtils::ExecutionContext& aExec) { nsJSUtils::ExecutionContext& aExec) {
JS::Rooted<JSScript*> script(aCx, aExec.GetScript()); JS::Rooted<JSScript*> script(aCx, aExec.MaybeGetScript());
if (!script) { if (!script) {
// Compilation succeeds without producing a script if scripting is // Compilation succeeds without producing a script if scripting is
// disabled for the global. // disabled for the global.

Просмотреть файл

@ -4,11 +4,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsSMILInterval.h" #include "SMILInterval.h"
nsSMILInterval::nsSMILInterval() : mBeginFixed(false), mEndFixed(false) {} namespace mozilla {
nsSMILInterval::nsSMILInterval(const nsSMILInterval& aOther) SMILInterval::SMILInterval() : mBeginFixed(false), mEndFixed(false) {}
SMILInterval::SMILInterval(const SMILInterval& aOther)
: mBegin(aOther.mBegin), : mBegin(aOther.mBegin),
mEnd(aOther.mEnd), mEnd(aOther.mEnd),
mBeginFixed(false), mBeginFixed(false),
@ -25,13 +27,13 @@ nsSMILInterval::nsSMILInterval(const nsSMILInterval& aOther)
"Attempt to copy-construct an interval with fixed endpoints"); "Attempt to copy-construct an interval with fixed endpoints");
} }
nsSMILInterval::~nsSMILInterval() { SMILInterval::~SMILInterval() {
MOZ_ASSERT(mDependentTimes.IsEmpty(), MOZ_ASSERT(mDependentTimes.IsEmpty(),
"Destroying interval without disassociating dependent instance " "Destroying interval without disassociating dependent instance "
"times. Unlink was not called"); "times. Unlink was not called");
} }
void nsSMILInterval::Unlink(bool aFiltered) { void SMILInterval::Unlink(bool aFiltered) {
for (int32_t i = mDependentTimes.Length() - 1; i >= 0; --i) { for (int32_t i = mDependentTimes.Length() - 1; i >= 0; --i) {
if (aFiltered) { if (aFiltered) {
mDependentTimes[i]->HandleFilteredInterval(); mDependentTimes[i]->HandleFilteredInterval();
@ -50,17 +52,17 @@ void nsSMILInterval::Unlink(bool aFiltered) {
mEnd = nullptr; mEnd = nullptr;
} }
nsSMILInstanceTime* nsSMILInterval::Begin() { nsSMILInstanceTime* SMILInterval::Begin() {
MOZ_ASSERT(mBegin && mEnd, "Requesting Begin() on un-initialized interval."); MOZ_ASSERT(mBegin && mEnd, "Requesting Begin() on un-initialized interval.");
return mBegin; return mBegin;
} }
nsSMILInstanceTime* nsSMILInterval::End() { nsSMILInstanceTime* SMILInterval::End() {
MOZ_ASSERT(mBegin && mEnd, "Requesting End() on un-initialized interval."); MOZ_ASSERT(mBegin && mEnd, "Requesting End() on un-initialized interval.");
return mEnd; return mEnd;
} }
void nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin) { void SMILInterval::SetBegin(nsSMILInstanceTime& aBegin) {
MOZ_ASSERT(aBegin.Time().IsDefinite(), MOZ_ASSERT(aBegin.Time().IsDefinite(),
"Attempt to set unresolved or indefinite begin time on interval"); "Attempt to set unresolved or indefinite begin time on interval");
MOZ_ASSERT(!mBeginFixed, MOZ_ASSERT(!mBeginFixed,
@ -74,7 +76,7 @@ void nsSMILInterval::SetBegin(nsSMILInstanceTime& aBegin) {
mBegin = &aBegin; mBegin = &aBegin;
} }
void nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd) { void SMILInterval::SetEnd(nsSMILInstanceTime& aEnd) {
MOZ_ASSERT(!mEndFixed, "Attempt to set end time but the end point is fixed"); MOZ_ASSERT(!mEndFixed, "Attempt to set end time but the end point is fixed");
// As with SetBegin, check we're not making an instance time dependent on // As with SetBegin, check we're not making an instance time dependent on
// itself. // itself.
@ -84,14 +86,14 @@ void nsSMILInterval::SetEnd(nsSMILInstanceTime& aEnd) {
mEnd = &aEnd; mEnd = &aEnd;
} }
void nsSMILInterval::FixBegin() { void SMILInterval::FixBegin() {
MOZ_ASSERT(mBegin && mEnd, "Fixing begin point on un-initialized interval"); MOZ_ASSERT(mBegin && mEnd, "Fixing begin point on un-initialized interval");
MOZ_ASSERT(!mBeginFixed, "Duplicate calls to FixBegin()"); MOZ_ASSERT(!mBeginFixed, "Duplicate calls to FixBegin()");
mBeginFixed = true; mBeginFixed = true;
mBegin->AddRefFixedEndpoint(); mBegin->AddRefFixedEndpoint();
} }
void nsSMILInterval::FixEnd() { void SMILInterval::FixEnd() {
MOZ_ASSERT(mBegin && mEnd, "Fixing end point on un-initialized interval"); MOZ_ASSERT(mBegin && mEnd, "Fixing end point on un-initialized interval");
MOZ_ASSERT(mBeginFixed, MOZ_ASSERT(mBeginFixed,
"Fixing the end of an interval without a fixed begin"); "Fixing the end of an interval without a fixed begin");
@ -100,7 +102,7 @@ void nsSMILInterval::FixEnd() {
mEnd->AddRefFixedEndpoint(); mEnd->AddRefFixedEndpoint();
} }
void nsSMILInterval::AddDependentTime(nsSMILInstanceTime& aTime) { void SMILInterval::AddDependentTime(nsSMILInstanceTime& aTime) {
RefPtr<nsSMILInstanceTime>* inserted = RefPtr<nsSMILInstanceTime>* inserted =
mDependentTimes.InsertElementSorted(&aTime); mDependentTimes.InsertElementSorted(&aTime);
if (!inserted) { if (!inserted) {
@ -108,7 +110,7 @@ void nsSMILInterval::AddDependentTime(nsSMILInstanceTime& aTime) {
} }
} }
void nsSMILInterval::RemoveDependentTime(const nsSMILInstanceTime& aTime) { void SMILInterval::RemoveDependentTime(const nsSMILInstanceTime& aTime) {
#ifdef DEBUG #ifdef DEBUG
bool found = bool found =
#endif #endif
@ -116,11 +118,11 @@ void nsSMILInterval::RemoveDependentTime(const nsSMILInstanceTime& aTime) {
MOZ_ASSERT(found, "Couldn't find instance time to delete."); MOZ_ASSERT(found, "Couldn't find instance time to delete.");
} }
void nsSMILInterval::GetDependentTimes(InstanceTimeList& aTimes) { void SMILInterval::GetDependentTimes(InstanceTimeList& aTimes) {
aTimes = mDependentTimes; aTimes = mDependentTimes;
} }
bool nsSMILInterval::IsDependencyChainLink() const { bool SMILInterval::IsDependencyChainLink() const {
if (!mBegin || !mEnd) if (!mBegin || !mEnd)
return false; // Not yet initialised so it can't be part of a chain return false; // Not yet initialised so it can't be part of a chain
@ -132,3 +134,5 @@ bool nsSMILInterval::IsDependencyChainLink() const {
return (mBegin->IsDependent() && mBegin->GetBaseInterval() != this) || return (mBegin->IsDependent() && mBegin->GetBaseInterval() != this) ||
(mEnd->IsDependent() && mEnd->GetBaseInterval() != this); (mEnd->IsDependent() && mEnd->GetBaseInterval() != this);
} }
} // namespace mozilla

Просмотреть файл

@ -10,8 +10,10 @@
#include "nsSMILInstanceTime.h" #include "nsSMILInstanceTime.h"
#include "nsTArray.h" #include "nsTArray.h"
namespace mozilla {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// nsSMILInterval class // SMILInterval class
// //
// A structure consisting of a begin and end time. The begin time must be // A structure consisting of a begin and end time. The begin time must be
// resolved (i.e. not indefinite or unresolved). // resolved (i.e. not indefinite or unresolved).
@ -19,11 +21,11 @@
// For an overview of how this class is related to other SMIL time classes see // For an overview of how this class is related to other SMIL time classes see
// the documentation in nsSMILTimeValue.h // the documentation in nsSMILTimeValue.h
class nsSMILInterval { class SMILInterval {
public: public:
nsSMILInterval(); SMILInterval();
nsSMILInterval(const nsSMILInterval& aOther); SMILInterval(const SMILInterval& aOther);
~nsSMILInterval(); ~SMILInterval();
void Unlink(bool aFiltered = false); void Unlink(bool aFiltered = false);
const nsSMILInstanceTime* Begin() const { const nsSMILInstanceTime* Begin() const {
@ -79,4 +81,6 @@ class nsSMILInterval {
bool mEndFixed; bool mEndFixed;
}; };
} // namespace mozilla
#endif // NS_SMILINTERVAL_H_ #endif // NS_SMILINTERVAL_H_

Просмотреть файл

@ -5,15 +5,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SMILParserUtils.h" #include "SMILParserUtils.h"
#include "mozilla/SMILKeySpline.h"
#include "mozilla/SMILRepeatCount.h"
#include "mozilla/SVGContentUtils.h" #include "mozilla/SVGContentUtils.h"
#include "mozilla/TextUtils.h" #include "mozilla/TextUtils.h"
#include "SMILKeySpline.h"
#include "nsISMILAttr.h" #include "nsISMILAttr.h"
#include "nsSMILValue.h" #include "nsSMILValue.h"
#include "nsSMILTimeValue.h" #include "nsSMILTimeValue.h"
#include "nsSMILTimeValueSpecParams.h" #include "nsSMILTimeValueSpecParams.h"
#include "nsSMILTypes.h" #include "nsSMILTypes.h"
#include "nsSMILRepeatCount.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCharSeparatedTokenizer.h" #include "nsCharSeparatedTokenizer.h"
@ -551,7 +552,7 @@ bool SMILParserUtils::ParseValuesGeneric(const nsAString& aSpec,
} }
bool SMILParserUtils::ParseRepeatCount(const nsAString& aSpec, bool SMILParserUtils::ParseRepeatCount(const nsAString& aSpec,
nsSMILRepeatCount& aResult) { SMILRepeatCount& aResult) {
const nsAString& spec = SMILParserUtils::TrimWhitespace(aSpec); const nsAString& spec = SMILParserUtils::TrimWhitespace(aSpec);
if (spec.EqualsLiteral("indefinite")) { if (spec.EqualsLiteral("indefinite")) {

Просмотреть файл

@ -11,13 +11,13 @@
#include "nsStringFwd.h" #include "nsStringFwd.h"
class nsISMILAttr; class nsISMILAttr;
class SMILKeySpline;
class nsSMILTimeValue; class nsSMILTimeValue;
class nsSMILValue; class nsSMILValue;
class nsSMILRepeatCount;
class nsSMILTimeValueSpecParams; class nsSMILTimeValueSpecParams;
namespace mozilla { namespace mozilla {
class SMILKeySpline;
class SMILRepeatCount;
namespace dom { namespace dom {
class SVGAnimationElement; class SVGAnimationElement;
} // namespace dom } // namespace dom
@ -57,7 +57,7 @@ class SMILParserUtils {
GenericValueParser& aParser); GenericValueParser& aParser);
static bool ParseRepeatCount(const nsAString& aSpec, static bool ParseRepeatCount(const nsAString& aSpec,
nsSMILRepeatCount& aResult); SMILRepeatCount& aResult);
static bool ParseTimeValueSpecParams(const nsAString& aSpec, static bool ParseTimeValueSpecParams(const nsAString& aSpec,
nsSMILTimeValueSpecParams& aResult); nsSMILTimeValueSpecParams& aResult);

Просмотреть файл

@ -4,7 +4,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsSMILRepeatCount.h" #include "SMILRepeatCount.h"
namespace mozilla {
/*static*/ const double SMILRepeatCount::kNotSet = -1.0;
/*static*/ const double SMILRepeatCount::kIndefinite = -2.0;
} // namespace mozilla
/*static*/ const double nsSMILRepeatCount::kNotSet = -1.0;
/*static*/ const double nsSMILRepeatCount::kIndefinite = -2.0;

Просмотреть файл

@ -4,14 +4,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsSMILRepeatCount_h #ifndef SMILRepeatCount_h
#define nsSMILRepeatCount_h #define SMILRepeatCount_h
#include "nsDebug.h" #include "nsDebug.h"
#include <math.h> #include <math.h>
namespace mozilla {
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// nsSMILRepeatCount // SMILRepeatCount
// //
// A tri-state non-negative floating point number for representing the number of // A tri-state non-negative floating point number for representing the number of
// times an animation repeat, i.e. the SMIL repeatCount attribute. // times an animation repeat, i.e. the SMIL repeatCount attribute.
@ -21,10 +23,10 @@
// 2. set (with non-negative, non-zero count value) // 2. set (with non-negative, non-zero count value)
// 3. indefinite // 3. indefinite
// //
class nsSMILRepeatCount { class SMILRepeatCount {
public: public:
nsSMILRepeatCount() : mCount(kNotSet) {} SMILRepeatCount() : mCount(kNotSet) {}
explicit nsSMILRepeatCount(double aCount) : mCount(kNotSet) { explicit SMILRepeatCount(double aCount) : mCount(kNotSet) {
SetCount(aCount); SetCount(aCount);
} }
@ -37,7 +39,7 @@ class nsSMILRepeatCount {
bool IsIndefinite() const { return mCount == kIndefinite; } bool IsIndefinite() const { return mCount == kIndefinite; }
bool IsSet() const { return mCount != kNotSet; } bool IsSet() const { return mCount != kNotSet; }
nsSMILRepeatCount& operator=(double aCount) { SMILRepeatCount& operator=(double aCount) {
SetCount(aCount); SetCount(aCount);
return *this; return *this;
} }
@ -55,4 +57,6 @@ class nsSMILRepeatCount {
double mCount; double mCount;
}; };
} // namespace mozilla
#endif #endif

Просмотреть файл

@ -548,14 +548,14 @@ void SMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly) {
switch (mElementState) { switch (mElementState) {
case STATE_STARTUP: { case STATE_STARTUP: {
nsSMILInterval firstInterval; SMILInterval firstInterval;
mElementState = mElementState =
GetNextInterval(nullptr, nullptr, nullptr, firstInterval) GetNextInterval(nullptr, nullptr, nullptr, firstInterval)
? STATE_WAITING ? STATE_WAITING
: STATE_POSTACTIVE; : STATE_POSTACTIVE;
stateChanged = true; stateChanged = true;
if (mElementState == STATE_WAITING) { if (mElementState == STATE_WAITING) {
mCurrentInterval = MakeUnique<nsSMILInterval>(firstInterval); mCurrentInterval = MakeUnique<SMILInterval>(firstInterval);
NotifyNewInterval(); NotifyNewInterval();
} }
} break; } break;
@ -592,7 +592,7 @@ void SMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly) {
bool didApplyEarlyEnd = ApplyEarlyEnd(sampleTime); bool didApplyEarlyEnd = ApplyEarlyEnd(sampleTime);
if (mCurrentInterval->End()->Time() <= sampleTime) { if (mCurrentInterval->End()->Time() <= sampleTime) {
nsSMILInterval newInterval; SMILInterval newInterval;
mElementState = GetNextInterval(mCurrentInterval.get(), nullptr, mElementState = GetNextInterval(mCurrentInterval.get(), nullptr,
nullptr, newInterval) nullptr, newInterval)
? STATE_WAITING ? STATE_WAITING
@ -608,7 +608,7 @@ void SMILTimedElement::DoSampleAt(nsSMILTime aContainerTime, bool aEndOnly) {
mOldIntervals.AppendElement(std::move(mCurrentInterval)); mOldIntervals.AppendElement(std::move(mCurrentInterval));
SampleFillValue(); SampleFillValue();
if (mElementState == STATE_WAITING) { if (mElementState == STATE_WAITING) {
mCurrentInterval = MakeUnique<nsSMILInterval>(newInterval); mCurrentInterval = MakeUnique<SMILInterval>(newInterval);
} }
// We are now in a consistent state to dispatch notifications // We are now in a consistent state to dispatch notifications
if (didApplyEarlyEnd) { if (didApplyEarlyEnd) {
@ -950,7 +950,7 @@ nsresult SMILTimedElement::SetRepeatCount(const nsAString& aRepeatCountSpec) {
// Update the current interval before returning // Update the current interval before returning
AutoIntervalUpdater updater(*this); AutoIntervalUpdater updater(*this);
nsSMILRepeatCount newRepeatCount; SMILRepeatCount newRepeatCount;
if (SMILParserUtils::ParseRepeatCount(aRepeatCountSpec, newRepeatCount)) { if (SMILParserUtils::ParseRepeatCount(aRepeatCountSpec, newRepeatCount)) {
mRepeatCount = newRepeatCount; mRepeatCount = newRepeatCount;
@ -1354,7 +1354,7 @@ void SMILTimedElement::DoPostSeek() {
} }
void SMILTimedElement::UnpreserveInstanceTimes(InstanceTimeList& aList) { void SMILTimedElement::UnpreserveInstanceTimes(InstanceTimeList& aList) {
const nsSMILInterval* prevInterval = GetPreviousInterval(); const SMILInterval* prevInterval = GetPreviousInterval();
const nsSMILInstanceTime* cutoff = const nsSMILInstanceTime* cutoff =
mCurrentInterval ? mCurrentInterval->Begin() mCurrentInterval ? mCurrentInterval->Begin()
: prevInterval ? prevInterval->Begin() : nullptr; : prevInterval ? prevInterval->Begin() : nullptr;
@ -1409,7 +1409,7 @@ void SMILTimedElement::FilterIntervals() {
: 0; : 0;
IntervalList filteredList; IntervalList filteredList;
for (uint32_t i = 0; i < mOldIntervals.Length(); ++i) { for (uint32_t i = 0; i < mOldIntervals.Length(); ++i) {
nsSMILInterval* interval = mOldIntervals[i].get(); SMILInterval* interval = mOldIntervals[i].get();
if (i != 0 && /*skip first interval*/ if (i != 0 && /*skip first interval*/
i + 1 < mOldIntervals.Length() && /*skip previous interval*/ i + 1 < mOldIntervals.Length() && /*skip previous interval*/
(i < threshold || !interval->IsDependencyChainLink())) { (i < threshold || !interval->IsDependencyChainLink())) {
@ -1477,7 +1477,7 @@ void SMILTimedElement::FilterInstanceTimes(InstanceTimeList& aList) {
if (mCurrentInterval) { if (mCurrentInterval) {
timesToKeep.AppendElement(mCurrentInterval->Begin()); timesToKeep.AppendElement(mCurrentInterval->Begin());
} }
const nsSMILInterval* prevInterval = GetPreviousInterval(); const SMILInterval* prevInterval = GetPreviousInterval();
if (prevInterval) { if (prevInterval) {
timesToKeep.AppendElement(prevInterval->End()); timesToKeep.AppendElement(prevInterval->End());
} }
@ -1496,9 +1496,8 @@ void SMILTimedElement::FilterInstanceTimes(InstanceTimeList& aList) {
// http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LC-Start // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#Timing-BeginEnd-LC-Start
// //
bool SMILTimedElement::GetNextInterval( bool SMILTimedElement::GetNextInterval(
const nsSMILInterval* aPrevInterval, const SMILInterval* aPrevInterval, const SMILInterval* aReplacedInterval,
const nsSMILInterval* aReplacedInterval, const nsSMILInstanceTime* aFixedBeginTime, SMILInterval& aResult) const {
const nsSMILInstanceTime* aFixedBeginTime, nsSMILInterval& aResult) const {
MOZ_ASSERT(!aFixedBeginTime || aFixedBeginTime->Time().IsDefinite(), MOZ_ASSERT(!aFixedBeginTime || aFixedBeginTime->Time().IsDefinite(),
"Unresolved or indefinite begin time given for interval start"); "Unresolved or indefinite begin time given for interval start");
static const nsSMILTimeValue zeroTime(0L); static const nsSMILTimeValue zeroTime(0L);
@ -1860,13 +1859,13 @@ void SMILTimedElement::UpdateCurrentInterval(bool aForceChangeNotice) {
// If the interval is active the begin time is fixed. // If the interval is active the begin time is fixed.
const nsSMILInstanceTime* beginTime = const nsSMILInstanceTime* beginTime =
mElementState == STATE_ACTIVE ? mCurrentInterval->Begin() : nullptr; mElementState == STATE_ACTIVE ? mCurrentInterval->Begin() : nullptr;
nsSMILInterval updatedInterval; SMILInterval updatedInterval;
if (GetNextInterval(GetPreviousInterval(), mCurrentInterval.get(), beginTime, if (GetNextInterval(GetPreviousInterval(), mCurrentInterval.get(), beginTime,
updatedInterval)) { updatedInterval)) {
if (mElementState == STATE_POSTACTIVE) { if (mElementState == STATE_POSTACTIVE) {
MOZ_ASSERT(!mCurrentInterval, MOZ_ASSERT(!mCurrentInterval,
"In postactive state but the interval has been set"); "In postactive state but the interval has been set");
mCurrentInterval = MakeUnique<nsSMILInterval>(updatedInterval); mCurrentInterval = MakeUnique<SMILInterval>(updatedInterval);
mElementState = STATE_WAITING; mElementState = STATE_WAITING;
NotifyNewInterval(); NotifyNewInterval();
@ -1930,7 +1929,7 @@ void SMILTimedElement::SampleFillValue() {
nsSMILTime activeTime; nsSMILTime activeTime;
if (mElementState == STATE_WAITING || mElementState == STATE_POSTACTIVE) { if (mElementState == STATE_WAITING || mElementState == STATE_POSTACTIVE) {
const nsSMILInterval* prevInterval = GetPreviousInterval(); const SMILInterval* prevInterval = GetPreviousInterval();
MOZ_ASSERT(prevInterval, MOZ_ASSERT(prevInterval,
"Attempting to sample fill value but there is no previous " "Attempting to sample fill value but there is no previous "
"interval"); "interval");
@ -2091,7 +2090,7 @@ void SMILTimedElement::NotifyNewInterval() {
} }
for (auto iter = mTimeDependents.Iter(); !iter.Done(); iter.Next()) { for (auto iter = mTimeDependents.Iter(); !iter.Done(); iter.Next()) {
nsSMILInterval* interval = mCurrentInterval.get(); SMILInterval* interval = mCurrentInterval.get();
// It's possible that in notifying one new time dependent of a new interval // It's possible that in notifying one new time dependent of a new interval
// that a chain reaction is triggered which results in the original // that a chain reaction is triggered which results in the original
// interval disappearing. If that's the case we can skip sending further // interval disappearing. If that's the case we can skip sending further
@ -2104,7 +2103,7 @@ void SMILTimedElement::NotifyNewInterval() {
} }
} }
void SMILTimedElement::NotifyChangedInterval(nsSMILInterval* aInterval, void SMILTimedElement::NotifyChangedInterval(SMILInterval* aInterval,
bool aBeginObjectChanged, bool aBeginObjectChanged,
bool aEndObjectChanged) { bool aEndObjectChanged) {
MOZ_ASSERT(aInterval, "Null interval for change notification"); MOZ_ASSERT(aInterval, "Null interval for change notification");
@ -2144,14 +2143,14 @@ const nsSMILInstanceTime* SMILTimedElement::GetEffectiveBeginInstance() const {
case STATE_WAITING: case STATE_WAITING:
case STATE_POSTACTIVE: { case STATE_POSTACTIVE: {
const nsSMILInterval* prevInterval = GetPreviousInterval(); const SMILInterval* prevInterval = GetPreviousInterval();
return prevInterval ? prevInterval->Begin() : nullptr; return prevInterval ? prevInterval->Begin() : nullptr;
} }
} }
MOZ_CRASH("Invalid element state"); MOZ_CRASH("Invalid element state");
} }
const nsSMILInterval* SMILTimedElement::GetPreviousInterval() const { const SMILInterval* SMILTimedElement::GetPreviousInterval() const {
return mOldIntervals.IsEmpty() return mOldIntervals.IsEmpty()
? nullptr ? nullptr
: mOldIntervals[mOldIntervals.Length() - 1].get(); : mOldIntervals[mOldIntervals.Length() - 1].get();

Просмотреть файл

@ -10,11 +10,11 @@
#include "mozilla/EventForwards.h" #include "mozilla/EventForwards.h"
#include "mozilla/Move.h" #include "mozilla/Move.h"
#include "mozilla/SMILMilestone.h" #include "mozilla/SMILMilestone.h"
#include "mozilla/SMILInterval.h"
#include "mozilla/SMILRepeatCount.h"
#include "mozilla/UniquePtr.h" #include "mozilla/UniquePtr.h"
#include "nsSMILInterval.h"
#include "nsSMILInstanceTime.h" #include "nsSMILInstanceTime.h"
#include "nsSMILTimeValueSpec.h" #include "nsSMILTimeValueSpec.h"
#include "nsSMILRepeatCount.h"
#include "nsSMILTypes.h" #include "nsSMILTypes.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsTHashtable.h" #include "nsTHashtable.h"
@ -348,7 +348,7 @@ class SMILTimedElement {
// Typedefs // Typedefs
typedef nsTArray<UniquePtr<nsSMILTimeValueSpec>> TimeValueSpecList; typedef nsTArray<UniquePtr<nsSMILTimeValueSpec>> TimeValueSpecList;
typedef nsTArray<RefPtr<nsSMILInstanceTime>> InstanceTimeList; typedef nsTArray<RefPtr<nsSMILInstanceTime>> InstanceTimeList;
typedef nsTArray<UniquePtr<nsSMILInterval>> IntervalList; typedef nsTArray<UniquePtr<SMILInterval>> IntervalList;
typedef nsPtrHashKey<nsSMILTimeValueSpec> TimeValueSpecPtrKey; typedef nsPtrHashKey<nsSMILTimeValueSpec> TimeValueSpecPtrKey;
typedef nsTHashtable<TimeValueSpecPtrKey> TimeValueSpecHashSet; typedef nsTHashtable<TimeValueSpecPtrKey> TimeValueSpecHashSet;
@ -459,13 +459,13 @@ class SMILTimedElement {
/** /**
* Helper function to iterate through this element's accumulated timing * Helper function to iterate through this element's accumulated timing
* information (specifically old nsSMILIntervals and nsSMILTimeInstanceTimes) * information (specifically old SMILIntervals and nsSMILTimeInstanceTimes)
* and discard items that are no longer needed or exceed some threshold of * and discard items that are no longer needed or exceed some threshold of
* accumulated state. * accumulated state.
*/ */
void FilterHistory(); void FilterHistory();
// Helper functions for FilterHistory to clear old nsSMILIntervals and // Helper functions for FilterHistory to clear old SMILIntervals and
// nsSMILInstanceTimes respectively. // nsSMILInstanceTimes respectively.
void FilterIntervals(); void FilterIntervals();
void FilterInstanceTimes(InstanceTimeList& aList); void FilterInstanceTimes(InstanceTimeList& aList);
@ -492,10 +492,10 @@ class SMILTimedElement {
* returned). * returned).
* @return true if a suitable interval was found, false otherwise. * @return true if a suitable interval was found, false otherwise.
*/ */
bool GetNextInterval(const nsSMILInterval* aPrevInterval, bool GetNextInterval(const SMILInterval* aPrevInterval,
const nsSMILInterval* aReplacedInterval, const SMILInterval* aReplacedInterval,
const nsSMILInstanceTime* aFixedBeginTime, const nsSMILInstanceTime* aFixedBeginTime,
nsSMILInterval& aResult) const; SMILInterval& aResult) const;
nsSMILInstanceTime* GetNextGreater(const InstanceTimeList& aList, nsSMILInstanceTime* GetNextGreater(const InstanceTimeList& aList,
const nsSMILTimeValue& aBase, const nsSMILTimeValue& aBase,
int32_t& aPosition) const; int32_t& aPosition) const;
@ -525,12 +525,12 @@ class SMILTimedElement {
// (ii) after calling these methods we must assume that the state of the // (ii) after calling these methods we must assume that the state of the
// element may have changed. // element may have changed.
void NotifyNewInterval(); void NotifyNewInterval();
void NotifyChangedInterval(nsSMILInterval* aInterval, void NotifyChangedInterval(SMILInterval* aInterval, bool aBeginObjectChanged,
bool aBeginObjectChanged, bool aEndObjectChanged); bool aEndObjectChanged);
void FireTimeEventAsync(EventMessage aMsg, int32_t aDetail); void FireTimeEventAsync(EventMessage aMsg, int32_t aDetail);
const nsSMILInstanceTime* GetEffectiveBeginInstance() const; const nsSMILInstanceTime* GetEffectiveBeginInstance() const;
const nsSMILInterval* GetPreviousInterval() const; const SMILInterval* GetPreviousInterval() const;
bool HasPlayed() const { return !mOldIntervals.IsEmpty(); } bool HasPlayed() const { return !mOldIntervals.IsEmpty(); }
bool HasClientInFillRange() const; bool HasClientInFillRange() const;
bool EndHasEventConditions() const; bool EndHasEventConditions() const;
@ -557,7 +557,7 @@ class SMILTimedElement {
nsSMILTimeValue mSimpleDur; nsSMILTimeValue mSimpleDur;
nsSMILRepeatCount mRepeatCount; SMILRepeatCount mRepeatCount;
nsSMILTimeValue mRepeatDur; nsSMILTimeValue mRepeatDur;
nsSMILTimeValue mMin; nsSMILTimeValue mMin;
@ -580,7 +580,7 @@ class SMILTimedElement {
uint32_t mInstanceSerialIndex; uint32_t mInstanceSerialIndex;
SMILAnimationFunction* mClient; SMILAnimationFunction* mClient;
UniquePtr<nsSMILInterval> mCurrentInterval; UniquePtr<SMILInterval> mCurrentInterval;
IntervalList mOldIntervals; IntervalList mOldIntervals;
uint32_t mCurrentRepeatIteration; uint32_t mCurrentRepeatIteration;
SMILMilestone mPrevRegisteredMilestone; SMILMilestone mPrevRegisteredMilestone;

Просмотреть файл

@ -12,8 +12,6 @@ MOCHITEST_MANIFESTS += ['test/mochitest.ini']
EXPORTS += [ EXPORTS += [
'nsISMILAttr.h', 'nsISMILAttr.h',
'nsSMILInstanceTime.h', 'nsSMILInstanceTime.h',
'nsSMILInterval.h',
'nsSMILRepeatCount.h',
'nsSMILTimeValue.h', 'nsSMILTimeValue.h',
'nsSMILTimeValueSpec.h', 'nsSMILTimeValueSpec.h',
'nsSMILTimeValueSpecParams.h', 'nsSMILTimeValueSpecParams.h',
@ -26,10 +24,12 @@ EXPORTS.mozilla += [
'SMILAnimationFunction.h', 'SMILAnimationFunction.h',
'SMILCompositorTable.h', 'SMILCompositorTable.h',
'SMILCSSValueType.h', 'SMILCSSValueType.h',
'SMILInterval.h',
'SMILKeySpline.h', 'SMILKeySpline.h',
'SMILMilestone.h', 'SMILMilestone.h',
'SMILNullType.h', 'SMILNullType.h',
'SMILParserUtils.h', 'SMILParserUtils.h',
'SMILRepeatCount.h',
'SMILSetAnimationFunction.h', 'SMILSetAnimationFunction.h',
'SMILTargetIdentifier.h', 'SMILTargetIdentifier.h',
'SMILTimeContainer.h', 'SMILTimeContainer.h',
@ -43,8 +43,6 @@ EXPORTS.mozilla.dom += [
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'nsSMILInstanceTime.cpp', 'nsSMILInstanceTime.cpp',
'nsSMILInterval.cpp',
'nsSMILRepeatCount.cpp',
'nsSMILTimeValue.cpp', 'nsSMILTimeValue.cpp',
'nsSMILTimeValueSpec.cpp', 'nsSMILTimeValueSpec.cpp',
'nsSMILValue.cpp', 'nsSMILValue.cpp',
@ -57,9 +55,11 @@ UNIFIED_SOURCES += [
'SMILEnumType.cpp', 'SMILEnumType.cpp',
'SMILFloatType.cpp', 'SMILFloatType.cpp',
'SMILIntegerType.cpp', 'SMILIntegerType.cpp',
'SMILInterval.cpp',
'SMILKeySpline.cpp', 'SMILKeySpline.cpp',
'SMILNullType.cpp', 'SMILNullType.cpp',
'SMILParserUtils.cpp', 'SMILParserUtils.cpp',
'SMILRepeatCount.cpp',
'SMILSetAnimationFunction.cpp', 'SMILSetAnimationFunction.cpp',
'SMILStringType.cpp', 'SMILStringType.cpp',
'SMILTimeContainer.cpp', 'SMILTimeContainer.cpp',

Просмотреть файл

@ -5,9 +5,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsSMILInstanceTime.h" #include "nsSMILInstanceTime.h"
#include "nsSMILInterval.h"
#include "nsSMILTimeValueSpec.h"
#include "mozilla/AutoRestore.h" #include "mozilla/AutoRestore.h"
#include "mozilla/SMILInterval.h"
#include "nsSMILTimeValueSpec.h"
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Implementation // Implementation
@ -15,7 +16,7 @@
nsSMILInstanceTime::nsSMILInstanceTime(const nsSMILTimeValue& aTime, nsSMILInstanceTime::nsSMILInstanceTime(const nsSMILTimeValue& aTime,
nsSMILInstanceTimeSource aSource, nsSMILInstanceTimeSource aSource,
nsSMILTimeValueSpec* aCreator, nsSMILTimeValueSpec* aCreator,
nsSMILInterval* aBaseInterval) SMILInterval* aBaseInterval)
: mTime(aTime), : mTime(aTime),
mFlags(0), mFlags(0),
mVisited(false), mVisited(false),
@ -165,7 +166,7 @@ const nsSMILInstanceTime* nsSMILInstanceTime::GetBaseTime() const {
: mBaseInterval->End(); : mBaseInterval->End();
} }
void nsSMILInstanceTime::SetBaseInterval(nsSMILInterval* aBaseInterval) { void nsSMILInstanceTime::SetBaseInterval(SMILInterval* aBaseInterval) {
MOZ_ASSERT(!mBaseInterval, MOZ_ASSERT(!mBaseInterval,
"Attempting to reassociate an instance time with a different " "Attempting to reassociate an instance time with a different "
"interval."); "interval.");

Просмотреть файл

@ -10,10 +10,10 @@
#include "nsISupportsImpl.h" #include "nsISupportsImpl.h"
#include "nsSMILTimeValue.h" #include "nsSMILTimeValue.h"
class nsSMILInterval;
class nsSMILTimeValueSpec; class nsSMILTimeValueSpec;
namespace mozilla { namespace mozilla {
class SMILInterval;
class SMILTimeContainer; class SMILTimeContainer;
} }
@ -29,15 +29,18 @@ class SMILTimeContainer;
// These objects are owned by an SMILTimedElement but MAY also be referenced // These objects are owned by an SMILTimedElement but MAY also be referenced
// by: // by:
// //
// a) nsSMILIntervals that belong to the same SMILTimedElement and which refer // a) SMILIntervals that belong to the same SMILTimedElement and which refer
// to the nsSMILInstanceTimes which form the interval endpoints; and/or // to the nsSMILInstanceTimes which form the interval endpoints; and/or
// b) nsSMILIntervals that belong to other SMILTimedElements but which need to // b) SMILIntervals that belong to other SMILTimedElements but which need to
// update dependent instance times when they change or are deleted. // update dependent instance times when they change or are deleted.
// E.g. for begin='a.begin', 'a' needs to inform dependent // E.g. for begin='a.begin', 'a' needs to inform dependent
// nsSMILInstanceTimes if its begin time changes. This notification is // nsSMILInstanceTimes if its begin time changes. This notification is
// performed by the nsSMILInterval. // performed by the SMILInterval.
class nsSMILInstanceTime final { class nsSMILInstanceTime final {
typedef mozilla::SMILInterval SMILInterval;
typedef mozilla::SMILTimeContainer SMILTimeContainer;
public: public:
// Instance time source. Times generated by events, syncbase relationships, // Instance time source. Times generated by events, syncbase relationships,
// and DOM calls behave differently in some circumstances such as when a timed // and DOM calls behave differently in some circumstances such as when a timed
@ -56,10 +59,10 @@ class nsSMILInstanceTime final {
explicit nsSMILInstanceTime(const nsSMILTimeValue& aTime, explicit nsSMILInstanceTime(const nsSMILTimeValue& aTime,
nsSMILInstanceTimeSource aSource = SOURCE_NONE, nsSMILInstanceTimeSource aSource = SOURCE_NONE,
nsSMILTimeValueSpec* aCreator = nullptr, nsSMILTimeValueSpec* aCreator = nullptr,
nsSMILInterval* aBaseInterval = nullptr); SMILInterval* aBaseInterval = nullptr);
void Unlink(); void Unlink();
void HandleChangedInterval(const mozilla::SMILTimeContainer* aSrcContainer, void HandleChangedInterval(const SMILTimeContainer* aSrcContainer,
bool aBeginObjectChanged, bool aEndObjectChanged); bool aBeginObjectChanged, bool aEndObjectChanged);
void HandleDeletedInterval(); void HandleDeletedInterval();
void HandleFilteredInterval(); void HandleFilteredInterval();
@ -85,7 +88,7 @@ class nsSMILInstanceTime final {
bool IsDependent() const { return !!mBaseInterval; } bool IsDependent() const { return !!mBaseInterval; }
bool IsDependentOn(const nsSMILInstanceTime& aOther) const; bool IsDependentOn(const nsSMILInstanceTime& aOther) const;
const nsSMILInterval* GetBaseInterval() const { return mBaseInterval; } const SMILInterval* GetBaseInterval() const { return mBaseInterval; }
const nsSMILInstanceTime* GetBaseTime() const; const nsSMILInstanceTime* GetBaseTime() const;
bool SameTimeAndBase(const nsSMILInstanceTime& aOther) const { bool SameTimeAndBase(const nsSMILInstanceTime& aOther) const {
@ -103,7 +106,7 @@ class nsSMILInstanceTime final {
// Private destructor, to discourage deletion outside of Release(): // Private destructor, to discourage deletion outside of Release():
~nsSMILInstanceTime(); ~nsSMILInstanceTime();
void SetBaseInterval(nsSMILInterval* aBaseInterval); void SetBaseInterval(SMILInterval* aBaseInterval);
nsSMILTimeValue mTime; nsSMILTimeValue mTime;
@ -159,7 +162,7 @@ class nsSMILInstanceTime final {
nsSMILTimeValueSpec* mCreator; // The nsSMILTimeValueSpec object that created nsSMILTimeValueSpec* mCreator; // The nsSMILTimeValueSpec object that created
// us. (currently only needed for syncbase // us. (currently only needed for syncbase
// instance times.) // instance times.)
nsSMILInterval* mBaseInterval; // Interval from which this time is derived SMILInterval* mBaseInterval; // Interval from which this time is derived
// (only used for syncbase instance times) // (only used for syncbase instance times)
}; };

Просмотреть файл

@ -23,7 +23,7 @@
* nsSMILInstanceTime -- an nsSMILTimeValue used for constructing intervals. It * nsSMILInstanceTime -- an nsSMILTimeValue used for constructing intervals. It
* contains additional fields to govern reset behavior * contains additional fields to govern reset behavior
* and track timing dependencies (e.g. syncbase timing). * and track timing dependencies (e.g. syncbase timing).
* nsSMILInterval -- a pair of nsSMILInstanceTimes that defines a begin and * SMILInterval -- a pair of nsSMILInstanceTimes that defines a begin and
* an end time for animation. * an end time for animation.
* nsSMILTimeValueSpec -- a component of a begin or end attribute, such as the * nsSMILTimeValueSpec -- a component of a begin or end attribute, such as the
* '5s' or 'a.end+2m' in begin="5s; a.end+2m". Acts as * '5s' or 'a.end+2m' in begin="5s; a.end+2m". Acts as

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/EventListenerManager.h" #include "mozilla/EventListenerManager.h"
#include "mozilla/SMILInterval.h"
#include "mozilla/SMILParserUtils.h" #include "mozilla/SMILParserUtils.h"
#include "mozilla/SMILTimeContainer.h" #include "mozilla/SMILTimeContainer.h"
#include "mozilla/SMILTimedElement.h" #include "mozilla/SMILTimedElement.h"
@ -12,7 +13,6 @@
#include "mozilla/dom/SVGAnimationElement.h" #include "mozilla/dom/SVGAnimationElement.h"
#include "mozilla/dom/TimeEvent.h" #include "mozilla/dom/TimeEvent.h"
#include "nsSMILTimeValueSpec.h" #include "nsSMILTimeValueSpec.h"
#include "nsSMILInterval.h"
#include "nsSMILTimeValue.h" #include "nsSMILTimeValue.h"
#include "nsSMILInstanceTime.h" #include "nsSMILInstanceTime.h"
#include "nsString.h" #include "nsString.h"
@ -108,7 +108,7 @@ bool nsSMILTimeValueSpec::IsEventBased() const {
} }
void nsSMILTimeValueSpec::HandleNewInterval( void nsSMILTimeValueSpec::HandleNewInterval(
nsSMILInterval& aInterval, const SMILTimeContainer* aSrcContainer) { SMILInterval& aInterval, const SMILTimeContainer* aSrcContainer) {
const nsSMILInstanceTime& baseInstance = const nsSMILInstanceTime& baseInstance =
mParams.mSyncBegin ? *aInterval.Begin() : *aInterval.End(); mParams.mSyncBegin ? *aInterval.Begin() : *aInterval.End();
nsSMILTimeValue newTime = nsSMILTimeValue newTime =

Просмотреть файл

@ -15,9 +15,9 @@
class nsSMILTimeValue; class nsSMILTimeValue;
class nsSMILInstanceTime; class nsSMILInstanceTime;
class nsSMILInterval;
namespace mozilla { namespace mozilla {
class SMILInterval;
class SMILTimeContainer; class SMILTimeContainer;
class SMILTimedElement; class SMILTimedElement;
namespace dom { namespace dom {
@ -40,6 +40,7 @@ class EventListenerManager;
class nsSMILTimeValueSpec { class nsSMILTimeValueSpec {
public: public:
typedef mozilla::SMILInterval SMILInterval;
typedef mozilla::SMILTimeContainer SMILTimeContainer; typedef mozilla::SMILTimeContainer SMILTimeContainer;
typedef mozilla::SMILTimedElement SMILTimedElement; typedef mozilla::SMILTimedElement SMILTimedElement;
typedef mozilla::dom::Element Element; typedef mozilla::dom::Element Element;
@ -53,7 +54,7 @@ class nsSMILTimeValueSpec {
void ResolveReferences(Element& aContextElement); void ResolveReferences(Element& aContextElement);
bool IsEventBased() const; bool IsEventBased() const;
void HandleNewInterval(nsSMILInterval& aInterval, void HandleNewInterval(SMILInterval& aInterval,
const SMILTimeContainer* aSrcContainer); const SMILTimeContainer* aSrcContainer);
void HandleTargetElementChange(Element* aNewTarget); void HandleTargetElementChange(Element* aNewTarget);

Просмотреть файл

@ -4390,13 +4390,13 @@ void WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
JS::PrepareForFullGC(aCx); JS::PrepareForFullGC(aCx);
if (aShrinking) { if (aShrinking) {
JS::NonIncrementalGC(aCx, GC_SHRINK, JS::gcreason::DOM_WORKER); JS::NonIncrementalGC(aCx, GC_SHRINK, JS::GCReason::DOM_WORKER);
if (!aCollectChildren) { if (!aCollectChildren) {
LOG(WorkerLog(), ("Worker %p collected idle garbage\n", this)); LOG(WorkerLog(), ("Worker %p collected idle garbage\n", this));
} }
} else { } else {
JS::NonIncrementalGC(aCx, GC_NORMAL, JS::gcreason::DOM_WORKER); JS::NonIncrementalGC(aCx, GC_NORMAL, JS::GCReason::DOM_WORKER);
LOG(WorkerLog(), ("Worker %p collected garbage\n", this)); LOG(WorkerLog(), ("Worker %p collected garbage\n", this));
} }
} else { } else {

Просмотреть файл

@ -39,7 +39,7 @@ static void MaybeForceDebugGC() {
if (sDebugGCs) { if (sDebugGCs) {
JSContext* cx = XPCJSContext::Get()->Context(); JSContext* cx = XPCJSContext::Get()->Context();
PrepareForFullGC(cx); PrepareForFullGC(cx);
NonIncrementalGC(cx, GC_NORMAL, gcreason::COMPONENT_UTILS); NonIncrementalGC(cx, GC_NORMAL, GCReason::COMPONENT_UTILS);
} }
} }

Просмотреть файл

@ -406,10 +406,7 @@ namespace JS {
D(DOCSHELL, 54) \ D(DOCSHELL, 54) \
D(HTML_PARSER, 55) D(HTML_PARSER, 55)
namespace gcreason { enum class GCReason {
/* GCReasons will end up looking like JSGC_MAYBEGC */
enum Reason {
#define MAKE_REASON(name, val) name = val, #define MAKE_REASON(name, val) name = val,
GCREASONS(MAKE_REASON) GCREASONS(MAKE_REASON)
#undef MAKE_REASON #undef MAKE_REASON
@ -418,9 +415,8 @@ enum Reason {
/* /*
* For telemetry, we want to keep a fixed max bucket size over time so we * For telemetry, we want to keep a fixed max bucket size over time so we
* don't have to switch histograms. 100 is conservative; as of this writing * don't have to switch histograms. 100 is conservative; but the cost of extra
* there are 52. But the cost of extra buckets seems to be low while the * buckets seems to be low while the cost of switching histograms is high.
* cost of switching histograms is high.
*/ */
NUM_TELEMETRY_REASONS = 100 NUM_TELEMETRY_REASONS = 100
}; };
@ -428,9 +424,7 @@ enum Reason {
/** /**
* Get a statically allocated C string explaining the given GC reason. * Get a statically allocated C string explaining the given GC reason.
*/ */
extern JS_PUBLIC_API const char* ExplainReason(JS::gcreason::Reason reason); extern JS_PUBLIC_API const char* ExplainGCReason(JS::GCReason reason);
} /* namespace gcreason */
/* /*
* Zone GC: * Zone GC:
@ -492,7 +486,7 @@ extern JS_PUBLIC_API void SkipZoneForGC(Zone* zone);
*/ */
extern JS_PUBLIC_API void NonIncrementalGC(JSContext* cx, extern JS_PUBLIC_API void NonIncrementalGC(JSContext* cx,
JSGCInvocationKind gckind, JSGCInvocationKind gckind,
gcreason::Reason reason); GCReason reason);
/* /*
* Incremental GC: * Incremental GC:
@ -525,7 +519,7 @@ extern JS_PUBLIC_API void NonIncrementalGC(JSContext* cx,
*/ */
extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx, extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx,
JSGCInvocationKind gckind, JSGCInvocationKind gckind,
gcreason::Reason reason, GCReason reason,
int64_t millis = 0); int64_t millis = 0);
/** /**
@ -536,8 +530,7 @@ extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx,
* Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or * Note: SpiderMonkey's GC is not realtime. Slices in practice may be longer or
* shorter than the requested interval. * shorter than the requested interval.
*/ */
extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx, extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx, GCReason reason,
gcreason::Reason reason,
int64_t millis = 0); int64_t millis = 0);
/** /**
@ -546,8 +539,7 @@ extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx,
* this is equivalent to NonIncrementalGC. When this function returns, * this is equivalent to NonIncrementalGC. When this function returns,
* IsIncrementalGCInProgress(cx) will always be false. * IsIncrementalGCInProgress(cx) will always be false.
*/ */
extern JS_PUBLIC_API void FinishIncrementalGC(JSContext* cx, extern JS_PUBLIC_API void FinishIncrementalGC(JSContext* cx, GCReason reason);
gcreason::Reason reason);
/** /**
* If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and * If IsIncrementalGCInProgress(cx), this call aborts the ongoing collection and
@ -623,10 +615,10 @@ struct JS_PUBLIC_API GCDescription {
bool isZone_; bool isZone_;
bool isComplete_; bool isComplete_;
JSGCInvocationKind invocationKind_; JSGCInvocationKind invocationKind_;
gcreason::Reason reason_; GCReason reason_;
GCDescription(bool isZone, bool isComplete, JSGCInvocationKind kind, GCDescription(bool isZone, bool isComplete, JSGCInvocationKind kind,
gcreason::Reason reason) GCReason reason)
: isZone_(isZone), : isZone_(isZone),
isComplete_(isComplete), isComplete_(isComplete),
invocationKind_(kind), invocationKind_(kind),
@ -681,7 +673,7 @@ enum class GCNurseryProgress {
*/ */
using GCNurseryCollectionCallback = void (*)(JSContext* cx, using GCNurseryCollectionCallback = void (*)(JSContext* cx,
GCNurseryProgress progress, GCNurseryProgress progress,
gcreason::Reason reason); GCReason reason);
/** /**
* Set the nursery collection callback for the given runtime. When set, it will * Set the nursery collection callback for the given runtime. When set, it will

Просмотреть файл

@ -428,7 +428,7 @@ static bool GC(JSContext* cx, unsigned argc, Value* vp) {
} }
JSGCInvocationKind gckind = shrinking ? GC_SHRINK : GC_NORMAL; JSGCInvocationKind gckind = shrinking ? GC_SHRINK : GC_NORMAL;
JS::NonIncrementalGC(cx, gckind, JS::gcreason::API); JS::NonIncrementalGC(cx, gckind, JS::GCReason::API);
char buf[256] = {'\0'}; char buf[256] = {'\0'};
#ifndef JS_MORE_DETERMINISTIC #ifndef JS_MORE_DETERMINISTIC
@ -442,10 +442,10 @@ static bool MinorGC(JSContext* cx, unsigned argc, Value* vp) {
CallArgs args = CallArgsFromVp(argc, vp); CallArgs args = CallArgsFromVp(argc, vp);
if (args.get(0) == BooleanValue(true)) { if (args.get(0) == BooleanValue(true)) {
cx->runtime()->gc.storeBuffer().setAboutToOverflow( cx->runtime()->gc.storeBuffer().setAboutToOverflow(
JS::gcreason::FULL_GENERIC_BUFFER); JS::GCReason::FULL_GENERIC_BUFFER);
} }
cx->minorGC(JS::gcreason::API); cx->minorGC(JS::GCReason::API);
args.rval().setUndefined(); args.rval().setUndefined();
return true; return true;
} }
@ -591,7 +591,7 @@ static bool RelazifyFunctions(JSContext* cx, unsigned argc, Value* vp) {
SetAllowRelazification(cx, true); SetAllowRelazification(cx, true);
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, GC_SHRINK, JS::gcreason::API); JS::NonIncrementalGC(cx, GC_SHRINK, JS::GCReason::API);
SetAllowRelazification(cx, false); SetAllowRelazification(cx, false);
args.rval().setUndefined(); args.rval().setUndefined();
@ -4186,7 +4186,7 @@ static void majorGC(JSContext* cx, JSGCStatus status, void* data) {
if (info->depth > 0) { if (info->depth > 0) {
info->depth--; info->depth--;
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, GC_NORMAL, JS::gcreason::API); JS::NonIncrementalGC(cx, GC_NORMAL, JS::GCReason::API);
info->depth++; info->depth++;
} }
} }
@ -4205,7 +4205,7 @@ static void minorGC(JSContext* cx, JSGCStatus status, void* data) {
if (info->active) { if (info->active) {
info->active = false; info->active = false;
if (cx->zone() && !cx->zone()->isAtomsZone()) { if (cx->zone() && !cx->zone()->isAtomsZone()) {
cx->runtime()->gc.evictNursery(JS::gcreason::DEBUG_GC); cx->runtime()->gc.evictNursery(JS::GCReason::DEBUG_GC);
} }
info->active = true; info->active = true;
} }

Просмотреть файл

@ -35,7 +35,7 @@ static int testBinASTReaderFuzz(const uint8_t* buf, size_t size) {
auto gcGuard = mozilla::MakeScopeExit([&] { auto gcGuard = mozilla::MakeScopeExit([&] {
JS::PrepareForFullGC(gCx); JS::PrepareForFullGC(gCx);
JS::NonIncrementalGC(gCx, GC_NORMAL, JS::gcreason::API); JS::NonIncrementalGC(gCx, GC_NORMAL, JS::GCReason::API);
}); });
if (!size) return 0; if (!size) return 0;

Просмотреть файл

@ -37,7 +37,7 @@ static int testExampleFuzz(const uint8_t* buf, size_t size) {
if it is not required in your use case, which will speed up fuzzing. */ if it is not required in your use case, which will speed up fuzzing. */
auto gcGuard = mozilla::MakeScopeExit([&] { auto gcGuard = mozilla::MakeScopeExit([&] {
JS::PrepareForFullGC(gCx); JS::PrepareForFullGC(gCx);
JS::NonIncrementalGC(gCx, GC_NORMAL, JS::gcreason::API); JS::NonIncrementalGC(gCx, GC_NORMAL, JS::GCReason::API);
}); });
/* Add code here that processes the given buffer. /* Add code here that processes the given buffer.

Просмотреть файл

@ -26,7 +26,7 @@ static int testStructuredCloneReaderInit(int* argc, char*** argv) { return 0; }
static int testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) { static int testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) {
auto gcGuard = mozilla::MakeScopeExit([&] { auto gcGuard = mozilla::MakeScopeExit([&] {
JS::PrepareForFullGC(gCx); JS::PrepareForFullGC(gCx);
JS::NonIncrementalGC(gCx, GC_NORMAL, JS::gcreason::API); JS::NonIncrementalGC(gCx, GC_NORMAL, JS::GCReason::API);
}); });
if (!size) return 0; if (!size) return 0;

Просмотреть файл

@ -108,7 +108,7 @@ JSObject* GCRuntime::tryNewNurseryObject(JSContext* cx, size_t thingSize,
} }
if (allowGC && !cx->suppressGC) { if (allowGC && !cx->suppressGC) {
cx->runtime()->gc.minorGC(JS::gcreason::OUT_OF_NURSERY); cx->runtime()->gc.minorGC(JS::GCReason::OUT_OF_NURSERY);
// Exceeding gcMaxBytes while tenuring can disable the Nursery. // Exceeding gcMaxBytes while tenuring can disable the Nursery.
if (cx->nursery().isEnabled()) { if (cx->nursery().isEnabled()) {
@ -164,7 +164,7 @@ JSString* GCRuntime::tryNewNurseryString(JSContext* cx, size_t thingSize,
} }
if (allowGC && !cx->suppressGC) { if (allowGC && !cx->suppressGC) {
cx->runtime()->gc.minorGC(JS::gcreason::OUT_OF_NURSERY); cx->runtime()->gc.minorGC(JS::GCReason::OUT_OF_NURSERY);
// Exceeding gcMaxBytes while tenuring can disable the Nursery, and // Exceeding gcMaxBytes while tenuring can disable the Nursery, and
// other heuristics can disable nursery strings for this zone. // other heuristics can disable nursery strings for this zone.
@ -276,7 +276,7 @@ template <typename T, AllowGC allowGC>
// all-compartments, non-incremental, shrinking GC and wait for // all-compartments, non-incremental, shrinking GC and wait for
// sweeping to finish. // sweeping to finish.
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
cx->runtime()->gc.gc(GC_SHRINK, JS::gcreason::LAST_DITCH); cx->runtime()->gc.gc(GC_SHRINK, JS::GCReason::LAST_DITCH);
cx->runtime()->gc.waitBackgroundSweepOrAllocEnd(); cx->runtime()->gc.waitBackgroundSweepOrAllocEnd();
t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize); t = tryNewTenuredThing<T, NoGC>(cx, kind, thingSize);
@ -351,7 +351,7 @@ bool GCRuntime::gcIfNeededAtAllocation(JSContext* cx) {
if (isIncrementalGCInProgress() && if (isIncrementalGCInProgress() &&
cx->zone()->zoneSize.gcBytes() > cx->zone()->threshold.gcTriggerBytes()) { cx->zone()->zoneSize.gcBytes() > cx->zone()->threshold.gcTriggerBytes()) {
PrepareZoneForGC(cx->zone()); PrepareZoneForGC(cx->zone());
gc(GC_NORMAL, JS::gcreason::INCREMENTAL_TOO_SLOW); gc(GC_NORMAL, JS::GCReason::INCREMENTAL_TOO_SLOW);
} }
return true; return true;

Просмотреть файл

@ -335,7 +335,7 @@ class ArenaLists {
bool checkEmptyArenaList(AllocKind kind); bool checkEmptyArenaList(AllocKind kind);
bool relocateArenas(Arena*& relocatedListOut, JS::gcreason::Reason reason, bool relocateArenas(Arena*& relocatedListOut, JS::GCReason reason,
js::SliceBudget& sliceBudget, gcstats::Statistics& stats); js::SliceBudget& sliceBudget, gcstats::Statistics& stats);
void queueForegroundObjectsForSweep(FreeOp* fop); void queueForegroundObjectsForSweep(FreeOp* fop);

Просмотреть файл

@ -915,7 +915,7 @@ GCRuntime::GCRuntime(JSRuntime* rt)
cleanUpEverything(false), cleanUpEverything(false),
grayBufferState(GCRuntime::GrayBufferState::Unused), grayBufferState(GCRuntime::GrayBufferState::Unused),
grayBitsValid(false), grayBitsValid(false),
majorGCTriggerReason(JS::gcreason::NO_REASON), majorGCTriggerReason(JS::GCReason::NO_REASON),
fullGCForAtomsRequested_(false), fullGCForAtomsRequested_(false),
minorGCNumber(0), minorGCNumber(0),
majorGCNumber(0), majorGCNumber(0),
@ -1053,12 +1053,12 @@ void GCRuntime::setZeal(uint8_t zeal, uint32_t frequency) {
if (zeal == 0) { if (zeal == 0) {
if (hasZealMode(ZealMode::GenerationalGC)) { if (hasZealMode(ZealMode::GenerationalGC)) {
evictNursery(JS::gcreason::DEBUG_GC); evictNursery(JS::GCReason::DEBUG_GC);
nursery().leaveZealMode(); nursery().leaveZealMode();
} }
if (isIncrementalGCInProgress()) { if (isIncrementalGCInProgress()) {
finishGC(JS::gcreason::DEBUG_GC); finishGC(JS::GCReason::DEBUG_GC);
} }
} }
@ -1098,7 +1098,7 @@ void GCRuntime::unsetZeal(uint8_t zeal) {
} }
if (zealMode == ZealMode::GenerationalGC) { if (zealMode == ZealMode::GenerationalGC) {
evictNursery(JS::gcreason::DEBUG_GC); evictNursery(JS::GCReason::DEBUG_GC);
nursery().leaveZealMode(); nursery().leaveZealMode();
} }
@ -1106,7 +1106,7 @@ void GCRuntime::unsetZeal(uint8_t zeal) {
if (zealModeBits == 0) { if (zealModeBits == 0) {
if (isIncrementalGCInProgress()) { if (isIncrementalGCInProgress()) {
finishGC(JS::gcreason::DEBUG_GC); finishGC(JS::GCReason::DEBUG_GC);
} }
zealFrequency = 0; zealFrequency = 0;
@ -2075,8 +2075,8 @@ bool GCRuntime::shouldCompact() {
return false; return false;
} }
if (initialReason == JS::gcreason::USER_INACTIVE || if (initialReason == JS::GCReason::USER_INACTIVE ||
initialReason == JS::gcreason::MEM_PRESSURE) { initialReason == JS::GCReason::MEM_PRESSURE) {
return true; return true;
} }
@ -2122,8 +2122,8 @@ Arena* ArenaList::removeRemainingArenas(Arena** arenap) {
return remainingArenas; return remainingArenas;
} }
static bool ShouldRelocateAllArenas(JS::gcreason::Reason reason) { static bool ShouldRelocateAllArenas(JS::GCReason reason) {
return reason == JS::gcreason::DEBUG_GC; return reason == JS::GCReason::DEBUG_GC;
} }
/* /*
@ -2297,12 +2297,12 @@ static inline bool CanProtectArenas() {
return SystemPageSize() <= ArenaSize; return SystemPageSize() <= ArenaSize;
} }
static inline bool ShouldProtectRelocatedArenas(JS::gcreason::Reason reason) { static inline bool ShouldProtectRelocatedArenas(JS::GCReason reason) {
// For zeal mode collections we don't release the relocated arenas // For zeal mode collections we don't release the relocated arenas
// immediately. Instead we protect them and keep them around until the next // immediately. Instead we protect them and keep them around until the next
// collection so we can catch any stray accesses to them. // collection so we can catch any stray accesses to them.
#ifdef DEBUG #ifdef DEBUG
return reason == JS::gcreason::DEBUG_GC && CanProtectArenas(); return reason == JS::GCReason::DEBUG_GC && CanProtectArenas();
#else #else
return false; return false;
#endif #endif
@ -2336,7 +2336,7 @@ Arena* ArenaList::relocateArenas(Arena* toRelocate, Arena* relocated,
static const float MIN_ZONE_RECLAIM_PERCENT = 2.0; static const float MIN_ZONE_RECLAIM_PERCENT = 2.0;
static bool ShouldRelocateZone(size_t arenaCount, size_t relocCount, static bool ShouldRelocateZone(size_t arenaCount, size_t relocCount,
JS::gcreason::Reason reason) { JS::GCReason reason) {
if (relocCount == 0) { if (relocCount == 0) {
return false; return false;
} }
@ -2358,8 +2358,7 @@ static AllocKinds CompactingAllocKinds() {
return result; return result;
} }
bool ArenaLists::relocateArenas(Arena*& relocatedListOut, bool ArenaLists::relocateArenas(Arena*& relocatedListOut, JS::GCReason reason,
JS::gcreason::Reason reason,
SliceBudget& sliceBudget, SliceBudget& sliceBudget,
gcstats::Statistics& stats) { gcstats::Statistics& stats) {
// This is only called from the main thread while we are doing a GC, so // This is only called from the main thread while we are doing a GC, so
@ -2411,7 +2410,7 @@ bool ArenaLists::relocateArenas(Arena*& relocatedListOut,
return true; return true;
} }
bool GCRuntime::relocateArenas(Zone* zone, JS::gcreason::Reason reason, bool GCRuntime::relocateArenas(Zone* zone, JS::GCReason reason,
Arena*& relocatedListOut, Arena*& relocatedListOut,
SliceBudget& sliceBudget) { SliceBudget& sliceBudget) {
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::COMPACT_MOVE); gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::COMPACT_MOVE);
@ -3190,7 +3189,7 @@ bool SliceBudget::checkOverBudget() {
return over; return over;
} }
void GCRuntime::requestMajorGC(JS::gcreason::Reason reason) { void GCRuntime::requestMajorGC(JS::GCReason reason) {
MOZ_ASSERT(!CurrentThreadIsPerformingGC()); MOZ_ASSERT(!CurrentThreadIsPerformingGC());
if (majorGCRequested()) { if (majorGCRequested()) {
@ -3201,7 +3200,7 @@ void GCRuntime::requestMajorGC(JS::gcreason::Reason reason) {
rt->mainContextFromOwnThread()->requestInterrupt(InterruptReason::GC); rt->mainContextFromOwnThread()->requestInterrupt(InterruptReason::GC);
} }
void Nursery::requestMinorGC(JS::gcreason::Reason reason) const { void Nursery::requestMinorGC(JS::GCReason reason) const {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime())); MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime()));
MOZ_ASSERT(!CurrentThreadIsPerformingGC()); MOZ_ASSERT(!CurrentThreadIsPerformingGC());
@ -3222,18 +3221,18 @@ void Nursery::requestMinorGC(JS::gcreason::Reason reason) const {
// memory or memory used by GC things may vary between recording or replaying, // memory or memory used by GC things may vary between recording or replaying,
// but other behaviors that would normally be non-deterministic (timers and so // but other behaviors that would normally be non-deterministic (timers and so
// forth) are captured in the recording and replayed exactly. // forth) are captured in the recording and replayed exactly.
static bool RecordReplayCheckCanGC(JS::gcreason::Reason reason) { static bool RecordReplayCheckCanGC(JS::GCReason reason) {
if (!mozilla::recordreplay::IsRecordingOrReplaying()) { if (!mozilla::recordreplay::IsRecordingOrReplaying()) {
return true; return true;
} }
switch (reason) { switch (reason) {
case JS::gcreason::EAGER_ALLOC_TRIGGER: case JS::GCReason::EAGER_ALLOC_TRIGGER:
case JS::gcreason::LAST_DITCH: case JS::GCReason::LAST_DITCH:
case JS::gcreason::TOO_MUCH_MALLOC: case JS::GCReason::TOO_MUCH_MALLOC:
case JS::gcreason::ALLOC_TRIGGER: case JS::GCReason::ALLOC_TRIGGER:
case JS::gcreason::DELAYED_ATOMS_GC: case JS::GCReason::DELAYED_ATOMS_GC:
case JS::gcreason::TOO_MUCH_WASM_MEMORY: case JS::GCReason::TOO_MUCH_WASM_MEMORY:
return false; return false;
default: default:
@ -3247,7 +3246,7 @@ static bool RecordReplayCheckCanGC(JS::gcreason::Reason reason) {
return true; return true;
} }
bool GCRuntime::triggerGC(JS::gcreason::Reason reason) { bool GCRuntime::triggerGC(JS::GCReason reason) {
/* /*
* Don't trigger GCs if this is being called off the main thread from * Don't trigger GCs if this is being called off the main thread from
* onTooMuchMalloc(). * onTooMuchMalloc().
@ -3286,7 +3285,7 @@ void GCRuntime::maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock) {
if (usedBytes >= thresholdBytes) { if (usedBytes >= thresholdBytes) {
// The threshold has been surpassed, immediately trigger a GC, which // The threshold has been surpassed, immediately trigger a GC, which
// will be done non-incrementally. // will be done non-incrementally.
triggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER, usedBytes, thresholdBytes); triggerZoneGC(zone, JS::GCReason::ALLOC_TRIGGER, usedBytes, thresholdBytes);
return; return;
} }
@ -3311,7 +3310,7 @@ void GCRuntime::maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock) {
// to try to avoid performing non-incremental GCs on zones // to try to avoid performing non-incremental GCs on zones
// which allocate a lot of data, even when incremental slices // which allocate a lot of data, even when incremental slices
// can't be triggered via scheduling in the event loop. // can't be triggered via scheduling in the event loop.
triggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER, usedBytes, triggerZoneGC(zone, JS::GCReason::ALLOC_TRIGGER, usedBytes,
igcThresholdBytes); igcThresholdBytes);
// Delay the next slice until a certain amount of allocation // Delay the next slice until a certain amount of allocation
@ -3322,8 +3321,8 @@ void GCRuntime::maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock) {
} }
} }
bool GCRuntime::triggerZoneGC(Zone* zone, JS::gcreason::Reason reason, bool GCRuntime::triggerZoneGC(Zone* zone, JS::GCReason reason, size_t used,
size_t used, size_t threshold) { size_t threshold) {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
/* GC is already running. */ /* GC is already running. */
@ -3367,7 +3366,7 @@ void GCRuntime::maybeGC(Zone* zone) {
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
if (hasZealMode(ZealMode::Alloc) || hasZealMode(ZealMode::RootsChange)) { if (hasZealMode(ZealMode::Alloc) || hasZealMode(ZealMode::RootsChange)) {
JS::PrepareForFullGC(rt->mainContextFromOwnThread()); JS::PrepareForFullGC(rt->mainContextFromOwnThread());
gc(GC_NORMAL, JS::gcreason::DEBUG_GC); gc(GC_NORMAL, JS::GCReason::DEBUG_GC);
return; return;
} }
#endif #endif
@ -3383,7 +3382,7 @@ void GCRuntime::maybeGC(Zone* zone) {
!isIncrementalGCInProgress() && !isBackgroundSweeping()) { !isIncrementalGCInProgress() && !isBackgroundSweeping()) {
stats().recordTrigger(usedBytes, threshold); stats().recordTrigger(usedBytes, threshold);
PrepareZoneForGC(zone); PrepareZoneForGC(zone);
startGC(GC_NORMAL, JS::gcreason::EAGER_ALLOC_TRIGGER); startGC(GC_NORMAL, JS::GCReason::EAGER_ALLOC_TRIGGER);
} }
} }
@ -3393,7 +3392,7 @@ void GCRuntime::triggerFullGCForAtoms(JSContext* cx) {
MOZ_ASSERT(!JS::RuntimeHeapIsCollecting()); MOZ_ASSERT(!JS::RuntimeHeapIsCollecting());
MOZ_ASSERT(cx->canCollectAtoms()); MOZ_ASSERT(cx->canCollectAtoms());
fullGCForAtomsRequested_ = false; fullGCForAtomsRequested_ = false;
MOZ_RELEASE_ASSERT(triggerGC(JS::gcreason::DELAYED_ATOMS_GC)); MOZ_RELEASE_ASSERT(triggerGC(JS::GCReason::DELAYED_ATOMS_GC));
} }
// Do all possible decommit immediately from the current thread without // Do all possible decommit immediately from the current thread without
@ -3962,7 +3961,7 @@ void GCRuntime::purgeRuntime() {
bool GCRuntime::shouldPreserveJITCode(Realm* realm, bool GCRuntime::shouldPreserveJITCode(Realm* realm,
const TimeStamp& currentTime, const TimeStamp& currentTime,
JS::gcreason::Reason reason, JS::GCReason reason,
bool canAllocateMoreCode) { bool canAllocateMoreCode) {
static const auto oneSecond = TimeDuration::FromSeconds(1); static const auto oneSecond = TimeDuration::FromSeconds(1);
@ -3986,7 +3985,7 @@ bool GCRuntime::shouldPreserveJITCode(Realm* realm,
return true; return true;
} }
if (reason == JS::gcreason::DEBUG_GC) { if (reason == JS::GCReason::DEBUG_GC) {
return true; return true;
} }
@ -4107,10 +4106,10 @@ static void RelazifyFunctions(Zone* zone, AllocKind kind) {
} }
} }
static bool ShouldCollectZone(Zone* zone, JS::gcreason::Reason reason) { static bool ShouldCollectZone(Zone* zone, JS::GCReason reason) {
// If we are repeating a GC because we noticed dead compartments haven't // If we are repeating a GC because we noticed dead compartments haven't
// been collected, then only collect zones containing those compartments. // been collected, then only collect zones containing those compartments.
if (reason == JS::gcreason::COMPARTMENT_REVIVED) { if (reason == JS::GCReason::COMPARTMENT_REVIVED) {
for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) { for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next()) {
if (comp->gcState.scheduledForDestruction) { if (comp->gcState.scheduledForDestruction) {
return true; return true;
@ -4147,7 +4146,7 @@ static bool ShouldCollectZone(Zone* zone, JS::gcreason::Reason reason) {
return zone->canCollect(); return zone->canCollect();
} }
bool GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason, bool GCRuntime::prepareZonesForCollection(JS::GCReason reason,
bool* isFullOut) { bool* isFullOut) {
#ifdef DEBUG #ifdef DEBUG
/* Assert that zone state is as we expect */ /* Assert that zone state is as we expect */
@ -4211,7 +4210,7 @@ bool GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason,
* Check that we do collect the atoms zone if we triggered a GC for that * Check that we do collect the atoms zone if we triggered a GC for that
* purpose. * purpose.
*/ */
MOZ_ASSERT_IF(reason == JS::gcreason::DELAYED_ATOMS_GC, MOZ_ASSERT_IF(reason == JS::GCReason::DELAYED_ATOMS_GC,
atomsZone->isGCMarking()); atomsZone->isGCMarking());
/* Check that at least one zone is scheduled for collection. */ /* Check that at least one zone is scheduled for collection. */
@ -4269,8 +4268,7 @@ static void BufferGrayRoots(GCParallelTask* task) {
task->runtime()->gc.bufferGrayRoots(); task->runtime()->gc.bufferGrayRoots();
} }
bool GCRuntime::beginMarkPhase(JS::gcreason::Reason reason, bool GCRuntime::beginMarkPhase(JS::GCReason reason, AutoGCSession& session) {
AutoGCSession& session) {
#ifdef DEBUG #ifdef DEBUG
if (fullCompartmentChecks) { if (fullCompartmentChecks) {
checkForCompartmentMismatches(); checkForCompartmentMismatches();
@ -4931,7 +4929,7 @@ bool GCRuntime::findInterZoneEdges() {
return true; return true;
} }
void GCRuntime::groupZonesForSweeping(JS::gcreason::Reason reason) { void GCRuntime::groupZonesForSweeping(JS::GCReason reason) {
#ifdef DEBUG #ifdef DEBUG
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
MOZ_ASSERT(zone->gcSweepGroupEdges().empty()); MOZ_ASSERT(zone->gcSweepGroupEdges().empty());
@ -5809,8 +5807,7 @@ IncrementalProgress GCRuntime::endSweepingSweepGroup(FreeOp* fop,
return Finished; return Finished;
} }
void GCRuntime::beginSweepPhase(JS::gcreason::Reason reason, void GCRuntime::beginSweepPhase(JS::GCReason reason, AutoGCSession& session) {
AutoGCSession& session) {
/* /*
* Sweep phase. * Sweep phase.
* *
@ -6655,7 +6652,7 @@ void GCRuntime::beginCompactPhase() {
startedCompacting = true; startedCompacting = true;
} }
IncrementalProgress GCRuntime::compactPhase(JS::gcreason::Reason reason, IncrementalProgress GCRuntime::compactPhase(JS::GCReason reason,
SliceBudget& sliceBudget, SliceBudget& sliceBudget,
AutoGCSession& session) { AutoGCSession& session) {
assertBackgroundSweepingFinished(); assertBackgroundSweepingFinished();
@ -6918,12 +6915,12 @@ void GCRuntime::pushZealSelectedObjects() {
#endif #endif
} }
static bool IsShutdownGC(JS::gcreason::Reason reason) { static bool IsShutdownGC(JS::GCReason reason) {
return reason == JS::gcreason::SHUTDOWN_CC || return reason == JS::GCReason::SHUTDOWN_CC ||
reason == JS::gcreason::DESTROY_RUNTIME; reason == JS::GCReason::DESTROY_RUNTIME;
} }
static bool ShouldCleanUpEverything(JS::gcreason::Reason reason, static bool ShouldCleanUpEverything(JS::GCReason reason,
JSGCInvocationKind gckind) { JSGCInvocationKind gckind) {
// During shutdown, we must clean everything up, for the sake of leak // During shutdown, we must clean everything up, for the sake of leak
// detection. When a runtime has no contexts, or we're doing a GC before a // detection. When a runtime has no contexts, or we're doing a GC before a
@ -6931,17 +6928,16 @@ static bool ShouldCleanUpEverything(JS::gcreason::Reason reason,
return IsShutdownGC(reason) || gckind == GC_SHRINK; return IsShutdownGC(reason) || gckind == GC_SHRINK;
} }
static bool ShouldSweepOnBackgroundThread(JS::gcreason::Reason reason) { static bool ShouldSweepOnBackgroundThread(JS::GCReason reason) {
return reason != JS::gcreason::DESTROY_RUNTIME && !gcTracer.traceEnabled() && return reason != JS::GCReason::DESTROY_RUNTIME && !gcTracer.traceEnabled() &&
CanUseExtraThreads(); CanUseExtraThreads();
} }
void GCRuntime::incrementalSlice(SliceBudget& budget, void GCRuntime::incrementalSlice(SliceBudget& budget, JS::GCReason reason,
JS::gcreason::Reason reason,
AutoGCSession& session) { AutoGCSession& session) {
AutoDisableBarriers disableBarriers(rt); AutoDisableBarriers disableBarriers(rt);
bool destroyingRuntime = (reason == JS::gcreason::DESTROY_RUNTIME); bool destroyingRuntime = (reason == JS::GCReason::DESTROY_RUNTIME);
number++; number++;
@ -6953,7 +6949,7 @@ void GCRuntime::incrementalSlice(SliceBudget& budget,
* collection was triggered by runDebugGC() and incremental GC has not been * collection was triggered by runDebugGC() and incremental GC has not been
* cancelled by resetIncrementalGC(). * cancelled by resetIncrementalGC().
*/ */
useZeal = reason == JS::gcreason::DEBUG_GC && !budget.isUnlimited(); useZeal = reason == JS::GCReason::DEBUG_GC && !budget.isUnlimited();
#else #else
bool useZeal = false; bool useZeal = false;
#endif #endif
@ -7182,7 +7178,7 @@ gc::AbortReason gc::IsIncrementalGCUnsafe(JSRuntime* rt) {
return gc::AbortReason::None; return gc::AbortReason::None;
} }
static inline void CheckZoneIsScheduled(Zone* zone, JS::gcreason::Reason reason, static inline void CheckZoneIsScheduled(Zone* zone, JS::GCReason reason,
const char* trigger) { const char* trigger) {
#ifdef DEBUG #ifdef DEBUG
if (zone->isGCScheduled()) { if (zone->isGCScheduled()) {
@ -7192,7 +7188,7 @@ static inline void CheckZoneIsScheduled(Zone* zone, JS::gcreason::Reason reason,
fprintf(stderr, fprintf(stderr,
"CheckZoneIsScheduled: Zone %p not scheduled as expected in %s GC " "CheckZoneIsScheduled: Zone %p not scheduled as expected in %s GC "
"for %s trigger\n", "for %s trigger\n",
zone, JS::gcreason::ExplainReason(reason), trigger); zone, JS::ExplainGCReason(reason), trigger);
JSRuntime* rt = zone->runtimeFromMainThread(); JSRuntime* rt = zone->runtimeFromMainThread();
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
fprintf(stderr, " Zone %p:%s%s\n", zone.get(), fprintf(stderr, " Zone %p:%s%s\n", zone.get(),
@ -7205,8 +7201,7 @@ static inline void CheckZoneIsScheduled(Zone* zone, JS::gcreason::Reason reason,
} }
GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC( GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC(
bool nonincrementalByAPI, JS::gcreason::Reason reason, bool nonincrementalByAPI, JS::GCReason reason, SliceBudget& budget) {
SliceBudget& budget) {
if (nonincrementalByAPI) { if (nonincrementalByAPI) {
stats().nonincremental(gc::AbortReason::NonIncrementalRequested); stats().nonincremental(gc::AbortReason::NonIncrementalRequested);
budget.makeUnlimited(); budget.makeUnlimited();
@ -7215,14 +7210,14 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC(
// API. This isn't required for correctness, but sometimes during tests // API. This isn't required for correctness, but sometimes during tests
// the caller expects this GC to collect certain objects, and we need // the caller expects this GC to collect certain objects, and we need
// to make sure to collect everything possible. // to make sure to collect everything possible.
if (reason != JS::gcreason::ALLOC_TRIGGER) { if (reason != JS::GCReason::ALLOC_TRIGGER) {
return resetIncrementalGC(gc::AbortReason::NonIncrementalRequested); return resetIncrementalGC(gc::AbortReason::NonIncrementalRequested);
} }
return IncrementalResult::Ok; return IncrementalResult::Ok;
} }
if (reason == JS::gcreason::ABORT_GC) { if (reason == JS::GCReason::ABORT_GC) {
budget.makeUnlimited(); budget.makeUnlimited();
stats().nonincremental(gc::AbortReason::AbortRequested); stats().nonincremental(gc::AbortReason::AbortRequested);
return resetIncrementalGC(gc::AbortReason::AbortRequested); return resetIncrementalGC(gc::AbortReason::AbortRequested);
@ -7230,7 +7225,7 @@ GCRuntime::IncrementalResult GCRuntime::budgetIncrementalGC(
AbortReason unsafeReason = IsIncrementalGCUnsafe(rt); AbortReason unsafeReason = IsIncrementalGCUnsafe(rt);
if (unsafeReason == AbortReason::None) { if (unsafeReason == AbortReason::None) {
if (reason == JS::gcreason::COMPARTMENT_REVIVED) { if (reason == JS::GCReason::COMPARTMENT_REVIVED) {
unsafeReason = gc::AbortReason::CompartmentRevived; unsafeReason = gc::AbortReason::CompartmentRevived;
} else if (mode != JSGC_MODE_INCREMENTAL) { } else if (mode != JSGC_MODE_INCREMENTAL) {
unsafeReason = gc::AbortReason::ModeChange; unsafeReason = gc::AbortReason::ModeChange;
@ -7381,7 +7376,7 @@ void GCRuntime::maybeCallGCCallback(JSGCStatus status) {
* implementation. * implementation.
*/ */
MOZ_NEVER_INLINE GCRuntime::IncrementalResult GCRuntime::gcCycle( MOZ_NEVER_INLINE GCRuntime::IncrementalResult GCRuntime::gcCycle(
bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::Reason reason) { bool nonincrementalByAPI, SliceBudget budget, JS::GCReason reason) {
// Assert if this is a GC unsafe region. // Assert if this is a GC unsafe region.
rt->mainContextFromOwnThread()->verifyIsSafeToGC(); rt->mainContextFromOwnThread()->verifyIsSafeToGC();
@ -7397,7 +7392,7 @@ MOZ_NEVER_INLINE GCRuntime::IncrementalResult GCRuntime::gcCycle(
auto result = budgetIncrementalGC(nonincrementalByAPI, reason, budget); auto result = budgetIncrementalGC(nonincrementalByAPI, reason, budget);
if (result == IncrementalResult::ResetIncremental) { if (result == IncrementalResult::ResetIncremental) {
reason = JS::gcreason::RESET; reason = JS::GCReason::RESET;
} }
if (shouldCollectNurseryForSlice(nonincrementalByAPI, budget)) { if (shouldCollectNurseryForSlice(nonincrementalByAPI, budget)) {
@ -7406,7 +7401,7 @@ MOZ_NEVER_INLINE GCRuntime::IncrementalResult GCRuntime::gcCycle(
AutoGCSession session(rt, JS::HeapState::MajorCollecting); AutoGCSession session(rt, JS::HeapState::MajorCollecting);
majorGCTriggerReason = JS::gcreason::NO_REASON; majorGCTriggerReason = JS::GCReason::NO_REASON;
{ {
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::WAIT_BACKGROUND_THREAD); gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::WAIT_BACKGROUND_THREAD);
@ -7479,18 +7474,18 @@ bool GCRuntime::shouldCollectNurseryForSlice(bool nonincrementalByAPI,
} }
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
static bool IsDeterministicGCReason(JS::gcreason::Reason reason) { static bool IsDeterministicGCReason(JS::GCReason reason) {
switch (reason) { switch (reason) {
case JS::gcreason::API: case JS::GCReason::API:
case JS::gcreason::DESTROY_RUNTIME: case JS::GCReason::DESTROY_RUNTIME:
case JS::gcreason::LAST_DITCH: case JS::GCReason::LAST_DITCH:
case JS::gcreason::TOO_MUCH_MALLOC: case JS::GCReason::TOO_MUCH_MALLOC:
case JS::gcreason::TOO_MUCH_WASM_MEMORY: case JS::GCReason::TOO_MUCH_WASM_MEMORY:
case JS::gcreason::ALLOC_TRIGGER: case JS::GCReason::ALLOC_TRIGGER:
case JS::gcreason::DEBUG_GC: case JS::GCReason::DEBUG_GC:
case JS::gcreason::CC_FORCED: case JS::GCReason::CC_FORCED:
case JS::gcreason::SHUTDOWN_CC: case JS::GCReason::SHUTDOWN_CC:
case JS::gcreason::ABORT_GC: case JS::GCReason::ABORT_GC:
return true; return true;
default: default:
@ -7547,7 +7542,7 @@ void GCRuntime::checkCanCallAPI() {
MOZ_RELEASE_ASSERT(!JS::RuntimeHeapIsBusy()); MOZ_RELEASE_ASSERT(!JS::RuntimeHeapIsBusy());
} }
bool GCRuntime::checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason) { bool GCRuntime::checkIfGCAllowedInCurrentState(JS::GCReason reason) {
if (rt->mainContextFromOwnThread()->suppressGC) { if (rt->mainContextFromOwnThread()->suppressGC) {
return false; return false;
} }
@ -7567,8 +7562,8 @@ bool GCRuntime::checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason) {
return true; return true;
} }
bool GCRuntime::shouldRepeatForDeadZone(JS::gcreason::Reason reason) { bool GCRuntime::shouldRepeatForDeadZone(JS::GCReason reason) {
MOZ_ASSERT_IF(reason == JS::gcreason::COMPARTMENT_REVIVED, !isIncremental); MOZ_ASSERT_IF(reason == JS::GCReason::COMPARTMENT_REVIVED, !isIncremental);
MOZ_ASSERT(!isIncrementalGCInProgress()); MOZ_ASSERT(!isIncrementalGCInProgress());
if (!isIncremental) { if (!isIncremental) {
@ -7585,7 +7580,7 @@ bool GCRuntime::shouldRepeatForDeadZone(JS::gcreason::Reason reason) {
} }
void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget,
JS::gcreason::Reason reason) { JS::GCReason reason) {
// Checks run for each request, even if we do not actually GC. // Checks run for each request, even if we do not actually GC.
checkCanCallAPI(); checkCanCallAPI();
@ -7607,7 +7602,7 @@ void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget,
IncrementalResult cycleResult = IncrementalResult cycleResult =
gcCycle(nonincrementalByAPI, budget, reason); gcCycle(nonincrementalByAPI, budget, reason);
if (reason == JS::gcreason::ABORT_GC) { if (reason == JS::GCReason::ABORT_GC) {
MOZ_ASSERT(!isIncrementalGCInProgress()); MOZ_ASSERT(!isIncrementalGCInProgress());
stats().writeLogMessage("GC aborted by request"); stats().writeLogMessage("GC aborted by request");
break; break;
@ -7629,10 +7624,10 @@ void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget,
/* Need to re-schedule all zones for GC. */ /* Need to re-schedule all zones for GC. */
JS::PrepareForFullGC(rt->mainContextFromOwnThread()); JS::PrepareForFullGC(rt->mainContextFromOwnThread());
repeat = true; repeat = true;
reason = JS::gcreason::ROOTS_REMOVED; reason = JS::GCReason::ROOTS_REMOVED;
} else if (shouldRepeatForDeadZone(reason)) { } else if (shouldRepeatForDeadZone(reason)) {
repeat = true; repeat = true;
reason = JS::gcreason::COMPARTMENT_REVIVED; reason = JS::GCReason::COMPARTMENT_REVIVED;
} }
} }
} while (repeat); } while (repeat);
@ -7646,7 +7641,7 @@ void GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget,
} }
#endif #endif
if (reason == JS::gcreason::COMPARTMENT_REVIVED) { if (reason == JS::GCReason::COMPARTMENT_REVIVED) {
maybeDoCycleCollection(); maybeDoCycleCollection();
} }
@ -7669,10 +7664,9 @@ js::AutoEnqueuePendingParseTasksAfterGC::
} }
} }
SliceBudget GCRuntime::defaultBudget(JS::gcreason::Reason reason, SliceBudget GCRuntime::defaultBudget(JS::GCReason reason, int64_t millis) {
int64_t millis) {
if (millis == 0) { if (millis == 0) {
if (reason == JS::gcreason::ALLOC_TRIGGER) { if (reason == JS::GCReason::ALLOC_TRIGGER) {
millis = defaultSliceBudget(); millis = defaultSliceBudget();
} else if (schedulingState.inHighFrequencyGCMode() && } else if (schedulingState.inHighFrequencyGCMode() &&
tunables.isDynamicMarkSliceEnabled()) { tunables.isDynamicMarkSliceEnabled()) {
@ -7685,7 +7679,7 @@ SliceBudget GCRuntime::defaultBudget(JS::gcreason::Reason reason,
return SliceBudget(TimeBudget(millis)); return SliceBudget(TimeBudget(millis));
} }
void GCRuntime::gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason) { void GCRuntime::gc(JSGCInvocationKind gckind, JS::GCReason reason) {
// Watch out for calls to gc() that don't go through triggerGC(). // Watch out for calls to gc() that don't go through triggerGC().
if (!RecordReplayCheckCanGC(reason)) { if (!RecordReplayCheckCanGC(reason)) {
return; return;
@ -7695,7 +7689,7 @@ void GCRuntime::gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason) {
collect(true, SliceBudget::unlimited(), reason); collect(true, SliceBudget::unlimited(), reason);
} }
void GCRuntime::startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, void GCRuntime::startGC(JSGCInvocationKind gckind, JS::GCReason reason,
int64_t millis) { int64_t millis) {
MOZ_ASSERT(!isIncrementalGCInProgress()); MOZ_ASSERT(!isIncrementalGCInProgress());
if (!JS::IsIncrementalGCEnabled(rt->mainContextFromOwnThread())) { if (!JS::IsIncrementalGCEnabled(rt->mainContextFromOwnThread())) {
@ -7706,12 +7700,12 @@ void GCRuntime::startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason,
collect(false, defaultBudget(reason, millis), reason); collect(false, defaultBudget(reason, millis), reason);
} }
void GCRuntime::gcSlice(JS::gcreason::Reason reason, int64_t millis) { void GCRuntime::gcSlice(JS::GCReason reason, int64_t millis) {
MOZ_ASSERT(isIncrementalGCInProgress()); MOZ_ASSERT(isIncrementalGCInProgress());
collect(false, defaultBudget(reason, millis), reason); collect(false, defaultBudget(reason, millis), reason);
} }
void GCRuntime::finishGC(JS::gcreason::Reason reason) { void GCRuntime::finishGC(JS::GCReason reason) {
MOZ_ASSERT(isIncrementalGCInProgress()); MOZ_ASSERT(isIncrementalGCInProgress());
// If we're not collecting because we're out of memory then skip the // If we're not collecting because we're out of memory then skip the
@ -7734,7 +7728,7 @@ void GCRuntime::abortGC() {
checkCanCallAPI(); checkCanCallAPI();
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC); MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
collect(false, SliceBudget::unlimited(), JS::gcreason::ABORT_GC); collect(false, SliceBudget::unlimited(), JS::GCReason::ABORT_GC);
} }
static bool ZonesSelected(JSRuntime* rt) { static bool ZonesSelected(JSRuntime* rt) {
@ -7752,7 +7746,7 @@ void GCRuntime::startDebugGC(JSGCInvocationKind gckind, SliceBudget& budget) {
JS::PrepareForFullGC(rt->mainContextFromOwnThread()); JS::PrepareForFullGC(rt->mainContextFromOwnThread());
} }
invocationKind = gckind; invocationKind = gckind;
collect(false, budget, JS::gcreason::DEBUG_GC); collect(false, budget, JS::GCReason::DEBUG_GC);
} }
void GCRuntime::debugGCSlice(SliceBudget& budget) { void GCRuntime::debugGCSlice(SliceBudget& budget) {
@ -7760,7 +7754,7 @@ void GCRuntime::debugGCSlice(SliceBudget& budget) {
if (!ZonesSelected(rt)) { if (!ZonesSelected(rt)) {
JS::PrepareForIncrementalGC(rt->mainContextFromOwnThread()); JS::PrepareForIncrementalGC(rt->mainContextFromOwnThread());
} }
collect(false, budget, JS::gcreason::DEBUG_GC); collect(false, budget, JS::GCReason::DEBUG_GC);
} }
/* Schedule a full GC unless a zone will already be collected. */ /* Schedule a full GC unless a zone will already be collected. */
@ -7798,10 +7792,10 @@ void GCRuntime::onOutOfMallocMemory(const AutoLockGC& lock) {
decommitAllWithoutUnlocking(lock); decommitAllWithoutUnlocking(lock);
} }
void GCRuntime::minorGC(JS::gcreason::Reason reason, gcstats::PhaseKind phase) { void GCRuntime::minorGC(JS::GCReason reason, gcstats::PhaseKind phase) {
MOZ_ASSERT(!JS::RuntimeHeapIsBusy()); MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
MOZ_ASSERT_IF(reason == JS::gcreason::EVICT_NURSERY, MOZ_ASSERT_IF(reason == JS::GCReason::EVICT_NURSERY,
!rt->mainContextFromOwnThread()->suppressGC); !rt->mainContextFromOwnThread()->suppressGC);
if (rt->mainContextFromOwnThread()->suppressGC) { if (rt->mainContextFromOwnThread()->suppressGC) {
return; return;
@ -7861,7 +7855,7 @@ void GCRuntime::startBackgroundFreeAfterMinorGC() {
JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSContext* cx) JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSContext* cx)
: cx(cx) { : cx(cx) {
if (!cx->generationalDisabled) { if (!cx->generationalDisabled) {
cx->runtime()->gc.evictNursery(JS::gcreason::API); cx->runtime()->gc.evictNursery(JS::GCReason::API);
cx->nursery().disable(); cx->nursery().disable();
} }
++cx->generationalDisabled; ++cx->generationalDisabled;
@ -7885,11 +7879,11 @@ bool GCRuntime::gcIfRequested() {
} }
if (majorGCRequested()) { if (majorGCRequested()) {
if (majorGCTriggerReason == JS::gcreason::DELAYED_ATOMS_GC && if (majorGCTriggerReason == JS::GCReason::DELAYED_ATOMS_GC &&
!rt->mainContextFromOwnThread()->canCollectAtoms()) { !rt->mainContextFromOwnThread()->canCollectAtoms()) {
// A GC was requested to collect the atoms zone, but it's no longer // A GC was requested to collect the atoms zone, but it's no longer
// possible. Skip this collection. // possible. Skip this collection.
majorGCTriggerReason = JS::gcreason::NO_REASON; majorGCTriggerReason = JS::GCReason::NO_REASON;
return false; return false;
} }
@ -7907,7 +7901,7 @@ bool GCRuntime::gcIfRequested() {
void js::gc::FinishGC(JSContext* cx) { void js::gc::FinishGC(JSContext* cx) {
if (JS::IsIncrementalGCInProgress(cx)) { if (JS::IsIncrementalGCInProgress(cx)) {
JS::PrepareForIncrementalGC(cx); JS::PrepareForIncrementalGC(cx);
JS::FinishIncrementalGC(cx, JS::gcreason::API); JS::FinishIncrementalGC(cx, JS::GCReason::API);
} }
cx->runtime()->gc.waitBackgroundFreeEnd(); cx->runtime()->gc.waitBackgroundFreeEnd();
@ -8188,7 +8182,7 @@ void GCRuntime::runDebugGC() {
} }
if (hasZealMode(ZealMode::GenerationalGC)) { if (hasZealMode(ZealMode::GenerationalGC)) {
return minorGC(JS::gcreason::DEBUG_GC); return minorGC(JS::GCReason::DEBUG_GC);
} }
PrepareForDebugGC(rt); PrepareForDebugGC(rt);
@ -8211,7 +8205,7 @@ void GCRuntime::runDebugGC() {
if (!isIncrementalGCInProgress()) { if (!isIncrementalGCInProgress()) {
invocationKind = GC_SHRINK; invocationKind = GC_SHRINK;
} }
collect(false, budget, JS::gcreason::DEBUG_GC); collect(false, budget, JS::GCReason::DEBUG_GC);
/* Reset the slice size when we get to the sweep or compact phases. */ /* Reset the slice size when we get to the sweep or compact phases. */
if ((initialState == State::Mark && incrementalState == State::Sweep) || if ((initialState == State::Mark && incrementalState == State::Sweep) ||
@ -8226,11 +8220,11 @@ void GCRuntime::runDebugGC() {
if (!isIncrementalGCInProgress()) { if (!isIncrementalGCInProgress()) {
invocationKind = GC_NORMAL; invocationKind = GC_NORMAL;
} }
collect(false, budget, JS::gcreason::DEBUG_GC); collect(false, budget, JS::GCReason::DEBUG_GC);
} else if (hasZealMode(ZealMode::Compact)) { } else if (hasZealMode(ZealMode::Compact)) {
gc(GC_SHRINK, JS::gcreason::DEBUG_GC); gc(GC_SHRINK, JS::GCReason::DEBUG_GC);
} else { } else {
gc(GC_NORMAL, JS::gcreason::DEBUG_GC); gc(GC_NORMAL, JS::GCReason::DEBUG_GC);
} }
#endif #endif
@ -8526,27 +8520,24 @@ JS_PUBLIC_API void JS::SkipZoneForGC(Zone* zone) { zone->unscheduleGC(); }
JS_PUBLIC_API void JS::NonIncrementalGC(JSContext* cx, JS_PUBLIC_API void JS::NonIncrementalGC(JSContext* cx,
JSGCInvocationKind gckind, JSGCInvocationKind gckind,
gcreason::Reason reason) { GCReason reason) {
MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK);
cx->runtime()->gc.gc(gckind, reason); cx->runtime()->gc.gc(gckind, reason);
} }
JS_PUBLIC_API void JS::StartIncrementalGC(JSContext* cx, JS_PUBLIC_API void JS::StartIncrementalGC(JSContext* cx,
JSGCInvocationKind gckind, JSGCInvocationKind gckind,
gcreason::Reason reason, GCReason reason, int64_t millis) {
int64_t millis) {
MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK); MOZ_ASSERT(gckind == GC_NORMAL || gckind == GC_SHRINK);
cx->runtime()->gc.startGC(gckind, reason, millis); cx->runtime()->gc.startGC(gckind, reason, millis);
} }
JS_PUBLIC_API void JS::IncrementalGCSlice(JSContext* cx, JS_PUBLIC_API void JS::IncrementalGCSlice(JSContext* cx, GCReason reason,
gcreason::Reason reason,
int64_t millis) { int64_t millis) {
cx->runtime()->gc.gcSlice(reason, millis); cx->runtime()->gc.gcSlice(reason, millis);
} }
JS_PUBLIC_API void JS::FinishIncrementalGC(JSContext* cx, JS_PUBLIC_API void JS::FinishIncrementalGC(JSContext* cx, GCReason reason) {
gcreason::Reason reason) {
cx->runtime()->gc.finishGC(reason); cx->runtime()->gc.finishGC(reason);
} }
@ -8921,7 +8912,7 @@ void AutoAssertEmptyNursery::checkCondition(JSContext* cx) {
AutoEmptyNursery::AutoEmptyNursery(JSContext* cx) : AutoAssertEmptyNursery() { AutoEmptyNursery::AutoEmptyNursery(JSContext* cx) : AutoAssertEmptyNursery() {
MOZ_ASSERT(!cx->suppressGC); MOZ_ASSERT(!cx->suppressGC);
cx->runtime()->gc.stats().suspendPhases(); cx->runtime()->gc.stats().suspendPhases();
cx->runtime()->gc.evictNursery(JS::gcreason::EVICT_NURSERY); cx->runtime()->gc.evictNursery(JS::GCReason::EVICT_NURSERY);
cx->runtime()->gc.stats().resumePhases(); cx->runtime()->gc.stats().resumePhases();
checkCondition(cx); checkCondition(cx);
} }

Просмотреть файл

@ -282,9 +282,9 @@ class MOZ_RAII AutoEmptyNursery : public AutoAssertEmptyNursery {
extern void DelayCrossCompartmentGrayMarking(JSObject* src); extern void DelayCrossCompartmentGrayMarking(JSObject* src);
inline bool IsOOMReason(JS::gcreason::Reason reason) { inline bool IsOOMReason(JS::GCReason reason) {
return reason == JS::gcreason::LAST_DITCH || return reason == JS::GCReason::LAST_DITCH ||
reason == JS::gcreason::MEM_PRESSURE; reason == JS::GCReason::MEM_PRESSURE;
} }
TenuredCell* AllocateCellInGC(JS::Zone* zone, AllocKind thingKind); TenuredCell* AllocateCellInGC(JS::Zone* zone, AllocKind thingKind);

Просмотреть файл

@ -246,19 +246,19 @@ class GCRuntime {
void resetParameter(JSGCParamKey key, AutoLockGC& lock); void resetParameter(JSGCParamKey key, AutoLockGC& lock);
uint32_t getParameter(JSGCParamKey key, const AutoLockGC& lock); uint32_t getParameter(JSGCParamKey key, const AutoLockGC& lock);
MOZ_MUST_USE bool triggerGC(JS::gcreason::Reason reason); MOZ_MUST_USE bool triggerGC(JS::GCReason reason);
void maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock); void maybeAllocTriggerZoneGC(Zone* zone, const AutoLockGC& lock);
// The return value indicates if we were able to do the GC. // The return value indicates if we were able to do the GC.
bool triggerZoneGC(Zone* zone, JS::gcreason::Reason reason, size_t usedBytes, bool triggerZoneGC(Zone* zone, JS::GCReason reason, size_t usedBytes,
size_t thresholdBytes); size_t thresholdBytes);
void maybeGC(Zone* zone); void maybeGC(Zone* zone);
// The return value indicates whether a major GC was performed. // The return value indicates whether a major GC was performed.
bool gcIfRequested(); bool gcIfRequested();
void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason); void gc(JSGCInvocationKind gckind, JS::GCReason reason);
void startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, void startGC(JSGCInvocationKind gckind, JS::GCReason reason,
int64_t millis = 0); int64_t millis = 0);
void gcSlice(JS::gcreason::Reason reason, int64_t millis = 0); void gcSlice(JS::GCReason reason, int64_t millis = 0);
void finishGC(JS::gcreason::Reason reason); void finishGC(JS::GCReason reason);
void abortGC(); void abortGC();
void startDebugGC(JSGCInvocationKind gckind, SliceBudget& budget); void startDebugGC(JSGCInvocationKind gckind, SliceBudget& budget);
void debugGCSlice(SliceBudget& budget); void debugGCSlice(SliceBudget& budget);
@ -356,7 +356,7 @@ class GCRuntime {
return false; return false;
} }
if (!triggerGC(JS::gcreason::TOO_MUCH_MALLOC)) { if (!triggerGC(JS::GCReason::TOO_MUCH_MALLOC)) {
return false; return false;
} }
@ -420,7 +420,7 @@ class GCRuntime {
void setGrayBitsInvalid() { grayBitsValid = false; } void setGrayBitsInvalid() { grayBitsValid = false; }
bool majorGCRequested() const { bool majorGCRequested() const {
return majorGCTriggerReason != JS::gcreason::NO_REASON; return majorGCTriggerReason != JS::GCReason::NO_REASON;
} }
bool fullGCForAtomsRequested() const { return fullGCForAtomsRequested_; } bool fullGCForAtomsRequested() const { return fullGCForAtomsRequested_; }
@ -550,10 +550,10 @@ class GCRuntime {
bool wantBackgroundAllocation(const AutoLockGC& lock) const; bool wantBackgroundAllocation(const AutoLockGC& lock) const;
bool startBackgroundAllocTaskIfIdle(); bool startBackgroundAllocTaskIfIdle();
void requestMajorGC(JS::gcreason::Reason reason); void requestMajorGC(JS::GCReason reason);
SliceBudget defaultBudget(JS::gcreason::Reason reason, int64_t millis); SliceBudget defaultBudget(JS::GCReason reason, int64_t millis);
IncrementalResult budgetIncrementalGC(bool nonincrementalByAPI, IncrementalResult budgetIncrementalGC(bool nonincrementalByAPI,
JS::gcreason::Reason reason, JS::GCReason reason,
SliceBudget& budget); SliceBudget& budget);
IncrementalResult resetIncrementalGC(AbortReason reason); IncrementalResult resetIncrementalGC(AbortReason reason);
@ -563,11 +563,11 @@ class GCRuntime {
// Check if the system state is such that GC has been supressed // Check if the system state is such that GC has been supressed
// or otherwise delayed. // or otherwise delayed.
MOZ_MUST_USE bool checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason); MOZ_MUST_USE bool checkIfGCAllowedInCurrentState(JS::GCReason reason);
gcstats::ZoneGCStats scanZonesBeforeGC(); gcstats::ZoneGCStats scanZonesBeforeGC();
void collect(bool nonincrementalByAPI, SliceBudget budget, void collect(bool nonincrementalByAPI, SliceBudget budget,
JS::gcreason::Reason reason) JS_HAZ_GC_CALL; JS::GCReason reason) JS_HAZ_GC_CALL;
/* /*
* Run one GC "cycle" (either a slice of incremental GC or an entire * Run one GC "cycle" (either a slice of incremental GC or an entire
@ -580,9 +580,9 @@ class GCRuntime {
*/ */
MOZ_MUST_USE IncrementalResult gcCycle(bool nonincrementalByAPI, MOZ_MUST_USE IncrementalResult gcCycle(bool nonincrementalByAPI,
SliceBudget budget, SliceBudget budget,
JS::gcreason::Reason reason); JS::GCReason reason);
bool shouldRepeatForDeadZone(JS::gcreason::Reason reason); bool shouldRepeatForDeadZone(JS::GCReason reason);
void incrementalSlice(SliceBudget& budget, JS::gcreason::Reason reason, void incrementalSlice(SliceBudget& budget, JS::GCReason reason,
AutoGCSession& session); AutoGCSession& session);
MOZ_MUST_USE bool shouldCollectNurseryForSlice(bool nonincrementalByAPI, MOZ_MUST_USE bool shouldCollectNurseryForSlice(bool nonincrementalByAPI,
SliceBudget& budget); SliceBudget& budget);
@ -592,13 +592,11 @@ class GCRuntime {
void pushZealSelectedObjects(); void pushZealSelectedObjects();
void purgeRuntime(); void purgeRuntime();
MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, MOZ_MUST_USE bool beginMarkPhase(JS::GCReason reason, AutoGCSession& session);
AutoGCSession& session); bool prepareZonesForCollection(JS::GCReason reason, bool* isFullOut);
bool prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut);
bool shouldPreserveJITCode(JS::Realm* realm, bool shouldPreserveJITCode(JS::Realm* realm,
const mozilla::TimeStamp& currentTime, const mozilla::TimeStamp& currentTime,
JS::gcreason::Reason reason, JS::GCReason reason, bool canAllocateMoreCode);
bool canAllocateMoreCode);
void startBackgroundFreeAfterMinorGC(); void startBackgroundFreeAfterMinorGC();
void traceRuntimeForMajorGC(JSTracer* trc, AutoGCSession& session); void traceRuntimeForMajorGC(JSTracer* trc, AutoGCSession& session);
void traceRuntimeAtoms(JSTracer* trc, const AutoAccessAtomsZone& atomsAccess); void traceRuntimeAtoms(JSTracer* trc, const AutoAccessAtomsZone& atomsAccess);
@ -618,8 +616,8 @@ class GCRuntime {
void markAllWeakReferences(gcstats::PhaseKind phase); void markAllWeakReferences(gcstats::PhaseKind phase);
void markAllGrayReferences(gcstats::PhaseKind phase); void markAllGrayReferences(gcstats::PhaseKind phase);
void beginSweepPhase(JS::gcreason::Reason reason, AutoGCSession& session); void beginSweepPhase(JS::GCReason reason, AutoGCSession& session);
void groupZonesForSweeping(JS::gcreason::Reason reason); void groupZonesForSweeping(JS::GCReason reason);
MOZ_MUST_USE bool findInterZoneEdges(); MOZ_MUST_USE bool findInterZoneEdges();
void getNextSweepGroup(); void getNextSweepGroup();
IncrementalProgress markGrayReferencesInCurrentGroup(FreeOp* fop, IncrementalProgress markGrayReferencesInCurrentGroup(FreeOp* fop,
@ -655,13 +653,13 @@ class GCRuntime {
void assertBackgroundSweepingFinished(); void assertBackgroundSweepingFinished();
bool shouldCompact(); bool shouldCompact();
void beginCompactPhase(); void beginCompactPhase();
IncrementalProgress compactPhase(JS::gcreason::Reason reason, IncrementalProgress compactPhase(JS::GCReason reason,
SliceBudget& sliceBudget, SliceBudget& sliceBudget,
AutoGCSession& session); AutoGCSession& session);
void endCompactPhase(); void endCompactPhase();
void sweepTypesAfterCompacting(Zone* zone); void sweepTypesAfterCompacting(Zone* zone);
void sweepZoneAfterCompacting(Zone* zone); void sweepZoneAfterCompacting(Zone* zone);
MOZ_MUST_USE bool relocateArenas(Zone* zone, JS::gcreason::Reason reason, MOZ_MUST_USE bool relocateArenas(Zone* zone, JS::GCReason reason,
Arena*& relocatedListOut, Arena*& relocatedListOut,
SliceBudget& sliceBudget); SliceBudget& sliceBudget);
void updateTypeDescrObjects(MovingTracer* trc, Zone* zone); void updateTypeDescrObjects(MovingTracer* trc, Zone* zone);
@ -804,7 +802,7 @@ class GCRuntime {
*/ */
UnprotectedData<bool> grayBitsValid; UnprotectedData<bool> grayBitsValid;
mozilla::Atomic<JS::gcreason::Reason, mozilla::Relaxed, mozilla::Atomic<JS::GCReason, mozilla::Relaxed,
mozilla::recordreplay::Behavior::DontPreserve> mozilla::recordreplay::Behavior::DontPreserve>
majorGCTriggerReason; majorGCTriggerReason;
@ -834,7 +832,7 @@ class GCRuntime {
MainThreadData<JSGCInvocationKind> invocationKind; MainThreadData<JSGCInvocationKind> invocationKind;
/* The initial GC reason, taken from the first slice. */ /* The initial GC reason, taken from the first slice. */
MainThreadData<JS::gcreason::Reason> initialReason; MainThreadData<JS::GCReason> initialReason;
/* /*
* The current incremental GC phase. This is also used internally in * The current incremental GC phase. This is also used internally in
@ -1041,10 +1039,10 @@ class GCRuntime {
return stats().addressOfAllocsSinceMinorGCNursery(); return stats().addressOfAllocsSinceMinorGCNursery();
} }
void minorGC(JS::gcreason::Reason reason, void minorGC(JS::GCReason reason,
gcstats::PhaseKind phase = gcstats::PhaseKind::MINOR_GC) gcstats::PhaseKind phase = gcstats::PhaseKind::MINOR_GC)
JS_HAZ_GC_CALL; JS_HAZ_GC_CALL;
void evictNursery(JS::gcreason::Reason reason = JS::gcreason::EVICT_NURSERY) { void evictNursery(JS::GCReason reason = JS::GCReason::EVICT_NURSERY) {
minorGC(reason, gcstats::PhaseKind::EVICT_NURSERY); minorGC(reason, gcstats::PhaseKind::EVICT_NURSERY);
} }

Просмотреть файл

@ -95,20 +95,20 @@ using mozilla::PodCopy;
// '---------' '----------' '-----------------' // // '---------' '----------' '-----------------' //
// | // // | //
// | // // | //
// .--------. // // .-----------. //
// o---------------->|traverse| . // // o------------->|traverse(T)| . //
// /_\ '--------' ' . // // /_\ '-----------' ' . //
// | . . ' . // // | . . ' . //
// | . . ' . // // | . . ' . //
// | . . ' . // // | . . ' . //
// | .-----------. .-----------. ' . .--------------------. // // | .--------------. .--------------. ' . .-----------------------. //
// | |markAndScan| |markAndPush| ' - |markAndTraceChildren|----> // // | |markAndScan(T)| |markAndPush(T)| ' - |markAndTraceChildren(T)| //
// | '-----------' '-----------' '--------------------' // // | '--------------' '--------------' '-----------------------' //
// | | \ // // | | \ | //
// | | \ // // | | \ | //
// | .----------------------. .----------------. // // | .----------------------. .----------------. .------------------. //
// | |T::eagerlyMarkChildren| |pushMarkStackTop|<===Oo // // | |eagerlyMarkChildren(T)| |pushMarkStackTop|<===Oo |T::traceChildren()|--> //
// | '----------------------' '----------------' || // // | '----------------------' '----------------' || '------------------' //
// | | || || // // | | || || //
// | | || || // // | | || || //
// | | || || // // | | || || //
@ -847,7 +847,6 @@ void GCMarker::traverse(JSString* thing) {
template <> template <>
void GCMarker::traverse(LazyScript* thing) { void GCMarker::traverse(LazyScript* thing) {
markAndScan(thing); markAndScan(thing);
markImplicitEdges(thing);
} }
template <> template <>
void GCMarker::traverse(Shape* thing) { void GCMarker::traverse(Shape* thing) {
@ -1032,7 +1031,7 @@ void LazyScript::traceChildren(JSTracer* trc) {
} }
if (trc->isMarkingTracer()) { if (trc->isMarkingTracer()) {
return GCMarker::fromTracer(trc)->markImplicitEdges(this); GCMarker::fromTracer(trc)->markImplicitEdges(this);
} }
} }
inline void js::GCMarker::eagerlyMarkChildren(LazyScript* thing) { inline void js::GCMarker::eagerlyMarkChildren(LazyScript* thing) {
@ -1068,6 +1067,8 @@ inline void js::GCMarker::eagerlyMarkChildren(LazyScript* thing) {
for (auto i : IntegerRange(thing->numInnerFunctions())) { for (auto i : IntegerRange(thing->numInnerFunctions())) {
traverseEdge(thing, static_cast<JSObject*>(innerFunctions[i])); traverseEdge(thing, static_cast<JSObject*>(innerFunctions[i]));
} }
markImplicitEdges(thing);
} }
void Shape::traceChildren(JSTracer* trc) { void Shape::traceChildren(JSTracer* trc) {
@ -1101,7 +1102,7 @@ inline void js::GCMarker::eagerlyMarkChildren(Shape* shape) {
traverseEdge(shape, shape->propidRef().get()); traverseEdge(shape, shape->propidRef().get());
// When triggered between slices on belhalf of a barrier, these // When triggered between slices on behalf of a barrier, these
// objects may reside in the nursery, so require an extra check. // objects may reside in the nursery, so require an extra check.
// FIXME: Bug 1157967 - remove the isTenured checks. // FIXME: Bug 1157967 - remove the isTenured checks.
if (shape->hasGetterObject() && shape->getterObject()->isTenured()) { if (shape->hasGetterObject() && shape->getterObject()->isTenured()) {

Просмотреть файл

@ -112,7 +112,7 @@ js::Nursery::Nursery(JSRuntime* rt)
enableProfiling_(false), enableProfiling_(false),
canAllocateStrings_(false), canAllocateStrings_(false),
reportTenurings_(0), reportTenurings_(0),
minorGCTriggerReason_(JS::gcreason::NO_REASON) minorGCTriggerReason_(JS::GCReason::NO_REASON)
#ifdef JS_GC_ZEAL #ifdef JS_GC_ZEAL
, ,
lastCanary_(nullptr) lastCanary_(nullptr)
@ -588,7 +588,7 @@ void js::Nursery::renderProfileJSON(JSONPrinter& json) const {
return; return;
} }
if (previousGC.reason == JS::gcreason::NO_REASON) { if (previousGC.reason == JS::GCReason::NO_REASON) {
// If the nursery was empty when the last minorGC was requested, then // If the nursery was empty when the last minorGC was requested, then
// no nursery collection will have been performed but JSON may still be // no nursery collection will have been performed but JSON may still be
// requested. (And as a public API, this function should not crash in // requested. (And as a public API, this function should not crash in
@ -603,7 +603,7 @@ void js::Nursery::renderProfileJSON(JSONPrinter& json) const {
json.property("status", "complete"); json.property("status", "complete");
json.property("reason", JS::gcreason::ExplainReason(previousGC.reason)); json.property("reason", JS::ExplainGCReason(previousGC.reason));
json.property("bytes_tenured", previousGC.tenuredBytes); json.property("bytes_tenured", previousGC.tenuredBytes);
json.property("cells_tenured", previousGC.tenuredCells); json.property("cells_tenured", previousGC.tenuredCells);
json.property("strings_tenured", json.property("strings_tenured",
@ -702,16 +702,16 @@ bool js::Nursery::needIdleTimeCollection() const {
return minorGCRequested() || freeSpace() < threshold; return minorGCRequested() || freeSpace() < threshold;
} }
static inline bool IsFullStoreBufferReason(JS::gcreason::Reason reason) { static inline bool IsFullStoreBufferReason(JS::GCReason reason) {
return reason == JS::gcreason::FULL_WHOLE_CELL_BUFFER || return reason == JS::GCReason::FULL_WHOLE_CELL_BUFFER ||
reason == JS::gcreason::FULL_GENERIC_BUFFER || reason == JS::GCReason::FULL_GENERIC_BUFFER ||
reason == JS::gcreason::FULL_VALUE_BUFFER || reason == JS::GCReason::FULL_VALUE_BUFFER ||
reason == JS::gcreason::FULL_CELL_PTR_BUFFER || reason == JS::GCReason::FULL_CELL_PTR_BUFFER ||
reason == JS::gcreason::FULL_SLOT_BUFFER || reason == JS::GCReason::FULL_SLOT_BUFFER ||
reason == JS::gcreason::FULL_SHAPE_BUFFER; reason == JS::GCReason::FULL_SHAPE_BUFFER;
} }
void js::Nursery::collect(JS::gcreason::Reason reason) { void js::Nursery::collect(JS::GCReason reason) {
JSRuntime* rt = runtime(); JSRuntime* rt = runtime();
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC); MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
@ -750,7 +750,7 @@ void js::Nursery::collect(JS::gcreason::Reason reason) {
MOZ_ASSERT(!IsNurseryAllocable(AllocKind::OBJECT_GROUP)); MOZ_ASSERT(!IsNurseryAllocable(AllocKind::OBJECT_GROUP));
TenureCountCache tenureCounts; TenureCountCache tenureCounts;
previousGC.reason = JS::gcreason::NO_REASON; previousGC.reason = JS::GCReason::NO_REASON;
if (!isEmpty()) { if (!isEmpty()) {
doCollection(reason, tenureCounts); doCollection(reason, tenureCounts);
} else { } else {
@ -843,9 +843,9 @@ void js::Nursery::collect(JS::gcreason::Reason reason) {
TimeDuration totalTime = profileDurations_[ProfileKey::Total]; TimeDuration totalTime = profileDurations_[ProfileKey::Total];
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime.ToMicroseconds()); rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime.ToMicroseconds());
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, reason); rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, uint32_t(reason));
if (totalTime.ToMilliseconds() > 1.0) { if (totalTime.ToMilliseconds() > 1.0) {
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, reason); rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, uint32_t(reason));
} }
rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, sizeOfHeapCommitted()); rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, sizeOfHeapCommitted());
rt->addTelemetry(JS_TELEMETRY_GC_PRETENURE_COUNT, pretenureCount); rt->addTelemetry(JS_TELEMETRY_GC_PRETENURE_COUNT, pretenureCount);
@ -859,8 +859,7 @@ void js::Nursery::collect(JS::gcreason::Reason reason) {
stats().maybePrintProfileHeaders(); stats().maybePrintProfileHeaders();
fprintf(stderr, "MinorGC: %20s %5.1f%% %4u ", fprintf(stderr, "MinorGC: %20s %5.1f%% %4u ",
JS::gcreason::ExplainReason(reason), promotionRate * 100, JS::ExplainGCReason(reason), promotionRate * 100, maxChunkCount());
maxChunkCount());
printProfileDurations(profileDurations_); printProfileDurations(profileDurations_);
if (reportTenurings_) { if (reportTenurings_) {
@ -875,7 +874,7 @@ void js::Nursery::collect(JS::gcreason::Reason reason) {
} }
} }
void js::Nursery::doCollection(JS::gcreason::Reason reason, void js::Nursery::doCollection(JS::GCReason reason,
TenureCountCache& tenureCounts) { TenureCountCache& tenureCounts) {
JSRuntime* rt = runtime(); JSRuntime* rt = runtime();
AutoGCSession session(rt, JS::HeapState::MinorCollecting); AutoGCSession session(rt, JS::HeapState::MinorCollecting);
@ -1119,7 +1118,7 @@ MOZ_ALWAYS_INLINE void js::Nursery::setStartPosition() {
currentStartPosition_ = position(); currentStartPosition_ = position();
} }
void js::Nursery::maybeResizeNursery(JS::gcreason::Reason reason) { void js::Nursery::maybeResizeNursery(JS::GCReason reason) {
static const double GrowThreshold = 0.03; static const double GrowThreshold = 0.03;
static const double ShrinkThreshold = 0.01; static const double ShrinkThreshold = 0.01;
unsigned newMaxNurseryChunks; unsigned newMaxNurseryChunks;

Просмотреть файл

@ -271,7 +271,7 @@ class Nursery {
static const size_t MaxNurseryBufferSize = 1024; static const size_t MaxNurseryBufferSize = 1024;
/* Do a minor collection. */ /* Do a minor collection. */
void collect(JS::gcreason::Reason reason); void collect(JS::GCReason reason);
/* /*
* If the thing at |*ref| in the Nursery has been forwarded, set |*ref| to * If the thing at |*ref| in the Nursery has been forwarded, set |*ref| to
@ -352,16 +352,14 @@ class Nursery {
return (void*)&currentStringEnd_; return (void*)&currentStringEnd_;
} }
void requestMinorGC(JS::gcreason::Reason reason) const; void requestMinorGC(JS::GCReason reason) const;
bool minorGCRequested() const { bool minorGCRequested() const {
return minorGCTriggerReason_ != JS::gcreason::NO_REASON; return minorGCTriggerReason_ != JS::GCReason::NO_REASON;
}
JS::gcreason::Reason minorGCTriggerReason() const {
return minorGCTriggerReason_;
} }
JS::GCReason minorGCTriggerReason() const { return minorGCTriggerReason_; }
void clearMinorGCRequest() { void clearMinorGCRequest() {
minorGCTriggerReason_ = JS::gcreason::NO_REASON; minorGCTriggerReason_ = JS::GCReason::NO_REASON;
} }
bool needIdleTimeCollection() const; bool needIdleTimeCollection() const;
@ -442,7 +440,7 @@ class Nursery {
* mutable as it is set by the store buffer, which otherwise cannot modify * mutable as it is set by the store buffer, which otherwise cannot modify
* anything in the nursery. * anything in the nursery.
*/ */
mutable JS::gcreason::Reason minorGCTriggerReason_; mutable JS::GCReason minorGCTriggerReason_;
/* Profiling data. */ /* Profiling data. */
@ -465,7 +463,7 @@ class Nursery {
ProfileDurations totalDurations_; ProfileDurations totalDurations_;
struct { struct {
JS::gcreason::Reason reason = JS::gcreason::NO_REASON; JS::GCReason reason = JS::GCReason::NO_REASON;
size_t nurseryCapacity = 0; size_t nurseryCapacity = 0;
size_t nurseryLazyCapacity = 0; size_t nurseryLazyCapacity = 0;
size_t nurseryUsedBytes = 0; size_t nurseryUsedBytes = 0;
@ -562,8 +560,7 @@ class Nursery {
/* Common internal allocator function. */ /* Common internal allocator function. */
void* allocate(size_t size); void* allocate(size_t size);
void doCollection(JS::gcreason::Reason reason, void doCollection(JS::GCReason reason, gc::TenureCountCache& tenureCounts);
gc::TenureCountCache& tenureCounts);
/* /*
* Move the object at |src| in the Nursery to an already-allocated cell * Move the object at |src| in the Nursery to an already-allocated cell
@ -600,7 +597,7 @@ class Nursery {
void sweepMapAndSetObjects(); void sweepMapAndSetObjects();
/* Change the allocable space provided by the nursery. */ /* Change the allocable space provided by the nursery. */
void maybeResizeNursery(JS::gcreason::Reason reason); void maybeResizeNursery(JS::GCReason reason);
void growAllocableSpace(); void growAllocableSpace();
void shrinkAllocableSpace(unsigned newCount); void shrinkAllocableSpace(unsigned newCount);
void minimizeAllocableSpace(); void minimizeAllocableSpace();

Просмотреть файл

@ -90,13 +90,13 @@
* *
* While code generally takes the above factors into account in only an ad-hoc * While code generally takes the above factors into account in only an ad-hoc
* fashion, the API forces the user to pick a "reason" for the GC. We have a * fashion, the API forces the user to pick a "reason" for the GC. We have a
* bunch of JS::gcreason reasons in GCAPI.h. These fall into a few categories * bunch of JS::GCReason reasons in GCAPI.h. These fall into a few categories
* that generally coincide with one or more of the above factors. * that generally coincide with one or more of the above factors.
* *
* Embedding reasons: * Embedding reasons:
* *
* 1) Do a GC now because the embedding knows something useful about the * 1) Do a GC now because the embedding knows something useful about the
* zone's memory retention state. These are gcreasons like LOAD_END, * zone's memory retention state. These are GCReasons like LOAD_END,
* PAGE_HIDE, SET_NEW_DOCUMENT, DOM_UTILS. Mostly, Gecko uses these to * PAGE_HIDE, SET_NEW_DOCUMENT, DOM_UTILS. Mostly, Gecko uses these to
* indicate that a significant fraction of the scheduled zone's memory is * indicate that a significant fraction of the scheduled zone's memory is
* probably reclaimable. * probably reclaimable.

Просмотреть файл

@ -40,8 +40,8 @@ using mozilla::TimeStamp;
* larger-numbered reasons to pile up in the last telemetry bucket, or switch * larger-numbered reasons to pile up in the last telemetry bucket, or switch
* to GC_REASON_3 and bump the max value. * to GC_REASON_3 and bump the max value.
*/ */
JS_STATIC_ASSERT(JS::gcreason::NUM_TELEMETRY_REASONS >= JS_STATIC_ASSERT(JS::GCReason::NUM_TELEMETRY_REASONS >=
JS::gcreason::NUM_REASONS); JS::GCReason::NUM_REASONS);
using PhaseKindRange = using PhaseKindRange =
decltype(mozilla::MakeEnumeratedRange(PhaseKind::FIRST, PhaseKind::LIMIT)); decltype(mozilla::MakeEnumeratedRange(PhaseKind::FIRST, PhaseKind::LIMIT));
@ -64,11 +64,10 @@ const char* js::gcstats::ExplainInvocationKind(JSGCInvocationKind gckind) {
} }
} }
JS_PUBLIC_API const char* JS::gcreason::ExplainReason( JS_PUBLIC_API const char* JS::ExplainGCReason(JS::GCReason reason) {
JS::gcreason::Reason reason) {
switch (reason) { switch (reason) {
#define SWITCH_REASON(name, _) \ #define SWITCH_REASON(name, _) \
case JS::gcreason::name: \ case JS::GCReason::name: \
return #name; return #name;
GCREASONS(SWITCH_REASON) GCREASONS(SWITCH_REASON)
@ -279,7 +278,8 @@ UniqueChars Statistics::formatCompactSliceMessage() const {
"%s%s; Times: "; "%s%s; Times: ";
char buffer[1024]; char buffer[1024];
SprintfLiteral(buffer, format, index, t(slice.duration()), budgetDescription, SprintfLiteral(buffer, format, index, t(slice.duration()), budgetDescription,
t(slice.start - slices_[0].start), ExplainReason(slice.reason), t(slice.start - slices_[0].start),
ExplainGCReason(slice.reason),
slice.wasReset() ? "yes - " : "no", slice.wasReset() ? "yes - " : "no",
slice.wasReset() ? ExplainAbortReason(slice.resetReason) : ""); slice.wasReset() ? ExplainAbortReason(slice.resetReason) : "");
@ -442,7 +442,7 @@ UniqueChars Statistics::formatDetailedDescription() const {
char buffer[1024]; char buffer[1024];
SprintfLiteral( SprintfLiteral(
buffer, format, ExplainInvocationKind(gckind), buffer, format, ExplainInvocationKind(gckind),
ExplainReason(slices_[0].reason), nonincremental() ? "no - " : "yes", ExplainGCReason(slices_[0].reason), nonincremental() ? "no - " : "yes",
nonincremental() ? ExplainAbortReason(nonincrementalReason_) : "", nonincremental() ? ExplainAbortReason(nonincrementalReason_) : "",
zoneStats.collectedZoneCount, zoneStats.zoneCount, zoneStats.collectedZoneCount, zoneStats.zoneCount,
zoneStats.sweptZoneCount, zoneStats.collectedCompartmentCount, zoneStats.sweptZoneCount, zoneStats.collectedCompartmentCount,
@ -475,7 +475,7 @@ UniqueChars Statistics::formatDetailedSliceDescription(
"; ";
char buffer[1024]; char buffer[1024];
SprintfLiteral( SprintfLiteral(
buffer, format, i, ExplainReason(slice.reason), buffer, format, i, ExplainGCReason(slice.reason),
slice.wasReset() ? "yes - " : "no", slice.wasReset() ? "yes - " : "no",
slice.wasReset() ? ExplainAbortReason(slice.resetReason) : "", slice.wasReset() ? ExplainAbortReason(slice.resetReason) : "",
gc::StateName(slice.initialState), gc::StateName(slice.finalState), gc::StateName(slice.initialState), gc::StateName(slice.finalState),
@ -650,7 +650,7 @@ void Statistics::formatJsonDescription(uint64_t timestamp, JSONPrinter& json,
json.property("total_time", total, JSONPrinter::MILLISECONDS); // #4 json.property("total_time", total, JSONPrinter::MILLISECONDS); // #4
// We might be able to omit reason if perf.html was able to retrive it // We might be able to omit reason if perf.html was able to retrive it
// from the first slice. But it doesn't do this yet. // from the first slice. But it doesn't do this yet.
json.property("reason", ExplainReason(slices_[0].reason)); // #5 json.property("reason", ExplainGCReason(slices_[0].reason)); // #5
json.property("zones_collected", zoneStats.collectedZoneCount); // #6 json.property("zones_collected", zoneStats.collectedZoneCount); // #6
json.property("total_zones", zoneStats.zoneCount); // #7 json.property("total_zones", zoneStats.zoneCount); // #7
json.property("total_compartments", zoneStats.compartmentCount); // #8 json.property("total_compartments", zoneStats.compartmentCount); // #8
@ -713,7 +713,7 @@ void Statistics::formatJsonSliceDescription(unsigned i, const SliceData& slice,
json.property("slice", i); // JSON Property #1 json.property("slice", i); // JSON Property #1
json.property("pause", slice.duration(), JSONPrinter::MILLISECONDS); // #2 json.property("pause", slice.duration(), JSONPrinter::MILLISECONDS); // #2
json.property("reason", ExplainReason(slice.reason)); // #3 json.property("reason", ExplainGCReason(slice.reason)); // #3
json.property("initial_state", gc::StateName(slice.initialState)); // #4 json.property("initial_state", gc::StateName(slice.initialState)); // #4
json.property("final_state", gc::StateName(slice.finalState)); // #5 json.property("final_state", gc::StateName(slice.finalState)); // #5
json.property("budget", budgetDescription); // #6 json.property("budget", budgetDescription); // #6
@ -1024,7 +1024,7 @@ void Statistics::endGC() {
thresholdTriggered = false; thresholdTriggered = false;
} }
void Statistics::beginNurseryCollection(JS::gcreason::Reason reason) { void Statistics::beginNurseryCollection(JS::GCReason reason) {
count(COUNT_MINOR_GC); count(COUNT_MINOR_GC);
startingMinorGCNumber = runtime->gc.minorGCCount(); startingMinorGCNumber = runtime->gc.minorGCCount();
if (nurseryCollectionCallback) { if (nurseryCollectionCallback) {
@ -1034,7 +1034,7 @@ void Statistics::beginNurseryCollection(JS::gcreason::Reason reason) {
} }
} }
void Statistics::endNurseryCollection(JS::gcreason::Reason reason) { void Statistics::endNurseryCollection(JS::GCReason reason) {
if (nurseryCollectionCallback) { if (nurseryCollectionCallback) {
(*nurseryCollectionCallback)( (*nurseryCollectionCallback)(
runtime->mainContextFromOwnThread(), runtime->mainContextFromOwnThread(),
@ -1046,7 +1046,7 @@ void Statistics::endNurseryCollection(JS::gcreason::Reason reason) {
void Statistics::beginSlice(const ZoneGCStats& zoneStats, void Statistics::beginSlice(const ZoneGCStats& zoneStats,
JSGCInvocationKind gckind, SliceBudget budget, JSGCInvocationKind gckind, SliceBudget budget,
JS::gcreason::Reason reason) { JS::GCReason reason) {
MOZ_ASSERT(phaseStack.empty() || MOZ_ASSERT(phaseStack.empty() ||
(phaseStack.length() == 1 && phaseStack[0] == Phase::MUTATOR)); (phaseStack.length() == 1 && phaseStack[0] == Phase::MUTATOR));
@ -1064,7 +1064,7 @@ void Statistics::beginSlice(const ZoneGCStats& zoneStats,
return; return;
} }
runtime->addTelemetry(JS_TELEMETRY_GC_REASON, reason); runtime->addTelemetry(JS_TELEMETRY_GC_REASON, uint32_t(reason));
// Slice callbacks should only fire for the outermost level. // Slice callbacks should only fire for the outermost level.
bool wasFullGC = zoneStats.isFullCollection(); bool wasFullGC = zoneStats.isFullCollection();
@ -1485,7 +1485,7 @@ void Statistics::printSliceProfile() {
bool full = zoneStats.isFullCollection(); bool full = zoneStats.isFullCollection();
fprintf(stderr, "MajorGC: %20s %1d -> %1d %1s%1s%1s%1s ", fprintf(stderr, "MajorGC: %20s %1d -> %1d %1s%1s%1s%1s ",
ExplainReason(slice.reason), int(slice.initialState), ExplainGCReason(slice.reason), int(slice.initialState),
int(slice.finalState), full ? "F" : "", shrinking ? "S" : "", int(slice.finalState), full ? "F" : "", shrinking ? "S" : "",
nonIncremental ? "N" : "", reset ? "R" : ""); nonIncremental ? "N" : "", reset ? "R" : "");

Просмотреть файл

@ -163,7 +163,7 @@ struct Statistics {
void resumePhases(); void resumePhases();
void beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind, void beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
SliceBudget budget, JS::gcreason::Reason reason); SliceBudget budget, JS::GCReason reason);
void endSlice(); void endSlice();
MOZ_MUST_USE bool startTimingMutator(); MOZ_MUST_USE bool startTimingMutator();
@ -223,8 +223,8 @@ struct Statistics {
return &allocsSinceMinorGC.nursery; return &allocsSinceMinorGC.nursery;
} }
void beginNurseryCollection(JS::gcreason::Reason reason); void beginNurseryCollection(JS::GCReason reason);
void endNurseryCollection(JS::gcreason::Reason reason); void endNurseryCollection(JS::GCReason reason);
TimeStamp beginSCC(); TimeStamp beginSCC();
void endSCC(unsigned scc, TimeStamp start); void endSCC(unsigned scc, TimeStamp start);
@ -245,7 +245,7 @@ struct Statistics {
static const size_t MAX_SUSPENDED_PHASES = MAX_PHASE_NESTING * 3; static const size_t MAX_SUSPENDED_PHASES = MAX_PHASE_NESTING * 3;
struct SliceData { struct SliceData {
SliceData(SliceBudget budget, JS::gcreason::Reason reason, TimeStamp start, SliceData(SliceBudget budget, JS::GCReason reason, TimeStamp start,
size_t startFaults, gc::State initialState) size_t startFaults, gc::State initialState)
: budget(budget), : budget(budget),
reason(reason), reason(reason),
@ -257,7 +257,7 @@ struct Statistics {
endFaults(0) {} endFaults(0) {}
SliceBudget budget; SliceBudget budget;
JS::gcreason::Reason reason; JS::GCReason reason;
gc::State initialState, finalState; gc::State initialState, finalState;
gc::AbortReason resetReason; gc::AbortReason resetReason;
TimeStamp start, end; TimeStamp start, end;
@ -457,7 +457,7 @@ struct Statistics {
struct MOZ_RAII AutoGCSlice { struct MOZ_RAII AutoGCSlice {
AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats, AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats,
JSGCInvocationKind gckind, SliceBudget budget, JSGCInvocationKind gckind, SliceBudget budget,
JS::gcreason::Reason reason) JS::GCReason reason)
: stats(stats) { : stats(stats) {
stats.beginSlice(zoneStats, gckind, budget, reason); stats.beginSlice(zoneStats, gckind, budget, reason);
} }

Просмотреть файл

@ -81,7 +81,7 @@ void StoreBuffer::clear() {
bufferGeneric.clear(); bufferGeneric.clear();
} }
void StoreBuffer::setAboutToOverflow(JS::gcreason::Reason reason) { void StoreBuffer::setAboutToOverflow(JS::GCReason reason) {
if (!aboutToOverflow_) { if (!aboutToOverflow_) {
aboutToOverflow_ = true; aboutToOverflow_ = true;
runtime_->gc.stats().count(gcstats::COUNT_STOREBUFFER_OVERFLOW); runtime_->gc.stats().count(gcstats::COUNT_STOREBUFFER_OVERFLOW);
@ -132,7 +132,7 @@ ArenaCellSet* StoreBuffer::WholeCellBuffer::allocateCellSet(Arena* arena) {
if (isAboutToOverflow()) { if (isAboutToOverflow()) {
rt->gc.storeBuffer().setAboutToOverflow( rt->gc.storeBuffer().setAboutToOverflow(
JS::gcreason::FULL_WHOLE_CELL_BUFFER); JS::GCReason::FULL_WHOLE_CELL_BUFFER);
} }
return cells; return cells;

Просмотреть файл

@ -237,7 +237,7 @@ class StoreBuffer {
} }
if (isAboutToOverflow()) { if (isAboutToOverflow()) {
owner->setAboutToOverflow(JS::gcreason::FULL_GENERIC_BUFFER); owner->setAboutToOverflow(JS::GCReason::FULL_GENERIC_BUFFER);
} }
} }
@ -292,7 +292,7 @@ class StoreBuffer {
typedef PointerEdgeHasher<CellPtrEdge> Hasher; typedef PointerEdgeHasher<CellPtrEdge> Hasher;
static const auto FullBufferReason = JS::gcreason::FULL_CELL_PTR_BUFFER; static const auto FullBufferReason = JS::GCReason::FULL_CELL_PTR_BUFFER;
}; };
struct ValueEdge { struct ValueEdge {
@ -327,7 +327,7 @@ class StoreBuffer {
typedef PointerEdgeHasher<ValueEdge> Hasher; typedef PointerEdgeHasher<ValueEdge> Hasher;
static const auto FullBufferReason = JS::gcreason::FULL_VALUE_BUFFER; static const auto FullBufferReason = JS::GCReason::FULL_VALUE_BUFFER;
}; };
struct SlotsEdge { struct SlotsEdge {
@ -410,7 +410,7 @@ class StoreBuffer {
static bool match(const SlotsEdge& k, const Lookup& l) { return k == l; } static bool match(const SlotsEdge& k, const Lookup& l) { return k == l; }
} Hasher; } Hasher;
static const auto FullBufferReason = JS::gcreason::FULL_SLOT_BUFFER; static const auto FullBufferReason = JS::GCReason::FULL_SLOT_BUFFER;
}; };
template <typename Buffer, typename Edge> template <typename Buffer, typename Edge>
@ -520,7 +520,7 @@ class StoreBuffer {
void traceGenericEntries(JSTracer* trc) { bufferGeneric.trace(this, trc); } void traceGenericEntries(JSTracer* trc) { bufferGeneric.trace(this, trc); }
/* For use by our owned buffers and for testing. */ /* For use by our owned buffers and for testing. */
void setAboutToOverflow(JS::gcreason::Reason); void setAboutToOverflow(JS::GCReason);
void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf, void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
JS::GCSizes* sizes); JS::GCSizes* sizes);

Просмотреть файл

@ -489,7 +489,7 @@ void JS::Zone::maybeTriggerGCForTooMuchMalloc(js::gc::MemoryCounter& counter,
return; return;
} }
if (!rt->gc.triggerZoneGC(this, JS::gcreason::TOO_MUCH_MALLOC, if (!rt->gc.triggerZoneGC(this, JS::GCReason::TOO_MUCH_MALLOC,
counter.bytes(), counter.maxBytes())) { counter.bytes(), counter.maxBytes())) {
return; return;
} }

Просмотреть файл

@ -0,0 +1,18 @@
// |jit-test| error: ReferenceError
gczeal(0);
gcparam("markStackLimit", 1);
var g = newGlobal({
newCompartment: true
});
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
dbg.onDebuggerStatement = function(frame) {
frame.environment.parent.getVariable('y')
};
g.eval(`
let y = 1;
g = function () { debugger; };
g();
`);
gczeal(9, 10);
f4();

Просмотреть файл

@ -245,7 +245,7 @@ void runTestFromPath(JSContext* cx, const char* path) {
// running everything from the same cx and without returning to JS, there // running everything from the same cx and without returning to JS, there
// is nothing to deallocate the ASTs. // is nothing to deallocate the ASTs.
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::NO_REASON); cx->runtime()->gc.gc(GC_NORMAL, JS::GCReason::NO_REASON);
} }
LifoAllocScope allocScope(&cx->tempLifoAlloc()); LifoAllocScope allocScope(&cx->tempLifoAlloc());

Просмотреть файл

@ -8,7 +8,7 @@ namespace {
struct ErrorInterceptorWithGC : JSErrorInterceptor { struct ErrorInterceptorWithGC : JSErrorInterceptor {
void interceptError(JSContext* cx, JS::HandleValue val) override { void interceptError(JSContext* cx, JS::HandleValue val) override {
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, GC_SHRINK, JS::gcreason::DEBUG_GC); JS::NonIncrementalGC(cx, GC_SHRINK, JS::GCReason::DEBUG_GC);
} }
}; };

Просмотреть файл

@ -21,10 +21,10 @@ BEGIN_TEST(testGCFinalizeCallback) {
/* Full GC, incremental. */ /* Full GC, incremental. */
FinalizeCalls = 0; FinalizeCalls = 0;
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::StartIncrementalGC(cx, GC_NORMAL, JS::gcreason::API, 1000000); JS::StartIncrementalGC(cx, GC_NORMAL, JS::GCReason::API, 1000000);
while (cx->runtime()->gc.isIncrementalGCInProgress()) { while (cx->runtime()->gc.isIncrementalGCInProgress()) {
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::IncrementalGCSlice(cx, JS::gcreason::API, 1000000); JS::IncrementalGCSlice(cx, JS::GCReason::API, 1000000);
} }
CHECK(!cx->runtime()->gc.isIncrementalGCInProgress()); CHECK(!cx->runtime()->gc.isIncrementalGCInProgress());
CHECK(cx->runtime()->gc.isFullGc()); CHECK(cx->runtime()->gc.isFullGc());
@ -47,7 +47,7 @@ BEGIN_TEST(testGCFinalizeCallback) {
/* Zone GC, non-incremental, single zone. */ /* Zone GC, non-incremental, single zone. */
FinalizeCalls = 0; FinalizeCalls = 0;
JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global1->zone());
JS::NonIncrementalGC(cx, GC_NORMAL, JS::gcreason::API); JS::NonIncrementalGC(cx, GC_NORMAL, JS::GCReason::API);
CHECK(!cx->runtime()->gc.isFullGc()); CHECK(!cx->runtime()->gc.isFullGc());
CHECK(checkSingleGroup()); CHECK(checkSingleGroup());
CHECK(checkFinalizeStatus()); CHECK(checkFinalizeStatus());
@ -57,7 +57,7 @@ BEGIN_TEST(testGCFinalizeCallback) {
JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global1->zone());
JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global2->zone());
JS::PrepareZoneForGC(global3->zone()); JS::PrepareZoneForGC(global3->zone());
JS::NonIncrementalGC(cx, GC_NORMAL, JS::gcreason::API); JS::NonIncrementalGC(cx, GC_NORMAL, JS::GCReason::API);
CHECK(!cx->runtime()->gc.isFullGc()); CHECK(!cx->runtime()->gc.isFullGc());
CHECK(checkSingleGroup()); CHECK(checkSingleGroup());
CHECK(checkFinalizeStatus()); CHECK(checkFinalizeStatus());
@ -65,10 +65,10 @@ BEGIN_TEST(testGCFinalizeCallback) {
/* Zone GC, incremental, single zone. */ /* Zone GC, incremental, single zone. */
FinalizeCalls = 0; FinalizeCalls = 0;
JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global1->zone());
JS::StartIncrementalGC(cx, GC_NORMAL, JS::gcreason::API, 1000000); JS::StartIncrementalGC(cx, GC_NORMAL, JS::GCReason::API, 1000000);
while (cx->runtime()->gc.isIncrementalGCInProgress()) { while (cx->runtime()->gc.isIncrementalGCInProgress()) {
JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global1->zone());
JS::IncrementalGCSlice(cx, JS::gcreason::API, 1000000); JS::IncrementalGCSlice(cx, JS::GCReason::API, 1000000);
} }
CHECK(!cx->runtime()->gc.isIncrementalGCInProgress()); CHECK(!cx->runtime()->gc.isIncrementalGCInProgress());
CHECK(!cx->runtime()->gc.isFullGc()); CHECK(!cx->runtime()->gc.isFullGc());
@ -80,12 +80,12 @@ BEGIN_TEST(testGCFinalizeCallback) {
JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global1->zone());
JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global2->zone());
JS::PrepareZoneForGC(global3->zone()); JS::PrepareZoneForGC(global3->zone());
JS::StartIncrementalGC(cx, GC_NORMAL, JS::gcreason::API, 1000000); JS::StartIncrementalGC(cx, GC_NORMAL, JS::GCReason::API, 1000000);
while (cx->runtime()->gc.isIncrementalGCInProgress()) { while (cx->runtime()->gc.isIncrementalGCInProgress()) {
JS::PrepareZoneForGC(global1->zone()); JS::PrepareZoneForGC(global1->zone());
JS::PrepareZoneForGC(global2->zone()); JS::PrepareZoneForGC(global2->zone());
JS::PrepareZoneForGC(global3->zone()); JS::PrepareZoneForGC(global3->zone());
JS::IncrementalGCSlice(cx, JS::gcreason::API, 1000000); JS::IncrementalGCSlice(cx, JS::GCReason::API, 1000000);
} }
CHECK(!cx->runtime()->gc.isIncrementalGCInProgress()); CHECK(!cx->runtime()->gc.isIncrementalGCInProgress());
CHECK(!cx->runtime()->gc.isFullGc()); CHECK(!cx->runtime()->gc.isFullGc());

Просмотреть файл

@ -464,7 +464,7 @@ bool TestCCWs() {
CHECK(GetCrossCompartmentWrapper(target) == wrapper); CHECK(GetCrossCompartmentWrapper(target) == wrapper);
CHECK(IsMarkedBlack(wrapper)); CHECK(IsMarkedBlack(wrapper));
JS::FinishIncrementalGC(cx, JS::gcreason::API); JS::FinishIncrementalGC(cx, JS::GCReason::API);
// Test behaviour of gray CCWs marked black by a barrier during incremental // Test behaviour of gray CCWs marked black by a barrier during incremental
// GC. // GC.
@ -500,7 +500,7 @@ bool TestCCWs() {
CHECK(!JS::ObjectIsMarkedGray(target)); CHECK(!JS::ObjectIsMarkedGray(target));
// Final state: source and target are black. // Final state: source and target are black.
JS::FinishIncrementalGC(cx, JS::gcreason::API); JS::FinishIncrementalGC(cx, JS::GCReason::API);
CHECK(IsMarkedBlack(wrapper)); CHECK(IsMarkedBlack(wrapper));
CHECK(IsMarkedBlack(target)); CHECK(IsMarkedBlack(target));
@ -739,7 +739,7 @@ bool ZoneGC(JS::Zone* zone) {
uint32_t oldMode = JS_GetGCParameter(cx, JSGC_MODE); uint32_t oldMode = JS_GetGCParameter(cx, JSGC_MODE);
JS_SetGCParameter(cx, JSGC_MODE, JSGC_MODE_ZONE); JS_SetGCParameter(cx, JSGC_MODE, JSGC_MODE_ZONE);
JS::PrepareZoneForGC(zone); JS::PrepareZoneForGC(zone);
cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::API); cx->runtime()->gc.gc(GC_NORMAL, JS::GCReason::API);
CHECK(!cx->runtime()->gc.isFullGc()); CHECK(!cx->runtime()->gc.isFullGc());
JS_SetGCParameter(cx, JSGC_MODE, oldMode); JS_SetGCParameter(cx, JSGC_MODE, oldMode);
return true; return true;

Просмотреть файл

@ -131,7 +131,7 @@ bool TestHeapPostBarrierUpdate() {
ptr = testStruct.release(); ptr = testStruct.release();
} }
cx->minorGC(JS::gcreason::API); cx->minorGC(JS::GCReason::API);
W& wrapper = ptr->wrapper; W& wrapper = ptr->wrapper;
CHECK(uintptr_t(wrapper.get()) != initialObjAsInt); CHECK(uintptr_t(wrapper.get()) != initialObjAsInt);
@ -140,7 +140,7 @@ bool TestHeapPostBarrierUpdate() {
JS::DeletePolicy<TestStruct<W>>()(ptr); JS::DeletePolicy<TestStruct<W>>()(ptr);
cx->minorGC(JS::gcreason::API); cx->minorGC(JS::GCReason::API);
return true; return true;
} }
@ -166,7 +166,7 @@ bool TestHeapPostBarrierInitFailure() {
// testStruct deleted here, as if we left this block due to an error. // testStruct deleted here, as if we left this block due to an error.
} }
cx->minorGC(JS::gcreason::API); cx->minorGC(JS::GCReason::API);
return true; return true;
} }

Просмотреть файл

@ -20,7 +20,7 @@ static void NonIncrementalGCSliceCallback(JSContext* cx,
MOZ_RELEASE_ASSERT(progress == expect[gSliceCallbackCount++]); MOZ_RELEASE_ASSERT(progress == expect[gSliceCallbackCount++]);
MOZ_RELEASE_ASSERT(desc.isZone_ == false); MOZ_RELEASE_ASSERT(desc.isZone_ == false);
MOZ_RELEASE_ASSERT(desc.invocationKind_ == GC_NORMAL); MOZ_RELEASE_ASSERT(desc.invocationKind_ == GC_NORMAL);
MOZ_RELEASE_ASSERT(desc.reason_ == JS::gcreason::API); MOZ_RELEASE_ASSERT(desc.reason_ == JS::GCReason::API);
if (progress == GC_CYCLE_END) { if (progress == GC_CYCLE_END) {
mozilla::UniquePtr<char16_t> summary(desc.formatSummaryMessage(cx)); mozilla::UniquePtr<char16_t> summary(desc.formatSummaryMessage(cx));
mozilla::UniquePtr<char16_t> message(desc.formatSliceMessage(cx)); mozilla::UniquePtr<char16_t> message(desc.formatSliceMessage(cx));
@ -41,16 +41,17 @@ END_TEST(testGCSliceCallback)
static void RootsRemovedGCSliceCallback(JSContext* cx, JS::GCProgress progress, static void RootsRemovedGCSliceCallback(JSContext* cx, JS::GCProgress progress,
const JS::GCDescription& desc) { const JS::GCDescription& desc) {
using namespace JS; using namespace JS;
using namespace JS::gcreason;
static GCProgress expectProgress[] = { static GCProgress expectProgress[] = {
GC_CYCLE_BEGIN, GC_SLICE_BEGIN, GC_SLICE_END, GC_SLICE_BEGIN, GC_CYCLE_BEGIN, GC_SLICE_BEGIN, GC_SLICE_END, GC_SLICE_BEGIN,
GC_SLICE_END, GC_CYCLE_END, GC_CYCLE_BEGIN, GC_SLICE_BEGIN, GC_SLICE_END, GC_CYCLE_END, GC_CYCLE_BEGIN, GC_SLICE_BEGIN,
GC_SLICE_END, GC_CYCLE_END}; GC_SLICE_END, GC_CYCLE_END};
static Reason expectReasons[] = { static GCReason expectReasons[] = {
DEBUG_GC, DEBUG_GC, DEBUG_GC, DEBUG_GC, DEBUG_GC, GCReason::DEBUG_GC, GCReason::DEBUG_GC, GCReason::DEBUG_GC,
DEBUG_GC, ROOTS_REMOVED, ROOTS_REMOVED, ROOTS_REMOVED, ROOTS_REMOVED}; GCReason::DEBUG_GC, GCReason::DEBUG_GC, GCReason::DEBUG_GC,
GCReason::ROOTS_REMOVED, GCReason::ROOTS_REMOVED, GCReason::ROOTS_REMOVED,
GCReason::ROOTS_REMOVED};
static_assert( static_assert(
mozilla::ArrayLength(expectProgress) == mozilla::ArrayLength(expectProgress) ==
@ -87,7 +88,7 @@ BEGIN_TEST(testGCRootsRemoved) {
// Trigger another GC after the current one in shrinking / shutdown GCs. // Trigger another GC after the current one in shrinking / shutdown GCs.
cx->runtime()->gc.notifyRootsRemoved(); cx->runtime()->gc.notifyRootsRemoved();
JS::FinishIncrementalGC(cx, JS::gcreason::DEBUG_GC); JS::FinishIncrementalGC(cx, JS::GCReason::DEBUG_GC);
CHECK(!JS::IsIncrementalGCInProgress(cx)); CHECK(!JS::IsIncrementalGCInProgress(cx));
JS::SetGCSliceCallback(cx, nullptr); JS::SetGCSliceCallback(cx, nullptr);

Просмотреть файл

@ -341,7 +341,7 @@ BEGIN_TEST(testIncrementalRoots) {
// Tenure everything so intentionally unrooted objects don't move before we // Tenure everything so intentionally unrooted objects don't move before we
// can use them. // can use them.
cx->runtime()->gc.minorGC(JS::gcreason::API); cx->runtime()->gc.minorGC(JS::GCReason::API);
// Release all roots except for the AutoObjectVector. // Release all roots except for the AutoObjectVector.
obj = root = nullptr; obj = root = nullptr;

Просмотреть файл

@ -110,7 +110,7 @@ BEGIN_TEST(testGCUID) {
// Force a compaction to move the object and check that the uid moved to // Force a compaction to move the object and check that the uid moved to
// the new tenured heap location. // the new tenured heap location.
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, GC_SHRINK, JS::gcreason::API); JS::NonIncrementalGC(cx, GC_SHRINK, JS::GCReason::API);
// There's a very low probability that this check could fail, but it is // There's a very low probability that this check could fail, but it is
// possible. If it becomes an annoying intermittent then we should make // possible. If it becomes an annoying intermittent then we should make

Просмотреть файл

@ -249,7 +249,7 @@ bool SweepCacheAndFinishGC(JSContext* cx, const Cache& cache) {
CHECK(IsIncrementalGCInProgress(cx)); CHECK(IsIncrementalGCInProgress(cx));
PrepareForIncrementalGC(cx); PrepareForIncrementalGC(cx);
IncrementalGCSlice(cx, JS::gcreason::API); IncrementalGCSlice(cx, JS::GCReason::API);
JS::Zone* zone = JS::GetObjectZone(global); JS::Zone* zone = JS::GetObjectZone(global);
CHECK(!IsIncrementalGCInProgress(cx)); CHECK(!IsIncrementalGCInProgress(cx));

Просмотреть файл

@ -28,7 +28,7 @@ BEGIN_TEST(testGCWeakRef) {
JS::Rooted<MyHeap> heap(cx, MyHeap(obj)); JS::Rooted<MyHeap> heap(cx, MyHeap(obj));
obj = nullptr; obj = nullptr;
cx->runtime()->gc.minorGC(JS::gcreason::API); cx->runtime()->gc.minorGC(JS::GCReason::API);
// The minor collection should have treated the weak ref as a strong ref, // The minor collection should have treated the weak ref as a strong ref,
// so the object should still be live, despite not having any other live // so the object should still be live, despite not having any other live

Просмотреть файл

@ -75,10 +75,10 @@ bool testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts) {
CHECK_EQUAL(value.toInt32(), 45); CHECK_EQUAL(value.toInt32(), 45);
CHECK_EQUAL(countIonScripts(global), 1u); CHECK_EQUAL(countIonScripts(global), 1u);
NonIncrementalGC(cx, GC_NORMAL, gcreason::API); NonIncrementalGC(cx, GC_NORMAL, GCReason::API);
CHECK_EQUAL(countIonScripts(global), remainingIonScripts); CHECK_EQUAL(countIonScripts(global), remainingIonScripts);
NonIncrementalGC(cx, GC_SHRINK, gcreason::API); NonIncrementalGC(cx, GC_SHRINK, GCReason::API);
CHECK_EQUAL(countIonScripts(global), 0u); CHECK_EQUAL(countIonScripts(global), 0u);
return true; return true;

Просмотреть файл

@ -498,7 +498,7 @@ class AutoLeaveZeal {
JS_GetGCZealBits(cx_, &zealBits_, &frequency_, &dummy); JS_GetGCZealBits(cx_, &zealBits_, &frequency_, &dummy);
JS_SetGCZeal(cx_, 0, 0); JS_SetGCZeal(cx_, 0, 0);
JS::PrepareForFullGC(cx_); JS::PrepareForFullGC(cx_);
JS::NonIncrementalGC(cx_, GC_SHRINK, JS::gcreason::DEBUG_GC); JS::NonIncrementalGC(cx_, GC_SHRINK, JS::GCReason::DEBUG_GC);
} }
~AutoLeaveZeal() { ~AutoLeaveZeal() {
JS_SetGCZeal(cx_, 0, 0); JS_SetGCZeal(cx_, 0, 0);

Просмотреть файл

@ -1167,14 +1167,14 @@ JS_PUBLIC_API bool JS::IsIdleGCTaskNeeded(JSRuntime* rt) {
JS_PUBLIC_API void JS::RunIdleTimeGCTask(JSRuntime* rt) { JS_PUBLIC_API void JS::RunIdleTimeGCTask(JSRuntime* rt) {
gc::GCRuntime& gc = rt->gc; gc::GCRuntime& gc = rt->gc;
if (gc.nursery().needIdleTimeCollection()) { if (gc.nursery().needIdleTimeCollection()) {
gc.minorGC(JS::gcreason::IDLE_TIME_COLLECTION); gc.minorGC(JS::GCReason::IDLE_TIME_COLLECTION);
} }
} }
JS_PUBLIC_API void JS_GC(JSContext* cx) { JS_PUBLIC_API void JS_GC(JSContext* cx) {
AssertHeapIsIdle(); AssertHeapIsIdle();
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::API); cx->runtime()->gc.gc(GC_NORMAL, JS::GCReason::API);
} }
JS_PUBLIC_API void JS_MaybeGC(JSContext* cx) { JS_PUBLIC_API void JS_MaybeGC(JSContext* cx) {

Просмотреть файл

@ -1118,7 +1118,7 @@ void DumpHeapTracer::onChild(const JS::GCCellPtr& thing) {
void js::DumpHeap(JSContext* cx, FILE* fp, void js::DumpHeap(JSContext* cx, FILE* fp,
js::DumpHeapNurseryBehaviour nurseryBehaviour) { js::DumpHeapNurseryBehaviour nurseryBehaviour) {
if (nurseryBehaviour == js::CollectNurseryBeforeDump) { if (nurseryBehaviour == js::CollectNurseryBeforeDump) {
cx->runtime()->gc.evictNursery(JS::gcreason::API); cx->runtime()->gc.evictNursery(JS::GCReason::API);
} }
DumpHeapTracer dtrc(fp, cx); DumpHeapTracer dtrc(fp, cx);

Просмотреть файл

@ -1840,7 +1840,7 @@ static void my_LargeAllocFailCallback() {
MOZ_ASSERT(!JS::RuntimeHeapIsBusy()); MOZ_ASSERT(!JS::RuntimeHeapIsBusy());
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::SHARED_MEMORY_LIMIT); cx->runtime()->gc.gc(GC_NORMAL, JS::GCReason::SHARED_MEMORY_LIMIT);
} }
static const uint32_t CacheEntry_SOURCE = 0; static const uint32_t CacheEntry_SOURCE = 0;

Просмотреть файл

@ -846,12 +846,12 @@ static bool CreateBuffer(
// See MaximumLiveMappedBuffers comment above. // See MaximumLiveMappedBuffers comment above.
if (liveBufferCount > StartSyncFullGCAtLiveBufferCount) { if (liveBufferCount > StartSyncFullGCAtLiveBufferCount) {
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, GC_NORMAL, JS::gcreason::TOO_MUCH_WASM_MEMORY); JS::NonIncrementalGC(cx, GC_NORMAL, JS::GCReason::TOO_MUCH_WASM_MEMORY);
allocatedSinceLastTrigger = 0; allocatedSinceLastTrigger = 0;
} else if (liveBufferCount > StartTriggeringAtLiveBufferCount) { } else if (liveBufferCount > StartTriggeringAtLiveBufferCount) {
allocatedSinceLastTrigger++; allocatedSinceLastTrigger++;
if (allocatedSinceLastTrigger > AllocatedBuffersPerTrigger) { if (allocatedSinceLastTrigger > AllocatedBuffersPerTrigger) {
Unused << cx->runtime()->gc.triggerGC(JS::gcreason::TOO_MUCH_WASM_MEMORY); Unused << cx->runtime()->gc.triggerGC(JS::GCReason::TOO_MUCH_WASM_MEMORY);
allocatedSinceLastTrigger = 0; allocatedSinceLastTrigger = 0;
} }
} else { } else {

Просмотреть файл

@ -12395,7 +12395,7 @@ namespace dbg {
// reasons this data is stored and replicated on each slice. Each // reasons this data is stored and replicated on each slice. Each
// slice used to have its own GCReason, but now they are all the // slice used to have its own GCReason, but now they are all the
// same. // same.
data->reason = gcreason::ExplainReason(slice.reason); data->reason = ExplainGCReason(slice.reason);
MOZ_ASSERT(data->reason); MOZ_ASSERT(data->reason);
} }

Просмотреть файл

@ -305,7 +305,7 @@ inline js::LifoAlloc& JSContext::typeLifoAlloc() {
inline js::Nursery& JSContext::nursery() { return runtime()->gc.nursery(); } inline js::Nursery& JSContext::nursery() { return runtime()->gc.nursery(); }
inline void JSContext::minorGC(JS::gcreason::Reason reason) { inline void JSContext::minorGC(JS::GCReason reason) {
runtime()->gc.minorGC(reason); runtime()->gc.minorGC(reason);
} }

Просмотреть файл

@ -740,7 +740,7 @@ struct JSContext : public JS::RootingContext,
AllowCrossRealm allowCrossRealm = AllowCrossRealm::DontAllow) const; AllowCrossRealm allowCrossRealm = AllowCrossRealm::DontAllow) const;
inline js::Nursery& nursery(); inline js::Nursery& nursery();
inline void minorGC(JS::gcreason::Reason reason); inline void minorGC(JS::GCReason reason);
public: public:
bool isExceptionPending() const { return throwing; } bool isExceptionPending() const { return throwing; }

Просмотреть файл

@ -4202,6 +4202,10 @@ void JSObject::traceChildren(JSTracer* trc) {
if (clasp->hasTrace()) { if (clasp->hasTrace()) {
clasp->doTrace(trc, this); clasp->doTrace(trc, this);
} }
if (trc->isMarkingTracer()) {
GCMarker::fromTracer(trc)->markImplicitEdges(this);
}
} }
static JSAtom* displayAtomFromObjectGroup(ObjectGroup& group) { static JSAtom* displayAtomFromObjectGroup(ObjectGroup& group) {

Просмотреть файл

@ -4411,7 +4411,7 @@ void JSScript::traceChildren(JSTracer* trc) {
jit::TraceJitScripts(trc, this); jit::TraceJitScripts(trc, this);
if (trc->isMarkingTracer()) { if (trc->isMarkingTracer()) {
return GCMarker::fromTracer(trc)->markImplicitEdges(this); GCMarker::fromTracer(trc)->markImplicitEdges(this);
} }
} }

Просмотреть файл

@ -280,7 +280,7 @@ void JSRuntime::destroyRuntime() {
profilingScripts = false; profilingScripts = false;
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
gc.gc(GC_NORMAL, JS::gcreason::DESTROY_RUNTIME); gc.gc(GC_NORMAL, JS::GCReason::DESTROY_RUNTIME);
} }
AutoNoteSingleThreadedRegion anstr; AutoNoteSingleThreadedRegion anstr;

Просмотреть файл

@ -151,7 +151,7 @@ static inline void GetterSetterWriteBarrierPost(AccessorShape* shape) {
if (nurseryShapes.length() == 1) { if (nurseryShapes.length() == 1) {
sb->putGeneric(NurseryShapesRef(shape->zone())); sb->putGeneric(NurseryShapesRef(shape->zone()));
} else if (nurseryShapes.length() == MaxShapeVectorLength) { } else if (nurseryShapes.length() == MaxShapeVectorLength) {
sb->setAboutToOverflow(JS::gcreason::FULL_SHAPE_BUFFER); sb->setAboutToOverflow(JS::GCReason::FULL_SHAPE_BUFFER);
} }
} }

Просмотреть файл

@ -1637,7 +1637,7 @@ NS_IMETHODIMP
nsXPCComponents_Utils::ForceGC() { nsXPCComponents_Utils::ForceGC() {
JSContext* cx = XPCJSContext::Get()->Context(); JSContext* cx = XPCJSContext::Get()->Context();
PrepareForFullGC(cx); PrepareForFullGC(cx);
NonIncrementalGC(cx, GC_NORMAL, gcreason::COMPONENT_UTILS); NonIncrementalGC(cx, GC_NORMAL, GCReason::COMPONENT_UTILS);
return NS_OK; return NS_OK;
} }
@ -1683,7 +1683,7 @@ NS_IMETHODIMP
nsXPCComponents_Utils::ForceShrinkingGC() { nsXPCComponents_Utils::ForceShrinkingGC() {
JSContext* cx = dom::danger::GetJSContext(); JSContext* cx = dom::danger::GetJSContext();
PrepareForFullGC(cx); PrepareForFullGC(cx);
NonIncrementalGC(cx, GC_SHRINK, gcreason::COMPONENT_UTILS); NonIncrementalGC(cx, GC_SHRINK, GCReason::COMPONENT_UTILS);
return NS_OK; return NS_OK;
} }
@ -1696,7 +1696,7 @@ class PreciseGCRunnable : public Runnable {
NS_IMETHOD Run() override { NS_IMETHOD Run() override {
nsJSContext::GarbageCollectNow( nsJSContext::GarbageCollectNow(
gcreason::COMPONENT_UTILS, nsJSContext::NonIncrementalGC, GCReason::COMPONENT_UTILS, nsJSContext::NonIncrementalGC,
mShrinking ? nsJSContext::ShrinkingGC : nsJSContext::NonShrinkingGC); mShrinking ? nsJSContext::ShrinkingGC : nsJSContext::NonShrinkingGC);
mCallback->Callback(); mCallback->Callback();

Просмотреть файл

@ -91,7 +91,7 @@ nsXPConnect::~nsXPConnect() {
// XPConnect, to clean the stuff we forcibly disconnected. The forced // XPConnect, to clean the stuff we forcibly disconnected. The forced
// shutdown code defaults to leaking in a number of situations, so we can't // shutdown code defaults to leaking in a number of situations, so we can't
// get by with only the second GC. :-( // get by with only the second GC. :-(
mRuntime->GarbageCollect(JS::gcreason::XPCONNECT_SHUTDOWN); mRuntime->GarbageCollect(JS::GCReason::XPCONNECT_SHUTDOWN);
mShuttingDown = true; mShuttingDown = true;
XPCWrappedNativeScope::SystemIsBeingShutDown(); XPCWrappedNativeScope::SystemIsBeingShutDown();
@ -101,7 +101,7 @@ nsXPConnect::~nsXPConnect() {
// after which point we need to GC to clean everything up. We need to do // after which point we need to GC to clean everything up. We need to do
// this before deleting the XPCJSContext, because doing so destroys the // this before deleting the XPCJSContext, because doing so destroys the
// maps that our finalize callback depends on. // maps that our finalize callback depends on.
mRuntime->GarbageCollect(JS::gcreason::XPCONNECT_SHUTDOWN); mRuntime->GarbageCollect(JS::GCReason::XPCONNECT_SHUTDOWN);
NS_RELEASE(gSystemPrincipal); NS_RELEASE(gSystemPrincipal);
gScriptSecurityManager = nullptr; gScriptSecurityManager = nullptr;

Просмотреть файл

@ -1156,7 +1156,7 @@ nsDocumentViewer::LoadComplete(nsresult aStatus) {
// It's probably a good idea to GC soon since we have finished loading. // It's probably a good idea to GC soon since we have finished loading.
nsJSContext::PokeGC( nsJSContext::PokeGC(
JS::gcreason::LOAD_END, JS::GCReason::LOAD_END,
mDocument ? mDocument->GetWrapperPreserveColor() : nullptr); mDocument ? mDocument->GetWrapperPreserveColor() : nullptr);
#ifdef NS_PRINTING #ifdef NS_PRINTING
@ -1412,7 +1412,7 @@ nsDocumentViewer::PageHide(bool aIsUnload) {
if (aIsUnload) { if (aIsUnload) {
// Poke the GC. The window might be collectable garbage now. // Poke the GC. The window might be collectable garbage now.
nsJSContext::PokeGC(JS::gcreason::PAGE_HIDE, nsJSContext::PokeGC(JS::GCReason::PAGE_HIDE,
mDocument->GetWrapperPreserveColor(), NS_GC_DELAY * 2); mDocument->GetWrapperPreserveColor(), NS_GC_DELAY * 2);
} }
@ -2361,7 +2361,7 @@ UniquePtr<ServoStyleSet> nsDocumentViewer::CreateStyleSet(Document* aDocument) {
NS_IMETHODIMP NS_IMETHODIMP
nsDocumentViewer::ClearHistoryEntry() { nsDocumentViewer::ClearHistoryEntry() {
if (mDocument) { if (mDocument) {
nsJSContext::PokeGC(JS::gcreason::PAGE_HIDE, nsJSContext::PokeGC(JS::GCReason::PAGE_HIDE,
mDocument->GetWrapperPreserveColor(), NS_GC_DELAY * 2); mDocument->GetWrapperPreserveColor(), NS_GC_DELAY * 2);
} }

Просмотреть файл

@ -561,7 +561,7 @@ VARCACHE_PREF(
VARCACHE_PREF( VARCACHE_PREF(
"html5.flushtimer.initialdelay", "html5.flushtimer.initialdelay",
html5_flushtimer_initialdelay, html5_flushtimer_initialdelay,
RelaxedAtomicInt32, 120 RelaxedAtomicInt32, 16
) )
// Time in milliseconds between the time a network buffer is seen and the timer // Time in milliseconds between the time a network buffer is seen and the timer
@ -569,7 +569,7 @@ VARCACHE_PREF(
VARCACHE_PREF( VARCACHE_PREF(
"html5.flushtimer.subsequentdelay", "html5.flushtimer.subsequentdelay",
html5_flushtimer_subsequentdelay, html5_flushtimer_subsequentdelay,
RelaxedAtomicInt32, 120 RelaxedAtomicInt32, 16
) )
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

Просмотреть файл

@ -863,7 +863,7 @@ class MaybeRunCollector : public Runnable {
NS_IMETHOD Run() override { NS_IMETHOD Run() override {
nsJSContext::MaybeRunNextCollectorSlice(mDocShell, nsJSContext::MaybeRunNextCollectorSlice(mDocShell,
JS::gcreason::HTML_PARSER); JS::GCReason::HTML_PARSER);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -547,7 +547,7 @@ the histogram."""
if not self._strict_type_checks: if not self._strict_type_checks:
# This handles some old non-numeric expressions. # This handles some old non-numeric expressions.
EXPRESSIONS = { EXPRESSIONS = {
"JS::gcreason::NUM_TELEMETRY_REASONS": 101, "JS::GCReason::NUM_TELEMETRY_REASONS": 101,
"mozilla::StartupTimeline::MAX_EVENT_ID": 12, "mozilla::StartupTimeline::MAX_EVENT_ID": 12,
} }

Просмотреть файл

@ -2342,11 +2342,11 @@ void TelemetryHistogram::InitializeGlobalState(bool canRecordBase,
// We add static asserts here for those values to match so that future changes // We add static asserts here for those values to match so that future changes
// don't go unnoticed. // don't go unnoticed.
// clang-format off // clang-format off
static_assert((JS::gcreason::NUM_TELEMETRY_REASONS + 1) == static_assert((uint32_t(JS::GCReason::NUM_TELEMETRY_REASONS) + 1) ==
gHistogramInfos[mozilla::Telemetry::GC_MINOR_REASON].bucketCount && gHistogramInfos[mozilla::Telemetry::GC_MINOR_REASON].bucketCount &&
(JS::gcreason::NUM_TELEMETRY_REASONS + 1) == (uint32_t(JS::GCReason::NUM_TELEMETRY_REASONS) + 1) ==
gHistogramInfos[mozilla::Telemetry::GC_MINOR_REASON_LONG].bucketCount && gHistogramInfos[mozilla::Telemetry::GC_MINOR_REASON_LONG].bucketCount &&
(JS::gcreason::NUM_TELEMETRY_REASONS + 1) == (uint32_t(JS::GCReason::NUM_TELEMETRY_REASONS) + 1) ==
gHistogramInfos[mozilla::Telemetry::GC_REASON_2].bucketCount, gHistogramInfos[mozilla::Telemetry::GC_REASON_2].bucketCount,
"NUM_TELEMETRY_REASONS is assumed to be a fixed value in Histograms.json." "NUM_TELEMETRY_REASONS is assumed to be a fixed value in Histograms.json."
" If this was an intentional change, update the n_values for the " " If this was an intentional change, update the n_values for the "

Просмотреть файл

@ -52,7 +52,7 @@ class TestParser(unittest.TestCase):
"TEST_NON_NUMERIC_HISTOGRAM": { "TEST_NON_NUMERIC_HISTOGRAM": {
"kind": "linear", "kind": "linear",
"description": "sample", "description": "sample",
"n_buckets": "JS::gcreason::NUM_TELEMETRY_REASONS", "n_buckets": "JS::GCReason::NUM_TELEMETRY_REASONS",
"high": "mozilla::StartupTimeline::MAX_EVENT_ID" "high": "mozilla::StartupTimeline::MAX_EVENT_ID"
}} }}

Просмотреть файл

@ -814,12 +814,12 @@ void CycleCollectedJSRuntime::TraverseNativeRoots(
if (aProgress == JS::GC_CYCLE_END && if (aProgress == JS::GC_CYCLE_END &&
JS::dbg::FireOnGarbageCollectionHookRequired(aContext)) { JS::dbg::FireOnGarbageCollectionHookRequired(aContext)) {
JS::gcreason::Reason reason = aDesc.reason_; JS::GCReason reason = aDesc.reason_;
Unused << NS_WARN_IF( Unused << NS_WARN_IF(
NS_FAILED(DebuggerOnGCRunnable::Enqueue(aContext, aDesc)) && NS_FAILED(DebuggerOnGCRunnable::Enqueue(aContext, aDesc)) &&
reason != JS::gcreason::SHUTDOWN_CC && reason != JS::GCReason::SHUTDOWN_CC &&
reason != JS::gcreason::DESTROY_RUNTIME && reason != JS::GCReason::DESTROY_RUNTIME &&
reason != JS::gcreason::XPCONNECT_SHUTDOWN); reason != JS::GCReason::XPCONNECT_SHUTDOWN);
} }
if (self->mPrevGCSliceCallback) { if (self->mPrevGCSliceCallback) {
@ -829,17 +829,17 @@ void CycleCollectedJSRuntime::TraverseNativeRoots(
class MinorGCMarker : public TimelineMarker { class MinorGCMarker : public TimelineMarker {
private: private:
JS::gcreason::Reason mReason; JS::GCReason mReason;
public: public:
MinorGCMarker(MarkerTracingType aTracingType, JS::gcreason::Reason aReason) MinorGCMarker(MarkerTracingType aTracingType, JS::GCReason aReason)
: TimelineMarker("MinorGC", aTracingType, MarkerStackRequest::NO_STACK), : TimelineMarker("MinorGC", aTracingType, MarkerStackRequest::NO_STACK),
mReason(aReason) { mReason(aReason) {
MOZ_ASSERT(aTracingType == MarkerTracingType::START || MOZ_ASSERT(aTracingType == MarkerTracingType::START ||
aTracingType == MarkerTracingType::END); aTracingType == MarkerTracingType::END);
} }
MinorGCMarker(JS::GCNurseryProgress aProgress, JS::gcreason::Reason aReason) MinorGCMarker(JS::GCNurseryProgress aProgress, JS::GCReason aReason)
: TimelineMarker( : TimelineMarker(
"MinorGC", "MinorGC",
aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START
@ -853,7 +853,7 @@ class MinorGCMarker : public TimelineMarker {
TimelineMarker::AddDetails(aCx, aMarker); TimelineMarker::AddDetails(aCx, aMarker);
if (GetTracingType() == MarkerTracingType::START) { if (GetTracingType() == MarkerTracingType::START) {
auto reason = JS::gcreason::ExplainReason(mReason); auto reason = JS::ExplainGCReason(mReason);
aMarker.mCauseName.Construct(NS_ConvertUTF8toUTF16(reason)); aMarker.mCauseName.Construct(NS_ConvertUTF8toUTF16(reason));
} }
} }
@ -867,7 +867,7 @@ class MinorGCMarker : public TimelineMarker {
/* static */ void CycleCollectedJSRuntime::GCNurseryCollectionCallback( /* static */ void CycleCollectedJSRuntime::GCNurseryCollectionCallback(
JSContext* aContext, JS::GCNurseryProgress aProgress, JSContext* aContext, JS::GCNurseryProgress aProgress,
JS::gcreason::Reason aReason) { JS::GCReason aReason) {
CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get(); CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get();
MOZ_ASSERT(CycleCollectedJSContext::Get()->Context() == aContext); MOZ_ASSERT(CycleCollectedJSContext::Get()->Context() == aContext);
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
@ -1125,13 +1125,10 @@ bool CycleCollectedJSRuntime::AreGCGrayBitsValid() const {
return js::AreGCGrayBitsValid(mJSRuntime); return js::AreGCGrayBitsValid(mJSRuntime);
} }
void CycleCollectedJSRuntime::GarbageCollect(uint32_t aReason) const { void CycleCollectedJSRuntime::GarbageCollect(JS::GCReason aReason) const {
MOZ_ASSERT(aReason < JS::gcreason::NUM_REASONS);
JS::gcreason::Reason gcreason = static_cast<JS::gcreason::Reason>(aReason);
JSContext* cx = CycleCollectedJSContext::Get()->Context(); JSContext* cx = CycleCollectedJSContext::Get()->Context();
JS::PrepareForFullGC(cx); JS::PrepareForFullGC(cx);
JS::NonIncrementalGC(cx, GC_NORMAL, gcreason); JS::NonIncrementalGC(cx, GC_NORMAL, aReason);
} }
void CycleCollectedJSRuntime::JSObjectsTenured() { void CycleCollectedJSRuntime::JSObjectsTenured() {

Просмотреть файл

@ -157,7 +157,7 @@ class CycleCollectedJSRuntime {
const JS::GCDescription& aDesc); const JS::GCDescription& aDesc);
static void GCNurseryCollectionCallback(JSContext* aContext, static void GCNurseryCollectionCallback(JSContext* aContext,
JS::GCNurseryProgress aProgress, JS::GCNurseryProgress aProgress,
JS::gcreason::Reason aReason); JS::GCReason aReason);
static void OutOfMemoryCallback(JSContext* aContext, void* aData); static void OutOfMemoryCallback(JSContext* aContext, void* aData);
/** /**
* Callback for reporting external string memory. * Callback for reporting external string memory.
@ -264,7 +264,7 @@ class CycleCollectedJSRuntime {
void FixWeakMappingGrayBits() const; void FixWeakMappingGrayBits() const;
void CheckGrayBits() const; void CheckGrayBits() const;
bool AreGCGrayBitsValid() const; bool AreGCGrayBitsValid() const;
void GarbageCollect(uint32_t aReason) const; void GarbageCollect(JS::GCReason aReason) const;
// This needs to be an nsWrapperCache, not a JSObject, because we need to know // This needs to be an nsWrapperCache, not a JSObject, because we need to know
// when our object gets moved. But we can't trace it (and hence update our // when our object gets moved. But we can't trace it (and hence update our

Просмотреть файл

@ -3272,8 +3272,8 @@ void nsCycleCollector::FixGrayBits(bool aForceGC, TimeLog& aTimeLog) {
uint32_t count = 0; uint32_t count = 0;
do { do {
mCCJSRuntime->GarbageCollect(aForceGC ? JS::gcreason::SHUTDOWN_CC mCCJSRuntime->GarbageCollect(aForceGC ? JS::GCReason::SHUTDOWN_CC
: JS::gcreason::CC_FORCED); : JS::GCReason::CC_FORCED);
mCCJSRuntime->FixWeakMappingGrayBits(); mCCJSRuntime->FixWeakMappingGrayBits();
@ -3296,7 +3296,7 @@ void nsCycleCollector::FinishAnyIncrementalGCInProgress() {
NS_WARNING("Finishing incremental GC in progress during CC"); NS_WARNING("Finishing incremental GC in progress during CC");
JSContext* cx = CycleCollectedJSContext::Get()->Context(); JSContext* cx = CycleCollectedJSContext::Get()->Context();
JS::PrepareForIncrementalGC(cx); JS::PrepareForIncrementalGC(cx);
JS::FinishIncrementalGC(cx, JS::gcreason::CC_FORCED); JS::FinishIncrementalGC(cx, JS::GCReason::CC_FORCED);
} }
} }