mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-31 05:09:12 +00:00
LibWeb: Make Agent's MutationObserver list weak
Before this change, Agent held on to all of the live MutationObserver objects via GC::Root. This prevented them from ever getting garbage-collected. Instead of roots, we now use a simple IntrusiveList and remove them from it in the finalizer for MutationObserver. This fixes a massive GC leak on Speedometer.
This commit is contained in:
parent
f1801fb1d2
commit
53c9c6f3ee
Notes:
github-actions[bot]
2025-02-07 15:54:21 +00:00
Author: https://github.com/awesomekling
Commit: 53c9c6f3ee
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3488
Reviewed-by: https://github.com/shannonbooth
4 changed files with 14 additions and 6 deletions
|
@ -675,7 +675,7 @@ void queue_mutation_observer_microtask(DOM::Document const& document)
|
||||||
// 2. Let notifySet be a clone of the surrounding agent’s mutation observers.
|
// 2. Let notifySet be a clone of the surrounding agent’s mutation observers.
|
||||||
GC::RootVector<DOM::MutationObserver*> notify_set(heap);
|
GC::RootVector<DOM::MutationObserver*> notify_set(heap);
|
||||||
for (auto& observer : surrounding_agent.mutation_observers)
|
for (auto& observer : surrounding_agent.mutation_observers)
|
||||||
notify_set.append(observer);
|
notify_set.append(&observer);
|
||||||
|
|
||||||
// FIXME: 3. Let signalSet be a clone of the surrounding agent’s signal slots.
|
// FIXME: 3. Let signalSet be a clone of the surrounding agent’s signal slots.
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,11 @@ MutationObserver::MutationObserver(JS::Realm& realm, GC::Ptr<WebIDL::CallbackTyp
|
||||||
|
|
||||||
MutationObserver::~MutationObserver()
|
MutationObserver::~MutationObserver()
|
||||||
{
|
{
|
||||||
HTML::relevant_agent(*this).mutation_observers.remove_all_matching([this](auto& observer) {
|
}
|
||||||
return observer.ptr() == this;
|
|
||||||
});
|
void MutationObserver::finalize()
|
||||||
|
{
|
||||||
|
HTML::relevant_agent(*this).mutation_observers.remove(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MutationObserver::initialize(JS::Realm& realm)
|
void MutationObserver::initialize(JS::Realm& realm)
|
||||||
|
|
|
@ -53,6 +53,7 @@ private:
|
||||||
|
|
||||||
virtual void initialize(JS::Realm&) override;
|
virtual void initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
virtual void finalize() override;
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-mo-callback
|
// https://dom.spec.whatwg.org/#concept-mo-callback
|
||||||
GC::Ptr<WebIDL::CallbackType> m_callback;
|
GC::Ptr<WebIDL::CallbackType> m_callback;
|
||||||
|
@ -64,6 +65,11 @@ private:
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#concept-mo-queue
|
// https://dom.spec.whatwg.org/#concept-mo-queue
|
||||||
Vector<GC::Ref<MutationRecord>> m_record_queue;
|
Vector<GC::Ref<MutationRecord>> m_record_queue;
|
||||||
|
|
||||||
|
IntrusiveListNode<MutationObserver> m_list_node;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using List = IntrusiveList<&MutationObserver::m_list_node>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#registered-observer
|
// https://dom.spec.whatwg.org/#registered-observer
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibGC/Root.h>
|
#include <LibGC/Root.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
|
#include <LibWeb/DOM/MutationObserver.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibWeb/HTML/CustomElements/CustomElementReactionsStack.h>
|
#include <LibWeb/HTML/CustomElements/CustomElementReactionsStack.h>
|
||||||
|
|
||||||
|
@ -25,8 +26,7 @@ struct Agent {
|
||||||
bool mutation_observer_microtask_queued { false };
|
bool mutation_observer_microtask_queued { false };
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#mutation-observer-list
|
// https://dom.spec.whatwg.org/#mutation-observer-list
|
||||||
// FIXME: This should be a set.
|
DOM::MutationObserver::List mutation_observers;
|
||||||
Vector<GC::Root<DOM::MutationObserver>> mutation_observers;
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reactions-stack
|
// https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reactions-stack
|
||||||
// Each similar-origin window agent has a custom element reactions stack, which is initially empty.
|
// Each similar-origin window agent has a custom element reactions stack, which is initially empty.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue