Skip to content

build: re-enable ThinLTO on macOS#51669

Merged
jkleinsc merged 2 commits into
mainfrom
fix/reland-thin-lto-mac
Jun 1, 2026
Merged

build: re-enable ThinLTO on macOS#51669
jkleinsc merged 2 commits into
mainfrom
fix/reland-thin-lto-mac

Conversation

@ckerr

@ckerr ckerr commented May 16, 2026

Copy link
Copy Markdown
Member

Description of Change

Fixes #44632.

Re-enable ThinLTO on macOS. Add a new patch to ensure N-API entry points aren't stripped by ThinLTO by copying the __attribute__((used)) approach from nodejs/node#49037 .

All reviews welcomed; CC @VerteDinde as a stakeholder for opening 44632

Checklist

Release Notes

Notes: Enabled ThinLTO on macOS builds.

@ckerr ckerr requested a review from a team as a code owner May 16, 2026 23:02
@ckerr ckerr marked this pull request as draft May 16, 2026 23:02
@ckerr ckerr force-pushed the fix/reland-thin-lto-mac branch from 3bc4823 to 9a99741 Compare May 16, 2026 23:07
@ckerr ckerr added target/42-x-y PR should also be added to the "42-x-y" branch. target/43-x-y PR should also be added to the "43-x-y" branch. target/41-x-y PR should also be added to the "41-x-y" branch. labels May 17, 2026
@ckerr ckerr marked this pull request as ready for review May 17, 2026 17:44
@deepak1556

Copy link
Copy Markdown
Member

Could you trigger a release build from this branch before merging for verification, thanks!

@ckerr ckerr marked this pull request as draft May 19, 2026 00:23
@ckerr

ckerr commented May 19, 2026

Copy link
Copy Markdown
Member Author

Re-enabling ThinLTO on macOS is surfacing a new issue for header-only classes with vtables. I need to fix this & then I'll mark this as ready for review again.

ckerr and others added 2 commits May 30, 2026 19:14
Re-enable ThinLTO on macOS. Add a patch to the bundled Node.js source
that anchors weak vtables and N-API entry points so they survive
clang's -fwhole-program-vtables under ThinLTO. See the patch's commit
message for details.
The previous approach (out-of-line member definitions plus explicit
template instantiations) still produces weak_odr vtables, which Mach-O
ThinLTO localizes during code generation even when other LTO partitions
reference them. This breaks the link of executables that link libnode
(electron_natives_codecache, node_mksnapshot) with undefined vtable
symbol errors.

Replace that part of the node patch with explicit specializations of
the affected instantiations:

  - StaticExternalByteResource<uint8_t, char, ExternalOneByteStringResource>
  - StaticExternalByteResource<uint16_t, uint16_t, ExternalStringResource>
  - NgRcBufPointer<Http2RcBufferPointerTraits>::External

An explicit specialization is an ordinary class that can have a key
function (an out-of-line destructor), so its vtable is a strong symbol
that LTO must keep external. The primary templates and all user code
are unchanged, and no linker or compiler optimizations are disabled.

The non-template fixes (MemoryRetainerNode, JSGraphJSNode key
functions) and the N-API __attribute__((used)) changes are kept as-is.
@MarshallOfSound MarshallOfSound force-pushed the fix/reland-thin-lto-mac branch from e66dbe9 to e82171a Compare May 31, 2026 03:25
@MarshallOfSound MarshallOfSound marked this pull request as ready for review May 31, 2026 03:25
@MarshallOfSound

Copy link
Copy Markdown
Member

Rebased onto main and reworked the template vtable part of the node patch - explicit instantiations still produce weak_odr vtables which lld-macho localizes during LTO codegen, so the new libnode-linking executables (electron_natives_codecache, node_mksnapshot) failed to link with the same undefined vtable errors. Replaced them with explicit specializations + out-of-line destructors so the vtables are strong symbols, same trick as your MemoryRetainerNode fix. The napi __attribute__((used)) and key function changes are untouched.

Full arm64 release build is green locally - framework links, napi symbols all survive, app boots.

@deepak1556 deepak1556 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A way to reduce patch churn would be to upstream thin lto support for macOS, Node.js already got windows support via nodejs/node#61964

@jkleinsc jkleinsc merged commit 39c5071 into main Jun 1, 2026
126 of 128 checks passed
@jkleinsc jkleinsc deleted the fix/reland-thin-lto-mac branch June 1, 2026 14:21
@release-clerk

release-clerk Bot commented Jun 1, 2026

Copy link
Copy Markdown

Release Notes Persisted

Enabled ThinLTO on macOS builds.

@trop

trop Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

I was unable to backport this PR to "42-x-y" cleanly;
you will need to perform this backport manually.

@trop

trop Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

I was unable to backport this PR to "41-x-y" cleanly;
you will need to perform this backport manually.

@trop trop Bot added needs-manual-bp/42-x-y needs-manual-bp/41-x-y and removed target/42-x-y PR should also be added to the "42-x-y" branch. target/41-x-y PR should also be added to the "41-x-y" branch. labels Jun 1, 2026
@trop

trop Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

I have automatically backported this PR to "43-x-y", please check out #51819

@trop trop Bot added in-flight/43-x-y merged/43-x-y PR was merged to the "43-x-y" branch. and removed target/43-x-y PR should also be added to the "43-x-y" branch. in-flight/43-x-y labels Jun 1, 2026
@trop

trop Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

@MarshallOfSound has manually backported this PR to "42-x-y", please check out #51823

MarshallOfSound added a commit that referenced this pull request Jun 1, 2026
* build: re-enable ThinLTO on macOS (#51669)

* build: re-enable ThinLTO on macOS

Re-enable ThinLTO on macOS. Add a patch to the bundled Node.js source
that anchors weak vtables and N-API entry points so they survive
clang's -fwhole-program-vtables under ThinLTO. See the patch's commit
message for details.

* build: anchor node template vtables with explicit specializations

The previous approach (out-of-line member definitions plus explicit
template instantiations) still produces weak_odr vtables, which Mach-O
ThinLTO localizes during code generation even when other LTO partitions
reference them. This breaks the link of executables that link libnode
(electron_natives_codecache, node_mksnapshot) with undefined vtable
symbol errors.

Replace that part of the node patch with explicit specializations of
the affected instantiations:

  - StaticExternalByteResource<uint8_t, char, ExternalOneByteStringResource>
  - StaticExternalByteResource<uint16_t, uint16_t, ExternalStringResource>
  - NgRcBufPointer<Http2RcBufferPointerTraits>::External

An explicit specialization is an ordinary class that can have a key
function (an out-of-line destructor), so its vtable is a strong symbol
that LTO must keep external. The primary templates and all user code
are unchanged, and no linker or compiler optimizations are disabled.

The non-template fixes (MemoryRetainerNode, JSGraphJSNode key
functions) and the N-API __attribute__((used)) changes are kept as-is.

---------

Co-authored-by: Samuel Attard <sam@electronjs.org>

* chore: update patches

---------

Co-authored-by: Charles Kerr <charles@charleskerr.com>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
@trop trop Bot added merged/42-x-y PR was merged to the "42-x-y" branch. and removed in-flight/42-x-y labels Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged/42-x-y PR was merged to the "42-x-y" branch. merged/43-x-y PR was merged to the "43-x-y" branch. needs-manual-bp/41-x-y semver/none

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Upgrades Follow Up]: re-enable thin LTO on Mac release builds

4 participants