Repository: electron/electron
Pull request: perf: enable V8 builtins PGO

Backport of #50416

See that PR for details.


Notes: Enabled profile-guided optimization for V8 builtins in release builds, improving JavaScript builtin performance (Array, String, RegExp, etc.).

Changed files:
filename: .github/actions/build-electron/action.yml
patch: @@ -125,6 +125,9 @@ runs:
         fi
         sed $SEDOPTION '/.*builtins-pgo/d' out/Default/mksnapshot_args
         sed $SEDOPTION '/--turbo-profiling-input/d' out/Default/mksnapshot_args
+        sed $SEDOPTION '/--reorder-builtins/d' out/Default/mksnapshot_args
+        sed $SEDOPTION '/--warn-about-builtin-profile-data/d' out/Default/mksnapshot_args
+        sed $SEDOPTION '/--abort-on-bad-builtin-profile-data/d' out/Default/mksnapshot_args
 
         if [ "${{ inputs.target-platform }}" = "win" ]; then
           cd out/Default

filename: build/args/all.gn
patch: @@ -51,9 +51,6 @@ is_cfi = false
 use_qt5 = false
 use_qt6 = false
 
-# Disables the builtins PGO for V8
-v8_builtins_profiling_log_file = ""
-
 # https://chromium.googlesource.com/chromium/src/+/main/docs/dangling_ptr.md
 # TODO(vertedinde): hunt down dangling pointers on Linux
 enable_dangling_raw_ptr_checks = false

filename: patches/v8/.patches
patch: @@ -1 +1,2 @@
 chore_allow_customizing_microtask_policy_per_context.patch
+build_warn_instead_of_abort_on_builtin_pgo_profile_mismatch.patch

filename: patches/v8/build_warn_instead_of_abort_on_builtin_pgo_profile_mismatch.patch
patch: @@ -0,0 +1,35 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Sam Attard <sattard@anthropic.com>
+Date: Sun, 22 Mar 2026 10:51:26 +0000
+Subject: build: warn instead of abort on builtin PGO profile mismatch
+
+Electron sets v8_enable_javascript_promise_hooks = true to support
+Node.js async_hooks (see node/src/env.cc SetPromiseHooks usage:
+https://github.com/nodejs/node/blob/abff716eaccd0c4f4949d1315cb057a45979649d/src/env.cc#L223-L236).
+This flag adds conditional branches to builtins-microtask-queue-gen.cc
+and promise-misc.tq, changing the control-flow graph hash of several
+Promise/async builtins. This invalidates V8's pre-generated PGO profile
+for those builtins (built with Chrome defaults where the flag is off).
+
+Rather than disabling builtins PGO entirely, warn and skip mismatched
+builtins so all other builtins still benefit from PGO.
+
+diff --git a/BUILD.gn b/BUILD.gn
+index 15de2179a0e5ce50d5c659a9d15a920c50124c3e..9fb3a69450bdcab42c2571e8b1f57c4f3c283d9a 100644
+--- a/BUILD.gn
++++ b/BUILD.gn
+@@ -2764,9 +2764,11 @@ template("run_mksnapshot") {
+         "--turbo-profiling-input",
+         rebase_path(v8_builtins_profiling_log_file, root_build_dir),
+ 
+-        # Replace this with --warn-about-builtin-profile-data to see the full
+-        # list of builtins with incompatible profiles.
+-        "--abort-on-bad-builtin-profile-data",
++        # Electron: Use warn instead of abort so that builtins whose control
++        # flow is changed by Electron's build flags (e.g. RunMicrotasks via
++        # v8_enable_javascript_promise_hooks) are skipped rather than failing
++        # the build. All other builtins still receive PGO.
++        "--warn-about-builtin-profile-data",
+       ]
+ 
+       if (!v8_enable_builtins_profiling && v8_enable_builtins_reordering) {