try building with -fno-omit-frame-pointer -momit-leaf-frame-pointer

The idea is -momit-leaf-frame-pointer gives us performance pretty much
same as fully omitting frame pointers. And having frame pointers
elsewhere allows us to support cases when user's code is built with
frame pointers. We also pass all tests with
TCMALLOC_STACKTRACE_METHOD=generic_fp (not just libunwind or libgcc).
This commit is contained in:
Aliaksey Kandratsenka 2023-07-02 19:35:46 -04:00
parent e5ac219780
commit 4b78ffd03c
4 changed files with 42 additions and 81 deletions

View File

@ -249,17 +249,25 @@ if(gperftools_enable_libunwind)
endif()
endif()
# On x86_64, we know that default is to omit frame pointer.
if(x86_64)
set(omit_fp_by_default ON)
endif()
# See if the compiler supports -Wno-unused-result.
# Newer ubuntu's turn on -D_FORTIFY_SOURCE=2, enabling
# __attribute__((warn_unused_result)) for things like write(),
# which we don't care about.
check_c_compiler_flag("-Wno-unused-result" have_w_no_unused_result)
check_c_compiler_flag("-fno-omit-frame-pointer -momit-leaf-frame-pointer" have_omit_leaf_fp)
check_c_source_compiles("
#if !(__i386__ || __x86_64__ || __riscv || __aarch64__)
#error unsupported arch
#endif
int main() { return 0; }
"
use_omit_leaf_fp)
if (use_omit_leaf_fp)
add_compile_options(-fno-omit-frame-pointer -momit-leaf-frame-pointer)
endif()
option(gperftools_dynamic_sized_delete_support
"Try to build run-time switch for sized delete operator"
OFF)
@ -438,26 +446,6 @@ if(GPERFTOOLS_BUILD_CPU_PROFILER OR
set(WITH_STACK_TRACE ON)
endif()
# The following matters only if we're not using libunwind and if we
# care about backtrace capturing, and frame pointers are not available
# to capture backtraces. The idea is to warn user about less stable or
# known bad configurations (e.g. encourage to install libunwind).
if (NOT unwind_libs AND NOT gperftools_build_minimal AND
omit_fp_by_default AND NOT gperftools_enable_frame_pointers)
if(HAVE_UNWIND_BACKTRACE)
message(WARNING "No frame pointers and no libunwind. "
"Using experimental backtrace capturing via libgcc. "
"Expect crashy cpu profiler.")
elseif(gperftools_enable_stacktrace_via_backtrace)
message(WARNING "No frame pointers and no libunwind. "
"Using experimental backtrace(). "
"Expect crashy cpu profiler.")
else()
message(FATAL_ERROR "No frame pointers and no libunwind. "
"The compilation will fail.")
endif()
endif()
# Based on Makefile.am
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
@ -472,13 +460,6 @@ endif()
# These are good warnings to turn on by default.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare")
# x86-es (starting from gcc-4.6 as per earlier comment) have
# -momit-leaf-frame-pointer by default. And on i386 we "traditionally"
# used to re-enable frame pointers. So lets keep doing it.
if(i386)
add_compile_options(-fno-omit-frame-pointer)
endif()
endif()
if(have_w_no_unused_result)
@ -502,11 +483,7 @@ option(
OFF)
if(gperftools_enable_frame_pointers)
add_compile_options(-fno-omit-frame-pointer)
endif()
if(omit_fp_by_default AND NOT gperftools_enable_frame_pointers)
add_compile_definitions(NO_FRAME_POINTER)
add_compile_options(-fno-omit-frame-pointer -DFORCED_FRAME_POINTERS)
endif()
# For windows systems (at least, mingw), we need to tell all our

View File

@ -22,14 +22,12 @@ AM_CXXFLAGS =
if GCC
AM_CXXFLAGS += -Wall -Wwrite-strings -Woverloaded-virtual \
-Wno-sign-compare
# x86-es (starting from gcc-4.6 as per earlier comment) have
# -momit-leaf-frame-pointer by default. And on i386 we "traditionally"
# used to re-enable frame pointers. So lets keep doing it.
if I386
AM_CXXFLAGS += -fno-omit-frame-pointer
endif I386
endif GCC
if ENABLE_FP_FLAGS
AM_CXXFLAGS += -fno-omit-frame-pointer -momit-leaf-frame-pointer
endif
if HAVE_W_NO_UNUSED_RESULT
AM_CXXFLAGS += -Wno-unused-result
endif HAVE_W_NO_UNUSED_RESULT
@ -44,19 +42,9 @@ endif HAVE_F_ALIGNED_NEW
# Cygwin and MinGW. LIBSTDCXX_LA_LINKER_FLAG is used to fix a Solaris bug.
AM_LDFLAGS = -no-undefined $(LIBSTDCXX_LA_LINKER_FLAG)
# These are x86-specific, having to do with frame-pointers. In
# particular, some x86_64 systems do not insert frame pointers by
# default (all i386 systems that I know of, do. I don't know about
# non-x86 chips). We need to tell perftools what to do about that.
if OMIT_FP_BY_DEFAULT
if !ENABLE_FRAME_POINTERS
AM_CXXFLAGS += -DNO_FRAME_POINTER
endif !ENABLE_FRAME_POINTERS
endif OMIT_FP_BY_DEFAULT
# respect --enable-frame-pointers regardless of architecture
if ENABLE_FRAME_POINTERS
AM_CXXFLAGS += -fno-omit-frame-pointer
AM_CXXFLAGS += -fno-omit-frame-pointer -DFORCED_FRAME_POINTERS
endif ENABLE_FRAME_POINTERS
# For windows systems (at least, mingw), we need to tell all our

View File

@ -206,6 +206,27 @@ AM_CONDITIONAL(HAVE_OBJCOPY_WEAKEN, test $gpt_cv_objcopy_weaken = yes)
LT_INIT
# Lets try enable frame pointers to enable simpler stacktrace
# capturing methods, but keep performace for critical bits with
# -momit-leaf-frame-pointer. However, we should be conservative so
# that we don't disable leaf frame pointers on whatever architectures
# that have them enabled by default.
AC_CACHE_CHECK(
[compiler and target supports -fno-omit-frame-pointer -momit-leaf-frame-pointer],
[ac_cv_frame_pointer_cflags],
[OLD_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer -momit-leaf-frame-pointer"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
#if !(__i386__ || __x86_64__ || __riscv || __aarch64__)
#error unsupported arch
#endif
)],
[ac_cv_frame_pointer_cflags=yes],
[ac_cv_frame_pointer_cflags=no])
CXXFLAGS="$OLD_CXXFLAGS"])
AM_CONDITIONAL(ENABLE_FP_FLAGS, [test "x$ac_cv_frame_pointer_cflags" = "xyes"])
AX_C___ATTRIBUTE__
AC_MSG_CHECKING(for __attribute__((aligned(N))) on functions)
@ -297,28 +318,12 @@ if test "$enable_libunwind" = yes; then
fi
AC_SUBST(UNWIND_LIBS)
# On x86_64, instead of libunwind, we can choose to compile with frame-pointers.
AC_ARG_ENABLE(frame_pointers,
AS_HELP_STRING([--enable-frame-pointers],
[On x86_64 systems, compile with -fno-omit-frame-pointer (see INSTALL)]),
[Add -fno-omit-frame-pointer to compile flags]),
, enable_frame_pointers=no)
AM_CONDITIONAL(ENABLE_FRAME_POINTERS, test "$enable_frame_pointers" = yes)
AC_MSG_CHECKING([for x86 without frame pointers])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
[is_x86_64=yes], [is_x86_64=no])
omit_fp_by_default=no
AS_IF([test "$is_x86_64" = yes], [omit_fp_by_default=yes])
AM_CONDITIONAL(OMIT_FP_BY_DEFAULT,
test "$omit_fp_by_default" = yes)
AC_MSG_RESULT([$omit_fp_by_default])
# We need to know if we're i386 so we can turn on -mmms, which is not
# on by default for i386 (it is for x86_64).
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __i386__ == 1 ? 0 : 1])],
[is_i386=yes], [is_i386=no])
AM_CONDITIONAL(I386, test "$is_i386" = yes)
# See if the compiler supports -Wno-unused-result.
# Newer ubuntu's turn on -D_FORTIFY_SOURCE=2, enabling
# __attribute__((warn_unused_result)) for things like write(),
@ -662,10 +667,3 @@ AS_IF([test "x$enable_aggressive_decommit_by_default" = xyes],
AC_CONFIG_FILES([Makefile
src/gperftools/tcmalloc.h src/windows/gperftools/tcmalloc.h])
AC_OUTPUT
AS_IF([test "$omit_fp_by_default" = yes && test "x$enable_frame_pointers" != xyes && test "x$UNWIND_LIBS" = x && test "x$enable_minimal" != xyes],
[AS_IF([test "x$perftools_cv_have_unwind_backtrace" = xyes],
[AC_MSG_WARN([No frame pointers and no libunwind. Using experimental backtrace capturing via libgcc. Expect crashy cpu profiler.])],
[AS_IF([test "x$enable_backtrace" = xyes],
[AC_MSG_WARN([No frame pointers and no libunwind. Using experimental backtrace(). Expect crashy cpu profiler.])],
[AC_MSG_FAILURE([No frame pointers and no libunwind. The compilation will fail])])])])

View File

@ -1461,7 +1461,6 @@ static SpinLock alignment_checker_lock(SpinLock::LINKER_INITIALIZED);
}
if (size < sizeof(void*)) continue;
#ifdef NO_FRAME_POINTER
// Frame pointer omission requires us to use libunwind, which uses direct
// mmap and munmap system calls, and that needs special handling.
if (name2 == kUnnamedProcSelfMapEntry) {
@ -1483,7 +1482,6 @@ static SpinLock alignment_checker_lock(SpinLock::LINKER_INITIALIZED);
}
}
}
#endif
const char* const max_object = object + size - sizeof(void*);
while (object <= max_object) {