LibWeb: Avoid dynamic_cast in SlottableMixin::assigned_slot()

`SlottableMixin::assigned_slot()` was using `as<DOM::Node>(*this)` to
get a `Node` reference. Since `SlottableMixin` has no inheritance
relationship with `Node`, `as_if<>` can't use `static_cast` and falls
through to `dynamic_cast`, which is expensive. Replace this with a
virtual `slottable_as_node()` accessor overridden in `Element` and
`Text`.

This showed up as hot in profiles when loading the GC heap explorer
page.
This commit is contained in:
Aliaksandr Kalenik 2026-02-07 14:34:43 +01:00 committed by Alexander Kalenik
parent 488123c75b
commit c62996abd7
4 changed files with 7 additions and 1 deletions

View file

@ -125,6 +125,8 @@ public:
virtual bool is_dom_element() const final { return true; }
virtual Node& slottable_as_node() override { return *this; }
FlyString const& qualified_name() const { return m_qualified_name.as_string(); }
FlyString const& html_uppercased_qualified_name() const;

View file

@ -27,7 +27,7 @@ void SlottableMixin::visit_edges(JS::Cell::Visitor& visitor)
// https://dom.spec.whatwg.org/#dom-slotable-assignedslot
GC::Ptr<HTML::HTMLSlotElement> SlottableMixin::assigned_slot()
{
auto& node = as<DOM::Node>(*this);
auto& node = slottable_as_node();
// The assignedSlot getter steps are to return the result of find a slot given this and with the open flag set.
return find_a_slot(node.as_slottable(), OpenFlag::Set);

View file

@ -23,6 +23,8 @@ class WEB_API SlottableMixin {
public:
virtual ~SlottableMixin();
virtual Node& slottable_as_node() = 0;
FlyString const& slottable_name() const { return m_name; } // Not called `name` to distinguish from `Element::name`.
void set_slottable_name(FlyString name) { m_name = move(name); }

View file

@ -28,6 +28,8 @@ public:
// ^Node
virtual FlyString node_name() const override { return "#text"_fly_string; }
virtual Node& slottable_as_node() override { return *this; }
Optional<size_t> max_length() const { return m_max_length; }
void set_max_length(Optional<size_t> max_length) { m_max_length = move(max_length); }