New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ResizeObserver] The initial last reported size of ResizeObservation should be -1x-1 which always notify observed elements #9112
[ResizeObserver] The initial last reported size of ResizeObservation should be -1x-1 which always notify observed elements #9112
Conversation
Hi, this patch is to address the failure found by #8839. We need to address the crash issue in
The direct reason for this crash issue is that: when calling
Meanwhile, When
And ResizeObserver would own the So the target and ResizeObserver are connected by I must misunderstand something. Would someone explain me a little bit how does GC work in this scenario? Thanks! |
@@ -141,6 +143,8 @@ void ResizeObserver::deliverObservations() | |||
m_activeObservations.clear(); | |||
auto activeObservationTargets = std::exchange(m_activeObservationTargets, { }); | |||
|
|||
std::exchange(m_targetsWaitingForFirstObservation, { }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not an expert in these things, but my worry is that, unlike IntersectionObserver::notify
, you might not be keeping the old value alive by storing it into a variable.
Could it then be possible for the callbacks to be garbage collected before m_callback->handleEvent(*this, entries, *this);
? I will defer the review to someone who knows better about these things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we should clear this after calling m_callback->handleEvent. Maybe use ScopeExit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks!
LayoutTests/resize-observer/resize-observer-should-not-leak-observed-nodes.html fails, because we need to make sure every resizeobserver should be delivered once, otherwise it would postpone GC of elements. To avoid the fake failure in EWS, I will merge the two patches together. #8839 |
075d7ac
to
5766a52
Compare
EWS run on previous version of this PR (hash 5766a52)
|
5766a52
to
72c9198
Compare
EWS run on previous version of this PR (hash 72c9198)
|
Thanks for the review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are merging this with #8839, then I think you should use the title and bug number from that one.
...utTests/platform/mac-wk1/imported/w3c/web-platform-tests/resize-observer/notify-expected.txt
Show resolved
Hide resolved
@@ -141,6 +144,10 @@ void ResizeObserver::deliverObservations() | |||
m_activeObservations.clear(); | |||
auto activeObservationTargets = std::exchange(m_activeObservationTargets, { }); | |||
|
|||
auto scopeExit = makeScopeExit([&] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if I understand makeScopeExit
. It seems that it will clear m_targetsWaitingForFirstObservation
once scopeExit
is destroyed, which I guess it's at the end of the function? But then m_targetsWaitingForFirstObservation
will be cleared after m_callback->handleEvent
, which seems bad, because the callbacks could be observing new elements that will be appended into m_targetsWaitingForFirstObservation
and shouldn't be cleared yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, yes, that is possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we std::exchange it to a local variable instead? Then the list still keeps object alive during the duration of this function, and it goes away at the end of function.
targetsWaitingForFirstObservation = std::exchange(m_targetsWaitingForFirstObservation);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, like for IntersectionObserver
auto targetsWaitingForFirstObservation = std::exchange(m_targetsWaitingForFirstObservation, { }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
72c9198
to
3a7305d
Compare
EWS run on previous version of this PR (hash 3a7305d)
|
3a7305d
to
5a3d673
Compare
EWS run on previous version of this PR (hash 5a3d673)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to address the failure in the style bot:
ERROR: Source/WebCore/page/ResizeObservation.cpp:44: Code inside a namespace should not be indented. [whitespace/indent] [4]
Hmm, I don't quite understand the style error. Maybe the uniform initialization is treated as the function body? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assert isn't currently failing, so I think the commit title should be about the -1x-1 to always notify observed elements.
...utTests/platform/mac-wk1/imported/w3c/web-platform-tests/resize-observer/notify-expected.txt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with the changes in the commit message
5a3d673
to
1408ba6
Compare
EWS run on current version of this PR (hash 1408ba6)
|
Done, thanks! I just updated the commit message, not the bug URL. The discussion here explains the reason we merge the two patches together, so I prefer to upload it in this PR. |
I think I kinda figured this out \o/
This is not always true. In the example, there are 9 ResizeObservers, and it's the ninth one not released.
This is not true either, ResizeObserver could be released after if change the number of RO. |
β¦should be -1x-1 which always notify observed elements https://bugs.webkit.org/show_bug.cgi?id=251015 Reviewed by Oriol Brufau and Ryosuke Niwa. This patch initializes the lastReportedSize of ResizeObservation to -1 x -1, which is the conclusion of [1], it indicates that -1 x -1 is the initial size when first observing an element with ResizeObserver. The previous change makes every ResizeObservation be delivered at least once, even if the target is a disconnected element. When GC happens between observe and gather ResizeObservations, JSC::Weak<JSC::JSObject> m_callback inside JSCallbackDataWeak could be released, and the element and JSResizeObserver might not be released, for they are not strong connected, this scenario would trigger the ASSERT in ResizeObserver::deliverObservations. To fix it, this patch adds m_targetsWaitingForFirstObservation to extend the life cycle of ResizeObserver to the first time of deliverObservations. The fix is similar to what IntersectionObserver does in bug 231235. The test6 of resize-observer/notify.html still fails in mac-wk1, because updaterendering is not triggered properly. Filed [2] to track it. [1] w3c/csswg-drafts#3664 [2] https://bugs.webkit.org/show_bug.cgi?id=250900 * LayoutTests/imported/w3c/web-platform-tests/resize-observer/notify-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/resize-observer/observe-expected.txt: * LayoutTests/imported/w3c/web-platform-tests/resize-observer/svg-expected.txt: * LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/resize-observer/notify-expected.txt: Copied from LayoutTests/imported/w3c/web-platform-tests/resize-observer/notify-expected.txt. * LayoutTests/platform/mac/imported/w3c/web-platform-tests/resize-observer/svg-expected.txt: * Source/WebCore/page/ResizeObservation.cpp: * Source/WebCore/page/ResizeObserver.cpp: (WebCore::ResizeObserver::observe): (WebCore::ResizeObserver::deliverObservations): (WebCore::ResizeObserver::isReachableFromOpaqueRoots const): (WebCore::ResizeObserver::removeAllTargets): (WebCore::ResizeObserver::removeObservation): * Source/WebCore/page/ResizeObserver.h: Canonical link: https://commits.webkit.org/259673@main
1408ba6
to
2861d8c
Compare
Committed 259673@main (2861d8c): https://commits.webkit.org/259673@main Reviewed commits have been landed. Closing PR #9112 and removing active labels. |
2861d8c
1408ba6
π wincairo