From c0cf6e3744ac1190ca735d1de8974df1fa90b511 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sat, 12 Aug 2023 00:40:34 +0200 Subject: [PATCH] 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 --- Meta/CMake/common_compile_options.cmake | 5 +++++ Meta/CMake/lagom_compile_options.cmake | 3 --- Meta/CMake/serenity_compile_options.cmake | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Meta/CMake/common_compile_options.cmake b/Meta/CMake/common_compile_options.cmake index 410273bc95..0acf0cd0cb 100644 --- a/Meta/CMake/common_compile_options.cmake +++ b/Meta/CMake/common_compile_options.cmake @@ -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() diff --git a/Meta/CMake/lagom_compile_options.cmake b/Meta/CMake/lagom_compile_options.cmake index f65b48b5c2..7be594b6bd 100644 --- a/Meta/CMake/lagom_compile_options.cmake +++ b/Meta/CMake/lagom_compile_options.cmake @@ -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() diff --git a/Meta/CMake/serenity_compile_options.cmake b/Meta/CMake/serenity_compile_options.cmake index 1680b0fa9d..1c94e0c999 100644 --- a/Meta/CMake/serenity_compile_options.cmake +++ b/Meta/CMake/serenity_compile_options.cmake @@ -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)