LibWeb: Cache UniversalGlobalScopeMixin pointer on ESO

Avoid expensive cross-hierarchy dynamic_cast from JS::Object to
UniversalGlobalScopeMixin on every microtask checkpoint.

Since UniversalGlobalScopeMixin is not in the JS::Object
inheritance chain, as<UniversalGlobalScopeMixin>(JS::Object&)
falls through to dynamic_cast, which is very costly. Profiling
showed this taking ~14% of total CPU time.

Add EnvironmentSettingsObject::universal_global_scope() backed
by a pointer cached eagerly during initialization.
This commit is contained in:
Andreas Kling
2026-03-23 20:30:19 +01:00
committed by Andreas Kling
parent e49ab8a1f2
commit b5babda288
Notes: github-actions[bot] 2026-03-24 07:29:35 +00:00
4 changed files with 14 additions and 3 deletions

View File

@@ -19,6 +19,7 @@
#include <LibWeb/HTML/Scripting/Environments.h>
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
#include <LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h>
#include <LibWeb/HTML/UniversalGlobalScope.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/HTML/WorkerGlobalScope.h>
#include <LibWeb/Page/Page.h>
@@ -56,6 +57,7 @@ void EnvironmentSettingsObject::initialize(JS::Realm& realm)
{
Base::initialize(realm);
m_module_map = realm.heap().allocate<ModuleMap>();
m_universal_global_scope = &as<UniversalGlobalScopeMixin>(global_object());
}
void EnvironmentSettingsObject::visit_edges(Cell::Visitor& visitor)
@@ -109,6 +111,11 @@ JS::Object& EnvironmentSettingsObject::global_object()
return realm().global_object();
}
UniversalGlobalScopeMixin& EnvironmentSettingsObject::universal_global_scope()
{
return *m_universal_global_scope;
}
// https://html.spec.whatwg.org/multipage/webappapis.html#responsible-event-loop
EventLoop& EnvironmentSettingsObject::responsible_event_loop()
{