Skip to content

Reduce alloc and copying in AsyncNodeDeletionQueue #47198

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Andrew-Fryer
Copy link
Contributor

@Andrew-Fryer Andrew-Fryer commented Jun 25, 2025

e131d10

Reduce alloc and copying in AsyncNodeDeletionQueue
https://bugs.webkit.org/show_bug.cgi?id=294987
rdar://154311875

Reviewed by NOBODY (OOPS!).

Instead of moving the contents of the NodeVector to m_queue,
just move the inline part of the NodeVector so that we don't
need to grow m_queue as many times, can destruct the NodeVector
opportunistically, and do less copying.

* Source/WebCore/dom/AsyncNodeDeletionQueue.h:
* Source/WebCore/dom/AsyncNodeDeletionQueueInlines.h:
(WebCore::AsyncNodeDeletionQueue::addIfSubtreeSizeIsUnderLimit):

e131d10

Misc iOS, visionOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 win
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-AS-debug ✅ 🧪 wpe-wk2 ⏳ 🧪 win-tests
✅ 🧪 webkitperl ✅ 🧪 ios-wk2 ✅ 🧪 api-mac ✅ 🧪 api-wpe
✅ 🧪 ios-wk2-wpt ✅ 🧪 mac-wk1 ✅ 🛠 wpe-cairo
✅ 🧪 api-ios ✅ 🧪 mac-wk2 ✅ 🛠 gtk
✅ 🛠 vision ✅ 🧪 mac-AS-debug-wk2 ✅ 🧪 gtk-wk2
✅ 🛠 vision-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 api-gtk
✅ 🧪 vision-wk2 ✅ 🧪 mac-intel-wk2 ✅ 🛠 playstation
✅ 🛠 tv ✅ 🛠 mac-safer-cpp
✅ 🛠 tv-sim
✅ 🛠 watch
✅ 🛠 watch-sim

@Andrew-Fryer Andrew-Fryer self-assigned this Jun 25, 2025
@Andrew-Fryer Andrew-Fryer added the New Bugs Unclassified bugs are placed in this component until the correct component can be determined. label Jun 25, 2025
@@ -43,7 +43,7 @@ class AsyncNodeDeletionQueue {
ALWAYS_INLINE static bool isNodeLikelyLarge(const Node&);

private:
Vector<Ref<Node>> m_queue;
Vector<Vector<Ref<Node>>> m_queue;
Copy link
Member

@rniwa rniwa Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not right. We need to use NodeVector, which has inline capacity of 11.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!
I assume my patch is destructing Vector<Ref<Node>, 11> and constructing Vector<Ref<Node>, 0> right now then...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this fix seems to hurt perf, which seems very strange to me.
I stepped through to make sure it's behaving as expected after this fix and can see that we aren't moving the NodeVector contents.
Any idea what could be going on?

Copy link
Contributor

@cdumez cdumez Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vectors with inline buffers are not cheap to move. Here NodeVector has an inline cache of 11. So until it reaches 12 nodes in it, moving it is actually a copy. This may be related.

The move I'm referring to is here:

m_queue.append(WTFMove(children));

Most of the time it will just copy all children's into a few vector instead of just quickly "moving" a VectorBuffer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right.
Inline contents are moved...

https://bugs.webkit.org/show_bug.cgi?id=294987
rdar://154311875

Reviewed by NOBODY (OOPS!).

Instead of moving the contents of the NodeVector to m_queue,
just move the inline part of the NodeVector so that we don't
need to grow m_queue as many times, can destruct the NodeVector
opportunistically, and do less copying.

* Source/WebCore/dom/AsyncNodeDeletionQueue.h:
* Source/WebCore/dom/AsyncNodeDeletionQueueInlines.h:
(WebCore::AsyncNodeDeletionQueue::addIfSubtreeSizeIsUnderLimit):
@Andrew-Fryer Andrew-Fryer force-pushed the less_alloc_in_AsyncNodeDeletionQueue branch from 94d615d to e131d10 Compare June 25, 2025 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Bugs Unclassified bugs are placed in this component until the correct component can be determined.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants