LibWeb: Avoid expensive Vector filtering in event loop
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run

Instead of collecting all documents in a big vector and then filtering
the vector (twice!) with remove_all_matching(), we now pass a filter
callback to documents_in_this_event_loop_matching() and avoid all the
extra shuffling work.

Saw this stuff hogging ~20% of CPU time when profiling a WebContent
process in the middle of a WPT run.
This commit is contained in:
Andreas Kling 2024-11-24 15:47:18 +01:00 committed by Andreas Kling
parent eafa70331d
commit 26f32b11f9
Notes: github-actions[bot] 2024-11-24 16:18:45 +00:00
2 changed files with 23 additions and 17 deletions

View file

@ -260,30 +260,28 @@ void EventLoop::update_the_rendering()
// FIXME: 1. Let frameTimestamp be eventLoop's last render opportunity time.
// FIXME: 2. Let docs be all fully active Document objects whose relevant agent's event loop is eventLoop, sorted arbitrarily except that the following conditions must be met:
auto docs = documents_in_this_event_loop();
docs.remove_all_matching([&](auto& document) {
return !document->is_fully_active();
});
// 3. Filter non-renderable documents: Remove from docs any Document object doc for which any of the following are true:
docs.remove_all_matching([&](auto const& document) {
auto navigable = document->navigable();
if (!navigable)
return true;
auto docs = documents_in_this_event_loop_matching([&](auto const& document) {
if (!document.is_fully_active())
return false;
// FIXME: doc is render-blocked;
// doc's visibility state is "hidden";
if (document->hidden())
return true;
if (document.hidden())
return false;
// FIXME: doc's rendering is suppressed for view transitions; or
auto navigable = document.navigable();
if (!navigable)
return false;
// doc's node navigable doesn't currently have a rendering opportunity.
if (!navigable->has_a_rendering_opportunity())
return true;
return false;
return false;
return true;
});
// FIXME: 4. Unnecessary rendering: Remove from docs any Document object doc for which all of the following are true:
@ -515,18 +513,25 @@ void EventLoop::perform_a_microtask_checkpoint()
// FIXME: 8. Record timing info for microtask checkpoint.
}
Vector<GC::Root<DOM::Document>> EventLoop::documents_in_this_event_loop() const
Vector<GC::Root<DOM::Document>> EventLoop::documents_in_this_event_loop_matching(auto callback) const
{
Vector<GC::Root<DOM::Document>> documents;
for (auto& document : m_documents) {
VERIFY(document);
if (document->is_decoded_svg())
continue;
if (!callback(*document))
continue;
documents.append(GC::make_root(*document));
}
return documents;
}
Vector<GC::Root<DOM::Document>> EventLoop::documents_in_this_event_loop() const
{
return documents_in_this_event_loop_matching([](auto&) { return true; });
}
void EventLoop::register_document(Badge<DOM::Document>, DOM::Document& document)
{
m_documents.append(&document);
@ -568,9 +573,8 @@ void EventLoop::unregister_environment_settings_object(Badge<EnvironmentSettings
Vector<GC::Root<HTML::Window>> EventLoop::same_loop_windows() const
{
Vector<GC::Root<HTML::Window>> windows;
for (auto& document : documents_in_this_event_loop()) {
if (document->is_fully_active())
windows.append(GC::make_root(document->window()));
for (auto& document : documents_in_this_event_loop_matching([](auto& document) { return document.is_fully_active(); })) {
windows.append(GC::make_root(document->window()));
}
return windows;
}

View file

@ -95,6 +95,8 @@ private:
virtual void visit_edges(Visitor&) override;
[[nodiscard]] Vector<GC::Root<DOM::Document>> documents_in_this_event_loop_matching(auto callback) const;
void update_the_rendering();
Type m_type { Type::Window };