WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
221243
Avoid creating JS wrapper on a removed node when the subtree is not observable
https://bugs.webkit.org/show_bug.cgi?id=221243
Summary
Avoid creating JS wrapper on a removed node when the subtree is not observable
Ryosuke Niwa
Reported
2021-02-01 20:28:32 PST
We should avoid force creating JS wrappers for the root node of a removed subtree when the subtree is not otherwise observable.
Attachments
WIP
(13.05 KB, patch)
2021-02-01 20:29 PST
,
Ryosuke Niwa
no flags
Details
Formatted Diff
Diff
Patch
(18.05 KB, patch)
2021-02-02 22:18 PST
,
Ryosuke Niwa
no flags
Details
Formatted Diff
Diff
Patch
(17.38 KB, patch)
2021-02-03 21:11 PST
,
Ryosuke Niwa
no flags
Details
Formatted Diff
Diff
Patch
(17.37 KB, patch)
2021-02-03 21:35 PST
,
Ryosuke Niwa
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Ryosuke Niwa
Comment 1
2021-02-01 20:29:48 PST
Created
attachment 418955
[details]
WIP
Ryosuke Niwa
Comment 2
2021-02-01 20:30:19 PST
<
rdar://problem/73719386
>
Ryosuke Niwa
Comment 3
2021-02-02 22:18:46 PST
Created
attachment 419109
[details]
Patch
Geoffrey Garen
Comment 4
2021-02-03 15:25:09 PST
Comment on
attachment 419109
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=419109&action=review
> Source/WebCore/ChangeLog:18 > + it has a significant runtime and memory cost - the latter is because we never collect the JS wrappers of > + DOM nodes once they're created.
Surely it's not *never*?
> Source/WebCore/ChangeLog:21 > + won't be observable by scripts in the future. The current heuristics is to check if the removed node
heuristic
> Source/WebCore/ChangeLog:24 > + into existence, which increments the reference counnt. The two notable exceptions are StaticRange and
count I think the explanation for why this approach is sufficient need not be tied to any statement about JS wrappers. The explanation is simply that "if there is no reference count, then there is no external reference" -- because those are the rules of reference counting.
> Source/WebCore/ChangeLog:39 > + condition is refCount() > 2 because this function collects the list of child nodes to be removed in > + Vector<Ref<Node>> and the removeBetween loop itself stores it again in a RefPtr, the latter of which is
The refCount() > 2 comment probably belongs inside the function. That's a little subtle.
> Source/WebCore/dom/ContainerNode.cpp:116 > + bool hasChildListChanged = false; > while (RefPtr<Node> child = m_firstChild) { > + if (i >= children.size() || children[i++].ptr() != child) > + hasChildListChanged = true;
I don't understand why we care if children have changed. If a child has been removed, that is not an external reference to this subtree. If a child has been added, that is not an external reference to this subtree unless the child has an external reference, which the refcount check will cover. If a child has been moved, that is just a removal followed by an addition, so it is covered by the logic above.
Geoffrey Garen
Comment 5
2021-02-03 15:26:24 PST
(If we do have some reason to care about children changing, then we need to think a little bit about the ABA case where children change, and then change back. Our hasChildListChanged would not be able to detect that case.)
Geoffrey Garen
Comment 6
2021-02-03 20:29:16 PST
Comment on
attachment 419109
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=419109&action=review
>> Source/WebCore/dom/ContainerNode.cpp:116 >> + hasChildListChanged = true; > > I don't understand why we care if children have changed. > > If a child has been removed, that is not an external reference to this subtree. > > If a child has been added, that is not an external reference to this subtree unless the child has an external reference, which the refcount check will cover. > > If a child has been moved, that is just a removal followed by an addition, so it is covered by the logic above.
I guess the issue here is that, if an event fired above, and then added a node to the subtree, we don't know what refCount check to do. Nodes in the children set should be checked for > 2, and other nodes should be checked for > 1, and we don't have an obvious way to tell the difference.
Geoffrey Garen
Comment 7
2021-02-03 20:34:44 PST
Comment on
attachment 419109
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=419109&action=review
r=me
>>> Source/WebCore/dom/ContainerNode.cpp:116 >>> + hasChildListChanged = true; >> >> I don't understand why we care if children have changed. >> >> If a child has been removed, that is not an external reference to this subtree. >> >> If a child has been added, that is not an external reference to this subtree unless the child has an external reference, which the refcount check will cover. >> >> If a child has been moved, that is just a removal followed by an addition, so it is covered by the logic above. > > I guess the issue here is that, if an event fired above, and then added a node to the subtree, we don't know what refCount check to do. Nodes in the children set should be checked for > 2, and other nodes should be checked for > 1, and we don't have an obvious way to tell the difference.
^ I guess this is worth a comment next to hasChildListChanged; but I can't think of an obviously better alternative.
Ryosuke Niwa
Comment 8
2021-02-03 21:11:38 PST
(In reply to Geoffrey Garen from
comment #7
)
> Comment on
attachment 419109
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=419109&action=review
> > r=me > > >>> Source/WebCore/dom/ContainerNode.cpp:116 > >>> + hasChildListChanged = true; > >> > >> I don't understand why we care if children have changed. > >> > >> If a child has been removed, that is not an external reference to this subtree. > >> > >> If a child has been added, that is not an external reference to this subtree unless the child has an external reference, which the refcount check will cover. > >> > >> If a child has been moved, that is just a removal followed by an addition, so it is covered by the logic above. > > > > I guess the issue here is that, if an event fired above, and then added a node to the subtree, we don't know what refCount check to do. Nodes in the children set should be checked for > 2, and other nodes should be checked for > 1, and we don't have an obvious way to tell the difference. > > ^ I guess this is worth a comment next to hasChildListChanged; but I can't > think of an obviously better alternative.
Turns out that we don't actually need this check after all.
Ryosuke Niwa
Comment 9
2021-02-03 21:11:45 PST
Created
attachment 419226
[details]
Patch
Ryosuke Niwa
Comment 10
2021-02-03 21:35:15 PST
Created
attachment 419228
[details]
Patch
Geoffrey Garen
Comment 11
2021-02-04 10:30:29 PST
Comment on
attachment 419228
[details]
Patch So much better! :P
Ryosuke Niwa
Comment 12
2021-02-04 14:52:41 PST
(In reply to Geoffrey Garen from
comment #11
)
> Comment on
attachment 419228
[details]
> Patch > > So much better! :P
Indeed!
EWS
Comment 13
2021-02-04 15:14:10 PST
commit-queue failed to commit
attachment 419228
[details]
to WebKit repository. To retry, please set cq+ flag again.
Ryosuke Niwa
Comment 14
2021-02-04 16:10:32 PST
Comment on
attachment 419228
[details]
Patch Clearing flags on attachment: 419228 Committed
r272394
: <
https://trac.webkit.org/changeset/272394
>
Ryosuke Niwa
Comment 15
2021-02-04 16:10:35 PST
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug