diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d04760331e..277d9c09207 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ STATIC_BUILD_WITH_DYNAMIC_STDLIB." OFF) OPTION (STATIC_BUILD_WITH_DYNAMIC_STDLIB "Build a (mostly) statically linked release binary. \ Glibc and C++ standard library is linked dynamically." OFF) -if (STATIC_BUILD_WITH_DYNAMIC_GLIBC OR STATIC_BUILD_WITH_DYNAMIC_STDLIB) +if (STATIC_BUILD_WITH_DYNAMIC_GLIBC OR STATIC_BUILD_WITH_DYNAMIC_STDLIB OR CMAKE_INTERPROCEDURAL_OPTIMIZATION) # We want to optimize the binary size for a static release binary by default. set (_ENABLE_LTO_DEFAULT ON) else() diff --git a/lib/gc.cpp b/lib/gc.cpp index 656fba83fae..2ab529e6db2 100644 --- a/lib/gc.cpp +++ b/lib/gc.cpp @@ -81,6 +81,33 @@ static void maybe_initialize_gc() { } } +#ifdef __GLIBC__ +#define GNOEXCEPT __THROW +#else +#define GNOEXCEPT +#endif +void *operator new(std::size_t size) __attribute__((used)); +void *operator new(std::size_t size, const std::nothrow_t &) noexcept __attribute__((used)); +void *operator new(std::size_t size, std::align_val_t alignment) __attribute__((used)); +void *operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t &) noexcept __attribute__((used)); +void operator delete(void *p) noexcept __attribute__((used)); +void operator delete(void *p, std::size_t /*size*/) noexcept __attribute__((used)); +void operator delete(void *p, std::size_t, std::align_val_t) noexcept __attribute__((used)); +void *operator new[](std::size_t size) __attribute__((used)); +void *operator new[](std::size_t size, std::align_val_t alignment) __attribute__((used)); +void *operator new[](std::size_t size, const std::nothrow_t &tag) noexcept __attribute__((used)); +void *operator new[](std::size_t size, std::align_val_t alignment, + const std::nothrow_t &tag) noexcept __attribute__((used)); +void operator delete[](void *p) noexcept __attribute__((used)); +void operator delete[](void *p, std::size_t) noexcept __attribute__((used)); +void operator delete[](void *p, std::align_val_t) noexcept __attribute__((used)); +void operator delete[](void *p, std::size_t, std::align_val_t) noexcept __attribute__((used)); +void *realloc(void *ptr, size_t size) GNOEXCEPT __attribute__((used)); +void *malloc(size_t size) GNOEXCEPT __attribute__((used)); +void free(void *ptr) GNOEXCEPT __attribute__((used)); +void *calloc(size_t size, size_t elsize) GNOEXCEPT __attribute__((used)); +int posix_memalign(void **memptr, size_t alignment, size_t size) GNOEXCEPT __attribute__((used)); + void *operator new(std::size_t size) { TRACE_ALLOC(size) @@ -226,7 +253,7 @@ void raw_free(void *ptr) { } // namespace -void *realloc(void *ptr, size_t size) { +void *realloc(void *ptr, size_t size) GNOEXCEPT { if (!done_init) { if (started_init) { // called from within GC_INIT, so we can't call it again. Fall back to using @@ -259,16 +286,16 @@ void *realloc(void *ptr, size_t size) { // IMPORTANT: do not simplify this to realloc(nullptr, size) // As it could be optimized to malloc(size) call causing // infinite loops -void *malloc(size_t size) { +void *malloc(size_t size) GNOEXCEPT { if (!done_init) return realloc(nullptr, size); TRACE_ALLOC(size) return GC_malloc(size); } -void free(void *ptr) { +void free(void *ptr) GNOEXCEPT { if (done_init && GC_is_heap_ptr(ptr)) GC_free(ptr); } -void *calloc(size_t size, size_t elsize) { +void *calloc(size_t size, size_t elsize) GNOEXCEPT { size *= elsize; void *rv = malloc(size); if (rv) memset(rv, 0, size);