1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:57:45 +00:00

LibWeb: Put most LibWeb GC objects in type-specific heap blocks

With this change, we now have ~1200 CellAllocators across both LibJS and
LibWeb in a normal WebContent instance.

This gives us a minimum heap size of 4.7 MiB in the scenario where we
only have one cell allocated per type. Of course, in practice there will
be many more of each type, so the effective overhead is quite a bit
smaller than that in practice.

I left a few types unconverted to this mechanism because I got tired of
doing this. :^)
This commit is contained in:
Andreas Kling 2023-11-19 19:47:52 +01:00
parent 536596632b
commit bfd354492e
599 changed files with 933 additions and 3 deletions

View file

@ -10,6 +10,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(AbortController);
WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortController>> AbortController::construct_impl(JS::Realm& realm)
{
auto signal = TRY(AbortSignal::construct_impl(realm));

View file

@ -14,6 +14,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#abortcontroller
class AbortController final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(AbortController, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(AbortController);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortController>> construct_impl(JS::Realm&);

View file

@ -12,6 +12,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(AbortSignal);
WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> AbortSignal::construct_impl(JS::Realm& realm)
{
return realm.heap().allocate<AbortSignal>(realm, realm);

View file

@ -17,6 +17,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#abortsignal
class AbortSignal final : public EventTarget {
WEB_PLATFORM_OBJECT(AbortSignal, EventTarget);
JS_DECLARE_ALLOCATOR(AbortSignal);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<AbortSignal>> construct_impl(JS::Realm&);

View file

@ -13,6 +13,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(AccessibilityTreeNode);
JS::NonnullGCPtr<AccessibilityTreeNode> AccessibilityTreeNode::create(Document* document, DOM::Node const* value)
{
return document->heap().allocate<AccessibilityTreeNode>(document->realm(), value);

View file

@ -9,13 +9,16 @@
#include <AK/JsonObjectSerializer.h>
#include <AK/Vector.h>
#include <LibJS/Heap/Cell.h>
#include <LibJS/Heap/CellAllocator.h>
#include <LibWeb/DOM/Node.h>
#include <LibWeb/Forward.h>
namespace Web::DOM {
class AccessibilityTreeNode final : public JS::Cell {
JS_CELL(AccessibilityTreeNode, JS::Cell)
JS_CELL(AccessibilityTreeNode, JS::Cell);
JS_DECLARE_ALLOCATOR(AccessibilityTreeNode);
public:
static JS::NonnullGCPtr<AccessibilityTreeNode> create(Document*, DOM::Node const*);
virtual ~AccessibilityTreeNode() override = default;

View file

@ -15,6 +15,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Attr);
JS::NonnullGCPtr<Attr> Attr::create(Document& document, FlyString local_name, String value, Element* owner_element)
{
return document.heap().allocate<Attr>(document.realm(), document, QualifiedName(move(local_name), Optional<FlyString> {}, Optional<FlyString> {}), move(value), owner_element);

View file

@ -15,6 +15,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#attr
class Attr final : public Node {
WEB_PLATFORM_OBJECT(Attr, Node);
JS_DECLARE_ALLOCATOR(Attr);
public:
[[nodiscard]] static JS::NonnullGCPtr<Attr> create(Document&, QualifiedName, String value = {}, Element* = nullptr);

View file

@ -9,6 +9,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(CDATASection);
CDATASection::CDATASection(Document& document, String const& data)
: Text(document, NodeType::CDATA_SECTION_NODE, data)
{

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
class CDATASection final : public Text {
WEB_PLATFORM_OBJECT(CDATASection, Text);
JS_DECLARE_ALLOCATOR(CDATASection);
public:
virtual ~CDATASection() override;

View file

@ -14,6 +14,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(CharacterData);
CharacterData::CharacterData(Document& document, NodeType type, String const& data)
: Node(document, type)
, m_data(data)

View file

@ -18,6 +18,7 @@ class CharacterData
, public ChildNode<CharacterData>
, public NonDocumentTypeChildNode<CharacterData> {
WEB_PLATFORM_OBJECT(CharacterData, Node);
JS_DECLARE_ALLOCATOR(CharacterData);
public:
virtual ~CharacterData() override = default;

View file

@ -11,6 +11,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Comment);
Comment::Comment(Document& document, String const& data)
: CharacterData(document, NodeType::COMMENT_NODE, data)
{

View file

@ -12,6 +12,7 @@ namespace Web::DOM {
class Comment final : public CharacterData {
WEB_PLATFORM_OBJECT(Comment, CharacterData);
JS_DECLARE_ALLOCATOR(Comment);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<Comment>> construct_impl(JS::Realm&, String const& data);

View file

@ -11,6 +11,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(CustomEvent);
JS::NonnullGCPtr<CustomEvent> CustomEvent::create(JS::Realm& realm, FlyString const& event_name, CustomEventInit const& event_init)
{
return realm.heap().allocate<CustomEvent>(realm, realm, event_name, event_init);

View file

@ -19,6 +19,7 @@ struct CustomEventInit : public EventInit {
// https://dom.spec.whatwg.org/#customevent
class CustomEvent : public Event {
WEB_PLATFORM_OBJECT(CustomEvent, Event);
JS_DECLARE_ALLOCATOR(CustomEvent);
public:
[[nodiscard]] static JS::NonnullGCPtr<CustomEvent> create(JS::Realm&, FlyString const& event_name, CustomEventInit const& = {});

View file

@ -10,6 +10,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(DOMEventListener);
DOMEventListener::DOMEventListener() = default;
DOMEventListener::~DOMEventListener() = default;

View file

@ -17,6 +17,7 @@ namespace Web::DOM {
// NOTE: The spec calls this "event listener", and it's *importantly* not the same as "EventListener"
class DOMEventListener : public JS::Cell {
JS_CELL(DOMEventListener, JS::Cell);
JS_DECLARE_ALLOCATOR(DOMEventListener);
public:
DOMEventListener();

View file

@ -17,6 +17,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(DOMImplementation);
JS::NonnullGCPtr<DOMImplementation> DOMImplementation::create(Document& document)
{
auto& realm = document.realm();

View file

@ -15,6 +15,7 @@ namespace Web::DOM {
class DOMImplementation final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(DOMImplementation, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(DOMImplementation);
public:
[[nodiscard]] static JS::NonnullGCPtr<DOMImplementation> create(Document&);

View file

@ -52,6 +52,8 @@ inline void replace_in_ordered_set(Vector<String>& set, String const& item, Stri
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(DOMTokenList);
JS::NonnullGCPtr<DOMTokenList> DOMTokenList::create(Element& associated_element, FlyString associated_attribute)
{
auto& realm = associated_element.realm();

View file

@ -22,6 +22,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#domtokenlist
class DOMTokenList final : public Bindings::LegacyPlatformObject {
WEB_PLATFORM_OBJECT(DOMTokenList, Bindings::LegacyPlatformObject);
JS_DECLARE_ALLOCATOR(DOMTokenList);
public:
[[nodiscard]] static JS::NonnullGCPtr<DOMTokenList> create(Element& associated_element, FlyString associated_attribute);

View file

@ -106,6 +106,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Document);
// https://html.spec.whatwg.org/multipage/origin.html#obtain-browsing-context-navigation
static JS::NonnullGCPtr<HTML::BrowsingContext> obtain_a_browsing_context_to_use_for_a_navigation_response(
HTML::BrowsingContext& browsing_context,

View file

@ -81,6 +81,7 @@ class Document
, public NonElementParentNode<Document>
, public HTML::GlobalEventHandlers {
WEB_PLATFORM_OBJECT(Document, ParentNode);
JS_DECLARE_ALLOCATOR(Document);
public:
enum class Type {

View file

@ -9,6 +9,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(DocumentFragment);
DocumentFragment::DocumentFragment(Document& document)
: ParentNode(document, NodeType::DOCUMENT_FRAGMENT_NODE)
{

View file

@ -16,6 +16,7 @@ class DocumentFragment
: public ParentNode
, public NonElementParentNode<DocumentFragment> {
WEB_PLATFORM_OBJECT(DocumentFragment, ParentNode);
JS_DECLARE_ALLOCATOR(DocumentFragment);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentFragment>> construct_impl(JS::Realm& realm);

View file

@ -10,6 +10,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(DocumentObserver);
DocumentObserver::DocumentObserver(JS::Realm& realm, DOM::Document& document)
: Bindings::PlatformObject(realm)
, m_document(document)

View file

@ -16,6 +16,7 @@ namespace Web::DOM {
class DocumentObserver final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(DocumentObserver, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(DocumentObserver);
public:
[[nodiscard]] JS::GCPtr<JS::HeapFunction<void()>> document_became_inactive() const { return m_document_became_inactive; }

View file

@ -9,6 +9,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(DocumentType);
JS::NonnullGCPtr<DocumentType> DocumentType::create(Document& document)
{
return document.heap().allocate<DocumentType>(document.realm(), document);

View file

@ -16,6 +16,7 @@ class DocumentType final
: public Node
, public ChildNode<DocumentType> {
WEB_PLATFORM_OBJECT(DocumentType, Node);
JS_DECLARE_ALLOCATOR(DocumentType);
public:
[[nodiscard]] static JS::NonnullGCPtr<DocumentType> create(Document&);

View file

@ -14,6 +14,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Event);
JS::NonnullGCPtr<Event> Event::create(JS::Realm& realm, FlyString const& event_name, EventInit const& event_init)
{
return realm.heap().allocate<Event>(realm, realm, event_name, event_init);

View file

@ -20,6 +20,7 @@ struct EventInit {
class Event : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(Event, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(Event);
public:
enum Phase : u16 {

View file

@ -13,6 +13,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(HTMLCollection);
JS::NonnullGCPtr<HTMLCollection> HTMLCollection::create(ParentNode& root, Scope scope, Function<bool(Element const&)> filter)
{
return root.heap().allocate<HTMLCollection>(root.realm(), root, scope, move(filter));

View file

@ -27,6 +27,7 @@ namespace Web::DOM {
class HTMLCollection : public Bindings::LegacyPlatformObject {
WEB_PLATFORM_OBJECT(HTMLCollection, Bindings::LegacyPlatformObject);
JS_DECLARE_ALLOCATOR(HTMLCollection);
public:
enum class Scope {

View file

@ -12,6 +12,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(HTMLFormControlsCollection);
JS::NonnullGCPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ParentNode& root, Scope scope, Function<bool(Element const&)> filter)
{
return root.heap().allocate<HTMLFormControlsCollection>(root.realm(), root, scope, move(filter));

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
class HTMLFormControlsCollection : public HTMLCollection {
WEB_PLATFORM_OBJECT(HTMLFormControlsCollection, HTMLCollection);
JS_DECLARE_ALLOCATOR(HTMLFormControlsCollection);
public:
[[nodiscard]] static JS::NonnullGCPtr<HTMLFormControlsCollection> create(ParentNode& root, Scope, Function<bool(Element const&)> filter);

View file

@ -12,6 +12,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(LiveNodeList);
JS::NonnullGCPtr<NodeList> LiveNodeList::create(JS::Realm& realm, Node& root, Scope scope, Function<bool(Node const&)> filter)
{
return realm.heap().allocate<LiveNodeList>(realm, realm, root, scope, move(filter));

View file

@ -16,6 +16,7 @@ namespace Web::DOM {
class LiveNodeList : public NodeList {
WEB_PLATFORM_OBJECT(LiveNodeList, NodeList);
JS_DECLARE_ALLOCATOR(LiveNodeList);
public:
enum class Scope {

View file

@ -11,6 +11,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(MutationObserver);
WebIDL::ExceptionOr<JS::NonnullGCPtr<MutationObserver>> MutationObserver::construct_impl(JS::Realm& realm, JS::GCPtr<WebIDL::CallbackType> callback)
{
return realm.heap().allocate<MutationObserver>(realm, realm, callback);

View file

@ -29,6 +29,7 @@ struct MutationObserverInit {
// https://dom.spec.whatwg.org/#mutationobserver
class MutationObserver final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(MutationObserver, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(MutationObserver);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<MutationObserver>> construct_impl(JS::Realm&, JS::GCPtr<WebIDL::CallbackType>);

View file

@ -12,6 +12,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(MutationRecord);
JS::NonnullGCPtr<MutationRecord> MutationRecord::create(JS::Realm& realm, FlyString const& type, Node const& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, Optional<String> const& attribute_name, Optional<String> const& attribute_namespace, Optional<String> const& old_value)
{
return realm.heap().allocate<MutationRecord>(realm, realm, type, target, added_nodes, removed_nodes, previous_sibling, next_sibling, attribute_name, attribute_namespace, old_value);

View file

@ -14,6 +14,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#mutationrecord
class MutationRecord : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(MutationRecord, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(MutationRecord);
public:
[[nodiscard]] static JS::NonnullGCPtr<MutationRecord> create(JS::Realm&, FlyString const& type, Node const& target, NodeList& added_nodes, NodeList& removed_nodes, Node* previous_sibling, Node* next_sibling, Optional<String> const& attribute_name, Optional<String> const& attribute_namespace, Optional<String> const& old_value);

View file

@ -13,6 +13,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(NamedNodeMap);
JS::NonnullGCPtr<NamedNodeMap> NamedNodeMap::create(Element& element)
{
auto& realm = element.realm();

View file

@ -20,6 +20,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#interface-namednodemap
class NamedNodeMap : public Bindings::LegacyPlatformObject {
WEB_PLATFORM_OBJECT(NamedNodeMap, Bindings::LegacyPlatformObject);
JS_DECLARE_ALLOCATOR(NamedNodeMap);
public:
[[nodiscard]] static JS::NonnullGCPtr<NamedNodeMap> create(Element&);

View file

@ -10,6 +10,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(NodeFilter);
JS::NonnullGCPtr<NodeFilter> NodeFilter::create(JS::Realm& realm, WebIDL::CallbackType& callback)
{
return realm.heap().allocate<NodeFilter>(realm, realm, callback);

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
class NodeFilter final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(NodeFilter, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(NodeFilter);
public:
[[nodiscard]] static JS::NonnullGCPtr<NodeFilter> create(JS::Realm&, WebIDL::CallbackType&);

View file

@ -11,6 +11,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(NodeIterator);
NodeIterator::NodeIterator(Node& root)
: PlatformObject(root.realm())
, m_root(root)

View file

@ -14,6 +14,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#nodeiterator
class NodeIterator final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(NodeIterator, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(NodeIterator);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<NodeIterator>> create(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);

View file

@ -13,6 +13,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Position);
Position::Position(JS::GCPtr<Node> node, unsigned offset)
: m_node(node)
, m_offset(offset)

View file

@ -18,6 +18,7 @@ namespace Web::DOM {
class Position final : public JS::Cell {
JS_CELL(Position, JS::Cell);
JS_DECLARE_ALLOCATOR(Position);
public:
[[nodiscard]] static JS::NonnullGCPtr<Position> create(JS::Realm& realm, JS::NonnullGCPtr<Node> node, unsigned offset)

View file

@ -11,6 +11,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(ProcessingInstruction);
ProcessingInstruction::ProcessingInstruction(Document& document, DeprecatedString const& data, DeprecatedString const& target)
: CharacterData(document, NodeType::PROCESSING_INSTRUCTION_NODE, MUST(String::from_deprecated_string(data)))
, m_target(target)

View file

@ -12,6 +12,7 @@ namespace Web::DOM {
class ProcessingInstruction final : public CharacterData {
WEB_PLATFORM_OBJECT(ProcessingInstruction, CharacterData);
JS_DECLARE_ALLOCATOR(ProcessingInstruction);
public:
virtual ~ProcessingInstruction() override = default;

View file

@ -12,6 +12,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(RadioNodeList);
JS::NonnullGCPtr<RadioNodeList> RadioNodeList::create(JS::Realm& realm, Node& root, Scope scope, Function<bool(Node const&)> filter)
{
return realm.heap().allocate<RadioNodeList>(realm, realm, root, scope, move(filter));

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
// https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#radionodelist
class RadioNodeList : public LiveNodeList {
WEB_PLATFORM_OBJECT(RadioNodeList, LiveNodeList);
JS_DECLARE_ALLOCATOR(RadioNodeList);
public:
[[nodiscard]] static JS::NonnullGCPtr<RadioNodeList> create(JS::Realm& realm, Node& root, Scope scope, Function<bool(Node const&)> filter);

View file

@ -25,6 +25,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Range);
HashTable<Range*>& Range::live_ranges()
{
static HashTable<Range*> ranges;

View file

@ -24,6 +24,7 @@ RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_bound
class Range final : public AbstractRange {
WEB_PLATFORM_OBJECT(Range, AbstractRange);
JS_DECLARE_ALLOCATOR(Range);
public:
[[nodiscard]] static JS::NonnullGCPtr<Range> create(Document&);

View file

@ -12,6 +12,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(ShadowRoot);
ShadowRoot::ShadowRoot(Document& document, Element& host, Bindings::ShadowRootMode mode)
: DocumentFragment(document)
, m_mode(mode)

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
class ShadowRoot final : public DocumentFragment {
WEB_PLATFORM_OBJECT(ShadowRoot, DocumentFragment);
JS_DECLARE_ALLOCATOR(ShadowRoot);
public:
Bindings::ShadowRootMode mode() const { return m_mode; }

View file

@ -10,6 +10,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(StaticNodeList);
JS::NonnullGCPtr<NodeList> StaticNodeList::create(JS::Realm& realm, Vector<JS::Handle<Node>> static_nodes)
{
return realm.heap().allocate<StaticNodeList>(realm, realm, move(static_nodes));

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
class StaticNodeList final : public NodeList {
WEB_PLATFORM_OBJECT(StaticNodeList, NodeList);
JS_DECLARE_ALLOCATOR(StaticNodeList);
public:
[[nodiscard]] static JS::NonnullGCPtr<NodeList> create(JS::Realm&, Vector<JS::Handle<Node>>);

View file

@ -14,6 +14,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(StaticRange);
StaticRange::StaticRange(Node& start_container, u32 start_offset, Node& end_container, u32 end_offset)
: AbstractRange(start_container, start_offset, end_container, end_offset)
{

View file

@ -22,6 +22,7 @@ struct StaticRangeInit {
class StaticRange final : public AbstractRange {
WEB_PLATFORM_OBJECT(StaticRange, AbstractRange);
JS_DECLARE_ALLOCATOR(StaticRange);
public:
static WebIDL::ExceptionOr<JS::NonnullGCPtr<StaticRange>> construct_impl(JS::Realm&, StaticRangeInit& init);

View file

@ -13,6 +13,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(Text);
Text::Text(Document& document, String const& data)
: CharacterData(document, NodeType::TEXT_NODE, data)
{

View file

@ -22,6 +22,7 @@ class Text
: public CharacterData
, public SlottableMixin {
WEB_PLATFORM_OBJECT(Text, CharacterData);
JS_DECLARE_ALLOCATOR(Text);
public:
virtual ~Text() override = default;

View file

@ -13,6 +13,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(TreeWalker);
TreeWalker::TreeWalker(Node& root)
: PlatformObject(root.realm())
, m_root(root)

View file

@ -13,6 +13,7 @@ namespace Web::DOM {
// https://dom.spec.whatwg.org/#treewalker
class TreeWalker final : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(TreeWalker, Bindings::PlatformObject);
JS_DECLARE_ALLOCATOR(TreeWalker);
public:
[[nodiscard]] static JS::NonnullGCPtr<TreeWalker> create(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);

View file

@ -9,6 +9,8 @@
namespace Web::DOM {
JS_DEFINE_ALLOCATOR(XMLDocument);
JS::NonnullGCPtr<XMLDocument> XMLDocument::create(JS::Realm& realm, AK::URL const& url)
{
return realm.heap().allocate<XMLDocument>(realm, realm, url);

View file

@ -12,6 +12,7 @@ namespace Web::DOM {
class XMLDocument final : public Document {
WEB_PLATFORM_OBJECT(XMLDocument, Document);
JS_DECLARE_ALLOCATOR(XMLDocument);
public:
static JS::NonnullGCPtr<XMLDocument> create(JS::Realm&, AK::URL const&);