diff --git a/Ladybird/Qt/BrowserWindow.cpp b/Ladybird/Qt/BrowserWindow.cpp index e0628f4fb0..049f166ab4 100644 --- a/Ladybird/Qt/BrowserWindow.cpp +++ b/Ladybird/Qt/BrowserWindow.cpp @@ -278,7 +278,12 @@ BrowserWindow::BrowserWindow(Vector const& initial_urls, WebView::CookieJar auto* dump_gc_graph_action = new QAction("Dump GC graph", this); debug_menu->addAction(dump_gc_graph_action); QObject::connect(dump_gc_graph_action, &QAction::triggered, this, [this] { - debug_request("dump-gc-graph"); + if (m_current_tab) { + auto gc_graph_path = m_current_tab->view().dump_gc_graph(); + warnln("\033[33;1mDumped GC-graph into {}" + "\033[0m", + gc_graph_path); + } }); auto* clear_cache_action = new QAction("Clear &Cache", this); diff --git a/Userland/Libraries/LibJS/Heap/Heap.cpp b/Userland/Libraries/LibJS/Heap/Heap.cpp index 806b0beda0..7f88eb93f0 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.cpp +++ b/Userland/Libraries/LibJS/Heap/Heap.cpp @@ -192,7 +192,7 @@ public: } } - void dump() + AK::JsonObject dump() { auto graph = AK::JsonObject(); for (auto& it : m_graph) { @@ -233,7 +233,7 @@ public: graph.set(DeprecatedString::number(it.key), node); } - dbgln("{}", graph.to_deprecated_string()); + return graph; } private: @@ -253,14 +253,14 @@ private: FlatPtr m_max_block_address; }; -void Heap::dump_graph() +AK::JsonObject Heap::dump_graph() { HashMap roots; gather_roots(roots); GraphConstructorVisitor visitor(*this, roots); vm().bytecode_interpreter().visit_edges(visitor); visitor.visit_all_cells(); - visitor.dump(); + return visitor.dump(); } void Heap::collect_garbage(CollectionType collection_type, bool print_report) diff --git a/Userland/Libraries/LibJS/Heap/Heap.h b/Userland/Libraries/LibJS/Heap/Heap.h index 9ca0a64b1b..8ebe0bcb7d 100644 --- a/Userland/Libraries/LibJS/Heap/Heap.h +++ b/Userland/Libraries/LibJS/Heap/Heap.h @@ -64,7 +64,7 @@ public: }; void collect_garbage(CollectionType = CollectionType::CollectGarbage, bool print_report = false); - void dump_graph(); + AK::JsonObject dump_graph(); bool should_collect_on_every_allocation() const { return m_should_collect_on_every_allocation; } void set_should_collect_on_every_allocation(bool b) { m_should_collect_on_every_allocation = b; } diff --git a/Userland/Libraries/LibWebView/ViewImplementation.cpp b/Userland/Libraries/LibWebView/ViewImplementation.cpp index 4a97beaa9e..816e9e1c24 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.cpp +++ b/Userland/Libraries/LibWebView/ViewImplementation.cpp @@ -403,8 +403,8 @@ static ErrorOr save_screenshot(Gfx::ShareableBitmap const& bitmap) auto encoded = TRY(Gfx::PNGWriter::encode(*bitmap.bitmap())); - auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); - TRY(screenshot_file->write_until_depleted(encoded)); + auto dump_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); + TRY(dump_file->write_until_depleted(encoded)); return path; } @@ -432,6 +432,19 @@ ErrorOr ViewImplementation::take_dom_node_screenshot(i32 node_id) return save_screenshot(bitmap); } +ErrorOr ViewImplementation::dump_gc_graph() +{ + auto gc_graph_json = client().dump_gc_graph(); + + LexicalPath path { Core::StandardPaths::tempfile_directory() }; + path = path.append(TRY(Core::DateTime::now().to_string("gc-graph-%Y-%m-%d-%H-%M-%S.json"sv))); + + auto screenshot_file = TRY(Core::File::open(path.string(), Core::File::OpenMode::Write)); + TRY(screenshot_file->write_until_depleted(gc_graph_json.bytes())); + + return path; +} + void ViewImplementation::set_user_style_sheet(String source) { client().async_set_user_style(move(source)); diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index 811ac773fa..44113015fd 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -99,6 +99,8 @@ public: ErrorOr take_screenshot(ScreenshotType); ErrorOr take_dom_node_screenshot(i32); + ErrorOr dump_gc_graph(); + void set_user_style_sheet(String source); // Load Native.css as the User style sheet, which attempts to make WebView content look as close to // native GUI widgets as possible. diff --git a/Userland/Services/WebContent/ConnectionFromClient.cpp b/Userland/Services/WebContent/ConnectionFromClient.cpp index ae07fa896f..07a33fbdec 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.cpp +++ b/Userland/Services/WebContent/ConnectionFromClient.cpp @@ -443,11 +443,6 @@ void ConnectionFromClient::debug_request(DeprecatedString const& request, Deprec return; } - if (request == "dump-gc-graph") { - Web::Bindings::main_thread_vm().heap().dump_graph(); - return; - } - if (request == "set-line-box-borders") { bool state = argument == "on"; page().set_should_show_line_box_borders(state); @@ -876,6 +871,12 @@ Messages::WebContentServer::TakeDomNodeScreenshotResponse ConnectionFromClient:: return bitmap->to_shareable_bitmap(); } +Messages::WebContentServer::DumpGcGraphResponse ConnectionFromClient::dump_gc_graph() +{ + auto gc_graph_json = Web::Bindings::main_thread_vm().heap().dump_graph(); + return MUST(String::from_deprecated_string(gc_graph_json.to_deprecated_string())); +} + Messages::WebContentServer::GetSelectedTextResponse ConnectionFromClient::get_selected_text() { return page().page().focused_context().selected_text(); diff --git a/Userland/Services/WebContent/ConnectionFromClient.h b/Userland/Services/WebContent/ConnectionFromClient.h index d0a05ef60e..30e37313f7 100644 --- a/Userland/Services/WebContent/ConnectionFromClient.h +++ b/Userland/Services/WebContent/ConnectionFromClient.h @@ -124,6 +124,8 @@ private: virtual Messages::WebContentServer::TakeDocumentScreenshotResponse take_document_screenshot() override; virtual Messages::WebContentServer::TakeDomNodeScreenshotResponse take_dom_node_screenshot(i32 node_id) override; + virtual Messages::WebContentServer::DumpGcGraphResponse dump_gc_graph() override; + virtual Messages::WebContentServer::GetLocalStorageEntriesResponse get_local_storage_entries() override; virtual Messages::WebContentServer::GetSessionStorageEntriesResponse get_session_storage_entries() override; diff --git a/Userland/Services/WebContent/WebContentServer.ipc b/Userland/Services/WebContent/WebContentServer.ipc index 45b76691aa..da81bc9ab4 100644 --- a/Userland/Services/WebContent/WebContentServer.ipc +++ b/Userland/Services/WebContent/WebContentServer.ipc @@ -59,6 +59,8 @@ endpoint WebContentServer take_document_screenshot() => (Gfx::ShareableBitmap data) take_dom_node_screenshot(i32 node_id) => (Gfx::ShareableBitmap data) + dump_gc_graph() => (String json) + run_javascript(DeprecatedString js_source) =| dump_layout_tree() => (DeprecatedString dump)