build: generate Electron-specific PGO profiles in CI#51812
Merged
Conversation
9162bca to
b74c74a
Compare
5 tasks
b610abd to
a185fbf
Compare
Adds a workflow_dispatch pipeline that builds PGO-instrumented Electron for every published platform/arch combo, collects optimization profiles by running benchmark and app-style workloads against each build, and publishes merged profiles to https://dev-cdn.electronjs.org/pgo/. Why: Electron release builds apply Chrome's published PGO profile, which matches functions by symbol name and control-flow hash. Every function that differs from Chrome - all of Node.js, patched Chromium code, V8 built with Node's flags, and the shell/ code - silently gets no optimization guidance and is laid out as cold. The same applies to V8's builtins profile: Chrome's published profiles reject Electron's promise/async builtins because the Node integration changes their codegen. Measured on Linux x64, an Electron-collected profile is worth +9.5% on Speedometer 3.1 and +16% geomean across 22 app-operation benchmarks (contextBridge calls +44-51%) versus Chrome's profile. The pipeline: - Instrumented builds (chrome_pgo_phase = 1) for linux x64/arm/arm64, win x64/x86/arm64, and macos x64/arm64, each collecting on hosts that can run its own binaries. - Collection workloads: Speedometer 3 (x3), JetStream 2, and MotionMark (the same set Chromium's PGO recipe uses), plus Electron-specific phases browser benchmarks cannot cover: main-process Node.js (Buffer/crypto/fs/JSON), contextBridge and ipcRenderer.invoke marshaling, and renderer/Node networking over HTTPS + HTTP/2 with real certificate verification via an ephemeral CA installed in the collection host's trust store. - A V8 builtins profile generated from an instrumented d8 built with Electron's exact V8 configuration; one x64 profile covers x64 and arm64 (builtin block graphs are arch-independent, mirroring upstream). - Per-platform profraw sets merged with in-tree llvm-profdata tooling, then uploaded via OIDC through the pgo-upload GitHub environment (manual approval, no long-lived credentials). Build-system changes: - build/args/pgo-instrument.gn and pgo-builtins-instrument.gn instrumented build configurations (symbol_level = 0, no dSYMs - instrumented binaries are never shipped and do not fit on macOS runners with debug info). - A Chromium patch fixing profile-runtime resolution for instrumented builds on Linux arm32 (clang package ships the armv7 triple; the driver resolves the arm triple) and Windows cross-compiles (objects embed the per-target runtime lib name; the Windows package ships the legacy layout). Chrome never builds these configurations; the patch is upstreamable. - generate-chromedriver and generate-test-artifacts flags on the build segment and build-electron action (default true, no behavior change for existing callers) so instrumented builds skip artifacts only consumed by test jobs. Release builds do not consume these profiles yet; that is a follow-up change.
a185fbf to
de338ac
Compare
jkleinsc
approved these changes
Jun 1, 2026
Member
Author
|
Merging this in to get PGOs cooking for backport branches. Please ping me directly if I missed something here. 🏃 |
|
No Release Notes |
Contributor
|
I have automatically backported this PR to "43-x-y", please check out #51825 |
Contributor
|
I have automatically backported this PR to "42-x-y", please check out #51826 |
dsanders11
reviewed
Jun 1, 2026
| # JetStream 2.2 at the same pinned revision the browser collection uses. | ||
| git init /tmp/jetstream | ||
| git -C /tmp/jetstream remote add origin https://github.com/WebKit/JetStream.git | ||
| git -C /tmp/jetstream fetch --quiet --depth 1 origin 332d8ee1e4d5c40d9492c56f6865e64a9525ee9f |
Member
There was a problem hiding this comment.
If it's important to keep this in-sync with the the revision in script/pgo/serve-benchmarks.js, we should put it in a single place and plumb it through to both spots.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of Change
Adds a manually-triggered (
workflow_dispatch) pipeline that builds PGO-instrumented Electron for every published platform/arch combo, collects optimization profiles by running benchmark and app-style workloads against each build, and publishes merged profiles tohttps://dev-cdn.electronjs.org/pgo/.Why Electron needs its own profiles
Electron release builds apply Chrome's published PGO profile (
chrome_pgo_phase = 2). PGO profiles match functions by symbol name + control-flow hash, so every function that differs from Chrome — all of Node.js, patched Chromium code, V8 built with Node's flags, and theshell/code itself — silently gets no optimization guidance and is laid out as cold. The same applies to V8's builtins profile: Chrome's published profiles reject Electron's promise/async builtins (RunMicrotasks,AsyncFunctionAwait,FulfillPromise, …) because Node's integration changes their codegen.Measured impact of replacing Chrome's profile with an Electron-collected one (Linux x64, otherwise identical builds):
ipcRenderer.invoke(5 MB payloads)fetch()round-tripscrypto.randomBytesWhat the pipeline does
ipcRenderer.invokemarshaling, and renderer/Node networking over HTTPS + HTTP/2 with real certificate verification (an ephemeral CA is installed in the collection host's trust store)pgo-uploadGitHub environment (manual approval) and authenticated via OIDC — no long-lived credentials. Infra side: electron/infra#287 (merged)Build-system changes
build/args/pgo-instrument.gn/pgo-builtins-instrument.gn— instrumented build configurationsgenerate-chromedriver/generate-test-artifactsflags on the build segment (defaulttrue, no behavior change for existing callers) — instrumented builds skip artifacts only consumed by test jobs, saving ~10–20 min and ~700–950 MB per platformWhat this PR does not do
Release builds do not consume these profiles yet — that's a follow-up PR (download profile + set
pgo_data_path/v8_builtins_profiling_log_file). This PR only adds the generation side.The pipeline was validated end-to-end on this branch's history: 13 full runs, with the final runs producing all 8 platform profiles + the builtins profile and uploading them to dev-cdn through the OIDC environment.
Checklist
npm testpassesRelease Notes
Notes: none