MarshallOfSound

#51812: build: generate Electron-specific PGO profiles in CI

Merged
Created: May 31, 2026, 9:48:59 AM
Merged: Jun 1, 2026, 2:34:05 PM
4 comments
Target: main

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 to https://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 the shell/ 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):

Workload Improvement
Speedometer 3.1 +9.5%
contextBridge calls +44–51%
ipcRenderer.invoke (5 MB payloads) +10%
renderer fetch() round-trips +31–35%
Node crypto.randomBytes +13% (recovers a 2× regression vs Electron 42 caused by Chrome-profile mismatch on patched BoringSSL)
Geomean of 22 app-operation benchmarks +16%

What the pipeline does

8x instrumented builds          1x instrumented d8
(chrome_pgo_phase = 1)          (v8_enable_builtins_profiling)
        |                                |
        v                                v
8x profile collection            JetStream 2 -> get_hints.py
(benchmarks + app workloads)             |
        |                                |
        v                                v
merge (llvm-profdata)            electron-v8-x64.profile
        |                                |
        +----------------+---------------+
                         v
     OIDC upload -> dev-cdn.electronjs.org/pgo/
  • Platforms: linux x64/arm/arm64, win x64/x86/arm64, macos x64/arm64 — each combo collects on hardware/containers that can run its own binaries (matching how Chrome generates per-arch profiles)
  • Collection workloads: Speedometer 3 (×3), JetStream 2, MotionMark — the same set Chromium's PGO recipe uses — plus Electron-specific phases that browser benchmarks can't cover: main-process Node.js (Buffer/crypto/fs/JSON), contextBridge + ipcRenderer.invoke marshaling, and renderer/Node networking over HTTPS + HTTP/2 with real certificate verification (an ephemeral CA is installed in the collection host's trust store)
  • V8 builtins profile: generated from an instrumented d8 built with Electron's exact V8 configuration; one x64 profile covers x64 + arm64 (block graphs are arch-independent, mirroring upstream)
  • Upload: gated behind the pgo-upload GitHub 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 configurations
  • New Chromium patch fixing profile-runtime resolution for instrumented builds on Linux arm32 and Windows cross-compiles (upstreamable; Chrome never builds these configurations)
  • generate-chromedriver / generate-test-artifacts flags on the build segment (default true, no behavior change for existing callers) — instrumented builds skip artifacts only consumed by test jobs, saving ~10–20 min and ~700–950 MB per platform

What 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

  • I have built and tested this change
  • I have filled out the PR description
  • I have reviewed and verified the changes
  • npm test passes
  • PR release notes describe the change in a way relevant to app developers

Release Notes

Notes: none

Backports

42-x-y
Merged
PR Number
#51826
Merged At
Jun 1, 2026, 2:54:23 PM
Released In
v42.3.1
Release Date
Jun 1, 2026, 11:25:56 PM
43-x-y
Merged
PR Number
#51825
Merged At
Jun 1, 2026, 2:54:26 PM
Released In
v43.0.0-beta.1
Release Date
Jun 4, 2026, 3:31:55 PM

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

Semantic Versioning helps users understand the impact of updates:

  • Major (X.y.z): Breaking changes that may require code modifications
  • Minor (x.Y.z): New features that maintain backward compatibility
  • Patch (x.y.Z): Bug fixes that don't change the API
  • None: Changes that don't affect using facing parts of Electron