summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2023-04-15 01:04:28 +0100
committerAndreas Kling <kling@serenityos.org>2023-04-15 06:37:51 +0200
commit0329ddf46a0d24303fac5954bf3c70d5f3fe577c (patch)
tree83ca60d767bfde06438e191fe4b0a4c7b0da10aa
parent5db1eb996173b34960f48c7ea8ce4fd33acde157 (diff)
downloadserenity-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.cpp6
-rw-r--r--Ladybird/BrowserWindow.h3
-rw-r--r--Ladybird/Tab.cpp4
-rw-r--r--Ladybird/Tab.h2
-rw-r--r--Ladybird/WebContentView.cpp8
-rw-r--r--Ladybird/WebContentView.h4
-rw-r--r--Ladybird/main.cpp4
-rw-r--r--Userland/Libraries/LibWebView/OutOfProcessWebView.cpp2
-rw-r--r--Userland/Libraries/LibWebView/OutOfProcessWebView.h2
-rw-r--r--Userland/Libraries/LibWebView/ViewImplementation.cpp30
-rw-r--r--Userland/Libraries/LibWebView/ViewImplementation.h11
-rw-r--r--Userland/Utilities/headless-browser.cpp2
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)