From 242858bbc1b500e7c28cb46e59199b34cc76d1e9 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Fri, 21 Jun 2024 16:22:26 +0000 Subject: [PATCH] Bug 1899872 - Move SliceBudget (and {Work,Time}Budget) from js:: namespace to JS:: r=jonco,mccr8 Differential Revision: https://phabricator.services.mozilla.com/D212303 --- dom/base/CCGCScheduler.cpp | 16 ++-- dom/base/CCGCScheduler.h | 12 +-- dom/base/nsJSEnvironment.cpp | 16 ++-- dom/base/nsJSEnvironment.h | 2 +- dom/base/test/gtest/TestScheduler.cpp | 8 +- js/public/GCAPI.h | 11 +-- js/public/SliceBudget.h | 4 +- js/src/builtin/TestingFunctions.cpp | 2 + js/src/gc/ArenaList.h | 9 ++- js/src/gc/Compacting.cpp | 2 + js/src/gc/GC.cpp | 7 +- js/src/gc/GCAPI.cpp | 4 +- js/src/gc/GCMarker.h | 15 ++-- js/src/gc/GCRuntime.h | 77 ++++++++++--------- js/src/gc/Marking.cpp | 1 + js/src/gc/ParallelMarking.cpp | 2 + js/src/gc/ParallelMarking.h | 8 +- js/src/gc/ParallelWork.h | 6 +- js/src/gc/RootMarking.cpp | 1 + js/src/gc/Statistics.cpp | 2 + js/src/gc/Statistics.h | 8 +- js/src/gc/Sweeping.cpp | 2 + js/src/gc/Zone.h | 2 +- js/src/jsapi-tests/testGCFinalizeCallback.cpp | 1 + js/src/jsapi-tests/testGCGrayMarking.cpp | 10 +-- js/src/jsapi-tests/testGCHeapBarriers.cpp | 4 +- js/src/jsapi-tests/testGCHooks.cpp | 6 +- js/src/jsapi-tests/testGCMarking.cpp | 4 +- js/src/jsapi-tests/testGCWeakCache.cpp | 4 +- js/src/jsapi-tests/testSliceBudget.cpp | 3 + js/src/jsapi-tests/testWeakMap.cpp | 2 +- js/src/shell/js.cpp | 2 +- js/src/vm/AtomsTable.h | 2 +- js/src/vm/JSAtomUtils.cpp | 2 +- js/xpconnect/src/XPCJSRuntime.cpp | 2 +- xpcom/base/CycleCollectedJSRuntime.cpp | 8 +- xpcom/base/CycleCollectedJSRuntime.h | 6 +- xpcom/base/nsCycleCollector.cpp | 28 +++---- xpcom/base/nsCycleCollector.h | 8 +- 39 files changed, 169 insertions(+), 140 deletions(-) diff --git a/dom/base/CCGCScheduler.cpp b/dom/base/CCGCScheduler.cpp index cffb86dc4828..03bee3c19cf2 100644 --- a/dom/base/CCGCScheduler.cpp +++ b/dom/base/CCGCScheduler.cpp @@ -468,7 +468,7 @@ bool CCGCScheduler::GCRunnerFiredDoGC(TimeStamp aDeadline, MOZ_ASSERT(mActiveIntersliceGCBudget); TimeStamp startTimeStamp = TimeStamp::Now(); - js::SliceBudget budget = ComputeInterSliceGCBudget(aDeadline, startTimeStamp); + JS::SliceBudget budget = ComputeInterSliceGCBudget(aDeadline, startTimeStamp); nsJSContext::RunIncrementalGCSlice(aStep.mReason, is_shrinking, budget); // If the GC doesn't have any more work to do on the foreground thread (and @@ -778,7 +778,7 @@ void CCGCScheduler::KillAllTimersAndRunners() { KillGCRunner(); } -js::SliceBudget CCGCScheduler::ComputeCCSliceBudget( +JS::SliceBudget CCGCScheduler::ComputeCCSliceBudget( TimeStamp aDeadline, TimeStamp aCCBeginTime, TimeStamp aPrevSliceEndTime, TimeStamp aNow, bool* aPreferShorterSlices) const { *aPreferShorterSlices = @@ -789,14 +789,14 @@ js::SliceBudget CCGCScheduler::ComputeCCSliceBudget( if (aPrevSliceEndTime.IsNull()) { // The first slice gets the standard slice time. - return js::SliceBudget(js::TimeBudget(baseBudget)); + return JS::SliceBudget(JS::TimeBudget(baseBudget)); } // Only run a limited slice if we're within the max running time. MOZ_ASSERT(aNow >= aCCBeginTime); TimeDuration runningTime = aNow - aCCBeginTime; if (runningTime >= kMaxICCDuration) { - return js::SliceBudget::unlimited(); + return JS::SliceBudget::unlimited(); } const TimeDuration maxSlice = @@ -818,7 +818,7 @@ js::SliceBudget CCGCScheduler::ComputeCCSliceBudget( // Note: We may have already overshot the deadline, in which case // baseBudget will be negative and we will end up returning // laterSliceBudget. - return js::SliceBudget(js::TimeBudget( + return JS::SliceBudget(JS::TimeBudget( std::max({delaySliceBudget, laterSliceBudget, baseBudget}))); } @@ -828,7 +828,7 @@ js::SliceBudget CCGCScheduler::ComputeCCSliceBudget( // Inputs are an idle deadline (or null if this is not running in idle time), // and a timestamp (probably null) when the CC started being locked out while // waiting for the ongoing GC to finish. -js::SliceBudget CCGCScheduler::ComputeInterSliceGCBudget(TimeStamp aDeadline, +JS::SliceBudget CCGCScheduler::ComputeInterSliceGCBudget(TimeStamp aDeadline, TimeStamp aNow) { TimeDuration budget = aDeadline.IsNull() ? mActiveIntersliceGCBudget : aDeadline - aNow; @@ -1110,7 +1110,7 @@ GCRunnerStep CCGCScheduler::GetNextGCRunnerAction(TimeStamp aDeadline) const { return {GCRunnerAction::None, JS::GCReason::NO_REASON}; } -js::SliceBudget CCGCScheduler::ComputeForgetSkippableBudget( +JS::SliceBudget CCGCScheduler::ComputeForgetSkippableBudget( TimeStamp aStartTimeStamp, TimeStamp aDeadline) { if (mForgetSkippableFrequencyStartTime.IsNull()) { mForgetSkippableFrequencyStartTime = aStartTimeStamp; @@ -1137,7 +1137,7 @@ js::SliceBudget CCGCScheduler::ComputeForgetSkippableBudget( TimeDuration budgetTime = aDeadline ? (aDeadline - aStartTimeStamp) : kForgetSkippableSliceDuration; - return js::SliceBudget(budgetTime); + return JS::SliceBudget(budgetTime); } } // namespace mozilla diff --git a/dom/base/CCGCScheduler.h b/dom/base/CCGCScheduler.h index d24359175a17..e3d82e5e2b02 100644 --- a/dom/base/CCGCScheduler.h +++ b/dom/base/CCGCScheduler.h @@ -178,11 +178,11 @@ class CCGCScheduler { enum IsIdle { eNotIdle = false, eIdle = true }; enum IsExtended { eNormalBudget = false, eExtendedBudget = true }; enum IsInterruptible { eNonInterruptible = false, eInterruptible = true }; - js::SliceBudget CreateGCSliceBudget(mozilla::TimeDuration aDuration, + JS::SliceBudget CreateGCSliceBudget(mozilla::TimeDuration aDuration, IsIdle aIsIdle, IsExtended aIsExtended, IsInterruptible aIsInterruptible) { mInterruptRequested = false; - auto budget = js::SliceBudget(aDuration, aIsInterruptible == eInterruptible + auto budget = JS::SliceBudget(aDuration, aIsInterruptible == eInterruptible ? &mInterruptRequested : nullptr); budget.idle = aIsIdle == eIdle; @@ -352,13 +352,13 @@ class CCGCScheduler { // Return a budget along with a boolean saying whether to prefer to run short // slices and stop rather than continuing to the next phase of cycle // collection. - js::SliceBudget ComputeCCSliceBudget(TimeStamp aDeadline, + JS::SliceBudget ComputeCCSliceBudget(TimeStamp aDeadline, TimeStamp aCCBeginTime, TimeStamp aPrevSliceEndTime, TimeStamp aNow, bool* aPreferShorterSlices) const; - js::SliceBudget ComputeInterSliceGCBudget(TimeStamp aDeadline, + JS::SliceBudget ComputeInterSliceGCBudget(TimeStamp aDeadline, TimeStamp aNow); bool ShouldForgetSkippable(uint32_t aSuspectedCCObjects) const { @@ -459,7 +459,7 @@ class CCGCScheduler { // aStartTimeStamp : when the ForgetSkippable timer fired. This may be some // time ago, if an incremental GC needed to be finished. - js::SliceBudget ComputeForgetSkippableBudget(TimeStamp aStartTimeStamp, + JS::SliceBudget ComputeForgetSkippableBudget(TimeStamp aStartTimeStamp, TimeStamp aDeadline); private: @@ -482,7 +482,7 @@ class CCGCScheduler { // Set when the IdleTaskRunner requests the current task be interrupted. // Cleared when the GC slice budget has detected the interrupt request. - js::SliceBudget::InterruptRequestFlag mInterruptRequested; + JS::SliceBudget::InterruptRequestFlag mInterruptRequested; // When a shrinking GC has been requested but we back-out, if this is true // we run a non-shrinking GC. diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index a175fc93249b..95ee53785c12 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1039,7 +1039,7 @@ void nsJSContext::SetLowMemoryState(bool aState) { static void GarbageCollectImpl(JS::GCReason aReason, nsJSContext::IsShrinking aShrinking, - const js::SliceBudget& aBudget) { + const JS::SliceBudget& aBudget) { AUTO_PROFILER_LABEL_DYNAMIC_CSTR_NONSENSITIVE( "nsJSContext::GarbageCollectNow", GCCC, JS::ExplainGCReason(aReason)); @@ -1085,13 +1085,13 @@ static void GarbageCollectImpl(JS::GCReason aReason, // static void nsJSContext::GarbageCollectNow(JS::GCReason aReason, IsShrinking aShrinking) { - GarbageCollectImpl(aReason, aShrinking, js::SliceBudget::unlimited()); + GarbageCollectImpl(aReason, aShrinking, JS::SliceBudget::unlimited()); } // static void nsJSContext::RunIncrementalGCSlice(JS::GCReason aReason, IsShrinking aShrinking, - js::SliceBudget& aBudget) { + JS::SliceBudget& aBudget) { AUTO_PROFILER_LABEL_RELEVANT_FOR_JS("Incremental GC", GCCC); GarbageCollectImpl(aReason, aShrinking, aBudget); } @@ -1141,7 +1141,7 @@ static void FireForgetSkippable(bool aRemoveChildless, TimeStamp aDeadline) { FinishAnyIncrementalGC(); uint32_t suspectedBefore = nsCycleCollector_suspectedCount(); - js::SliceBudget budget = + JS::SliceBudget budget = sScheduler->ComputeForgetSkippableBudget(startTimeStamp, aDeadline); bool earlyForgetSkippable = sScheduler->IsEarlyForgetSkippable(); nsCycleCollector_forgetSkippable(budget, aRemoveChildless, @@ -1470,12 +1470,12 @@ void nsJSContext::RunCycleCollectorSlice(CCReason aReason, // Decide how long we want to budget for this slice. if (sIncrementalCC) { bool preferShorterSlices; - js::SliceBudget budget = sScheduler->ComputeCCSliceBudget( + JS::SliceBudget budget = sScheduler->ComputeCCSliceBudget( aDeadline, sCCStats.mBeginTime, sCCStats.mEndSliceTime, TimeStamp::Now(), &preferShorterSlices); nsCycleCollector_collectSlice(budget, aReason, preferShorterSlices); } else { - js::SliceBudget budget = js::SliceBudget::unlimited(); + JS::SliceBudget budget = JS::SliceBudget::unlimited(); nsCycleCollector_collectSlice(budget, aReason, false); } @@ -1492,7 +1492,7 @@ void nsJSContext::RunCycleCollectorWorkSlice(int64_t aWorkBudget) { PrepareForCycleCollectionSlice(CCReason::API, TimeStamp()); - js::SliceBudget budget = js::SliceBudget(js::WorkBudget(aWorkBudget)); + JS::SliceBudget budget = JS::SliceBudget(JS::WorkBudget(aWorkBudget)); nsCycleCollector_collectSlice(budget, CCReason::API); sCCStats.AfterCycleCollectionSlice(); @@ -2067,7 +2067,7 @@ static bool ConsumeStream(JSContext* aCx, JS::Handle aObj, nullptr); } -static js::SliceBudget CreateGCSliceBudget(JS::GCReason aReason, +static JS::SliceBudget CreateGCSliceBudget(JS::GCReason aReason, int64_t aMillis) { return sScheduler->CreateGCSliceBudget( mozilla::TimeDuration::FromMilliseconds(aMillis), CCGCScheduler::eNotIdle, diff --git a/dom/base/nsJSEnvironment.h b/dom/base/nsJSEnvironment.h index 41e7123a62f7..6e4edf05f001 100644 --- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -67,7 +67,7 @@ class nsJSContext : public nsIScriptContext { static void RunIncrementalGCSlice(JS::GCReason aReason, IsShrinking aShrinking, - js::SliceBudget& aBudget); + JS::SliceBudget& aBudget); static void CycleCollectNow(mozilla::CCReason aReason, nsICycleCollectorListener* aListener = nullptr); diff --git a/dom/base/test/gtest/TestScheduler.cpp b/dom/base/test/gtest/TestScheduler.cpp index 5d04926627c7..0cb987e2af86 100644 --- a/dom/base/test/gtest/TestScheduler.cpp +++ b/dom/base/test/gtest/TestScheduler.cpp @@ -58,7 +58,7 @@ void TestGC::Run(int aNumSlices) { for (int slice = 0; slice < aNumSlices; slice++) { EXPECT_TRUE(mScheduler.InIncrementalGC()); TimeStamp idleDeadline = Now() + kTenthSecond; - js::SliceBudget budget = + JS::SliceBudget budget = mScheduler.ComputeInterSliceGCBudget(idleDeadline, Now()); TimeDuration budgetDuration = TimeDuration::FromMilliseconds(budget.timeBudget()); @@ -154,7 +154,7 @@ void TestCC::TimerFires(int aNumSlices) { void TestCC::ForgetSkippable() { uint32_t suspectedBefore = sSuspected; // ...ForgetSkippable would happen here... - js::SliceBudget budget = + JS::SliceBudget budget = mScheduler.ComputeForgetSkippableBudget(Now(), Now() + kTenthSecond); EXPECT_NEAR(budget.timeBudget(), kTenthSecond.ToMilliseconds(), 1); AdvanceTime(kTenthSecond); @@ -213,7 +213,7 @@ void TestIdleCC::RunSlice(TimeStamp aCCStartTime, TimeStamp aPrevSliceEnd, EXPECT_FALSE(mScheduler.InIncrementalGC()); bool preferShorter; - js::SliceBudget budget = mScheduler.ComputeCCSliceBudget( + JS::SliceBudget budget = mScheduler.ComputeCCSliceBudget( idleDeadline, aCCStartTime, aPrevSliceEnd, Now(), &preferShorter); // The scheduler will set the budget to our deadline (0.1sec in the future). EXPECT_NEAR(budget.timeBudget(), kTenthSecond.ToMilliseconds(), 1); @@ -252,7 +252,7 @@ void TestNonIdleCC::RunSlice(TimeStamp aCCStartTime, TimeStamp aPrevSliceEnd, EXPECT_FALSE(mScheduler.InIncrementalGC()); bool preferShorter; - js::SliceBudget budget = mScheduler.ComputeCCSliceBudget( + JS::SliceBudget budget = mScheduler.ComputeCCSliceBudget( nullDeadline, aCCStartTime, aPrevSliceEnd, Now(), &preferShorter); if (aSliceNum == 0) { // First slice of the CC, so always use the baseBudget which is diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index fcaeb7262ed0..d7213c40e461 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -28,7 +28,6 @@ namespace js { namespace gc { class GCRuntime; } // namespace gc -class JS_PUBLIC_API SliceBudget; namespace gcstats { struct Statistics; } // namespace gcstats @@ -36,6 +35,8 @@ struct Statistics; namespace JS { +class JS_PUBLIC_API SliceBudget; + // Options used when starting a GC. enum class GCOptions : uint32_t { // Normal GC invocation. @@ -505,7 +506,7 @@ typedef void (*JSTraceDataOp)(JSTracer* trc, void* data); * While tracing this should check the budget and return false if it has been * exceeded. When passed an unlimited budget it should always return true. */ -typedef bool (*JSGrayRootsTracer)(JSTracer* trc, js::SliceBudget& budget, +typedef bool (*JSGrayRootsTracer)(JSTracer* trc, JS::SliceBudget& budget, void* data); typedef enum JSGCStatus { JSGC_BEGIN, JSGC_END } JSGCStatus; @@ -778,7 +779,7 @@ extern JS_PUBLIC_API void NonIncrementalGC(JSContext* cx, JS::GCOptions options, extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx, JS::GCOptions options, GCReason reason, - const js::SliceBudget& budget); + const JS::SliceBudget& budget); /** * Perform a slice of an ongoing incremental collection. When this function @@ -789,7 +790,7 @@ extern JS_PUBLIC_API void StartIncrementalGC(JSContext* cx, * shorter than the requested interval. */ extern JS_PUBLIC_API void IncrementalGCSlice(JSContext* cx, GCReason reason, - const js::SliceBudget& budget); + const JS::SliceBudget& budget); /** * Return whether an incremental GC has work to do on the foreground thread and @@ -957,7 +958,7 @@ typedef void (*DoCycleCollectionCallback)(JSContext* cx); extern JS_PUBLIC_API DoCycleCollectionCallback SetDoCycleCollectionCallback(JSContext* cx, DoCycleCollectionCallback callback); -using CreateSliceBudgetCallback = js::SliceBudget (*)(JS::GCReason reason, +using CreateSliceBudgetCallback = JS::SliceBudget (*)(JS::GCReason reason, int64_t millis); /** diff --git a/js/public/SliceBudget.h b/js/public/SliceBudget.h index 44450204840a..40edd5b81815 100644 --- a/js/public/SliceBudget.h +++ b/js/public/SliceBudget.h @@ -16,7 +16,7 @@ #include "jstypes.h" -namespace js { +namespace JS { struct JS_PUBLIC_API TimeBudget { const mozilla::TimeDuration budget; @@ -140,6 +140,6 @@ class JS_PUBLIC_API SliceBudget { int describe(char* buffer, size_t maxlen) const; }; -} // namespace js +} // namespace JS #endif /* js_SliceBudget_h */ diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index a5e685e16ba7..39a3daaf34fd 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -161,8 +161,10 @@ using mozilla::Span; using JS::AutoStableStringChars; using JS::CompileOptions; +using JS::SliceBudget; using JS::SourceOwnership; using JS::SourceText; +using JS::WorkBudget; // If fuzzingSafe is set, remove functionality that could cause problems with // fuzzers. Set this via the environment variable MOZ_FUZZING_SAFE. diff --git a/js/src/gc/ArenaList.h b/js/src/gc/ArenaList.h index cbde5118b183..b30c719f7d0d 100644 --- a/js/src/gc/ArenaList.h +++ b/js/src/gc/ArenaList.h @@ -18,10 +18,13 @@ #include "js/TypeDecls.h" #include "threading/ProtectedData.h" +namespace JS { +class SliceBudget; +} + namespace js { class Nursery; -class SliceBudget; namespace gcstats { struct Statistics; @@ -134,7 +137,7 @@ class ArenaList { Arena* removeRemainingArenas(Arena** arenap); Arena** pickArenasToRelocate(size_t& arenaTotalOut, size_t& relocTotalOut); Arena* relocateArenas(Arena* toRelocate, Arena* relocated, - js::SliceBudget& sliceBudget, + JS::SliceBudget& sliceBudget, gcstats::Statistics& stats); #ifdef DEBUG @@ -342,7 +345,7 @@ class ArenaLists { void checkEmptyArenaList(AllocKind kind); bool relocateArenas(Arena*& relocatedListOut, JS::GCReason reason, - js::SliceBudget& sliceBudget, gcstats::Statistics& stats); + JS::SliceBudget& sliceBudget, gcstats::Statistics& stats); void queueForegroundObjectsForSweep(JS::GCContext* gcx); void queueForegroundThingsForSweep(); diff --git a/js/src/gc/Compacting.cpp b/js/src/gc/Compacting.cpp index 79e8e0b71d27..6f3c78d9b62a 100644 --- a/js/src/gc/Compacting.cpp +++ b/js/src/gc/Compacting.cpp @@ -36,6 +36,8 @@ using namespace js::gc; using mozilla::Maybe; +using JS::SliceBudget; + bool GCRuntime::canRelocateZone(Zone* zone) const { return !zone->isAtomsZone(); } diff --git a/js/src/gc/GC.cpp b/js/src/gc/GC.cpp index 7940d1979788..79b684ceeb0e 100644 --- a/js/src/gc/GC.cpp +++ b/js/src/gc/GC.cpp @@ -260,6 +260,9 @@ using mozilla::TimeDuration; using mozilla::TimeStamp; using JS::AutoGCRooter; +using JS::SliceBudget; +using JS::TimeBudget; +using JS::WorkBudget; const AllocKind gc::slotsToThingKind[] = { // clang-format off @@ -4671,7 +4674,7 @@ void GCRuntime::gc(JS::GCOptions options, JS::GCReason reason) { } void GCRuntime::startGC(JS::GCOptions options, JS::GCReason reason, - const js::SliceBudget& budget) { + const SliceBudget& budget) { MOZ_ASSERT(!isIncrementalGCInProgress()); setGCOptions(options); @@ -4688,7 +4691,7 @@ void GCRuntime::setGCOptions(JS::GCOptions options) { maybeGcOptions = Some(options); } -void GCRuntime::gcSlice(JS::GCReason reason, const js::SliceBudget& budget) { +void GCRuntime::gcSlice(JS::GCReason reason, const SliceBudget& budget) { MOZ_ASSERT(isIncrementalGCInProgress()); collect(false, budget, reason); } diff --git a/js/src/gc/GCAPI.cpp b/js/src/gc/GCAPI.cpp index dcd08fd67b6f..a026d723e76a 100644 --- a/js/src/gc/GCAPI.cpp +++ b/js/src/gc/GCAPI.cpp @@ -302,7 +302,7 @@ JS_PUBLIC_API void JS::NonIncrementalGC(JSContext* cx, JS::GCOptions options, JS_PUBLIC_API void JS::StartIncrementalGC(JSContext* cx, JS::GCOptions options, GCReason reason, - const js::SliceBudget& budget) { + const JS::SliceBudget& budget) { AssertHeapIsIdle(); CHECK_THREAD(cx); CheckGCOptions(options); @@ -311,7 +311,7 @@ JS_PUBLIC_API void JS::StartIncrementalGC(JSContext* cx, JS::GCOptions options, } JS_PUBLIC_API void JS::IncrementalGCSlice(JSContext* cx, GCReason reason, - const js::SliceBudget& budget) { + const JS::SliceBudget& budget) { AssertHeapIsIdle(); CHECK_THREAD(cx); diff --git a/js/src/gc/GCMarker.h b/js/src/gc/GCMarker.h index 898f458c02be..731800960288 100644 --- a/js/src/gc/GCMarker.h +++ b/js/src/gc/GCMarker.h @@ -18,10 +18,13 @@ class JSRope; +namespace JS { +class SliceBudget; +} + namespace js { class GCMarker; -class SliceBudget; class WeakMapBase; #ifdef DEBUG @@ -371,7 +374,7 @@ class GCMarker { void reset(); [[nodiscard]] bool markUntilBudgetExhausted( - SliceBudget& budget, + JS::SliceBudget& budget, gc::ShouldReportMarkTime reportTime = gc::ReportMarkTime); void setRootMarkingMode(bool newState); @@ -397,10 +400,10 @@ class GCMarker { bool markOneObjectForTest(JSObject* obj); #endif - bool markCurrentColorInParallel(SliceBudget& budget); + bool markCurrentColorInParallel(JS::SliceBudget& budget); template - bool markOneColor(SliceBudget& budget); + bool markOneColor(JS::SliceBudget& budget); static void moveWork(GCMarker* dst, GCMarker* src); @@ -449,7 +452,7 @@ class GCMarker { friend class gc::AutoUpdateMarkStackRanges; template - bool processMarkStackTop(SliceBudget& budget); + bool processMarkStackTop(JS::SliceBudget& budget); friend class gc::GCRuntime; // Helper methods that coerce their second argument to the base pointer @@ -534,7 +537,7 @@ class GCMarker { #endif template - bool doMarking(SliceBudget& budget, gc::ShouldReportMarkTime reportTime); + bool doMarking(JS::SliceBudget& budget, gc::ShouldReportMarkTime reportTime); void delayMarkingChildrenOnOOM(gc::Cell* cell); diff --git a/js/src/gc/GCRuntime.h b/js/src/gc/GCRuntime.h index 7a0344d65ae1..72581c7f12d6 100644 --- a/js/src/gc/GCRuntime.h +++ b/js/src/gc/GCRuntime.h @@ -63,7 +63,7 @@ struct SweepAction { struct Args { GCRuntime* gc; JS::GCContext* gcx; - SliceBudget& budget; + JS::SliceBudget& budget; }; virtual ~SweepAction() = default; @@ -139,11 +139,11 @@ class ChunkPool { class BackgroundMarkTask : public GCParallelTask { public: explicit BackgroundMarkTask(GCRuntime* gc); - void setBudget(const SliceBudget& budget) { this->budget = budget; } + void setBudget(const JS::SliceBudget& budget) { this->budget = budget; } void run(AutoLockHelperThreadState& lock) override; private: - SliceBudget budget; + JS::SliceBudget budget; }; class BackgroundUnmarkTask : public GCParallelTask { @@ -335,12 +335,12 @@ class GCRuntime { void gc(JS::GCOptions options, JS::GCReason reason); void startGC(JS::GCOptions options, JS::GCReason reason, - const SliceBudget& budget); - void gcSlice(JS::GCReason reason, const SliceBudget& budget); + const JS::SliceBudget& budget); + void gcSlice(JS::GCReason reason, const JS::SliceBudget& budget); void finishGC(JS::GCReason reason); void abortGC(); - void startDebugGC(JS::GCOptions options, const SliceBudget& budget); - void debugGCSlice(const SliceBudget& budget); + void startDebugGC(JS::GCOptions options, const JS::SliceBudget& budget); + void debugGCSlice(const JS::SliceBudget& budget); void runDebugGC(); void notifyRootsRemoved(); @@ -711,13 +711,13 @@ class GCRuntime { void startBackgroundAllocTaskIfIdle(); void requestMajorGC(JS::GCReason reason); - SliceBudget defaultBudget(JS::GCReason reason, int64_t millis); - bool maybeIncreaseSliceBudget(SliceBudget& budget); - bool maybeIncreaseSliceBudgetForLongCollections(SliceBudget& budget); - bool maybeIncreaseSliceBudgetForUrgentCollections(SliceBudget& budget); + JS::SliceBudget defaultBudget(JS::GCReason reason, int64_t millis); + bool maybeIncreaseSliceBudget(JS::SliceBudget& budget); + bool maybeIncreaseSliceBudgetForLongCollections(JS::SliceBudget& budget); + bool maybeIncreaseSliceBudgetForUrgentCollections(JS::SliceBudget& budget); IncrementalResult budgetIncrementalGC(bool nonincrementalByAPI, JS::GCReason reason, - SliceBudget& budget); + JS::SliceBudget& budget); void checkZoneIsScheduled(Zone* zone, JS::GCReason reason, const char* trigger); IncrementalResult resetIncrementalGC(GCAbortReason reason); @@ -734,7 +734,7 @@ class GCRuntime { void setGCOptions(JS::GCOptions options); - void collect(bool nonincrementalByAPI, const SliceBudget& budget, + void collect(bool nonincrementalByAPI, const JS::SliceBudget& budget, JS::GCReason reason) JS_HAZ_GC_CALL; /* @@ -747,11 +747,11 @@ class GCRuntime { * * Ok otherwise. */ [[nodiscard]] IncrementalResult gcCycle(bool nonincrementalByAPI, - const SliceBudget& budgetArg, + const JS::SliceBudget& budgetArg, JS::GCReason reason); bool shouldRepeatForDeadZone(JS::GCReason reason); - void incrementalSlice(SliceBudget& budget, JS::GCReason reason, + void incrementalSlice(JS::SliceBudget& budget, JS::GCReason reason, bool budgetWasIncreased); bool mightSweepInThisSlice(bool nonIncremental); @@ -786,7 +786,7 @@ class GCRuntime { void traceEmbeddingBlackRoots(JSTracer* trc); void traceEmbeddingGrayRoots(JSTracer* trc); IncrementalProgress traceEmbeddingGrayRoots(JSTracer* trc, - SliceBudget& budget); + JS::SliceBudget& budget); void checkNoRuntimeRoots(AutoGCSession& session); void maybeDoCycleCollection(); void findDeadCompartments(); @@ -797,7 +797,7 @@ class GCRuntime { AllowParallelMarking = true }; IncrementalProgress markUntilBudgetExhausted( - SliceBudget& sliceBudget, + JS::SliceBudget& sliceBudget, ParallelMarking allowParallelMarking = SingleThreadedMarking, ShouldReportMarkTime reportTime = ReportMarkTime); bool canMarkInParallel() const; @@ -826,9 +826,9 @@ class GCRuntime { void forEachDelayedMarkingArena(F&& f); template - IncrementalProgress markWeakReferences(SliceBudget& budget); - IncrementalProgress markWeakReferencesInCurrentGroup(SliceBudget& budget); - IncrementalProgress markGrayRoots(SliceBudget& budget, + IncrementalProgress markWeakReferences(JS::SliceBudget& budget); + IncrementalProgress markWeakReferencesInCurrentGroup(JS::SliceBudget& budget); + IncrementalProgress markGrayRoots(JS::SliceBudget& budget, gcstats::PhaseKind phase); void markBufferedGrayRoots(JS::Zone* zone); IncrementalProgress markAllWeakReferences(); @@ -852,19 +852,19 @@ class GCRuntime { void moveToNextSweepGroup(); void resetGrayList(Compartment* comp); IncrementalProgress beginMarkingSweepGroup(JS::GCContext* gcx, - SliceBudget& budget); + JS::SliceBudget& budget); IncrementalProgress markGrayRootsInCurrentGroup(JS::GCContext* gcx, - SliceBudget& budget); - IncrementalProgress markGray(JS::GCContext* gcx, SliceBudget& budget); + JS::SliceBudget& budget); + IncrementalProgress markGray(JS::GCContext* gcx, JS::SliceBudget& budget); IncrementalProgress endMarkingSweepGroup(JS::GCContext* gcx, - SliceBudget& budget); + JS::SliceBudget& budget); void markIncomingGrayCrossCompartmentPointers(); IncrementalProgress beginSweepingSweepGroup(JS::GCContext* gcx, - SliceBudget& budget); + JS::SliceBudget& budget); void initBackgroundSweep(Zone* zone, JS::GCContext* gcx, const FinalizePhase& phase); IncrementalProgress markDuringSweeping(JS::GCContext* gcx, - SliceBudget& budget); + JS::SliceBudget& budget); void updateAtomsBitmap(); void sweepCCWrappers(); void sweepRealmGlobals(); @@ -880,17 +880,20 @@ class GCRuntime { void traceWeakFinalizationObserverEdges(JSTracer* trc, Zone* zone); void sweepWeakRefs(); IncrementalProgress endSweepingSweepGroup(JS::GCContext* gcx, - SliceBudget& budget); - IncrementalProgress performSweepActions(SliceBudget& sliceBudget); + JS::SliceBudget& budget); + IncrementalProgress performSweepActions(JS::SliceBudget& sliceBudget); void startSweepingAtomsTable(); - IncrementalProgress sweepAtomsTable(JS::GCContext* gcx, SliceBudget& budget); - IncrementalProgress sweepWeakCaches(JS::GCContext* gcx, SliceBudget& budget); + IncrementalProgress sweepAtomsTable(JS::GCContext* gcx, + JS::SliceBudget& budget); + IncrementalProgress sweepWeakCaches(JS::GCContext* gcx, + JS::SliceBudget& budget); IncrementalProgress finalizeAllocKind(JS::GCContext* gcx, - SliceBudget& budget); + JS::SliceBudget& budget); bool foregroundFinalize(JS::GCContext* gcx, Zone* zone, AllocKind thingKind, - js::SliceBudget& sliceBudget, + JS::SliceBudget& sliceBudget, SortedArenaList& sweepList); - IncrementalProgress sweepPropMapTree(JS::GCContext* gcx, SliceBudget& budget); + IncrementalProgress sweepPropMapTree(JS::GCContext* gcx, + JS::SliceBudget& budget); void endSweepPhase(bool destroyingRuntime); void queueZonesAndStartBackgroundSweep(ZoneList&& zones); void sweepFromBackgroundThread(AutoLockHelperThreadState& lock); @@ -916,14 +919,14 @@ class GCRuntime { bool shouldCompact(); void beginCompactPhase(); IncrementalProgress compactPhase(JS::GCReason reason, - SliceBudget& sliceBudget, + JS::SliceBudget& sliceBudget, AutoGCSession& session); void endCompactPhase(); void sweepZoneAfterCompacting(MovingTracer* trc, Zone* zone); bool canRelocateZone(Zone* zone) const; [[nodiscard]] bool relocateArenas(Zone* zone, JS::GCReason reason, Arena*& relocatedListOut, - SliceBudget& sliceBudget); + JS::SliceBudget& sliceBudget); void updateCellPointers(Zone* zone, AllocKinds kinds); void updateAllCellPointers(MovingTracer* trc, Zone* zone); void updateZonePointersToRelocatedCells(Zone* zone); @@ -954,8 +957,8 @@ class GCRuntime { }; IncrementalProgress waitForBackgroundTask( - GCParallelTask& task, const SliceBudget& budget, bool shouldPauseMutator, - ShouldTriggerSliceWhenFinished triggerSlice); + GCParallelTask& task, const JS::SliceBudget& budget, + bool shouldPauseMutator, ShouldTriggerSliceWhenFinished triggerSlice); void maybeRequestGCAfterBackgroundTask(const AutoLockHelperThreadState& lock); void cancelRequestedGCAfterBackgroundTask(); diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index ccad6a817ad1..fb193eb80a47 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -35,6 +35,7 @@ using namespace js; using namespace js::gc; using JS::MapTypeToTraceKind; +using JS::SliceBudget; using mozilla::DebugOnly; using mozilla::IntegerRange; diff --git a/js/src/gc/ParallelMarking.cpp b/js/src/gc/ParallelMarking.cpp index 2d77b12e4744..065697dc59b3 100644 --- a/js/src/gc/ParallelMarking.cpp +++ b/js/src/gc/ParallelMarking.cpp @@ -19,6 +19,8 @@ using mozilla::Maybe; using mozilla::TimeDuration; using mozilla::TimeStamp; +using JS::SliceBudget; + class AutoAddTimeDuration { TimeStamp start; TimeDuration& result; diff --git a/js/src/gc/ParallelMarking.h b/js/src/gc/ParallelMarking.h index 4c39328de1a5..3b58a230dd88 100644 --- a/js/src/gc/ParallelMarking.h +++ b/js/src/gc/ParallelMarking.h @@ -38,7 +38,7 @@ class MOZ_STACK_CLASS ParallelMarker { public: explicit ParallelMarker(GCRuntime* gc); - bool mark(SliceBudget& sliceBudget); + bool mark(JS::SliceBudget& sliceBudget); using AtomicCount = mozilla::Atomic; AtomicCount& waitingTaskCountRef() { return waitingTaskCount; } @@ -46,7 +46,7 @@ class MOZ_STACK_CLASS ParallelMarker { void donateWorkFrom(GCMarker* src); private: - bool markOneColor(MarkColor color, SliceBudget& sliceBudget); + bool markOneColor(MarkColor color, JS::SliceBudget& sliceBudget); bool hasWork(MarkColor color) const; @@ -88,7 +88,7 @@ class alignas(TypicalCacheLineSize) ParallelMarkTask friend class ParallelMarker; ParallelMarkTask(ParallelMarker* pm, GCMarker* marker, MarkColor color, - const SliceBudget& budget); + const JS::SliceBudget& budget); ~ParallelMarkTask(); void run(AutoLockHelperThreadState& lock) override; @@ -109,7 +109,7 @@ class alignas(TypicalCacheLineSize) ParallelMarkTask ParallelMarker* const pm; GCMarker* const marker; AutoSetMarkColor color; - SliceBudget budget; + JS::SliceBudget budget; ConditionVariable resumed; HelperThreadLockData isWaiting; diff --git a/js/src/gc/ParallelWork.h b/js/src/gc/ParallelWork.h index db97c750094e..1c747b56dad9 100644 --- a/js/src/gc/ParallelWork.h +++ b/js/src/gc/ParallelWork.h @@ -38,7 +38,7 @@ class ParallelWorker : public GCParallelTask { ParallelWorker(GCRuntime* gc, gcstats::PhaseKind phaseKind, GCUse use, WorkFunc func, WorkItemIterator& work, - const SliceBudget& budget, AutoLockHelperThreadState& lock) + const JS::SliceBudget& budget, AutoLockHelperThreadState& lock) : GCParallelTask(gc, phaseKind, use), func_(func), work_(work), @@ -79,7 +79,7 @@ class ParallelWorker : public GCParallelTask { HelperThreadLockData work_; // The budget that determines how long to run for. - SliceBudget budget_; + JS::SliceBudget budget_; // The next work item to process. WorkItem item_; @@ -97,7 +97,7 @@ class MOZ_RAII AutoRunParallelWork { AutoRunParallelWork(GCRuntime* gc, WorkFunc func, gcstats::PhaseKind phaseKind, GCUse use, - WorkItemIterator& work, const SliceBudget& budget, + WorkItemIterator& work, const JS::SliceBudget& budget, AutoLockHelperThreadState& lock) : gc(gc), phaseKind(phaseKind), lock(lock), tasksStarted(0) { size_t workerCount = gc->parallelWorkerCount(); diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index d1aa46d7edbf..fddc621e7eb2 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -28,6 +28,7 @@ using namespace js::gc; using mozilla::LinkedList; using JS::AutoGCRooter; +using JS::SliceBudget; using RootRange = RootedValueMap::Range; using RootEntry = RootedValueMap::Entry; diff --git a/js/src/gc/Statistics.cpp b/js/src/gc/Statistics.cpp index c12d44db976d..05a9fa7e978b 100644 --- a/js/src/gc/Statistics.cpp +++ b/js/src/gc/Statistics.cpp @@ -37,6 +37,8 @@ using mozilla::Maybe; using mozilla::TimeDuration; using mozilla::TimeStamp; +using JS::SliceBudget; + static const size_t BYTES_PER_MB = 1024 * 1024; /* diff --git a/js/src/gc/Statistics.h b/js/src/gc/Statistics.h index 6307af3e4825..d3c4b1e81771 100644 --- a/js/src/gc/Statistics.h +++ b/js/src/gc/Statistics.h @@ -178,7 +178,7 @@ struct Statistics { void resumePhases(); void beginSlice(const ZoneGCStats& zoneStats, JS::GCOptions options, - const SliceBudget& budget, JS::GCReason reason, + const JS::SliceBudget& budget, JS::GCReason reason, bool budgetWasIncreased); void endSlice(); @@ -253,11 +253,11 @@ struct Statistics { static const size_t MAX_SUSPENDED_PHASES = MAX_PHASE_NESTING * 3; struct SliceData { - SliceData(const SliceBudget& budget, mozilla::Maybe trigger, + SliceData(const JS::SliceBudget& budget, mozilla::Maybe trigger, JS::GCReason reason, TimeStamp start, size_t startFaults, gc::State initialState); - SliceBudget budget; + JS::SliceBudget budget; JS::GCReason reason = JS::GCReason::NO_REASON; mozilla::Maybe trigger; gc::State initialState = gc::State::NotActive; @@ -503,7 +503,7 @@ struct Statistics { struct MOZ_RAII AutoGCSlice { AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats, - JS::GCOptions options, const SliceBudget& budget, + JS::GCOptions options, const JS::SliceBudget& budget, JS::GCReason reason, bool budgetWasIncreased) : stats(stats) { stats.beginSlice(zoneStats, options, budget, reason, budgetWasIncreased); diff --git a/js/src/gc/Sweeping.cpp b/js/src/gc/Sweeping.cpp index 5a7e5438a994..a3f114315e94 100644 --- a/js/src/gc/Sweeping.cpp +++ b/js/src/gc/Sweeping.cpp @@ -56,6 +56,8 @@ using namespace js::gc; using mozilla::TimeStamp; +using JS::SliceBudget; + struct js::gc::FinalizePhase { gcstats::PhaseKind statsPhase; AllocKinds kinds; diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index 60f5cbeee9da..eecbe5e85875 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -794,7 +794,7 @@ class Zone : public js::ZoneAllocator, public js::gc::GraphNodeBase { // Perform all pending weakmap entry marking for this zone after // transitioning to weak marking mode. js::gc::IncrementalProgress enterWeakMarkingMode(js::GCMarker* marker, - js::SliceBudget& budget); + JS::SliceBudget& budget); // A set of edges from this zone to other zones used during GC to calculate // sweep groups. diff --git a/js/src/jsapi-tests/testGCFinalizeCallback.cpp b/js/src/jsapi-tests/testGCFinalizeCallback.cpp index e64fd81b16d8..e73fff049257 100644 --- a/js/src/jsapi-tests/testGCFinalizeCallback.cpp +++ b/js/src/jsapi-tests/testGCFinalizeCallback.cpp @@ -6,6 +6,7 @@ #include "jsapi-tests/tests.h" using namespace js; +using namespace JS; static const unsigned BufSize = 20; static unsigned FinalizeCalls = 0; diff --git a/js/src/jsapi-tests/testGCGrayMarking.cpp b/js/src/jsapi-tests/testGCGrayMarking.cpp index 279908c2294f..465782abe9ec 100644 --- a/js/src/jsapi-tests/testGCGrayMarking.cpp +++ b/js/src/jsapi-tests/testGCGrayMarking.cpp @@ -281,7 +281,7 @@ bool TestJSWeakMapWithGrayUnmarking(MarkKeyOrDelegate markKey, // Start an incremental GC and run until gray roots have been pushed onto // the mark stack. JS::PrepareForFullGC(cx); - js::SliceBudget budget(TimeBudget(1000000)); + JS::SliceBudget budget(JS::TimeBudget(1000000)); JS::StartIncrementalGC(cx, JS::GCOptions::Normal, JS::GCReason::DEBUG_GC, budget); MOZ_ASSERT(cx->runtime()->gc.state() == gc::State::Sweep); @@ -411,7 +411,7 @@ bool TestInternalWeakMapWithGrayUnmarking(CellColor keyMarkColor, // Start an incremental GC and run until gray roots have been pushed onto // the mark stack. JS::PrepareForFullGC(cx); - js::SliceBudget budget(TimeBudget(1000000)); + JS::SliceBudget budget(JS::TimeBudget(1000000)); JS::StartIncrementalGC(cx, JS::GCOptions::Normal, JS::GCReason::DEBUG_GC, budget); MOZ_ASSERT(cx->runtime()->gc.state() == gc::State::Sweep); @@ -503,7 +503,7 @@ bool TestCCWs() { JSRuntime* rt = cx->runtime(); JS::PrepareForFullGC(cx); - js::SliceBudget budget(js::WorkBudget(1)); + JS::SliceBudget budget(JS::WorkBudget(1)); rt->gc.startDebugGC(JS::GCOptions::Normal, budget); while (rt->gc.state() == gc::State::Prepare) { rt->gc.debugGCSlice(budget); @@ -531,7 +531,7 @@ bool TestCCWs() { // Incremental zone GC started: the source is now unmarked. JS::PrepareZoneForGC(cx, wrapper->zone()); - budget = js::SliceBudget(js::WorkBudget(1)); + budget = JS::SliceBudget(JS::WorkBudget(1)); rt->gc.startDebugGC(JS::GCOptions::Normal, budget); while (rt->gc.state() == gc::State::Prepare) { rt->gc.debugGCSlice(budget); @@ -664,7 +664,7 @@ void RemoveGrayRootTracer() { JS_SetGrayGCRootsTracer(cx, nullptr, nullptr); } -static bool TraceGrayRoots(JSTracer* trc, SliceBudget& budget, void* data) { +static bool TraceGrayRoots(JSTracer* trc, JS::SliceBudget& budget, void* data) { auto grayRoots = static_cast(data); TraceEdge(trc, &grayRoots->grayRoot1, "gray root 1"); TraceEdge(trc, &grayRoots->grayRoot2, "gray root 2"); diff --git a/js/src/jsapi-tests/testGCHeapBarriers.cpp b/js/src/jsapi-tests/testGCHeapBarriers.cpp index fdd83a1ee433..6a8044641e9f 100644 --- a/js/src/jsapi-tests/testGCHeapBarriers.cpp +++ b/js/src/jsapi-tests/testGCHeapBarriers.cpp @@ -504,7 +504,7 @@ bool CallDuringIncrementalGC(uint32_t mode, F&& f) { JS::SetGCZeal(cx, mode, 0); JS::PrepareZoneForGC(cx, js::GetContextZone(cx)); - js::SliceBudget budget{TimeBudget(BudgetMS)}; + JS::SliceBudget budget{JS::TimeBudget(BudgetMS)}; JS::StartIncrementalGC(cx, JS::GCOptions(), JS::GCReason::DEBUG_GC, budget); CHECK(JS::IsIncrementalGCInProgress(cx)); @@ -659,7 +659,7 @@ BEGIN_TEST(testGCHeapPreBarriers) { // Start an incremental GC so we can detect if we cause barriers to fire, as // these will mark objects black. JS::PrepareForFullGC(cx); - SliceBudget budget(WorkBudget(1)); + JS::SliceBudget budget(JS::WorkBudget(1)); gc::GCRuntime* gc = &cx->runtime()->gc; gc->startDebugGC(JS::GCOptions::Normal, budget); while (gc->state() != gc::State::Mark) { diff --git a/js/src/jsapi-tests/testGCHooks.cpp b/js/src/jsapi-tests/testGCHooks.cpp index 7c6a22499540..052350e389c3 100644 --- a/js/src/jsapi-tests/testGCHooks.cpp +++ b/js/src/jsapi-tests/testGCHooks.cpp @@ -86,7 +86,7 @@ BEGIN_TEST(testGCRootsRemoved) { CHECK(obj); JS::PrepareForFullGC(cx); - js::SliceBudget budget(js::WorkBudget(1)); + JS::SliceBudget budget(JS::WorkBudget(1)); cx->runtime()->gc.startDebugGC(JS::GCOptions::Shrink, budget); CHECK(JS::IsIncrementalGCInProgress(cx)); @@ -171,7 +171,7 @@ static void GCTreeCallback(JSContext* cx, JSGCStatus status, if (invocation.requestFullGC) { JS::PrepareForFullGC(cx); } - js::SliceBudget budget = js::SliceBudget(js::WorkBudget(1)); + JS::SliceBudget budget = JS::SliceBudget(JS::WorkBudget(1)); cx->runtime()->gc.startGC(GCOptions::Normal, invocation.reason, budget); MOZ_RELEASE_ASSERT(JS::IsIncrementalGCInProgress(cx)); @@ -265,7 +265,7 @@ BEGIN_TEST(testGCTree) { // Outer GC is a full GC. JS::PrepareForFullGC(cx); - js::SliceBudget budget(js::WorkBudget(1)); + JS::SliceBudget budget(JS::WorkBudget(1)); cx->runtime()->gc.startDebugGC(JS::GCOptions::Normal, budget); CHECK(JS::IsIncrementalGCInProgress(cx)); diff --git a/js/src/jsapi-tests/testGCMarking.cpp b/js/src/jsapi-tests/testGCMarking.cpp index 99fc1ec75c18..d12661387a1c 100644 --- a/js/src/jsapi-tests/testGCMarking.cpp +++ b/js/src/jsapi-tests/testGCMarking.cpp @@ -375,7 +375,7 @@ BEGIN_TEST(testIncrementalRoots) { // Do the root marking slice. This should mark 'root' and a bunch of its // descendants. It shouldn't make it all the way through (it gets a budget // of 1000, and the graph is about 3000 objects deep). - js::SliceBudget budget(js::WorkBudget(1000)); + JS::SliceBudget budget(JS::WorkBudget(1000)); AutoGCParameter param(cx, JSGC_INCREMENTAL_GC_ENABLED, true); rt->gc.startDebugGC(JS::GCOptions::Normal, budget); while (rt->gc.state() != gc::State::Mark) { @@ -436,7 +436,7 @@ BEGIN_TEST(testIncrementalRoots) { } // Finish the GC using an unlimited budget. - auto unlimited = js::SliceBudget::unlimited(); + auto unlimited = JS::SliceBudget::unlimited(); rt->gc.debugGCSlice(unlimited); // Access the leaf object to try to trigger a crash if it is dead. diff --git a/js/src/jsapi-tests/testGCWeakCache.cpp b/js/src/jsapi-tests/testGCWeakCache.cpp index fd3d9f2c8577..4fb6219f0fae 100644 --- a/js/src/jsapi-tests/testGCWeakCache.cpp +++ b/js/src/jsapi-tests/testGCWeakCache.cpp @@ -284,7 +284,7 @@ bool GCUntilCacheSweep(JSContext* cx, const Cache& cache) { JS::Zone* zone = JS::GetObjectZone(global); JS::PrepareZoneForGC(cx, zone); - SliceBudget budget(WorkBudget(1)); + JS::SliceBudget budget(JS::WorkBudget(1)); cx->runtime()->gc.startDebugGC(JS::GCOptions::Normal, budget); CHECK(IsIncrementalGCInProgress(cx)); @@ -299,7 +299,7 @@ bool SweepCacheAndFinishGC(JSContext* cx, const Cache& cache) { CHECK(IsIncrementalGCInProgress(cx)); PrepareForIncrementalGC(cx); - IncrementalGCSlice(cx, JS::GCReason::API, SliceBudget::unlimited()); + IncrementalGCSlice(cx, JS::GCReason::API, JS::SliceBudget::unlimited()); JS::Zone* zone = JS::GetObjectZone(global); CHECK(!IsIncrementalGCInProgress(cx)); diff --git a/js/src/jsapi-tests/testSliceBudget.cpp b/js/src/jsapi-tests/testSliceBudget.cpp index f73e1c8bebe5..a1d449b91474 100644 --- a/js/src/jsapi-tests/testSliceBudget.cpp +++ b/js/src/jsapi-tests/testSliceBudget.cpp @@ -9,6 +9,9 @@ #include "jsapi-tests/tests.h" using namespace js; +using JS::SliceBudget; +using JS::TimeBudget; +using JS::WorkBudget; BEGIN_TEST(testSliceBudgetUnlimited) { SliceBudget budget = SliceBudget::unlimited(); diff --git a/js/src/jsapi-tests/testWeakMap.cpp b/js/src/jsapi-tests/testWeakMap.cpp index 0872571d3d9d..d013bbb9b231 100644 --- a/js/src/jsapi-tests/testWeakMap.cpp +++ b/js/src/jsapi-tests/testWeakMap.cpp @@ -309,7 +309,7 @@ JSObject* newDelegate() { void performIncrementalGC() { JSRuntime* rt = cx->runtime(); - js::SliceBudget budget(js::WorkBudget(1000)); + JS::SliceBudget budget(JS::WorkBudget(1000)); rt->gc.startDebugGC(JS::GCOptions::Normal, budget); // Wait until we've started marking before finishing the GC diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index cc3e88629978..927b94e2a6b2 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -911,7 +911,7 @@ static void TraceBlackRoots(JSTracer* trc, void* data) { TraceRootArrays(trc, gc::MarkColor::Black); } -static bool TraceGrayRoots(JSTracer* trc, SliceBudget& budget, void* data) { +static bool TraceGrayRoots(JSTracer* trc, JS::SliceBudget& budget, void* data) { TraceRootArrays(trc, gc::MarkColor::Gray); return true; } diff --git a/js/src/vm/AtomsTable.h b/js/src/vm/AtomsTable.h index 38b41501a3ff..55a58b92cca8 100644 --- a/js/src/vm/AtomsTable.h +++ b/js/src/vm/AtomsTable.h @@ -184,7 +184,7 @@ class AtomsTable { bool startIncrementalSweep(mozilla::Maybe& atomsToSweepOut); // Sweep some atoms incrementally and return whether we finished. - bool sweepIncrementally(SweepIterator& atomsToSweep, SliceBudget& budget); + bool sweepIncrementally(SweepIterator& atomsToSweep, JS::SliceBudget& budget); size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; diff --git a/js/src/vm/JSAtomUtils.cpp b/js/src/vm/JSAtomUtils.cpp index 367ac5e284fb..bffd37602a34 100644 --- a/js/src/vm/JSAtomUtils.cpp +++ b/js/src/vm/JSAtomUtils.cpp @@ -343,7 +343,7 @@ void AtomsTable::mergeAtomsAddedWhileSweeping() { } bool AtomsTable::sweepIncrementally(SweepIterator& atomsToSweep, - SliceBudget& budget) { + JS::SliceBudget& budget) { // Sweep the table incrementally until we run out of work or budget. while (!atomsToSweep.empty()) { budget.step(); diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index dc0cb260373f..1783a4ba7995 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -154,7 +154,7 @@ class AsyncFreeSnowWhite : public Runnable { TimeStamp start = TimeStamp::Now(); // 2 ms budget, given that kICCSliceBudget is only 3 ms - js::SliceBudget budget = js::SliceBudget(js::TimeBudget(2)); + SliceBudget budget = SliceBudget(TimeBudget(2)); bool hadSnowWhiteObjects = nsCycleCollector_doDeferredDeletionWithBudget(budget); Telemetry::Accumulate( diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 73842d6ce33b..23da853f9166 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -993,7 +993,7 @@ void CycleCollectedJSRuntime::TraceBlackJS(JSTracer* aTracer, void* aData) { /* static */ bool CycleCollectedJSRuntime::TraceGrayJS(JSTracer* aTracer, - js::SliceBudget& budget, + JS::SliceBudget& budget, void* aData) { CycleCollectedJSRuntime* self = static_cast(aData); @@ -1366,7 +1366,7 @@ static inline bool ShouldCheckSingleZoneHolders() { #ifdef NS_BUILD_REFCNT_LOGGING void CycleCollectedJSRuntime::TraceAllNativeGrayRoots(JSTracer* aTracer) { MOZ_RELEASE_ASSERT(mHolderIter.isNothing()); - js::SliceBudget budget = js::SliceBudget::unlimited(); + JS::SliceBudget budget = JS::SliceBudget::unlimited(); MOZ_ALWAYS_TRUE( TraceNativeGrayRoots(aTracer, JSHolderMap::AllHolders, budget)); } @@ -1374,7 +1374,7 @@ void CycleCollectedJSRuntime::TraceAllNativeGrayRoots(JSTracer* aTracer) { bool CycleCollectedJSRuntime::TraceNativeGrayRoots( JSTracer* aTracer, JSHolderMap::WhichHolders aWhich, - js::SliceBudget& aBudget) { + JS::SliceBudget& aBudget) { if (!mHolderIter) { // NB: This is here just to preserve the existing XPConnect order. I doubt // it would hurt to do this after the JS holders. @@ -1398,7 +1398,7 @@ bool CycleCollectedJSRuntime::TraceNativeGrayRoots( bool CycleCollectedJSRuntime::TraceJSHolders(JSTracer* aTracer, JSHolderMap::Iter& aIter, - js::SliceBudget& aBudget) { + JS::SliceBudget& aBudget) { bool checkSingleZoneHolders = ShouldCheckSingleZoneHolders(); while (!aIter.Done() && !aBudget.isOverBudget()) { diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 3013e54d4502..78c3ec831d97 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -272,7 +272,7 @@ class CycleCollectedJSRuntime { // Trace gray JS roots until budget is exceeded and return whether we // finished. - static bool TraceGrayJS(JSTracer* aTracer, js::SliceBudget& budget, + static bool TraceGrayJS(JSTracer* aTracer, JS::SliceBudget& budget, void* aData); static void GCCallback(JSContext* aContext, JSGCStatus aStatus, @@ -296,9 +296,9 @@ class CycleCollectedJSRuntime { #endif bool TraceNativeGrayRoots(JSTracer* aTracer, JSHolderMap::WhichHolders aWhich, - js::SliceBudget& aBudget); + JS::SliceBudget& aBudget); bool TraceJSHolders(JSTracer* aTracer, JSHolderMap::Iter& aIter, - js::SliceBudget& aBudget); + JS::SliceBudget& aBudget); public: enum DeferredFinalizeType { diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp index 7908fe8037e6..2364d34d5a71 100644 --- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -198,6 +198,8 @@ using namespace mozilla; +using JS::SliceBudget; + struct NurseryPurpleBufferEntry { void* mPtr; nsCycleCollectionParticipant* mParticipant; @@ -1049,7 +1051,7 @@ struct nsPurpleBuffer { // (4) If aRemoveChildlessNodes is true, then any nodes in the purple buffer // that will have no children in the cycle collector graph will also be // removed. CanSkip() may be run on these children. - void RemoveSkippable(nsCycleCollector* aCollector, js::SliceBudget& aBudget, + void RemoveSkippable(nsCycleCollector* aCollector, SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing, CC_ForgetSkippableCallback aCb); @@ -1119,8 +1121,6 @@ enum ccIsManual { CCIsNotManual = false, CCIsManual = true }; // Top level structure for the cycle collector. //////////////////////////////////////////////////////////////////////// -using js::SliceBudget; - class JSPurpleBuffer; class nsCycleCollector : public nsIMemoryReporter { @@ -1186,10 +1186,10 @@ class nsCycleCollector : public nsIMemoryReporter { nsCycleCollectingAutoRefCnt* aRefCnt); void SuspectNurseryEntries(); uint32_t SuspectedCount(); - void ForgetSkippable(js::SliceBudget& aBudget, bool aRemoveChildlessNodes, + void ForgetSkippable(SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing); bool FreeSnowWhite(bool aUntilNoSWInPurpleBuffer); - bool FreeSnowWhiteWithBudget(js::SliceBudget& aBudget); + bool FreeSnowWhiteWithBudget(SliceBudget& aBudget); // This method assumes its argument is already canonicalized. void RemoveObjectFromGraph(void* aPtr); @@ -2482,7 +2482,7 @@ class SnowWhiteKiller : public TraceCallbacks { ObjectsVector; public: - SnowWhiteKiller(nsCycleCollector* aCollector, js::SliceBudget* aBudget) + SnowWhiteKiller(nsCycleCollector* aCollector, SliceBudget* aBudget) : mCollector(aCollector), mObjects(kSegmentSize), mBudget(aBudget), @@ -2590,13 +2590,13 @@ class SnowWhiteKiller : public TraceCallbacks { private: RefPtr mCollector; ObjectsVector mObjects; - js::SliceBudget* mBudget; + SliceBudget* mBudget; bool mSawSnowWhiteObjects; }; class RemoveSkippableVisitor : public SnowWhiteKiller { public: - RemoveSkippableVisitor(nsCycleCollector* aCollector, js::SliceBudget& aBudget, + RemoveSkippableVisitor(nsCycleCollector* aCollector, SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing, CC_ForgetSkippableCallback aCb) @@ -2649,7 +2649,7 @@ class RemoveSkippableVisitor : public SnowWhiteKiller { } private: - js::SliceBudget& mBudget; + SliceBudget& mBudget; bool mRemoveChildlessNodes; bool mAsyncSnowWhiteFreeing; bool mDispatchedDeferredDeletion; @@ -2657,7 +2657,7 @@ class RemoveSkippableVisitor : public SnowWhiteKiller { }; void nsPurpleBuffer::RemoveSkippable(nsCycleCollector* aCollector, - js::SliceBudget& aBudget, + SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing, CC_ForgetSkippableCallback aCb) { @@ -2690,7 +2690,7 @@ bool nsCycleCollector::FreeSnowWhite(bool aUntilNoSWInPurpleBuffer) { return hadSnowWhiteObjects; } -bool nsCycleCollector::FreeSnowWhiteWithBudget(js::SliceBudget& aBudget) { +bool nsCycleCollector::FreeSnowWhiteWithBudget(SliceBudget& aBudget) { CheckThreadSafety(); if (mFreeingSnowWhite) { @@ -2707,7 +2707,7 @@ bool nsCycleCollector::FreeSnowWhiteWithBudget(js::SliceBudget& aBudget) { ; } -void nsCycleCollector::ForgetSkippable(js::SliceBudget& aBudget, +void nsCycleCollector::ForgetSkippable(SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing) { CheckThreadSafety(); @@ -3950,7 +3950,7 @@ void nsCycleCollector_setForgetSkippableCallback( data->mCollector->SetForgetSkippableCallback(aCB); } -void nsCycleCollector_forgetSkippable(js::SliceBudget& aBudget, +void nsCycleCollector_forgetSkippable(SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing) { CollectorData* data = sCollectorData.get(); @@ -3984,7 +3984,7 @@ bool nsCycleCollector_doDeferredDeletion() { return data->mCollector->FreeSnowWhite(false); } -bool nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget) { +bool nsCycleCollector_doDeferredDeletionWithBudget(SliceBudget& aBudget) { CollectorData* data = sCollectorData.get(); // We should have started the cycle collector by now. diff --git a/xpcom/base/nsCycleCollector.h b/xpcom/base/nsCycleCollector.h index e25647175e74..0418b3cde6e7 100644 --- a/xpcom/base/nsCycleCollector.h +++ b/xpcom/base/nsCycleCollector.h @@ -16,7 +16,7 @@ struct already_AddRefed; #include #include "mozilla/Attributes.h" -namespace js { +namespace JS { class SliceBudget; } @@ -35,7 +35,7 @@ typedef void (*CC_ForgetSkippableCallback)(void); void nsCycleCollector_setForgetSkippableCallback( CC_ForgetSkippableCallback aCB); -void nsCycleCollector_forgetSkippable(js::SliceBudget& aBudget, +void nsCycleCollector_forgetSkippable(JS::SliceBudget& aBudget, bool aRemoveChildlessNodes = false, bool aAsyncSnowWhiteFreeing = false); @@ -47,7 +47,7 @@ void nsCycleCollector_finishAnyCurrentCollection(); void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false, bool aPurge = false); bool nsCycleCollector_doDeferredDeletion(); -bool nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget); +bool nsCycleCollector_doDeferredDeletionWithBudget(JS::SliceBudget& aBudget); already_AddRefed nsCycleCollector_createLogSink( bool aLogGC); @@ -57,7 +57,7 @@ already_AddRefed nsCycleCollector_createLogger(); bool nsCycleCollector_collect(mozilla::CCReason aReason, nsICycleCollectorListener* aManualListener); -void nsCycleCollector_collectSlice(js::SliceBudget& budget, +void nsCycleCollector_collectSlice(JS::SliceBudget& budget, mozilla::CCReason aReason, bool aPreferShorterSlices = false);