Bug 1110928, part 4 - Try to pass a relevant zone to PokeGC. r=smaug

This means the browser will do less full GCs.

MozReview-Commit-ID: BXf4GGhmbMx
This commit is contained in:
Andrew McCreight 2016-08-19 15:26:56 -07:00
parent 0e61ad42e5
commit a0ddf20ce7
5 changed files with 38 additions and 12 deletions

View File

@ -2890,7 +2890,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
newInnerWindow->mChromeEventHandler = mChromeEventHandler;
}
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT);
nsJSContext::PokeGC(JS::gcreason::SET_NEW_DOCUMENT,
GetWrapperPreserveColor());
mContext->DidInitializeContext();
// We wait to fire the debugger hook until the window is all set up and hooked
@ -3107,7 +3108,8 @@ nsGlobalWindow::DetachFromDocShell()
mChromeEventHandler = nullptr; // force release now
if (mContext) {
nsJSContext::PokeGC(JS::gcreason::SET_DOC_SHELL);
nsJSContext::PokeGC(JS::gcreason::SET_DOC_SHELL,
GetWrapperPreserveColor());
mContext = nullptr;
}

View File

@ -608,7 +608,7 @@ void
nsJSContext::Destroy()
{
if (mGCOnDestruction) {
PokeGC(JS::gcreason::NSJSCONTEXT_DESTROY);
PokeGC(JS::gcreason::NSJSCONTEXT_DESTROY, mWindowProxy);
}
DropJSObjects(this);
@ -1208,8 +1208,11 @@ nsJSContext::GarbageCollectNow(JS::gcreason::Reason aReason,
JSGCInvocationKind gckind = aShrinking == ShrinkingGC ? GC_SHRINK : GC_NORMAL;
if (sNeedsFullGC || aReason != JS::gcreason::CC_WAITING) {
sNeedsFullGC = false;
if (aIncremental == NonIncrementalGC || aReason == JS::gcreason::FULL_GC_TIMER) {
sNeedsFullGC = true;
}
if (sNeedsFullGC) {
JS::PrepareForFullGC(sContext);
} else {
CycleCollectedJSRuntime::Get()->PrepareWaitingZonesForGC();
@ -1586,7 +1589,7 @@ nsJSContext::EndCycleCollectionCallback(CycleCollectorResults &aResults)
uint32_t ccNowDuration = TimeBetween(gCCStats.mBeginTime, endCCTimeStamp);
if (NeedsGCAfterCC()) {
PokeGC(JS::gcreason::CC_WAITING,
PokeGC(JS::gcreason::CC_WAITING, nullptr,
NS_GC_DELAY - std::min(ccNowDuration, kMaxICCDuration));
}
@ -1923,11 +1926,22 @@ nsJSContext::RunNextCollectorTimer()
// static
void
nsJSContext::PokeGC(JS::gcreason::Reason aReason, int aDelay)
nsJSContext::PokeGC(JS::gcreason::Reason aReason,
JSObject* aObj,
int aDelay)
{
sNeedsFullGC = sNeedsFullGC || aReason != JS::gcreason::CC_WAITING;
if (sShuttingDown) {
return;
}
if (sGCTimer || sInterSliceGCTimer || sShuttingDown) {
if (aObj) {
JS::Zone* zone = JS::GetObjectZone(aObj);
CycleCollectedJSRuntime::Get()->AddZoneWaitingForGC(zone);
} else if (aReason != JS::gcreason::CC_WAITING) {
sNeedsFullGC = true;
}
if (sGCTimer || sInterSliceGCTimer) {
// There's already a timer for GC'ing, just return
return;
}
@ -2110,6 +2124,11 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
case JS::GC_CYCLE_BEGIN: {
// Prevent cycle collections and shrinking during incremental GC.
sCCLockedOut = true;
if (!aDesc.isCompartment_) {
sNeedsFullGC = false;
}
break;
}

View File

@ -108,7 +108,8 @@ public:
static void RunNextCollectorTimer();
static void PokeGC(JS::gcreason::Reason aReason, int aDelay = 0);
// The GC should probably run soon, in the zone of object aObj (if given).
static void PokeGC(JS::gcreason::Reason aReason, JSObject* aObj, int aDelay = 0);
static void KillGCTimer();
static void PokeShrinkingGC();

View File

@ -1038,7 +1038,8 @@ nsDocumentViewer::LoadComplete(nsresult aStatus)
nsJSContext::LoadEnd();
// It's probably a good idea to GC soon since we have finished loading.
PokeGC(JS::gcreason::LOAD_END);
nsJSContext::PokeGC(JS::gcreason::LOAD_END,
mDocument ? mDocument->GetWrapperPreserveColor() : nullptr);
#ifdef NS_PRINTING
// Check to see if someone tried to print during the load
@ -1286,7 +1287,9 @@ nsDocumentViewer::PageHide(bool aIsUnload)
if (aIsUnload) {
// Poke the GC. The window might be collectable garbage now.
nsJSContext::PokeGC(JS::gcreason::PAGE_HIDE, NS_GC_DELAY * 2);
nsJSContext::PokeGC(JS::gcreason::PAGE_HIDE,
mDocument->GetWrapperPreserveColor(),
NS_GC_DELAY * 2);
}
mDocument->OnPageHide(!aIsUnload, nullptr);

View File

@ -1668,6 +1668,7 @@ CycleCollectedJSRuntime::PrepareWaitingZonesForGC()
if (mZonesWaitingForGC.Count() == 0) {
JS::PrepareForFullGC(Context());
} else {
JS::PrepareSystemZoneForGC(Context());
for (auto iter = mZonesWaitingForGC.Iter(); !iter.Done(); iter.Next()) {
JS::PrepareZoneForGC(iter.Get()->GetKey());
}