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
Not yet
Release Date
Not yet
43-x-y
Merged
PR Number
#51825
Merged At
Jun 1, 2026, 2:54:26 PM
Released In
Not yet
Release Date
Not yet

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