1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:28:11 +00:00

LibWeb: Make HTML::DecodedImageData to be GC-allocated

This change fixes GC-leak caused by following mutual dependency:
- SVGDecodedImageData owns JS::Handle for Page.
- SVGDecodedImageData is owned by visited objects.
by making everything inherited from HTML::DecodedImageData and
ListOfAvailableImages to be GC-allocated.

Generally, if visited object has a handle, very likely we leak
everything visited from object in a handle.
This commit is contained in:
Aliaksandr Kalenik 2023-12-12 20:07:19 +01:00 committed by Andreas Kling
parent 57a04c536c
commit 41a3c19cfe
18 changed files with 100 additions and 54 deletions

View file

@ -23,6 +23,8 @@
namespace Web::SVG {
JS_DEFINE_ALLOCATOR(SVGDecodedImageData);
class SVGDecodedImageData::SVGPageClient final : public PageClient {
JS_CELL(SVGDecodedImageData::SVGPageClient, PageClient);
@ -54,7 +56,7 @@ private:
}
};
ErrorOr<NonnullRefPtr<SVGDecodedImageData>> SVGDecodedImageData::create(Page& host_page, AK::URL const& url, ByteBuffer data)
ErrorOr<JS::NonnullGCPtr<SVGDecodedImageData>> SVGDecodedImageData::create(JS::Realm& realm, JS::NonnullGCPtr<Page> host_page, AK::URL const& url, ByteBuffer data)
{
auto page_client = SVGPageClient::create(Bindings::main_thread_vm(), host_page);
auto page = Page::create(Bindings::main_thread_vm(), *page_client);
@ -98,19 +100,28 @@ ErrorOr<NonnullRefPtr<SVGDecodedImageData>> SVGDecodedImageData::create(Page& ho
MUST(document->append_child(*svg_root));
return adopt_nonnull_ref_or_enomem(new (nothrow) SVGDecodedImageData(page, move(page_client), move(document), move(svg_root)));
return realm.heap().allocate<SVGDecodedImageData>(realm, page, page_client, document, *svg_root);
}
SVGDecodedImageData::SVGDecodedImageData(JS::NonnullGCPtr<Page> page, JS::Handle<SVGPageClient> page_client, JS::Handle<DOM::Document> document, JS::Handle<SVG::SVGSVGElement> root_element)
: m_page(move(page))
, m_page_client(move(page_client))
, m_document(move(document))
, m_root_element(move(root_element))
SVGDecodedImageData::SVGDecodedImageData(JS::NonnullGCPtr<Page> page, JS::NonnullGCPtr<SVGPageClient> page_client, JS::NonnullGCPtr<DOM::Document> document, JS::NonnullGCPtr<SVG::SVGSVGElement> root_element)
: m_page(page)
, m_page_client(page_client)
, m_document(document)
, m_root_element(root_element)
{
}
SVGDecodedImageData::~SVGDecodedImageData() = default;
void SVGDecodedImageData::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_page);
visitor.visit(m_document);
visitor.visit(m_page_client);
visitor.visit(m_root_element);
}
RefPtr<Gfx::Bitmap> SVGDecodedImageData::render(Gfx::IntSize size) const
{
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, size).release_value_but_fixme_should_propagate_errors();