CMake: Set -fvisibility-inlines-hidden on ELF platforms

The C++ semantics of `inline` dictate that such functions might be
defined in multiple translation units. As with all other functions, they
must have the same address in all TUs. Because of this, the compiler
emits `inline` functions as weak symbols, which the dynamic linker can
then resolve to the same address everywhere.

This rule is responsible for a significant overhead at startup, as such
lookups happen by name. Namely, 86'000 of the 114'000 by-name symbol
lookups when loading LibWeb can be attributed to this. Most of these
are only ever defined in a single object, making this even more
pointless.

As nothing in our code relies on either ELF symbol interposition rules
or function address equality, we can use the -fvisibility-inlines-hidden
escape hatch, which causes this rule to be disregarded. As the symbols
are now hidden, no load-time symbol lookup is needed. This flag is used
without issues in other large C++ codebases like Chromium and LLVM.

Some relevant light reading, suggested by Nico:
- https://ridiculousfish.com/blog/posts/i-didnt-order-that-so-why-is-it-on-my-bill-episode-1.html
- https://www.cs.dartmouth.edu/~sergey/cs258/ABI/UlrichDrepper-How-To-Write-Shared-Libraries.pdf
- https://blog.llvm.org/2018/11/30-faster-windows-builds-with-clang-cl_14.html
- https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-fvisibility-inlines-hidden
This commit is contained in:
Daniel Bertalan 2023-08-12 00:40:34 +02:00 committed by Andreas Kling
parent 2299fe1481
commit c0cf6e3744
3 changed files with 5 additions and 4 deletions

View file

@ -32,3 +32,8 @@ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# FIXME: This warning seems useful but has too many false positives with GCC 13.
add_compile_options(-Wno-dangling-reference)
endif()
if (UNIX AND NOT APPLE AND NOT ENABLE_FUZZERS)
add_compile_options(-fno-semantic-interposition)
add_compile_options(-fvisibility-inlines-hidden)
endif()

View file

@ -5,9 +5,6 @@ add_compile_options(-Wno-shorten-64-to-32)
add_compile_options(-fsigned-char)
add_compile_options(-g1)
add_compile_options(-O2)
if (NOT ENABLE_FUZZERS AND NOT APPLE)
add_compile_options(-fno-semantic-interposition)
endif()
if (NOT WIN32)
add_compile_options(-fPIC)
endif()

View file

@ -18,7 +18,6 @@ add_compile_options(-Wwrite-strings)
add_compile_options(-fno-delete-null-pointer-checks)
add_compile_options(-ffile-prefix-map=${SerenityOS_SOURCE_DIR}=.)
add_compile_options(-fno-semantic-interposition)
add_compile_options(-fsized-deallocation)
add_compile_options(-fstack-clash-protection)
add_compile_options(-fstack-protector-strong)