mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 845545: Part 3 - Give the CycleCollectedJSRuntime more control over
SnowWhite. r=smaug
This commit is contained in:
parent
147c3dee65
commit
46d249128b
@ -222,6 +222,43 @@ XPCJSRuntime::CustomContextCallback(JSContext *cx, unsigned operation)
|
||||
return true;
|
||||
}
|
||||
|
||||
class AsyncFreeSnowWhite : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
TimeStamp start = TimeStamp::Now();
|
||||
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(NS_DispatchToCurrentThread(this))) {
|
||||
mActive = false;
|
||||
}
|
||||
} else {
|
||||
mActive = false;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void Dispatch(bool aContinuation = false)
|
||||
{
|
||||
if (mContinuation) {
|
||||
mContinuation = aContinuation;
|
||||
}
|
||||
if (!mActive && NS_SUCCEEDED(NS_DispatchToCurrentThread(this))) {
|
||||
mActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncFreeSnowWhite() : mContinuation(false), mActive(false) {}
|
||||
|
||||
public:
|
||||
bool mContinuation;
|
||||
bool mActive;
|
||||
};
|
||||
|
||||
namespace xpc {
|
||||
|
||||
CompartmentPrivate::~CompartmentPrivate()
|
||||
@ -566,6 +603,12 @@ XPCJSRuntime::PrepareForCollection()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
XPCJSRuntime::DispatchDeferredDeletion(bool aContinuation)
|
||||
{
|
||||
mAsyncSnowWhiteFreer->Dispatch(aContinuation);
|
||||
}
|
||||
|
||||
void
|
||||
xpc_UnmarkSkippableJSHolders()
|
||||
{
|
||||
@ -2698,6 +2741,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
mObjectHolderRoots(nullptr),
|
||||
mWatchdogManager(new WatchdogManager(this)),
|
||||
mJunkScope(nullptr),
|
||||
mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite()),
|
||||
mExceptionManagerNotAvailable(false)
|
||||
{
|
||||
#ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN
|
||||
|
@ -607,6 +607,8 @@ enum WatchdogTimestampCategory
|
||||
TimestampCount
|
||||
};
|
||||
|
||||
class AsyncFreeSnowWhite;
|
||||
|
||||
class XPCJSRuntime : public mozilla::CycleCollectedJSRuntime
|
||||
{
|
||||
public:
|
||||
@ -729,6 +731,7 @@ public:
|
||||
void UnmarkSkippableJSHolders();
|
||||
void PrepareForForgetSkippable() MOZ_OVERRIDE;
|
||||
void PrepareForCollection() MOZ_OVERRIDE;
|
||||
void DispatchDeferredDeletion(bool continuation) MOZ_OVERRIDE;
|
||||
|
||||
void CustomGCCallback(JSGCStatus status) MOZ_OVERRIDE;
|
||||
bool CustomContextCallback(JSContext *cx, unsigned operation) MOZ_OVERRIDE;
|
||||
@ -871,6 +874,7 @@ private:
|
||||
nsRefPtr<WatchdogManager> mWatchdogManager;
|
||||
JS::GCSliceCallback mPrevGCSliceCallback;
|
||||
JSObject* mJunkScope;
|
||||
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
|
||||
|
||||
nsCOMPtr<nsIException> mPendingException;
|
||||
nsCOMPtr<nsIExceptionManager> mExceptionManager;
|
||||
|
@ -204,6 +204,8 @@ public:
|
||||
void DeferredFinalize(nsISupports* aSupports);
|
||||
|
||||
void DumpJSHeap(FILE* aFile);
|
||||
|
||||
virtual void DispatchDeferredDeletion(bool aContinuation) = 0;
|
||||
|
||||
private:
|
||||
JSGCThingParticipant mGCThingCycleCollectorGlobal;
|
||||
|
@ -1001,8 +1001,6 @@ public:
|
||||
nsCycleCollectorParams mParams;
|
||||
|
||||
private:
|
||||
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
|
||||
|
||||
nsTArray<PtrInfo*> *mWhiteNodes;
|
||||
uint32_t mWhiteNodeCount;
|
||||
|
||||
@ -1080,18 +1078,8 @@ public:
|
||||
bool BeginCollection(ccType aCCType, nsICycleCollectorListener *aListener);
|
||||
bool FinishCollection(nsICycleCollectorListener *aListener);
|
||||
|
||||
AsyncFreeSnowWhite* AsyncSnowWhiteFreer()
|
||||
{
|
||||
return mAsyncSnowWhiteFreer;
|
||||
}
|
||||
|
||||
bool FreeSnowWhite(bool aUntilNoSWInPurpleBuffer);
|
||||
|
||||
// If there is a cycle collector available in the current thread,
|
||||
// this calls FreeSnowWhite(false). Returns true if some
|
||||
// snow-white objects were found.
|
||||
static bool TryToFreeSnowWhite();
|
||||
|
||||
uint32_t SuspectedCount();
|
||||
void Shutdown();
|
||||
|
||||
@ -2183,44 +2171,6 @@ MayHaveChild(void *o, nsCycleCollectionParticipant* cp)
|
||||
return cf.MayHaveChild();
|
||||
}
|
||||
|
||||
class AsyncFreeSnowWhite : public nsRunnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
TimeStamp start = TimeStamp::Now();
|
||||
bool hadSnowWhiteObjects = nsCycleCollector::TryToFreeSnowWhite();
|
||||
Telemetry::Accumulate(Telemetry::CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING,
|
||||
uint32_t((TimeStamp::Now() - start).ToMilliseconds()));
|
||||
if (hadSnowWhiteObjects && !mContinuation) {
|
||||
mContinuation = true;
|
||||
if (NS_FAILED(NS_DispatchToCurrentThread(this))) {
|
||||
mActive = false;
|
||||
}
|
||||
} else {
|
||||
mActive = false;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void Dispatch(nsCycleCollector* aCollector, bool aContinuation = false)
|
||||
{
|
||||
AsyncFreeSnowWhite* swf = aCollector->AsyncSnowWhiteFreer();
|
||||
if (swf->mContinuation) {
|
||||
swf->mContinuation = aContinuation;
|
||||
}
|
||||
if (!swf->mActive && NS_SUCCEEDED(NS_DispatchToCurrentThread(swf))) {
|
||||
swf->mActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncFreeSnowWhite() : mContinuation(false), mActive(false) {}
|
||||
|
||||
public:
|
||||
bool mContinuation;
|
||||
bool mActive;
|
||||
};
|
||||
|
||||
struct SnowWhiteObject
|
||||
{
|
||||
void* mPointer;
|
||||
@ -2302,7 +2252,7 @@ public:
|
||||
}
|
||||
if (HasSnowWhiteObjects()) {
|
||||
// Effectively a continuation.
|
||||
AsyncFreeSnowWhite::Dispatch(mCollector, true);
|
||||
nsCycleCollector_dispatchDeferredDeletion(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2315,7 +2265,7 @@ public:
|
||||
SnowWhiteKiller::Visit(aBuffer, aEntry);
|
||||
} else if (!mDispatchedDeferredDeletion) {
|
||||
mDispatchedDeferredDeletion = true;
|
||||
nsCycleCollector_dispatchDeferredDeletion();
|
||||
nsCycleCollector_dispatchDeferredDeletion(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2364,15 +2314,6 @@ nsCycleCollector::FreeSnowWhite(bool aUntilNoSWInPurpleBuffer)
|
||||
return hadSnowWhiteObjects;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsCycleCollector::TryToFreeSnowWhite()
|
||||
{
|
||||
CollectorData* data = sCollectorData.get();
|
||||
return data->mCollector ?
|
||||
data->mCollector->FreeSnowWhite(false) :
|
||||
false;
|
||||
}
|
||||
|
||||
void
|
||||
nsCycleCollector::SelectPurple(GCGraphBuilder &builder)
|
||||
{
|
||||
@ -2649,7 +2590,7 @@ nsCycleCollector::CollectWhite(nsICycleCollectorListener *aListener)
|
||||
}
|
||||
timeLog.Checkpoint("CollectWhite::Unroot");
|
||||
|
||||
nsCycleCollector_dispatchDeferredDeletion();
|
||||
nsCycleCollector_dispatchDeferredDeletion(false);
|
||||
|
||||
return count > 0;
|
||||
}
|
||||
@ -2740,7 +2681,6 @@ nsCycleCollector::nsCycleCollector(CCThreadingModel aModel) :
|
||||
mJSRuntime(nullptr),
|
||||
mRunner(nullptr),
|
||||
mThread(PR_GetCurrentThread()),
|
||||
mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite()),
|
||||
mWhiteNodes(nullptr),
|
||||
mWhiteNodeCount(0),
|
||||
mVisitedRefCounted(0),
|
||||
@ -3379,12 +3319,28 @@ nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes,
|
||||
}
|
||||
|
||||
void
|
||||
nsCycleCollector_dispatchDeferredDeletion()
|
||||
nsCycleCollector_dispatchDeferredDeletion(bool aContinuation)
|
||||
{
|
||||
CollectorData* data = sCollectorData.get();
|
||||
if (data && data->mCollector) {
|
||||
AsyncFreeSnowWhite::Dispatch(data->mCollector);
|
||||
CollectorData *data = sCollectorData.get();
|
||||
|
||||
if (!data || !data->mRuntime) {
|
||||
return;
|
||||
}
|
||||
|
||||
data->mRuntime->DispatchDeferredDeletion(aContinuation);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCycleCollector_doDeferredDeletion()
|
||||
{
|
||||
CollectorData *data = sCollectorData.get();
|
||||
|
||||
// We should have started the cycle collector by now.
|
||||
MOZ_ASSERT(data);
|
||||
MOZ_ASSERT(data->mCollector);
|
||||
MOZ_ASSERT(data->mRuntime);
|
||||
|
||||
return data->mCollector->FreeSnowWhite(false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -57,7 +57,8 @@ void nsCycleCollector_setForgetSkippableCallback(CC_ForgetSkippableCallback aCB)
|
||||
void nsCycleCollector_forgetSkippable(bool aRemoveChildlessNodes = false,
|
||||
bool aAsyncSnowWhiteFreeing = false);
|
||||
|
||||
void nsCycleCollector_dispatchDeferredDeletion();
|
||||
void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false);
|
||||
bool nsCycleCollector_doDeferredDeletion();
|
||||
|
||||
void nsCycleCollector_collect(bool aManuallyTriggered,
|
||||
nsCycleCollectorResults *aResults,
|
||||
|
Loading…
Reference in New Issue
Block a user