Bug 1582124 - Break Document cycles when they are destroyed r=smaug

This patch nulls out a Document's promises when it is destroyed to break cycles going through them and ensure Documents are cleaned up sooner.

Differential Revision: https://phabricator.services.mozilla.com/D46286

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jon Coppeard 2019-09-19 13:41:44 +00:00
Родитель 815ac794a5
Коммит 3fd1d3324c
3 изменённых файлов: 31 добавлений и 9 удалений

Просмотреть файл

@ -10581,6 +10581,10 @@ void Document::Destroy() {
// leak-fixing if we fix nsDocumentViewer to do cycle-collection, but
// tearing down all those frame trees right now is the right thing to do.
mExternalResourceMap.Shutdown();
// Manually break cycles via promise's global object pointer.
mReadyForIdle = nullptr;
mOrientationPendingPromise = nullptr;
}
void Document::RemovedFromDocShell() {
@ -12615,6 +12619,11 @@ already_AddRefed<nsIURI> Document::GetMozDocumentURIIfNotForErrorPages() {
}
Promise* Document::GetDocumentReadyForIdle(ErrorResult& aRv) {
if (mIsGoingAway) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return nullptr;
}
if (!mReadyForIdle) {
nsIGlobalObject* global = GetScopeObject();
if (!global) {
@ -13815,8 +13824,17 @@ bool Document::FullscreenEnabled(CallerType aCallerType) {
return !GetFullscreenError(this, aCallerType);
}
void Document::SetOrientationPendingPromise(Promise* aPromise) {
void Document::ClearOrientationPendingPromise() {
mOrientationPendingPromise = nullptr;
}
bool Document::SetOrientationPendingPromise(Promise* aPromise) {
if (mIsGoingAway) {
return false;
}
mOrientationPendingPromise = aPromise;
return true;
}
static void DispatchPointerLockChange(Document* aTarget) {

Просмотреть файл

@ -2263,7 +2263,8 @@ class Document : public nsINode,
OrientationType CurrentOrientationType() const {
return mCurrentOrientationType;
}
void SetOrientationPendingPromise(Promise* aPromise);
void ClearOrientationPendingPromise();
bool SetOrientationPendingPromise(Promise* aPromise);
Promise* GetOrientationPendingPromise() const {
return mOrientationPendingPromise;
}

Просмотреть файл

@ -170,14 +170,14 @@ ScreenOrientation::LockOrientationTask::Run() {
if (mDocument->Hidden()) {
// Active orientation lock is not the document's orientation lock.
mPromise->MaybeResolveWithUndefined();
mDocument->SetOrientationPendingPromise(nullptr);
mDocument->ClearOrientationPendingPromise();
return NS_OK;
}
if (mOrientationLock == hal::eScreenOrientation_None) {
mScreenOrientation->UnlockDeviceOrientation();
mPromise->MaybeResolveWithUndefined();
mDocument->SetOrientationPendingPromise(nullptr);
mDocument->ClearOrientationPendingPromise();
return NS_OK;
}
@ -190,7 +190,7 @@ ScreenOrientation::LockOrientationTask::Run() {
if (NS_WARN_IF(!result)) {
mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
mDocument->SetOrientationPendingPromise(nullptr);
mDocument->ClearOrientationPendingPromise();
return NS_OK;
}
@ -199,7 +199,7 @@ ScreenOrientation::LockOrientationTask::Run() {
mDocument->CurrentOrientationAngle() == 0)) {
// Orientation lock will not cause an orientation change.
mPromise->MaybeResolveWithUndefined();
mDocument->SetOrientationPendingPromise(nullptr);
mDocument->ClearOrientationPendingPromise();
}
return NS_OK;
@ -256,7 +256,7 @@ static inline void AbortOrientationPromises(nsIDocShell* aDocShell) {
Promise* promise = doc->GetOrientationPendingPromise();
if (promise) {
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
doc->SetOrientationPendingPromise(nullptr);
doc->ClearOrientationPendingPromise();
}
}
@ -325,7 +325,10 @@ already_AddRefed<Promise> ScreenOrientation::LockInternal(
rootShell->SetOrientationLock(aOrientation);
AbortOrientationPromises(rootShell);
doc->SetOrientationPendingPromise(p);
if (!doc->SetOrientationPendingPromise(p)) {
p->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
return p.forget();
}
nsCOMPtr<nsIRunnable> lockOrientationTask = new LockOrientationTask(
this, p, aOrientation, doc, perm == FULLSCREEN_LOCK_ALLOWED);
@ -553,7 +556,7 @@ ScreenOrientation::DispatchChangeEventAndResolvePromise() {
Promise* pendingPromise = doc->GetOrientationPendingPromise();
if (pendingPromise) {
pendingPromise->MaybeResolveWithUndefined();
doc->SetOrientationPendingPromise(nullptr);
doc->ClearOrientationPendingPromise();
}
}
});