mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 716014 Investigate if we could use CompartmentGC more often, r=billm+terrence
--HG-- extra : rebase_source : f0cfb9cdd2e2823898f4c18402df53e7b6041bac
This commit is contained in:
parent
2ec243c586
commit
5cd5cd6fc2
@ -1012,7 +1012,7 @@ nsDOMWindowUtils::GarbageCollect(nsICycleCollectorListener *aListener,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS);
|
nsJSContext::GarbageCollectNow(js::gcreason::DOM_UTILS, nsGCNormal, true);
|
||||||
nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
|
nsJSContext::CycleCollectNow(aListener, aExtraForgetSkippableCalls);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -134,6 +134,10 @@ static PRLogModuleInfo* gJSDiagnostics;
|
|||||||
// doing the first GC.
|
// doing the first GC.
|
||||||
#define NS_FIRST_GC_DELAY 10000 // ms
|
#define NS_FIRST_GC_DELAY 10000 // ms
|
||||||
|
|
||||||
|
#define NS_FULL_GC_DELAY 60000 // ms
|
||||||
|
|
||||||
|
#define NS_MAX_COMPARTMENT_GC_COUNT 20
|
||||||
|
|
||||||
// Maximum amount of time that should elapse between incremental GC slices
|
// Maximum amount of time that should elapse between incremental GC slices
|
||||||
#define NS_INTERSLICE_GC_DELAY 100 // ms
|
#define NS_INTERSLICE_GC_DELAY 100 // ms
|
||||||
|
|
||||||
@ -159,6 +163,7 @@ static PRLogModuleInfo* gJSDiagnostics;
|
|||||||
static nsITimer *sGCTimer;
|
static nsITimer *sGCTimer;
|
||||||
static nsITimer *sShrinkGCBuffersTimer;
|
static nsITimer *sShrinkGCBuffersTimer;
|
||||||
static nsITimer *sCCTimer;
|
static nsITimer *sCCTimer;
|
||||||
|
static nsITimer *sFullGCTimer;
|
||||||
|
|
||||||
static PRTime sLastCCEndTime;
|
static PRTime sLastCCEndTime;
|
||||||
|
|
||||||
@ -178,6 +183,7 @@ static bool sLoadingInProgress;
|
|||||||
|
|
||||||
static PRUint32 sCCollectedWaitingForGC;
|
static PRUint32 sCCollectedWaitingForGC;
|
||||||
static bool sPostGCEventsToConsole;
|
static bool sPostGCEventsToConsole;
|
||||||
|
static bool sDisableExplicitCompartmentGC;
|
||||||
static PRUint32 sCCTimerFireCount = 0;
|
static PRUint32 sCCTimerFireCount = 0;
|
||||||
static PRUint32 sMinForgetSkippableTime = PR_UINT32_MAX;
|
static PRUint32 sMinForgetSkippableTime = PR_UINT32_MAX;
|
||||||
static PRUint32 sMaxForgetSkippableTime = 0;
|
static PRUint32 sMaxForgetSkippableTime = 0;
|
||||||
@ -185,9 +191,10 @@ static PRUint32 sTotalForgetSkippableTime = 0;
|
|||||||
static PRUint32 sRemovedPurples = 0;
|
static PRUint32 sRemovedPurples = 0;
|
||||||
static PRUint32 sForgetSkippableBeforeCC = 0;
|
static PRUint32 sForgetSkippableBeforeCC = 0;
|
||||||
static PRUint32 sPreviousSuspectedCount = 0;
|
static PRUint32 sPreviousSuspectedCount = 0;
|
||||||
|
static PRUint32 sCompartmentGCCount = NS_MAX_COMPARTMENT_GC_COUNT;
|
||||||
static PRUint32 sCleanupsSinceLastGC = PR_UINT32_MAX;
|
static PRUint32 sCleanupsSinceLastGC = PR_UINT32_MAX;
|
||||||
static bool sNeedsFullCC = false;
|
static bool sNeedsFullCC = false;
|
||||||
|
static nsJSContext *sContextList = nsnull;
|
||||||
|
|
||||||
nsScriptNameSpaceManager *gNameSpaceManager;
|
nsScriptNameSpaceManager *gNameSpaceManager;
|
||||||
|
|
||||||
@ -229,7 +236,8 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
|||||||
const PRUnichar* aData)
|
const PRUnichar* aData)
|
||||||
{
|
{
|
||||||
if (sGCOnMemoryPressure) {
|
if (sGCOnMemoryPressure) {
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking);
|
nsJSContext::GarbageCollectNow(js::gcreason::MEM_PRESSURE, nsGCShrinking,
|
||||||
|
true);
|
||||||
nsJSContext::CycleCollectNow();
|
nsJSContext::CycleCollectNow();
|
||||||
}
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -929,6 +937,8 @@ static const char js_pccounts_content_str[] = JS_OPTIONS_DOT_STR "pccounts.con
|
|||||||
static const char js_pccounts_chrome_str[] = JS_OPTIONS_DOT_STR "pccounts.chrome";
|
static const char js_pccounts_chrome_str[] = JS_OPTIONS_DOT_STR "pccounts.chrome";
|
||||||
static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening";
|
static const char js_jit_hardening_str[] = JS_OPTIONS_DOT_STR "jit_hardening";
|
||||||
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
|
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
|
||||||
|
static const char js_disable_explicit_compartment_gc[] =
|
||||||
|
JS_OPTIONS_DOT_STR "disable_explicit_compartment_gc";
|
||||||
|
|
||||||
int
|
int
|
||||||
nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||||
@ -938,6 +948,8 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
|||||||
PRUint32 newDefaultJSOptions = oldDefaultJSOptions;
|
PRUint32 newDefaultJSOptions = oldDefaultJSOptions;
|
||||||
|
|
||||||
sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
|
sPostGCEventsToConsole = Preferences::GetBool(js_memlog_option_str);
|
||||||
|
sDisableExplicitCompartmentGC =
|
||||||
|
Preferences::GetBool(js_disable_explicit_compartment_gc);
|
||||||
|
|
||||||
bool strict = Preferences::GetBool(js_strict_option_str);
|
bool strict = Preferences::GetBool(js_strict_option_str);
|
||||||
if (strict)
|
if (strict)
|
||||||
@ -1038,9 +1050,16 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsJSContext::nsJSContext(JSRuntime *aRuntime)
|
nsJSContext::nsJSContext(JSRuntime *aRuntime)
|
||||||
: mGCOnDestruction(true),
|
: mActive(false),
|
||||||
|
mGCOnDestruction(true),
|
||||||
mExecuteDepth(0)
|
mExecuteDepth(0)
|
||||||
{
|
{
|
||||||
|
mNext = sContextList;
|
||||||
|
mPrev = &sContextList;
|
||||||
|
if (sContextList) {
|
||||||
|
sContextList->mPrev = &mNext;
|
||||||
|
}
|
||||||
|
sContextList = this;
|
||||||
|
|
||||||
++sContextCount;
|
++sContextCount;
|
||||||
|
|
||||||
@ -1079,6 +1098,11 @@ nsJSContext::~nsJSContext()
|
|||||||
nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptContext*>(this));
|
nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptContext*>(this));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
*mPrev = mNext;
|
||||||
|
if (mNext) {
|
||||||
|
mNext->mPrev = mPrev;
|
||||||
|
}
|
||||||
|
|
||||||
// We may still have pending termination functions if the context is destroyed
|
// We may still have pending termination functions if the context is destroyed
|
||||||
// before they could be executed. In this case, free the references to their
|
// before they could be executed. In this case, free the references to their
|
||||||
// parameters, but don't execute the functions (see bug 622326).
|
// parameters, but don't execute the functions (see bug 622326).
|
||||||
@ -2849,6 +2873,7 @@ nsJSContext::ScriptEvaluated(bool aTerminated)
|
|||||||
if (aTerminated) {
|
if (aTerminated) {
|
||||||
mOperationCallbackTime = 0;
|
mOperationCallbackTime = 0;
|
||||||
mModalStateTime = 0;
|
mModalStateTime = 0;
|
||||||
|
mActive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2916,9 +2941,20 @@ nsJSContext::ScriptExecuted()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FullGCTimerFired(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
NS_RELEASE(sFullGCTimer);
|
||||||
|
|
||||||
|
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||||
|
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||||
|
nsGCNormal, true);
|
||||||
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void
|
void
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason, PRUint32 aGckind,
|
||||||
|
bool aGlobal)
|
||||||
{
|
{
|
||||||
NS_TIME_FUNCTION_MIN(1.0);
|
NS_TIME_FUNCTION_MIN(1.0);
|
||||||
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
SAMPLE_LABEL("GC", "GarbageCollectNow");
|
||||||
@ -2935,9 +2971,35 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind)
|
|||||||
sPendingLoadCount = 0;
|
sPendingLoadCount = 0;
|
||||||
sLoadingInProgress = false;
|
sLoadingInProgress = false;
|
||||||
|
|
||||||
if (nsContentUtils::XPConnect()) {
|
if (!nsContentUtils::XPConnect()) {
|
||||||
nsContentUtils::XPConnect()->GarbageCollect(reason, gckind);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use compartment GC when we're not asked to do a shrinking GC nor
|
||||||
|
// global GC and compartment GC has been called less than
|
||||||
|
// NS_MAX_COMPARTMENT_GC_COUNT times after the previous global GC.
|
||||||
|
if (!sDisableExplicitCompartmentGC &&
|
||||||
|
aGckind != nsGCShrinking && !aGlobal &&
|
||||||
|
sCompartmentGCCount < NS_MAX_COMPARTMENT_GC_COUNT) {
|
||||||
|
js::PrepareForFullGC(nsJSRuntime::sRuntime);
|
||||||
|
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
|
||||||
|
if (!cx->mActive && cx->mContext) {
|
||||||
|
if (JSObject* global = cx->GetNativeGlobal()) {
|
||||||
|
js::SkipCompartmentForGC(js::GetObjectCompartment(global));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cx->mActive = false;
|
||||||
|
}
|
||||||
|
if (js::IsGCScheduled(nsJSRuntime::sRuntime)) {
|
||||||
|
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (nsJSContext* cx = sContextList; cx; cx = cx->mNext) {
|
||||||
|
cx->mActive = false;
|
||||||
|
}
|
||||||
|
nsContentUtils::XPConnect()->GarbageCollect(aReason, aGckind);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
@ -2963,7 +3025,7 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
|
|||||||
|
|
||||||
if (sCCLockedOut) {
|
if (sCCLockedOut) {
|
||||||
// We're in the middle of an incremental GC; finish it first
|
// We're in the middle of an incremental GC; finish it first
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED, nsGCNormal);
|
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED, nsGCNormal, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SAMPLE_LABEL("GC", "CycleCollectNow");
|
SAMPLE_LABEL("GC", "CycleCollectNow");
|
||||||
@ -3100,7 +3162,8 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||||||
NS_RELEASE(sGCTimer);
|
NS_RELEASE(sGCTimer);
|
||||||
|
|
||||||
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
|
||||||
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason), nsGCIncremental);
|
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
|
||||||
|
nsGCNormal, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -3156,7 +3219,7 @@ CCTimerFired(nsITimer *aTimer, void *aClosure)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finish the current incremental GC
|
// Finish the current incremental GC
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED, nsGCNormal);
|
nsJSContext::GarbageCollectNow(js::gcreason::CC_FORCED, nsGCNormal, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
++sCCTimerFireCount;
|
++sCCTimerFireCount;
|
||||||
@ -3309,6 +3372,15 @@ nsJSContext::KillGCTimer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsJSContext::KillFullGCTimer()
|
||||||
|
{
|
||||||
|
if (sFullGCTimer) {
|
||||||
|
sFullGCTimer->Cancel();
|
||||||
|
NS_RELEASE(sFullGCTimer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void
|
void
|
||||||
nsJSContext::KillShrinkGCBuffersTimer()
|
nsJSContext::KillShrinkGCBuffersTimer()
|
||||||
@ -3336,6 +3408,7 @@ nsJSContext::KillCCTimer()
|
|||||||
void
|
void
|
||||||
nsJSContext::GC(js::gcreason::Reason aReason)
|
nsJSContext::GC(js::gcreason::Reason aReason)
|
||||||
{
|
{
|
||||||
|
mActive = true;
|
||||||
PokeGC(aReason);
|
PokeGC(aReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3417,20 +3490,23 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
|
|||||||
|
|
||||||
sCCollectedWaitingForGC = 0;
|
sCCollectedWaitingForGC = 0;
|
||||||
sCleanupsSinceLastGC = 0;
|
sCleanupsSinceLastGC = 0;
|
||||||
|
|
||||||
if (aDesc.isCompartment) {
|
|
||||||
// If this is a compartment GC, restart it. We still want
|
|
||||||
// a full GC to happen. Compartment GCs usually happen as a
|
|
||||||
// result of last-ditch or MaybeGC. In both cases it is
|
|
||||||
// probably a time of heavy activity and we want to delay
|
|
||||||
// the full GC, but we do want it to happen eventually.
|
|
||||||
nsJSContext::PokeGC(js::gcreason::POST_COMPARTMENT);
|
|
||||||
}
|
|
||||||
|
|
||||||
sNeedsFullCC = true;
|
sNeedsFullCC = true;
|
||||||
nsJSContext::MaybePokeCC();
|
nsJSContext::MaybePokeCC();
|
||||||
|
|
||||||
if (!aDesc.isCompartment) {
|
if (aDesc.isCompartment) {
|
||||||
|
++sCompartmentGCCount;
|
||||||
|
if (!sFullGCTimer) {
|
||||||
|
CallCreateInstance("@mozilla.org/timer;1", &sFullGCTimer);
|
||||||
|
js::gcreason::Reason reason = js::gcreason::FULL_GC_TIMER;
|
||||||
|
sFullGCTimer->InitWithFuncCallback(FullGCTimerFired,
|
||||||
|
reinterpret_cast<void *>(reason),
|
||||||
|
NS_FULL_GC_DELAY,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sCompartmentGCCount = 0;
|
||||||
|
nsJSContext::KillFullGCTimer();
|
||||||
|
|
||||||
// Avoid shrinking during heavy activity, which is suggested by
|
// Avoid shrinking during heavy activity, which is suggested by
|
||||||
// compartment GC.
|
// compartment GC.
|
||||||
nsJSContext::PokeShrinkGCBuffers();
|
nsJSContext::PokeShrinkGCBuffers();
|
||||||
@ -3530,7 +3606,7 @@ void
|
|||||||
nsJSRuntime::Startup()
|
nsJSRuntime::Startup()
|
||||||
{
|
{
|
||||||
// initialize all our statics, so that we can restart XPCOM
|
// initialize all our statics, so that we can restart XPCOM
|
||||||
sGCTimer = sCCTimer = nsnull;
|
sGCTimer = sFullGCTimer = sCCTimer = nsnull;
|
||||||
sCCLockedOut = false;
|
sCCLockedOut = false;
|
||||||
sCCLockedOutTime = 0;
|
sCCLockedOutTime = 0;
|
||||||
sLastCCEndTime = 0;
|
sLastCCEndTime = 0;
|
||||||
@ -3538,6 +3614,7 @@ nsJSRuntime::Startup()
|
|||||||
sLoadingInProgress = false;
|
sLoadingInProgress = false;
|
||||||
sCCollectedWaitingForGC = 0;
|
sCCollectedWaitingForGC = 0;
|
||||||
sPostGCEventsToConsole = false;
|
sPostGCEventsToConsole = false;
|
||||||
|
sDisableExplicitCompartmentGC = false;
|
||||||
sNeedsFullCC = false;
|
sNeedsFullCC = false;
|
||||||
gNameSpaceManager = nsnull;
|
gNameSpaceManager = nsnull;
|
||||||
sRuntimeService = nsnull;
|
sRuntimeService = nsnull;
|
||||||
@ -3829,6 +3906,7 @@ nsJSRuntime::Shutdown()
|
|||||||
nsJSContext::KillGCTimer();
|
nsJSContext::KillGCTimer();
|
||||||
nsJSContext::KillShrinkGCBuffersTimer();
|
nsJSContext::KillShrinkGCBuffersTimer();
|
||||||
nsJSContext::KillCCTimer();
|
nsJSContext::KillCCTimer();
|
||||||
|
nsJSContext::KillFullGCTimer();
|
||||||
|
|
||||||
NS_IF_RELEASE(gNameSpaceManager);
|
NS_IF_RELEASE(gNameSpaceManager);
|
||||||
|
|
||||||
|
@ -184,7 +184,9 @@ public:
|
|||||||
static void LoadStart();
|
static void LoadStart();
|
||||||
static void LoadEnd();
|
static void LoadEnd();
|
||||||
|
|
||||||
static void GarbageCollectNow(js::gcreason::Reason reason, PRUint32 gckind = nsGCNormal);
|
static void GarbageCollectNow(js::gcreason::Reason reason,
|
||||||
|
PRUint32 aGckind,
|
||||||
|
bool aGlobal);
|
||||||
static void ShrinkGCBuffersNow();
|
static void ShrinkGCBuffersNow();
|
||||||
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
|
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
|
||||||
// called even if the previous collection was GC.
|
// called even if the previous collection was GC.
|
||||||
@ -199,6 +201,7 @@ public:
|
|||||||
|
|
||||||
static void MaybePokeCC();
|
static void MaybePokeCC();
|
||||||
static void KillCCTimer();
|
static void KillCCTimer();
|
||||||
|
static void KillFullGCTimer();
|
||||||
|
|
||||||
virtual void GC(js::gcreason::Reason aReason);
|
virtual void GC(js::gcreason::Reason aReason);
|
||||||
|
|
||||||
@ -238,7 +241,7 @@ private:
|
|||||||
nsrefcnt GetCCRefcnt();
|
nsrefcnt GetCCRefcnt();
|
||||||
|
|
||||||
JSContext *mContext;
|
JSContext *mContext;
|
||||||
PRUint32 mNumEvaluations;
|
bool mActive;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct TerminationFuncHolder;
|
struct TerminationFuncHolder;
|
||||||
@ -307,6 +310,9 @@ private:
|
|||||||
PRTime mModalStateTime;
|
PRTime mModalStateTime;
|
||||||
PRUint32 mModalStateDepth;
|
PRUint32 mModalStateDepth;
|
||||||
|
|
||||||
|
nsJSContext *mNext;
|
||||||
|
nsJSContext **mPrev;
|
||||||
|
|
||||||
// mGlobalObjectRef ensures that the outer window stays alive as long as the
|
// mGlobalObjectRef ensures that the outer window stays alive as long as the
|
||||||
// context does. It is eventually collected by the cycle collector.
|
// context does. It is eventually collected by the cycle collector.
|
||||||
nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;
|
nsCOMPtr<nsIScriptGlobalObject> mGlobalObjectRef;
|
||||||
|
@ -791,14 +791,14 @@ ContentChild::GetIndexedDBPath()
|
|||||||
bool
|
bool
|
||||||
ContentChild::RecvGarbageCollect()
|
ContentChild::RecvGarbageCollect()
|
||||||
{
|
{
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ContentChild::RecvCycleCollect()
|
ContentChild::RecvCycleCollect()
|
||||||
{
|
{
|
||||||
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC);
|
nsJSContext::GarbageCollectNow(js::gcreason::DOM_IPC, nsGCNormal, true);
|
||||||
nsJSContext::CycleCollectNow();
|
nsJSContext::CycleCollectNow();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,12 @@ struct JSCompartment
|
|||||||
gcState = GCScheduled;
|
gcState = GCScheduled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unscheduleGC() {
|
||||||
|
JS_ASSERT(!rt->gcRunning);
|
||||||
|
JS_ASSERT(gcState != GCRunning);
|
||||||
|
gcState = NoGCScheduled;
|
||||||
|
}
|
||||||
|
|
||||||
bool isGCScheduled() const {
|
bool isGCScheduled() const {
|
||||||
return gcState == GCScheduled;
|
return gcState == GCScheduled;
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,12 @@ js::IsGCScheduled(JSRuntime *rt)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_FRIEND_API(void)
|
||||||
|
js::SkipCompartmentForGC(JSCompartment *comp)
|
||||||
|
{
|
||||||
|
comp->unscheduleGC();
|
||||||
|
}
|
||||||
|
|
||||||
JS_FRIEND_API(void)
|
JS_FRIEND_API(void)
|
||||||
js::GCForReason(JSRuntime *rt, gcreason::Reason reason)
|
js::GCForReason(JSRuntime *rt, gcreason::Reason reason)
|
||||||
{
|
{
|
||||||
|
@ -619,7 +619,8 @@ SizeOfJSContext();
|
|||||||
D(DOM_IPC) \
|
D(DOM_IPC) \
|
||||||
D(DOM_WORKER) \
|
D(DOM_WORKER) \
|
||||||
D(INTER_SLICE_GC) \
|
D(INTER_SLICE_GC) \
|
||||||
D(REFRESH_FRAME)
|
D(REFRESH_FRAME) \
|
||||||
|
D(FULL_GC_TIMER)
|
||||||
|
|
||||||
namespace gcreason {
|
namespace gcreason {
|
||||||
|
|
||||||
@ -643,6 +644,9 @@ PrepareForFullGC(JSRuntime *rt);
|
|||||||
extern JS_FRIEND_API(bool)
|
extern JS_FRIEND_API(bool)
|
||||||
IsGCScheduled(JSRuntime *rt);
|
IsGCScheduled(JSRuntime *rt);
|
||||||
|
|
||||||
|
extern JS_FRIEND_API(void)
|
||||||
|
SkipCompartmentForGC(JSCompartment *comp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When triggering a GC using one of the functions below, it is first necessary
|
* When triggering a GC using one of the functions below, it is first necessary
|
||||||
* to select the compartments to be collected. To do this, you can call
|
* to select the compartments to be collected. To do this, you can call
|
||||||
|
Loading…
Reference in New Issue
Block a user