IntersectionObserver leaks documents
https://bugs.webkit.org/show_bug.cgi?id=189128
Reviewed by Simon Fraser.
Source/WebCore:
Currently, Documents own IntersectionObservers while IntersectionObservers own callbacks
that have strong references to Documents. To break this cycle, make Documents only have
weak pointers to IntersectionObservers. Instead, manage the lifetime of an
IntersectionObserver as an ActiveDOMObject, overriding hasPendingActivity to keep
the observer alive while there are ongoing observations.
However, there is a still a potential reference cycle. The callback keeps global
references alive, so if there's a global reference to the observer in JavaScript,
we have an observer->callback->observer cycle, keeping the callback (and hence the Document)
alive. To break this cycle, make IntersectionObserver release the callback when its
Document is stopped.
With these changes, there are no longer any leaks reported with run-webkit-tests --world-leaks
on LayoutTests/intersection-observer and LayoutTests/imported/w3c/web-platform-tests/intersection-observer.
Tests: intersection-observer/no-document-leak.html
intersection-observer/observer-and-callback-without-js-references.html
* dom/Document.cpp:
(WebCore::Document::addIntersectionObserver):
(WebCore::Document::removeIntersectionObserver):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::~IntersectionObserver):
(WebCore::IntersectionObserver::observe):
(WebCore::IntersectionObserver::rootDestroyed):
(WebCore::IntersectionObserver::createTimestamp const):
(WebCore::IntersectionObserver::notify):
(WebCore::IntersectionObserver::hasPendingActivity const):
(WebCore::IntersectionObserver::activeDOMObjectName const):
(WebCore::IntersectionObserver::canSuspendForDocumentSuspension const):
(WebCore::IntersectionObserver::stop):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::trackingDocument const):
(WebCore::IntersectionObserver::trackingDocument): Deleted.
* page/IntersectionObserver.idl:
LayoutTests:
* intersection-observer/no-document-leak-expected.txt: Added.
* intersection-observer/no-document-leak.html: Added.
* intersection-observer/observer-and-callback-without-js-references-expected.txt: Added.
* intersection-observer/observer-and-callback-without-js-references.html: Added.
* intersection-observer/resources/no-document-leak-frame.html: Added.
Canonical link: https://commits.webkit.org/204346@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-06 13:51:24 +00:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<script src="../resources/js-test-pre.js"></script>
|
2020-05-08 17:14:15 +00:00
|
|
|
<script src="../resources/gc.js"></script>
|
IntersectionObserver leaks documents
https://bugs.webkit.org/show_bug.cgi?id=189128
Reviewed by Simon Fraser.
Source/WebCore:
Currently, Documents own IntersectionObservers while IntersectionObservers own callbacks
that have strong references to Documents. To break this cycle, make Documents only have
weak pointers to IntersectionObservers. Instead, manage the lifetime of an
IntersectionObserver as an ActiveDOMObject, overriding hasPendingActivity to keep
the observer alive while there are ongoing observations.
However, there is a still a potential reference cycle. The callback keeps global
references alive, so if there's a global reference to the observer in JavaScript,
we have an observer->callback->observer cycle, keeping the callback (and hence the Document)
alive. To break this cycle, make IntersectionObserver release the callback when its
Document is stopped.
With these changes, there are no longer any leaks reported with run-webkit-tests --world-leaks
on LayoutTests/intersection-observer and LayoutTests/imported/w3c/web-platform-tests/intersection-observer.
Tests: intersection-observer/no-document-leak.html
intersection-observer/observer-and-callback-without-js-references.html
* dom/Document.cpp:
(WebCore::Document::addIntersectionObserver):
(WebCore::Document::removeIntersectionObserver):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::~IntersectionObserver):
(WebCore::IntersectionObserver::observe):
(WebCore::IntersectionObserver::rootDestroyed):
(WebCore::IntersectionObserver::createTimestamp const):
(WebCore::IntersectionObserver::notify):
(WebCore::IntersectionObserver::hasPendingActivity const):
(WebCore::IntersectionObserver::activeDOMObjectName const):
(WebCore::IntersectionObserver::canSuspendForDocumentSuspension const):
(WebCore::IntersectionObserver::stop):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::trackingDocument const):
(WebCore::IntersectionObserver::trackingDocument): Deleted.
* page/IntersectionObserver.idl:
LayoutTests:
* intersection-observer/no-document-leak-expected.txt: Added.
* intersection-observer/no-document-leak.html: Added.
* intersection-observer/observer-and-callback-without-js-references-expected.txt: Added.
* intersection-observer/observer-and-callback-without-js-references.html: Added.
* intersection-observer/resources/no-document-leak-frame.html: Added.
Canonical link: https://commits.webkit.org/204346@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-06 13:51:24 +00:00
|
|
|
</head>
|
|
|
|
<body>
|
2020-05-08 17:14:15 +00:00
|
|
|
<iframe id="testFrame" src=></iframe>
|
IntersectionObserver leaks documents
https://bugs.webkit.org/show_bug.cgi?id=189128
Reviewed by Simon Fraser.
Source/WebCore:
Currently, Documents own IntersectionObservers while IntersectionObservers own callbacks
that have strong references to Documents. To break this cycle, make Documents only have
weak pointers to IntersectionObservers. Instead, manage the lifetime of an
IntersectionObserver as an ActiveDOMObject, overriding hasPendingActivity to keep
the observer alive while there are ongoing observations.
However, there is a still a potential reference cycle. The callback keeps global
references alive, so if there's a global reference to the observer in JavaScript,
we have an observer->callback->observer cycle, keeping the callback (and hence the Document)
alive. To break this cycle, make IntersectionObserver release the callback when its
Document is stopped.
With these changes, there are no longer any leaks reported with run-webkit-tests --world-leaks
on LayoutTests/intersection-observer and LayoutTests/imported/w3c/web-platform-tests/intersection-observer.
Tests: intersection-observer/no-document-leak.html
intersection-observer/observer-and-callback-without-js-references.html
* dom/Document.cpp:
(WebCore::Document::addIntersectionObserver):
(WebCore::Document::removeIntersectionObserver):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::~IntersectionObserver):
(WebCore::IntersectionObserver::observe):
(WebCore::IntersectionObserver::rootDestroyed):
(WebCore::IntersectionObserver::createTimestamp const):
(WebCore::IntersectionObserver::notify):
(WebCore::IntersectionObserver::hasPendingActivity const):
(WebCore::IntersectionObserver::activeDOMObjectName const):
(WebCore::IntersectionObserver::canSuspendForDocumentSuspension const):
(WebCore::IntersectionObserver::stop):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::trackingDocument const):
(WebCore::IntersectionObserver::trackingDocument): Deleted.
* page/IntersectionObserver.idl:
LayoutTests:
* intersection-observer/no-document-leak-expected.txt: Added.
* intersection-observer/no-document-leak.html: Added.
* intersection-observer/observer-and-callback-without-js-references-expected.txt: Added.
* intersection-observer/observer-and-callback-without-js-references.html: Added.
* intersection-observer/resources/no-document-leak-frame.html: Added.
Canonical link: https://commits.webkit.org/204346@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-06 13:51:24 +00:00
|
|
|
<script>
|
|
|
|
description("Tests that using IntersectionObserver does not cause the document to get leaked.");
|
|
|
|
window.jsTestIsAsync = true;
|
|
|
|
|
2020-05-08 17:14:15 +00:00
|
|
|
let totalCount = 0;
|
|
|
|
window.onload = function () {
|
|
|
|
testDocumentIsNotLeaked(
|
|
|
|
async function initAndRemove(frameCount)
|
|
|
|
{
|
|
|
|
totalCount = frameCount;
|
|
|
|
let frames = await new Promise((resolve, reject) => {
|
|
|
|
let frames = [];
|
|
|
|
let counter = 0;
|
|
|
|
function onLoad() {
|
|
|
|
counter++;
|
|
|
|
if (counter == frameCount)
|
|
|
|
resolve(frames);
|
|
|
|
}
|
|
|
|
for (let i = 0; i < frameCount; ++i) {
|
|
|
|
let frame = document.createElement('iframe');
|
|
|
|
frame.src = "resources/no-document-leak-frame.html";
|
|
|
|
frame.onload = onLoad;
|
|
|
|
document.body.appendChild(frame);
|
|
|
|
frames.push(frame);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
totalCount = internals.numberOfIntersectionObservers(document);
|
|
|
|
let frameIdentifiers = [];
|
|
|
|
for (let i = 0; i < frameCount; ++i) {
|
|
|
|
let frame = frames[i];
|
|
|
|
frameIdentifiers.push(internals.documentIdentifier(frame.contentDocument));
|
|
|
|
frame.remove();
|
IntersectionObserver leaks documents
https://bugs.webkit.org/show_bug.cgi?id=189128
Reviewed by Simon Fraser.
Source/WebCore:
Currently, Documents own IntersectionObservers while IntersectionObservers own callbacks
that have strong references to Documents. To break this cycle, make Documents only have
weak pointers to IntersectionObservers. Instead, manage the lifetime of an
IntersectionObserver as an ActiveDOMObject, overriding hasPendingActivity to keep
the observer alive while there are ongoing observations.
However, there is a still a potential reference cycle. The callback keeps global
references alive, so if there's a global reference to the observer in JavaScript,
we have an observer->callback->observer cycle, keeping the callback (and hence the Document)
alive. To break this cycle, make IntersectionObserver release the callback when its
Document is stopped.
With these changes, there are no longer any leaks reported with run-webkit-tests --world-leaks
on LayoutTests/intersection-observer and LayoutTests/imported/w3c/web-platform-tests/intersection-observer.
Tests: intersection-observer/no-document-leak.html
intersection-observer/observer-and-callback-without-js-references.html
* dom/Document.cpp:
(WebCore::Document::addIntersectionObserver):
(WebCore::Document::removeIntersectionObserver):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::~IntersectionObserver):
(WebCore::IntersectionObserver::observe):
(WebCore::IntersectionObserver::rootDestroyed):
(WebCore::IntersectionObserver::createTimestamp const):
(WebCore::IntersectionObserver::notify):
(WebCore::IntersectionObserver::hasPendingActivity const):
(WebCore::IntersectionObserver::activeDOMObjectName const):
(WebCore::IntersectionObserver::canSuspendForDocumentSuspension const):
(WebCore::IntersectionObserver::stop):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::trackingDocument const):
(WebCore::IntersectionObserver::trackingDocument): Deleted.
* page/IntersectionObserver.idl:
LayoutTests:
* intersection-observer/no-document-leak-expected.txt: Added.
* intersection-observer/no-document-leak.html: Added.
* intersection-observer/observer-and-callback-without-js-references-expected.txt: Added.
* intersection-observer/observer-and-callback-without-js-references.html: Added.
* intersection-observer/resources/no-document-leak-frame.html: Added.
Canonical link: https://commits.webkit.org/204346@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-06 13:51:24 +00:00
|
|
|
}
|
2020-05-08 17:14:15 +00:00
|
|
|
nukeArray(frames);
|
|
|
|
frames = null;
|
|
|
|
return frameIdentifiers;
|
|
|
|
},
|
|
|
|
{
|
|
|
|
additionalCheck: function()
|
|
|
|
{
|
|
|
|
let count = internals.numberOfIntersectionObservers(document);
|
|
|
|
return count < totalCount || count === 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
).then(
|
|
|
|
() => testPassed("Document did not leak"),
|
|
|
|
(error) => testFailed(error.message)
|
|
|
|
).finally(finishJSTest);
|
IntersectionObserver leaks documents
https://bugs.webkit.org/show_bug.cgi?id=189128
Reviewed by Simon Fraser.
Source/WebCore:
Currently, Documents own IntersectionObservers while IntersectionObservers own callbacks
that have strong references to Documents. To break this cycle, make Documents only have
weak pointers to IntersectionObservers. Instead, manage the lifetime of an
IntersectionObserver as an ActiveDOMObject, overriding hasPendingActivity to keep
the observer alive while there are ongoing observations.
However, there is a still a potential reference cycle. The callback keeps global
references alive, so if there's a global reference to the observer in JavaScript,
we have an observer->callback->observer cycle, keeping the callback (and hence the Document)
alive. To break this cycle, make IntersectionObserver release the callback when its
Document is stopped.
With these changes, there are no longer any leaks reported with run-webkit-tests --world-leaks
on LayoutTests/intersection-observer and LayoutTests/imported/w3c/web-platform-tests/intersection-observer.
Tests: intersection-observer/no-document-leak.html
intersection-observer/observer-and-callback-without-js-references.html
* dom/Document.cpp:
(WebCore::Document::addIntersectionObserver):
(WebCore::Document::removeIntersectionObserver):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::~IntersectionObserver):
(WebCore::IntersectionObserver::observe):
(WebCore::IntersectionObserver::rootDestroyed):
(WebCore::IntersectionObserver::createTimestamp const):
(WebCore::IntersectionObserver::notify):
(WebCore::IntersectionObserver::hasPendingActivity const):
(WebCore::IntersectionObserver::activeDOMObjectName const):
(WebCore::IntersectionObserver::canSuspendForDocumentSuspension const):
(WebCore::IntersectionObserver::stop):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::trackingDocument const):
(WebCore::IntersectionObserver::trackingDocument): Deleted.
* page/IntersectionObserver.idl:
LayoutTests:
* intersection-observer/no-document-leak-expected.txt: Added.
* intersection-observer/no-document-leak.html: Added.
* intersection-observer/observer-and-callback-without-js-references-expected.txt: Added.
* intersection-observer/observer-and-callback-without-js-references.html: Added.
* intersection-observer/resources/no-document-leak-frame.html: Added.
Canonical link: https://commits.webkit.org/204346@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-06 13:51:24 +00:00
|
|
|
};
|
2020-05-08 17:14:15 +00:00
|
|
|
|
IntersectionObserver leaks documents
https://bugs.webkit.org/show_bug.cgi?id=189128
Reviewed by Simon Fraser.
Source/WebCore:
Currently, Documents own IntersectionObservers while IntersectionObservers own callbacks
that have strong references to Documents. To break this cycle, make Documents only have
weak pointers to IntersectionObservers. Instead, manage the lifetime of an
IntersectionObserver as an ActiveDOMObject, overriding hasPendingActivity to keep
the observer alive while there are ongoing observations.
However, there is a still a potential reference cycle. The callback keeps global
references alive, so if there's a global reference to the observer in JavaScript,
we have an observer->callback->observer cycle, keeping the callback (and hence the Document)
alive. To break this cycle, make IntersectionObserver release the callback when its
Document is stopped.
With these changes, there are no longer any leaks reported with run-webkit-tests --world-leaks
on LayoutTests/intersection-observer and LayoutTests/imported/w3c/web-platform-tests/intersection-observer.
Tests: intersection-observer/no-document-leak.html
intersection-observer/observer-and-callback-without-js-references.html
* dom/Document.cpp:
(WebCore::Document::addIntersectionObserver):
(WebCore::Document::removeIntersectionObserver):
* dom/Document.h:
* dom/Element.cpp:
(WebCore::Element::didMoveToNewDocument):
* page/IntersectionObserver.cpp:
(WebCore::IntersectionObserver::IntersectionObserver):
(WebCore::IntersectionObserver::~IntersectionObserver):
(WebCore::IntersectionObserver::observe):
(WebCore::IntersectionObserver::rootDestroyed):
(WebCore::IntersectionObserver::createTimestamp const):
(WebCore::IntersectionObserver::notify):
(WebCore::IntersectionObserver::hasPendingActivity const):
(WebCore::IntersectionObserver::activeDOMObjectName const):
(WebCore::IntersectionObserver::canSuspendForDocumentSuspension const):
(WebCore::IntersectionObserver::stop):
* page/IntersectionObserver.h:
(WebCore::IntersectionObserver::trackingDocument const):
(WebCore::IntersectionObserver::trackingDocument): Deleted.
* page/IntersectionObserver.idl:
LayoutTests:
* intersection-observer/no-document-leak-expected.txt: Added.
* intersection-observer/no-document-leak.html: Added.
* intersection-observer/observer-and-callback-without-js-references-expected.txt: Added.
* intersection-observer/observer-and-callback-without-js-references.html: Added.
* intersection-observer/resources/no-document-leak-frame.html: Added.
Canonical link: https://commits.webkit.org/204346@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@235736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2018-09-06 13:51:24 +00:00
|
|
|
</script>
|
|
|
|
<script src="../resources/js-test-post.js"></script>
|
|
|
|
</body>
|
|
|
|
</html>
|