WebKit Bugzilla
Attachment 369837 Details for
Bug 197457
: The JS wrapper of target in an ResizeObserverEntry should not get collected
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
To test wincairo build error
ro-gc-008.diff (text/plain), 23.38 KB, created by
cathiechen
on 2019-05-14 05:37:38 PDT
(
hide
)
Description:
To test wincairo build error
Filename:
MIME Type:
Creator:
cathiechen
Created:
2019-05-14 05:37:38 PDT
Size:
23.38 KB
patch
obsolete
>diff --git a/LayoutTests/resize-observer/element-leak-expected.txt b/LayoutTests/resize-observer/element-leak-expected.txt >new file mode 100644 >index 00000000000..84ad90becdf >--- /dev/null >+++ b/LayoutTests/resize-observer/element-leak-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS ResizeObserver implemented >+PASS test0: Test elements leak >+ >diff --git a/LayoutTests/resize-observer/element-leak.html b/LayoutTests/resize-observer/element-leak.html >new file mode 100644 >index 00000000000..1a1dcd7fc01 >--- /dev/null >+++ b/LayoutTests/resize-observer/element-leak.html >@@ -0,0 +1,75 @@ >+<!DOCTYPE html><!-- webkit-test-runner [ experimental:ResizeObserverEnabled=true ] --> >+<html> >+<meta name="timeout" content="long"> >+<head> >+<script src="../resources/testharness.js"></script> >+<script src="../resources/testharnessreport.js"></script> >+<script src="../resources/gc.js"></script> >+</head> >+<body> >+<div id="mylog"></div> >+<iframe id="testFrame" src="resources/element-leak-frame.html"></iframe> >+<script> >+if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+var testresult; >+function log(text) { >+ document.getElementById('mylog').textContent += text + `${internals.numberOfLiveNodes()}` + ` | `; >+} >+ >+function documentShouldDie(documentIdentifier) >+{ >+ return new Promise(function(resolve, reject) { >+ handle = setInterval(function() { >+ log('gc begin: '); >+ gc(); >+ log('gc end: '); >+ if (internals && !internals.isDocumentAlive(documentIdentifier)) { >+ clearInterval(handle); >+ resolve(); >+ testresult = true; >+ log('resolved: '); >+ } >+ }, 10); >+ }); >+} >+ >+function test0() { >+ let test = async_test('test0: Test elements leak'); >+ window.addEventListener('message', event => { >+ switch(event.data) { >+ case 'Notified': >+ log('notified with livenodes: '); >+ test.step( () => { >+ var testFrame = document.getElementById("testFrame"); >+ let frameDocumentIdentifier = internals.documentIdentifier(testFrame.contentDocument); >+ testFrame.remove(); >+ log('frame removed: '); >+ documentShouldDie(frameDocumentIdentifier).then(function() { >+ assert_true(testresult, 'element leaking'); >+ test.done(); >+ }); >+ >+ }); >+ break; >+ } >+ }, false); >+ >+ test.step_timeout(() => { >+ testresult = false; >+ assert_true(testresult, 'element leaking'); >+ log('timeout: '); >+ test.done(); >+ }, 5000); >+} >+ >+test(_ => { >+ assert_own_property(window, "ResizeObserver"); >+}, "ResizeObserver implemented"); >+ >+test0(); >+ >+</script> >+</body> >+</html> >diff --git a/LayoutTests/resize-observer/resize-observer-entry-keeps-js-wrapper-of-target-alive-expected.txt b/LayoutTests/resize-observer/resize-observer-entry-keeps-js-wrapper-of-target-alive-expected.txt >new file mode 100644 >index 00000000000..a5be9926a5a >--- /dev/null >+++ b/LayoutTests/resize-observer/resize-observer-entry-keeps-js-wrapper-of-target-alive-expected.txt >@@ -0,0 +1,22 @@ >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+CONSOLE MESSAGE: ResizeObserver loop completed with undelivered notifications. >+This tests that JS wrappers of targets in an ResizeObserverEntry do not get collected. >+ >+PASS >+PASS >+PASS >+PASS >+PASS >+PASS >+PASS >+PASS >+PASS >+PASS >+ >diff --git a/LayoutTests/resize-observer/resize-observer-entry-keeps-js-wrapper-of-target-alive.html b/LayoutTests/resize-observer/resize-observer-entry-keeps-js-wrapper-of-target-alive.html >new file mode 100644 >index 00000000000..0c2fb46c635 >--- /dev/null >+++ b/LayoutTests/resize-observer/resize-observer-entry-keeps-js-wrapper-of-target-alive.html >@@ -0,0 +1,60 @@ >+<!DOCTYPE html><!-- webkit-test-runner [ experimental:ResizeObserverEnabled=true ] --> >+<html> >+<body> >+<p>This tests that JS wrappers of targets in an ResizeObserverEntry do not get collected.</p> >+<pre id="log"></pre> >+<script src="../resources/gc.js"></script> >+<script> >+ >+if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+const targetCount = 5; >+const iterationCount = 10; >+ >+async function observe() { >+ for (let i = 0; i < targetCount; ++i) { >+ let target = document.createElement('div'); >+ target.myState = 'live'; >+ document.body.appendChild(target); >+ } >+ >+ return new Promise((resolve) => { >+ const observer = new ResizeObserver(entries => { >+ resolve(entries); >+ observer.disconnect(); >+ }); >+ document.querySelectorAll('div').forEach(target => { observer.observe(target); }); >+ }); >+} >+ >+function check(entries) { >+ let deadCount = 0; >+ for (const entry of entries) { >+ if (entry.target.myState != 'live') >+ deadCount++; >+ } >+ document.getElementById('log').textContent += (deadCount ? `FAIL - ${deadCount} targets lost JS wrappers` : 'PASS') + '\n'; >+} >+ >+async function runAll() { >+ if (window.testRunner) >+ testRunner.waitUntilDone(); >+ >+ for (let j = 0; j < iterationCount; ++j) { >+ const entries = await observe(); >+ document.querySelectorAll('div').forEach(target => { target.remove(); }); >+ await Promise.resolve(); >+ gc(); >+ check(entries); >+ } >+ >+ if (window.testRunner) >+ testRunner.notifyDone(); >+} >+ >+runAll(); >+ >+</script> >+</body> >+</html> >diff --git a/LayoutTests/resize-observer/resize-observer-keeps-js-wrapper-of-target-alive-expected.txt b/LayoutTests/resize-observer/resize-observer-keeps-js-wrapper-of-target-alive-expected.txt >new file mode 100644 >index 00000000000..1fe5345c387 >--- /dev/null >+++ b/LayoutTests/resize-observer/resize-observer-keeps-js-wrapper-of-target-alive-expected.txt >@@ -0,0 +1,4 @@ >+This tests that JS wrappers of targets removed from document to be delivered to an resize observer do not get collected. >+ >+PASS >+ >diff --git a/LayoutTests/resize-observer/resize-observer-keeps-js-wrapper-of-target-alive.html b/LayoutTests/resize-observer/resize-observer-keeps-js-wrapper-of-target-alive.html >new file mode 100644 >index 00000000000..3dff784c9e8 >--- /dev/null >+++ b/LayoutTests/resize-observer/resize-observer-keeps-js-wrapper-of-target-alive.html >@@ -0,0 +1,55 @@ >+<!DOCTYPE html><!-- webkit-test-runner [ experimental:ResizeObserverEnabled=true ] --> >+<html> >+<body> >+<p>This tests that JS wrappers of targets removed from document to be delivered to an resize observer do not get collected.</p> >+<pre id="log"></pre> >+<script src="../resources/gc.js"></script> >+<script> >+ >+if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+const targetCount = 5; >+const iterationCount = 10; >+var deadCount = 0; >+ >+async function runAll() { >+ if (window.testRunner) >+ testRunner.waitUntilDone(); >+ >+ for (let i = 0; i < iterationCount; ++i) { >+ runTest(); >+ gc(); >+ await new Promise((resolve) => requestAnimationFrame(resolve)) >+ } >+ >+ document.getElementById('log').textContent = (deadCount ? `FAIL - ${deadCount} targets lost JS wrappers` : 'PASS') + '\n'; >+ >+ if (window.testRunner) >+ testRunner.notifyDone(); >+} >+ >+function runTest() { >+ document.querySelectorAll('div').forEach(target => { target.remove(); }); >+ >+ for (let i = 0; i < targetCount; ++i) { >+ let target = document.createElement('div'); >+ target.myState = 'live'; >+ document.body.appendChild(target); >+ } >+ >+ document.querySelectorAll('div').forEach(target => { observer.observe(target); }); >+} >+ >+const observer = new ResizeObserver(entries => { >+ for (const entry of entries) { >+ if (entry.target.myState != 'live') >+ deadCount++; >+ } >+}); >+ >+runAll(); >+ >+</script> >+</body> >+</html> >diff --git a/LayoutTests/resize-observer/resources/element-leak-frame.html b/LayoutTests/resize-observer/resources/element-leak-frame.html >new file mode 100644 >index 00000000000..123b12d58bf >--- /dev/null >+++ b/LayoutTests/resize-observer/resources/element-leak-frame.html >@@ -0,0 +1,31 @@ >+<body></body> >+<script src="../../resources/gc.js"></script> >+ >+<script type="text/javascript"> >+ >+const targetCount = 1000; >+ >+var ro = new ResizeObserver( entries => { >+ for (let entry of entries) { >+ entry.target.myEntry = entry; >+ } >+ ro.disconnect(); >+ >+ document.querySelectorAll('div').forEach(target => { >+ target.remove(); >+ }); >+ gc(); >+ parent.postMessage('Notified', '*') >+}); >+ >+ >+for (let i = 0; i < targetCount; ++i) { >+ var target = document.createElement('div'); >+ document.body.appendChild(target); >+} >+ >+document.querySelectorAll('div').forEach(target => { >+ ro.observe(target); >+}); >+ >+</script> >\ No newline at end of file >diff --git a/Source/JavaScriptCore/heap/Heap.cpp b/Source/JavaScriptCore/heap/Heap.cpp >index 8d92313977d..87739e6711f 100644 >--- a/Source/JavaScriptCore/heap/Heap.cpp >+++ b/Source/JavaScriptCore/heap/Heap.cpp >@@ -1263,6 +1263,7 @@ NEVER_INLINE bool Heap::runBeginPhase(GCConductor conn) > > if (m_collectionScope && m_collectionScope.value() == CollectionScope::Full) { > m_opaqueRoots.clear(); >+ printf("Heap::runBeginPhase this=%p m_opaqueRoots.clear\n", this); > m_collectorSlotVisitor->clearMarkStacks(); > m_mutatorMarkStack->clear(); > } >@@ -1363,6 +1364,7 @@ NEVER_INLINE bool Heap::runFixpointPhase(GCConductor conn) > > if (slotVisitor.didReachTermination()) { > m_opaqueRoots.deleteOldTables(); >+ printf("Heap::runFixpointPhase %p m_opaqueRoots.deleteOldTables \n", this); > > m_scheduler->didReachTermination(); > >diff --git a/Source/JavaScriptCore/heap/SlotVisitorInlines.h b/Source/JavaScriptCore/heap/SlotVisitorInlines.h >index 2a390b675b1..e729edd4c9c 100644 >--- a/Source/JavaScriptCore/heap/SlotVisitorInlines.h >+++ b/Source/JavaScriptCore/heap/SlotVisitorInlines.h >@@ -142,6 +142,7 @@ inline bool SlotVisitor::addOpaqueRoot(void* ptr) > return false; > if (!heap()->m_opaqueRoots.add(ptr)) > return false; >+ printf("JSlotVisitor::addOpaqueRoot:%p heap()=%p\n", ptr, heap()); > m_visitCount++; > return true; > } >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index e09eb2eeb03..d727e4c9eb7 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -529,6 +529,7 @@ bindings/js/JSPromiseRejectionEventCustom.cpp > bindings/js/JSReadableStreamSourceCustom.cpp > bindings/js/JSRemoteDOMWindowBase.cpp > bindings/js/JSRemoteDOMWindowCustom.cpp >+bindings/js/JSResizeObserverEntryCustom.cpp > bindings/js/JSSVGPathSegCustom.cpp > bindings/js/JSSVGViewSpecCustom.cpp > bindings/js/JSStyleSheetCustom.cpp >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index 37d615ce10a..ad9920cfb56 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -8756,6 +8756,7 @@ > 585D6DFB1A15355600FA4F12 /* SimpleLineLayoutResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutResolver.cpp; sourceTree = "<group>"; }; > 585D6E011A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SimpleLineLayoutFlowContents.cpp; sourceTree = "<group>"; }; > 585D6E021A1A792E00FA4F12 /* SimpleLineLayoutFlowContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SimpleLineLayoutFlowContents.h; sourceTree = "<group>"; }; >+ 5884FE5622813E2D0040AFF6 /* JSResizeObserverEntryCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSResizeObserverEntryCustom.cpp; sourceTree = "<group>"; }; > 589556EC18D4A44000764B03 /* BorderEdge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BorderEdge.h; sourceTree = "<group>"; }; > 58AEE2F318D4BCCF0022E7FE /* BorderEdge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BorderEdge.cpp; sourceTree = "<group>"; }; > 58B2F9EA2232D43B00938D63 /* ResizeObserverEntry.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ResizeObserverEntry.idl; sourceTree = "<group>"; }; >@@ -20623,6 +20624,7 @@ > CB38FD551CD21D5B00592A3F /* JSPerformanceEntryCustom.cpp */, > 833CF70F20DB3F5F00141BCC /* JSPerformanceObserverCustom.cpp */, > A4A69B8BB91B49D0A804C31D /* JSPromiseRejectionEventCustom.cpp */, >+ 5884FE5622813E2D0040AFF6 /* JSResizeObserverEntryCustom.cpp */, > 83F572941FA1066F003837BE /* JSServiceWorkerClientCustom.cpp */, > 460D19441FCE21DD00C3DB85 /* JSServiceWorkerGlobalScopeCustom.cpp */, > BC98A27C0C0C9950004BEBF7 /* JSStyleSheetCustom.cpp */, >diff --git a/Source/WebCore/bindings/js/JSResizeObserverEntryCustom.cpp b/Source/WebCore/bindings/js/JSResizeObserverEntryCustom.cpp >new file mode 100644 >index 00000000000..81bafa0e915 >--- /dev/null >+++ b/Source/WebCore/bindings/js/JSResizeObserverEntryCustom.cpp >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2019 Igalia S.L. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "JSResizeObserverEntry.h" >+ >+#include "JSNodeCustom.h" >+ >+namespace WebCore { >+ >+void JSResizeObserverEntry::visitAdditionalChildren(JSC::SlotVisitor& visitor) >+{ >+ printf("JSResizeObserverEntry::visitAdditionalChildren begin %p\n", wrapped().target()); >+ visitor.addOpaqueRoot(root(wrapped().target())); >+ visitor.addOpaqueRoot(wrapped().contentRect()); >+ printf("JSResizeObserverEntry::visitAdditionalChildren end\n"); >+} >+ >+} >diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp >index 9136d9cf78c..088b6ec59d7 100644 >--- a/Source/WebCore/dom/Document.cpp >+++ b/Source/WebCore/dom/Document.cpp >@@ -561,6 +561,7 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig > nodeListAndCollectionCount = 0; > > InspectorInstrumentation::addEventListenersToNode(*this); >+ printf("Document %p m_identifier=%llu url=%s\n", this, m_identifier.toUInt64(), url.string().ascii().data()); > } > > Ref<Document> Document::create(Document& contextDocument) >@@ -578,6 +579,7 @@ Document::~Document() > > ASSERT(allDocumentsMap().contains(m_identifier)); > allDocumentsMap().remove(m_identifier); >+ printf("~Document:%p allDocumentsMap().remove m_identifier=%llu\n", this, m_identifier.toUInt64()); > // We need to remove from the contexts map very early in the destructor so that calling postTask() on this Document from another thread is safe. > removeFromContextsMap(); > >@@ -648,6 +650,7 @@ Document::~Document() > > for (unsigned count : m_nodeListAndCollectionCounts) > ASSERT_UNUSED(count, !count); >+ printf("~Document %p m_identifier=%llu end\n", this, m_identifier.toUInt64()); > } > > void Document::removedLastRef() >@@ -4428,6 +4431,10 @@ void Document::nodeChildrenWillBeRemoved(ContainerNode& container) > frame->eventHandler().nodeWillBeRemoved(*n); > frame->selection().nodeWillBeRemoved(*n); > frame->page()->dragCaretController().nodeWillBeRemoved(*n); >+#if ENABLE(RESIZE_OBSERVER) >+ if (is<Element>(*n)) >+ downcast<Element>(*n).addResizeObserverPendingTargetIfNeeded(); >+#endif > } > } > >@@ -4458,6 +4465,10 @@ void Document::nodeWillBeRemoved(Node& node) > frame->eventHandler().nodeWillBeRemoved(node); > frame->selection().nodeWillBeRemoved(node); > frame->page()->dragCaretController().nodeWillBeRemoved(node); >+#if ENABLE(RESIZE_OBSERVER) >+ if (is<Element>(node)) >+ downcast<Element>(node).addResizeObserverPendingTargetIfNeeded(); >+#endif > } > > if (is<Text>(node)) >diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp >index c4913bebf58..a9226276b6e 100644 >--- a/Source/WebCore/dom/Element.cpp >+++ b/Source/WebCore/dom/Element.cpp >@@ -3558,6 +3558,19 @@ ResizeObserverData* Element::resizeObserverData() > { > return hasRareData() ? elementRareData()->resizeObserverData() : nullptr; > } >+ >+void Element::addResizeObserverPendingTargetIfNeeded() >+{ >+ if (!isConnected()) >+ return; >+ >+ auto* observerData = resizeObserverData(); >+ if (!observerData) >+ return; >+ >+ for (auto& observer : observerData->observers) >+ observer->addPendingTarget(*this); >+} > #endif > > SpellcheckAttributeState Element::spellcheckAttributeState() const >diff --git a/Source/WebCore/dom/Element.h b/Source/WebCore/dom/Element.h >index 5f3f876268c..68a61da382a 100644 >--- a/Source/WebCore/dom/Element.h >+++ b/Source/WebCore/dom/Element.h >@@ -594,6 +594,7 @@ public: > #if ENABLE(RESIZE_OBSERVER) > ResizeObserverData& ensureResizeObserverData(); > ResizeObserverData* resizeObserverData(); >+ void addResizeObserverPendingTargetIfNeeded(); > #endif > > Element* findAnchorElementForLink(String& outAnchorName); >diff --git a/Source/WebCore/dom/TreeScope.cpp b/Source/WebCore/dom/TreeScope.cpp >index 7ba3578a4f7..685d991c0d9 100644 >--- a/Source/WebCore/dom/TreeScope.cpp >+++ b/Source/WebCore/dom/TreeScope.cpp >@@ -75,6 +75,7 @@ TreeScope::TreeScope(Document& document) > , m_parentTreeScope(nullptr) > , m_idTargetObserverRegistry(std::make_unique<IdTargetObserverRegistry>()) > { >+ printf("TreeScope:%p document%p\n", this, &document); > document.setTreeScope(*this); > } > >diff --git a/Source/WebCore/page/DOMWindow.cpp b/Source/WebCore/page/DOMWindow.cpp >index 7197b118313..af2082dc8c8 100644 >--- a/Source/WebCore/page/DOMWindow.cpp >+++ b/Source/WebCore/page/DOMWindow.cpp >@@ -408,6 +408,7 @@ DOMWindow::DOMWindow(Document& document) > : AbstractDOMWindow(GlobalWindowIdentifier { Process::identifier(), WindowIdentifier::generate() }) > , ContextDestructionObserver(&document) > { >+ printf("DOMWindow:%p doc=%p\n", this, &document); > ASSERT(frame()); > addLanguageChangeObserver(this, &languagesChangedCallback); > } >@@ -425,6 +426,8 @@ void DOMWindow::didSecureTransitionTo(Document& document) > > DOMWindow::~DOMWindow() > { >+ printf("~DOMWindow:%p doc=%p\n", this, document()); >+ > if (m_suspendedForDocumentSuspension) > willDestroyCachedFrame(); > else >diff --git a/Source/WebCore/page/ResizeObserver.cpp b/Source/WebCore/page/ResizeObserver.cpp >index 9ff2b6ebc45..25257316c59 100644 >--- a/Source/WebCore/page/ResizeObserver.cpp >+++ b/Source/WebCore/page/ResizeObserver.cpp >@@ -121,6 +121,7 @@ void ResizeObserver::deliverObservations() > entries.append(ResizeObserverEntry::create(observation->target(), observation->computeContentRect())); > } > m_activeObservations.clear(); >+ m_pendingTargets.clear(); > m_callback->handleEvent(entries, *this); > } > >@@ -145,6 +146,10 @@ void ResizeObserver::removeAllTargets() > > bool ResizeObserver::removeObservation(const Element& target) > { >+ m_pendingTargets.removeFirstMatching([&target](auto& pendingTarget) { >+ return pendingTarget.ptr() == ⌖ >+ }); >+ > m_activeObservations.removeFirstMatching([&target](auto& observation) { > return observation->target() == ⌖ > }); >@@ -154,6 +159,12 @@ bool ResizeObserver::removeObservation(const Element& target) > }); > } > >+void ResizeObserver::addPendingTarget(Element& target) >+{ >+ m_pendingTargets.append(target); >+} >+ >+ > bool ResizeObserver::hasPendingActivity() const > { > return (hasObservations() && m_document) || !m_activeObservations.isEmpty(); >@@ -173,7 +184,7 @@ void ResizeObserver::stop() > { > disconnect(); > m_callback = nullptr; >- m_observations.clear(); >+ m_pendingTargets.clear(); > m_activeObservations.clear(); > } > >diff --git a/Source/WebCore/page/ResizeObserver.h b/Source/WebCore/page/ResizeObserver.h >index a1819609f6e..d60648631d4 100644 >--- a/Source/WebCore/page/ResizeObserver.h >+++ b/Source/WebCore/page/ResizeObserver.h >@@ -28,6 +28,7 @@ > #if ENABLE(RESIZE_OBSERVER) > > #include "ActiveDOMObject.h" >+#include "GCReachableRef.h" > #include "ResizeObservation.h" > #include "ResizeObserverCallback.h" > #include <wtf/RefCounted.h> >@@ -62,6 +63,8 @@ public: > bool hasSkippedObservations() const { return m_hasSkippedObservations; } > void setHasSkippedObservations(bool skipped) { m_hasSkippedObservations = skipped; } > >+ void addPendingTarget(Element&); >+ > // ActiveDOMObject. > bool hasPendingActivity() const override; > const char* activeDOMObjectName() const override; >@@ -80,6 +83,7 @@ private: > Vector<Ref<ResizeObservation>> m_observations; > > Vector<Ref<ResizeObservation>> m_activeObservations; >+ Vector<GCReachableRef<Element>> m_pendingTargets; > bool m_hasSkippedObservations { false }; > }; > >diff --git a/Source/WebCore/page/ResizeObserverEntry.idl b/Source/WebCore/page/ResizeObserverEntry.idl >index b051bb57bec..72f85dcfce6 100644 >--- a/Source/WebCore/page/ResizeObserverEntry.idl >+++ b/Source/WebCore/page/ResizeObserverEntry.idl >@@ -28,7 +28,8 @@ > [ > Conditional=RESIZE_OBSERVER, > ImplementationLacksVTable, >- EnabledBySetting=ResizeObserver >+ EnabledBySetting=ResizeObserver, >+ JSCustomMarkFunction > ] interface ResizeObserverEntry { > readonly attribute Element target; > readonly attribute DOMRectReadOnly contentRect; >diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp >index d4cd40b7eb8..9f76a3d953d 100644 >--- a/Source/WebCore/testing/Internals.cpp >+++ b/Source/WebCore/testing/Internals.cpp >@@ -2423,6 +2423,8 @@ uint64_t Internals::documentIdentifier(const Document& document) const > > bool Internals::isDocumentAlive(uint64_t documentIdentifier) const > { >+ printf("Internals::isDocumentAlive documentIdentifier=%lu\n", documentIdentifier); >+ fflush(stdout); > return Document::allDocumentsMap().contains(makeObjectIdentifier<DocumentIdentifierType>(documentIdentifier)); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197457
:
368670
|
369394
|
369426
|
369680
|
369681
|
369683
|
369738
|
369746
|
369752
|
369755
|
369756
|
369764
|
369833
|
369837
|
369840
|
369844
|
369845
|
369846
|
369847
|
369848
|
369854
|
369861
|
369862
|
369866
|
369870
|
369876
|
369877
|
369921
|
369922
|
369923
|
369925
|
369926
|
369927
|
369935
|
369942
|
370111
|
370681
|
371183
|
371186
|
371241