diff options
author | MacDue <macdue@dueutil.tech> | 2023-04-15 01:04:28 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-04-15 06:37:51 +0200 |
commit | 0329ddf46a0d24303fac5954bf3c70d5f3fe577c (patch) | |
tree | 83ca60d767bfde06438e191fe4b0a4c7b0da10aa | |
parent | 5db1eb996173b34960f48c7ea8ce4fd33acde157 (diff) | |
download | serenity-0329ddf46a0d24303fac5954bf3c70d5f3fe577c.zip |
Ladybird+LibWebView: Add -P/--enable-callgrind-profiling option
This adds a -P option to run Ladybird under callgrind. It starts with
instrumentation disabled. To start capturing a profile (once Ladybird
has launched) run `callgrind_control -i on` and to stop it again run
`callgrind_control -i off`.
P.s. This is pretty much stolen from Andreas (and is based on the patch
everyone [that wants a profile] have been manually applying).
-rw-r--r-- | Ladybird/BrowserWindow.cpp | 6 | ||||
-rw-r--r-- | Ladybird/BrowserWindow.h | 3 | ||||
-rw-r--r-- | Ladybird/Tab.cpp | 4 | ||||
-rw-r--r-- | Ladybird/Tab.h | 2 | ||||
-rw-r--r-- | Ladybird/WebContentView.cpp | 8 | ||||
-rw-r--r-- | Ladybird/WebContentView.h | 4 | ||||
-rw-r--r-- | Ladybird/main.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/OutOfProcessWebView.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/OutOfProcessWebView.h | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/ViewImplementation.cpp | 30 | ||||
-rw-r--r-- | Userland/Libraries/LibWebView/ViewImplementation.h | 11 | ||||
-rw-r--r-- | Userland/Utilities/headless-browser.cpp | 2 |
12 files changed, 52 insertions, 26 deletions
diff --git a/Ladybird/BrowserWindow.cpp b/Ladybird/BrowserWindow.cpp index aea82e4d41..dc45a367c3 100644 --- a/Ladybird/BrowserWindow.cpp +++ b/Ladybird/BrowserWindow.cpp @@ -27,9 +27,11 @@ extern DeprecatedString s_serenity_resource_root; extern Browser::Settings* s_settings; -BrowserWindow::BrowserWindow(Browser::CookieJar& cookie_jar, StringView webdriver_content_ipc_path) +BrowserWindow::BrowserWindow(Browser::CookieJar& cookie_jar, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling) : m_cookie_jar(cookie_jar) , m_webdriver_content_ipc_path(webdriver_content_ipc_path) + , m_enable_callgrind_profiling(enable_callgrind_profiling) + { m_tabs_container = new QTabWidget(this); m_tabs_container->installEventFilter(this); @@ -348,7 +350,7 @@ void BrowserWindow::debug_request(DeprecatedString const& request, DeprecatedStr Tab& BrowserWindow::new_tab(QString const& url, Web::HTML::ActivateTab activate_tab) { - auto tab = make<Tab>(this, m_webdriver_content_ipc_path); + auto tab = make<Tab>(this, m_webdriver_content_ipc_path, m_enable_callgrind_profiling); auto tab_ptr = tab.ptr(); m_tabs.append(std::move(tab)); diff --git a/Ladybird/BrowserWindow.h b/Ladybird/BrowserWindow.h index ff51ebe79f..fe3274e8ae 100644 --- a/Ladybird/BrowserWindow.h +++ b/Ladybird/BrowserWindow.h @@ -26,7 +26,7 @@ class CookieJar; class BrowserWindow : public QMainWindow { Q_OBJECT public: - explicit BrowserWindow(Browser::CookieJar&, StringView webdriver_content_ipc_path); + explicit BrowserWindow(Browser::CookieJar&, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling); WebContentView& view() const { return m_current_tab->view(); } @@ -70,4 +70,5 @@ private: Browser::CookieJar& m_cookie_jar; StringView m_webdriver_content_ipc_path; + WebView::EnableCallgrindProfiling m_enable_callgrind_profiling; }; diff --git a/Ladybird/Tab.cpp b/Ladybird/Tab.cpp index 9fc60a5752..aff795dee7 100644 --- a/Ladybird/Tab.cpp +++ b/Ladybird/Tab.cpp @@ -20,7 +20,7 @@ extern DeprecatedString s_serenity_resource_root; extern Browser::Settings* s_settings; -Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path) +Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling) : QWidget(window) , m_window(window) { @@ -28,7 +28,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path) m_layout->setSpacing(0); m_layout->setContentsMargins(0, 0, 0, 0); - m_view = new WebContentView(webdriver_content_ipc_path); + m_view = new WebContentView(webdriver_content_ipc_path, enable_callgrind_profiling); m_toolbar = new QToolBar(this); m_location_edit = new LocationEdit(this); m_reset_zoom_button = new QToolButton(m_toolbar); diff --git a/Ladybird/Tab.h b/Ladybird/Tab.h index 3c89cd6ae9..2ab47470ea 100644 --- a/Ladybird/Tab.h +++ b/Ladybird/Tab.h @@ -24,7 +24,7 @@ class BrowserWindow; class Tab final : public QWidget { Q_OBJECT public: - Tab(BrowserWindow* window, StringView webdriver_content_ipc_path); + Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling); WebContentView& view() { return *m_view; } diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index 7210a15e07..3a02f536f7 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -55,7 +55,7 @@ #include <QTimer> #include <QToolTip> -WebContentView::WebContentView(StringView webdriver_content_ipc_path) +WebContentView::WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling) : m_webdriver_content_ipc_path(webdriver_content_ipc_path) { setMouseTracking(true); @@ -76,7 +76,7 @@ WebContentView::WebContentView(StringView webdriver_content_ipc_path) update_viewport_rect(); }); - create_client(); + create_client(enable_callgrind_profiling); } WebContentView::~WebContentView() @@ -599,12 +599,12 @@ void WebContentView::update_palette() client().async_update_system_theme(make_system_theme_from_qt_palette(*this)); } -void WebContentView::create_client() +void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_callgrind_profiling) { m_client_state = {}; auto candidate_web_content_paths = get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); - auto new_client = launch_web_content_process(candidate_web_content_paths).release_value_but_fixme_should_propagate_errors(); + auto new_client = launch_web_content_process(candidate_web_content_paths, enable_callgrind_profiling).release_value_but_fixme_should_propagate_errors(); m_web_content_notifier.setSocket(new_client->socket().fd().value()); m_web_content_notifier.setEnabled(true); diff --git a/Ladybird/WebContentView.h b/Ladybird/WebContentView.h index b6855c1435..3ec8c44878 100644 --- a/Ladybird/WebContentView.h +++ b/Ladybird/WebContentView.h @@ -47,7 +47,7 @@ class WebContentView final , public WebView::ViewImplementation { Q_OBJECT public: - explicit WebContentView(StringView webdriver_content_ipc_path); + explicit WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling); virtual ~WebContentView() override; Function<String(Web::HTML::ActivateTab)> on_new_tab; @@ -185,7 +185,7 @@ signals: private: // ^WebView::ViewImplementation - virtual void create_client() override; + virtual void create_client(WebView::EnableCallgrindProfiling = WebView::EnableCallgrindProfiling::No) override; virtual void update_zoom() override; void request_repaint(); diff --git a/Ladybird/main.cpp b/Ladybird/main.cpp index 9ef3e088b3..2eb14608a7 100644 --- a/Ladybird/main.cpp +++ b/Ladybird/main.cpp @@ -67,11 +67,13 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) StringView raw_url; StringView webdriver_content_ipc_path; + bool enable_callgrind_profiling = false; Core::ArgsParser args_parser; args_parser.set_general_help("The Ladybird web browser :^)"); args_parser.add_positional_argument(raw_url, "URL to open", "url", Core::ArgsParser::Required::No); args_parser.add_option(webdriver_content_ipc_path, "Path to WebDriver IPC for WebContent", "webdriver-content-path", 0, "path"); + args_parser.add_option(enable_callgrind_profiling, "Enable Callgrind profiling", "enable-callgrind-profiling", 'P'); args_parser.parse(arguments); auto get_formatted_url = [&](StringView const& raw_url) -> ErrorOr<URL> { @@ -90,7 +92,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments) auto cookie_jar = TRY(Browser::CookieJar::create(*database)); s_settings = adopt_own_if_nonnull(new Browser::Settings()); - BrowserWindow window(cookie_jar, webdriver_content_ipc_path); + BrowserWindow window(cookie_jar, webdriver_content_ipc_path, enable_callgrind_profiling ? WebView::EnableCallgrindProfiling::Yes : WebView::EnableCallgrindProfiling::No); window.setWindowTitle("Ladybird"); window.resize(800, 600); window.show(); diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp index cee2b51ba1..52a1185550 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp @@ -59,7 +59,7 @@ void OutOfProcessWebView::handle_web_content_process_crash() load_html(builder.to_deprecated_string(), m_url); } -void OutOfProcessWebView::create_client() +void OutOfProcessWebView::create_client(EnableCallgrindProfiling) { m_client_state = {}; diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.h b/Userland/Libraries/LibWebView/OutOfProcessWebView.h index e521b29751..1e66ecd62c 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.h @@ -121,7 +121,7 @@ private: virtual void did_scroll() override; // ^WebView::ViewImplementation - virtual void create_client() override; + virtual void create_client(EnableCallgrindProfiling = EnableCallgrindProfiling::No) override; virtual void update_zoom() override; virtual void notify_server_did_layout(Badge<WebContentClient>, Gfx::IntSize content_size) override; virtual void notify_server_did_paint(Badge<WebContentClient>, i32 bitmap_id) override; diff --git a/Userland/Libraries/LibWebView/ViewImplementation.cpp b/Userland/Libraries/LibWebView/ViewImplementation.cpp index c77b8c27f9..0686544921 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.cpp +++ b/Userland/Libraries/LibWebView/ViewImplementation.cpp @@ -126,7 +126,7 @@ void ViewImplementation::run_javascript(StringView js_source) #if !defined(AK_OS_SERENITY) -ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths) +ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling enable_callgrind_profiling) { int socket_fds[2] {}; TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds)); @@ -149,15 +149,22 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web auto webcontent_fd_passing_socket_string = TRY(String::number(wc_fd_passing_fd)); - auto arguments = Array { - "WebContent"sv, - "--webcontent-fd-passing-socket"sv, - webcontent_fd_passing_socket_string - }; - ErrorOr<void> result; for (auto const& path : candidate_web_content_paths) { - result = Core::System::exec(path, arguments, Core::System::SearchInPath::Yes); + constexpr auto callgrind_prefix_length = 3; + auto arguments_with_callgrind_prefix = Array { + "valgrind"sv, + "--tool=callgrind"sv, + "--instr-atstart=no"sv, + path.bytes_as_string_view(), + "--webcontent-fd-passing-socket"sv, + webcontent_fd_passing_socket_string + }; + auto arguments = arguments_with_callgrind_prefix.span(); + if (enable_callgrind_profiling == EnableCallgrindProfiling::No) + arguments = arguments.slice(callgrind_prefix_length); + + result = Core::System::exec(arguments[0], arguments, Core::System::SearchInPath::Yes); if (!result.is_error()) break; } @@ -176,6 +183,13 @@ ErrorOr<NonnullRefPtr<WebView::WebContentClient>> ViewImplementation::launch_web auto new_client = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) WebView::WebContentClient(move(socket), *this))); new_client->set_fd_passing_socket(TRY(Core::LocalSocket::adopt_fd(ui_fd_passing_fd))); + if (enable_callgrind_profiling == EnableCallgrindProfiling::Yes) { + dbgln(); + dbgln("\033[1;45mLaunched WebContent process under callgrind!\033[0m"); + dbgln("\033[100mRun `\033[4mcallgrind_control -i on\033[24m` to start instrumentation and `\033[4mcallgrind_control -i off\033[24m` stop it again.\033[0m"); + dbgln(); + } + return new_client; } diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index 0aa276da80..a7342a3cb8 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -18,6 +18,12 @@ namespace WebView { +// Note: This only exists inside Serenity to avoid #ifdefs in all implementors of ViewImplementation. +enum class EnableCallgrindProfiling { + No, + Yes +}; + class ViewImplementation { public: virtual ~ViewImplementation() { } @@ -120,11 +126,12 @@ protected: WebContentClient& client(); WebContentClient const& client() const; - virtual void create_client() = 0; virtual void update_zoom() = 0; + virtual void create_client(EnableCallgrindProfiling = EnableCallgrindProfiling::No) {}; + #if !defined(AK_OS_SERENITY) - ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths); + ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content_process(ReadonlySpan<String> candidate_web_content_paths, EnableCallgrindProfiling = EnableCallgrindProfiling::No); #endif struct SharedBitmap { diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp index 2dfca6f1ee..8c6420aca6 100644 --- a/Userland/Utilities/headless-browser.cpp +++ b/Userland/Utilities/headless-browser.cpp @@ -157,7 +157,7 @@ private: void notify_server_did_finish_handling_input_event(bool) override { } void update_zoom() override { } - void create_client() override { } + void create_client(WebView::EnableCallgrindProfiling) override { } }; static ErrorOr<NonnullRefPtr<Core::Timer>> load_page_for_screenshot_and_exit(Core::EventLoop& event_loop, HeadlessWebContentView& view, int screenshot_timeout) |