Bug 240204 - Add helper functions to queue task on Node with GCReachableRef
Summary: Add helper functions to queue task on Node with GCReachableRef
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Ryosuke Niwa
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2022-05-07 01:32 PDT by Ryosuke Niwa
Modified: 2022-09-24 08:56 PDT (History)
12 users (show)

See Also:


Attachments
Patch (9.82 KB, patch)
2022-05-07 01:36 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
Patch (9.89 KB, patch)
2022-05-07 01:38 PDT, Ryosuke Niwa
no flags Details | Formatted Diff | Diff
Patch for landing (10.60 KB, patch)
2022-05-07 21:40 PDT, Ryosuke Niwa
ews-feeder: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ryosuke Niwa 2022-05-07 01:32:55 PDT
Add helper functions to queue an event look task for Node using GCReachableRef.
Comment 1 Ryosuke Niwa 2022-05-07 01:36:18 PDT
Created attachment 458995 [details]
Patch
Comment 2 Ryosuke Niwa 2022-05-07 01:38:01 PDT
Created attachment 458996 [details]
Patch
Comment 3 Chris Dumez 2022-05-07 10:46:45 PDT
Comment on attachment 458996 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=458996&action=review

I like the idea but have one concern.

> Source/WebCore/dom/Node.cpp:1316
> +    document().eventLoop().queueTask(source, [protectedThis = GCReachableRef(*this), task = WTFMove(task)] () {

Shouldn't this capture `protectedThis = Ref { *this }` too (like ActiveDOMObject::queueTaskKeepingObjectAlive() does)? The function name says it is keeping the Node alive. Currently, what it does is keeping the JS wrapper alive (which it should definitely do).

It is true that if the JS wrapper is alive then the impl object would be alive too. However, we've run into trouble making such assumptions in the past because there may not be a wrapper alive when calling queueTaskKeepingThisNodeAlive() and thus constructing the GCReachableRef.

Right now, I think the function name is a little bit of a lie. It keeps this node's wrapper alive, not necessarily this node.

> Source/WebCore/dom/Node.cpp:1323
> +    queueTaskKeepingThisNodeAlive(source, [protectedThis = Ref { *this }, event = WTFMove(event)]() {

Assuming queueTaskKeepingThisNodeAlive() is updated to capture protectedThis, I suggest we only capture |this| here.

> Source/WebCore/html/HTMLDetailsElement.cpp:150
> +            queueTaskKeepingThisNodeAlive(TaskSource::DOMManipulation, [protectedThis = Ref { *this }] {

Seems like we shouldn't need to capture protectedThis when calling a function named queueTaskKeepingThisNodeAlive(), if the function is really keeping the Node alive, capturing |this| should suffice.

> Source/WebCore/html/HTMLDialogElement.cpp:116
> +    queueTaskKeepingThisNodeAlive(TaskSource::UserInteraction, [protectedThis = Ref { *this }] {

ditto.
Comment 4 Ryosuke Niwa 2022-05-07 10:55:33 PDT
(In reply to Chris Dumez from comment #3)
> Comment on attachment 458996 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=458996&action=review
> 
> I like the idea but have one concern.
> 
> > Source/WebCore/dom/Node.cpp:1316
> > +    document().eventLoop().queueTask(source, [protectedThis = GCReachableRef(*this), task = WTFMove(task)] () {
> 
> Shouldn't this capture `protectedThis = Ref { *this }` too (like
> ActiveDOMObject::queueTaskKeepingObjectAlive() does)? The function name says
> it is keeping the Node alive. Currently, what it does is keeping the JS
> wrapper alive (which it should definitely do).
> 
> It is true that if the JS wrapper is alive then the impl object would be
> alive too. However, we've run into trouble making such assumptions in the
> past because there may not be a wrapper alive when calling
> queueTaskKeepingThisNodeAlive() and thus constructing the GCReachableRef.
> 
> Right now, I think the function name is a little bit of a lie. It keeps this
> node's wrapper alive, not necessarily this node.

Oh, GCReachableRef<Node> contains RefPtr<Node> so it does BOTH.

> > Source/WebCore/dom/Node.cpp:1323
> > +    queueTaskKeepingThisNodeAlive(source, [protectedThis = Ref { *this }, event = WTFMove(event)]() {
> 
> Assuming queueTaskKeepingThisNodeAlive() is updated to capture
> protectedThis, I suggest we only capture |this| here.

Yeah, I debated between the two. If we have a compiler validation of captured variables, also explicitly ref'ing here makes sense. As is, I'm triggering a redundant ref call.
Comment 5 Chris Dumez 2022-05-07 13:06:03 PDT
Comment on attachment 458996 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=458996&action=review

I'd prefer if we avoided the unnecessary Ref<> captures personally.

>>> Source/WebCore/dom/Node.cpp:1316
>>> +    document().eventLoop().queueTask(source, [protectedThis = GCReachableRef(*this), task = WTFMove(task)] () {
>> 
>> Shouldn't this capture `protectedThis = Ref { *this }` too (like ActiveDOMObject::queueTaskKeepingObjectAlive() does)? The function name says it is keeping the Node alive. Currently, what it does is keeping the JS wrapper alive (which it should definitely do).
>> 
>> It is true that if the JS wrapper is alive then the impl object would be alive too. However, we've run into trouble making such assumptions in the past because there may not be a wrapper alive when calling queueTaskKeepingThisNodeAlive() and thus constructing the GCReachableRef.
>> 
>> Right now, I think the function name is a little bit of a lie. It keeps this node's wrapper alive, not necessarily this node.
> 
> Oh, GCReachableRef<Node> contains RefPtr<Node> so it does BOTH.

Oh, you're totally right, I missed that when I looked at the class earlier.
Comment 6 Ryosuke Niwa 2022-05-07 21:34:39 PDT
(In reply to Chris Dumez from comment #5)
> Comment on attachment 458996 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=458996&action=review
> 
> I'd prefer if we avoided the unnecessary Ref<> captures personally.

Okay, let's just capture "this" for now.
Comment 7 Ryosuke Niwa 2022-05-07 21:40:32 PDT
Created attachment 459006 [details]
Patch for landing
Comment 8 EWS 2022-05-07 22:51:10 PDT
Committed r293955 (250401@main): <https://commits.webkit.org/250401@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 459006 [details].
Comment 9 Radar WebKit Bug Importer 2022-05-07 22:52:13 PDT
<rdar://problem/92918315>