author | Dorel Luca <dluca@mozilla.com> |
Sat, 04 Aug 2018 01:27:15 +0300 | |
changeset 430081 | 4e56a2f51ad739ca52046723448f3129a58f1666 |
parent 430080 | ff0d3184379365cf5e9ab2bee57d7e561b7c2482 |
child 430100 | 3570d0c7b0c72804a15d285978d97b64441c5a62 |
child 430151 | b70410825f1e4aaad805869795e6dc6abfeadf20 |
push id | 34382 |
push user | dluca@mozilla.com |
push date | Fri, 03 Aug 2018 22:28:24 +0000 |
treeherder | mozilla-central@4e56a2f51ad7 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | backout |
bugs | 1397297 |
milestone | 63.0a1 |
backs out | 8c763e66ba84b13e2d83beb58ea108817aa6d53e |
first release with | nightly mac
4e56a2f51ad7
/
63.0a1
/
20180804100137
/
files
nightly linux32
nightly linux64
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly mac
63.0a1
/
20180804100137
/
pushlog to previous
|
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -124,37 +124,34 @@ const char* const XPCJSRuntime::mStrings class AsyncFreeSnowWhite : public Runnable { public: NS_IMETHOD Run() override { AUTO_PROFILER_LABEL("AsyncFreeSnowWhite::Run", GCCC); TimeStamp start = TimeStamp::Now(); - // 2 ms budget, given that kICCSliceBudget is only 3 ms - js::SliceBudget budget = js::SliceBudget(js::TimeBudget(2)); - bool hadSnowWhiteObjects = - nsCycleCollector_doDeferredDeletionWithBudget(budget); + bool hadSnowWhiteObjects = nsCycleCollector_doDeferredDeletion(); Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING, uint32_t((TimeStamp::Now() - start).ToMilliseconds())); if (hadSnowWhiteObjects && !mContinuation) { mContinuation = true; if (NS_FAILED(Dispatch())) { mActive = false; } } else { mActive = false; } return NS_OK; } nsresult Dispatch() { nsCOMPtr<nsIRunnable> self(this); - return NS_IdleDispatchToCurrentThread(self.forget(), 500); + return NS_IdleDispatchToCurrentThread(self.forget(), 2500); } void Start(bool aContinuation = false, bool aPurge = false) { if (mContinuation) { mContinuation = aContinuation; } mPurge = aPurge;
--- a/xpcom/base/nsCycleCollector.cpp +++ b/xpcom/base/nsCycleCollector.cpp @@ -1348,17 +1348,16 @@ public: void Suspect(void* aPtr, nsCycleCollectionParticipant* aCp, nsCycleCollectingAutoRefCnt* aRefCnt); void SuspectNurseryEntries(); uint32_t SuspectedCount(); void ForgetSkippable(js::SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing); bool FreeSnowWhite(bool aUntilNoSWInPurpleBuffer); - bool FreeSnowWhiteWithBudget(js::SliceBudget& aBudget); // This method assumes its argument is already canonicalized. void RemoveObjectFromGraph(void* aPtr); void PrepareForGarbageCollection(); void FinishAnyCurrentCollection(); bool Collect(ccType aCCType, @@ -2711,90 +2710,59 @@ class SnowWhiteKiller : public TraceCall }; // Segments are 4 KiB on 32-bit and 8 KiB on 64-bit. static const size_t kSegmentSize = sizeof(void*) * 1024; typedef SegmentedVector<SnowWhiteObject, kSegmentSize, InfallibleAllocPolicy> ObjectsVector; public: - SnowWhiteKiller(nsCycleCollector* aCollector, js::SliceBudget* aBudget) + explicit SnowWhiteKiller(nsCycleCollector* aCollector) : mCollector(aCollector) , mObjects(kSegmentSize) - , mBudget(aBudget) - , mSawSnowWhiteObjects(false) { MOZ_ASSERT(mCollector, "Calling SnowWhiteKiller after nsCC went away"); } - explicit SnowWhiteKiller(nsCycleCollector* aCollector) - : SnowWhiteKiller(aCollector, nullptr) - { - } - ~SnowWhiteKiller() { for (auto iter = mObjects.Iter(); !iter.Done(); iter.Next()) { SnowWhiteObject& o = iter.Get(); - MaybeKillObject(o); - } - } - - void - MaybeKillObject(SnowWhiteObject& aObject) - { - if (!aObject.mRefCnt->get() && !aObject.mRefCnt->IsInPurpleBuffer()) { - mCollector->RemoveObjectFromGraph(aObject.mPointer); - aObject.mRefCnt->stabilizeForDeletion(); - { - JS::AutoEnterCycleCollection autocc(mCollector->Runtime()->Runtime()); - aObject.mParticipant->Trace(aObject.mPointer, *this, nullptr); + if (!o.mRefCnt->get() && !o.mRefCnt->IsInPurpleBuffer()) { + mCollector->RemoveObjectFromGraph(o.mPointer); + o.mRefCnt->stabilizeForDeletion(); + { + JS::AutoEnterCycleCollection autocc(mCollector->Runtime()->Runtime()); + o.mParticipant->Trace(o.mPointer, *this, nullptr); + } + o.mParticipant->DeleteCycleCollectable(o.mPointer); } - aObject.mParticipant->DeleteCycleCollectable(aObject.mPointer); } } bool Visit(nsPurpleBuffer& aBuffer, nsPurpleBufferEntry* aEntry) { - if (mBudget) { - if (mBudget->isOverBudget()) { - return false; - } - mBudget->step(); - } - MOZ_ASSERT(aEntry->mObject, "Null object in purple buffer"); if (!aEntry->mRefCnt->get()) { - mSawSnowWhiteObjects = true; void* o = aEntry->mObject; nsCycleCollectionParticipant* cp = aEntry->mParticipant; ToParticipant(o, &cp); SnowWhiteObject swo = { o, cp, aEntry->mRefCnt }; - if (!mBudget) { - mObjects.InfallibleAppend(swo); - } + mObjects.InfallibleAppend(swo); aBuffer.Remove(aEntry); - if (mBudget) { - MaybeKillObject(swo); - } } return true; } bool HasSnowWhiteObjects() const { return !mObjects.IsEmpty(); } - bool SawSnowWhiteObjects() const - { - return mSawSnowWhiteObjects; - } - virtual void Trace(JS::Heap<JS::Value>* aValue, const char* aName, void* aClosure) const override { const JS::Value& val = aValue->unbarrieredGet(); if (val.isGCThing() && ValueIsGrayCCThing(val)) { MOZ_ASSERT(!js::gc::IsInsideNursery(val.toGCThing())); mCollector->GetJSPurpleBuffer()->mValues.InfallibleAppend(val); } @@ -2844,18 +2812,16 @@ public: virtual void Trace(JS::Heap<JSFunction*>* aFunction, const char* aName, void* aClosure) const override { } private: RefPtr<nsCycleCollector> mCollector; ObjectsVector mObjects; - js::SliceBudget* mBudget; - bool mSawSnowWhiteObjects; }; class RemoveSkippableVisitor : public SnowWhiteKiller { public: RemoveSkippableVisitor(nsCycleCollector* aCollector, js::SliceBudget& aBudget, bool aRemoveChildlessNodes, @@ -2954,33 +2920,16 @@ nsCycleCollector::FreeSnowWhite(bool aUn visitor.HasSnowWhiteObjects(); if (!visitor.HasSnowWhiteObjects()) { break; } } while (aUntilNoSWInPurpleBuffer); return hadSnowWhiteObjects; } -bool -nsCycleCollector::FreeSnowWhiteWithBudget(js::SliceBudget& aBudget) -{ - CheckThreadSafety(); - - if (mFreeingSnowWhite) { - return false; - } - - AutoRestore<bool> ar(mFreeingSnowWhite); - mFreeingSnowWhite = true; - - SnowWhiteKiller visitor(this, &aBudget); - mPurpleBuf.VisitEntries(visitor); - return visitor.SawSnowWhiteObjects();; -} - void nsCycleCollector::ForgetSkippable(js::SliceBudget& aBudget, bool aRemoveChildlessNodes, bool aAsyncSnowWhiteFreeing) { CheckThreadSafety(); mozilla::Maybe<mozilla::AutoGlobalTimelineMarker> marker; @@ -4366,29 +4315,16 @@ nsCycleCollector_doDeferredDeletion() // We should have started the cycle collector by now. MOZ_ASSERT(data); MOZ_ASSERT(data->mCollector); MOZ_ASSERT(data->mContext); return data->mCollector->FreeSnowWhite(false); } -bool -nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget) -{ - CollectorData* data = sCollectorData.get(); - - // We should have started the cycle collector by now. - MOZ_ASSERT(data); - MOZ_ASSERT(data->mCollector); - MOZ_ASSERT(data->mContext); - - return data->mCollector->FreeSnowWhiteWithBudget(aBudget); -} - already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink() { nsCOMPtr<nsICycleCollectorLogSink> sink = new nsCycleCollectorLogSinkToFile(); return sink.forget(); } void
--- a/xpcom/base/nsCycleCollector.h +++ b/xpcom/base/nsCycleCollector.h @@ -38,17 +38,16 @@ void nsCycleCollector_forgetSkippable(js void nsCycleCollector_prepareForGarbageCollection(); // If an incremental cycle collection is in progress, finish it. void nsCycleCollector_finishAnyCurrentCollection(); void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false, bool aPurge = false); bool nsCycleCollector_doDeferredDeletion(); -bool nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget); already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink(); void nsCycleCollector_collect(nsICycleCollectorListener* aManualListener); void nsCycleCollector_collectSlice(js::SliceBudget& budget, bool aPreferShorterSlices = false);