Path: blob/main/contrib/jemalloc/src/jemalloc_cpp.cpp
39536 views
#include <mutex>1#include <new>23#define JEMALLOC_CPP_CPP_4#ifdef __cplusplus5extern "C" {6#endif78#include "jemalloc/internal/jemalloc_preamble.h"9#include "jemalloc/internal/jemalloc_internal_includes.h"1011#ifdef __cplusplus12}13#endif1415// All operators in this file are exported.1617// Possibly alias hidden versions of malloc and sdallocx to avoid an extra plt18// thunk?19//20// extern __typeof (sdallocx) sdallocx_int21// __attribute ((alias ("sdallocx"),22// visibility ("hidden")));23//24// ... but it needs to work with jemalloc namespaces.2526void *operator new(std::size_t size);27void *operator new[](std::size_t size);28void *operator new(std::size_t size, const std::nothrow_t &) noexcept;29void *operator new[](std::size_t size, const std::nothrow_t &) noexcept;30void operator delete(void *ptr) noexcept;31void operator delete[](void *ptr) noexcept;32void operator delete(void *ptr, const std::nothrow_t &) noexcept;33void operator delete[](void *ptr, const std::nothrow_t &) noexcept;3435#if __cpp_sized_deallocation >= 20130936/* C++14's sized-delete operators. */37void operator delete(void *ptr, std::size_t size) noexcept;38void operator delete[](void *ptr, std::size_t size) noexcept;39#endif4041#if __cpp_aligned_new >= 20160642/* C++17's over-aligned operators. */43void *operator new(std::size_t size, std::align_val_t);44void *operator new(std::size_t size, std::align_val_t, const std::nothrow_t &) noexcept;45void *operator new[](std::size_t size, std::align_val_t);46void *operator new[](std::size_t size, std::align_val_t, const std::nothrow_t &) noexcept;47void operator delete(void* ptr, std::align_val_t) noexcept;48void operator delete(void* ptr, std::align_val_t, const std::nothrow_t &) noexcept;49void operator delete(void* ptr, std::size_t size, std::align_val_t al) noexcept;50void operator delete[](void* ptr, std::align_val_t) noexcept;51void operator delete[](void* ptr, std::align_val_t, const std::nothrow_t &) noexcept;52void operator delete[](void* ptr, std::size_t size, std::align_val_t al) noexcept;53#endif5455JEMALLOC_NOINLINE56static void *57handleOOM(std::size_t size, bool nothrow) {58if (opt_experimental_infallible_new) {59safety_check_fail("<jemalloc>: Allocation failed and "60"opt.experimental_infallible_new is true. Aborting.\n");61return nullptr;62}6364void *ptr = nullptr;6566while (ptr == nullptr) {67std::new_handler handler;68// GCC-4.8 and clang 4.0 do not have std::get_new_handler.69{70static std::mutex mtx;71std::lock_guard<std::mutex> lock(mtx);7273handler = std::set_new_handler(nullptr);74std::set_new_handler(handler);75}76if (handler == nullptr)77break;7879try {80handler();81} catch (const std::bad_alloc &) {82break;83}8485ptr = je_malloc(size);86}8788if (ptr == nullptr && !nothrow)89std::__throw_bad_alloc();90return ptr;91}9293template <bool IsNoExcept>94JEMALLOC_NOINLINE95static void *96fallback_impl(std::size_t size) noexcept(IsNoExcept) {97void *ptr = malloc_default(size);98if (likely(ptr != nullptr)) {99return ptr;100}101return handleOOM(size, IsNoExcept);102}103104template <bool IsNoExcept>105JEMALLOC_ALWAYS_INLINE106void *107newImpl(std::size_t size) noexcept(IsNoExcept) {108return imalloc_fastpath(size, &fallback_impl<IsNoExcept>);109}110111void *112operator new(std::size_t size) {113return newImpl<false>(size);114}115116void *117operator new[](std::size_t size) {118return newImpl<false>(size);119}120121void *122operator new(std::size_t size, const std::nothrow_t &) noexcept {123return newImpl<true>(size);124}125126void *127operator new[](std::size_t size, const std::nothrow_t &) noexcept {128return newImpl<true>(size);129}130131#if __cpp_aligned_new >= 201606132133template <bool IsNoExcept>134JEMALLOC_ALWAYS_INLINE135void *136alignedNewImpl(std::size_t size, std::align_val_t alignment) noexcept(IsNoExcept) {137void *ptr = je_aligned_alloc(static_cast<std::size_t>(alignment), size);138if (likely(ptr != nullptr)) {139return ptr;140}141142return handleOOM(size, IsNoExcept);143}144145void *146operator new(std::size_t size, std::align_val_t alignment) {147return alignedNewImpl<false>(size, alignment);148}149150void *151operator new[](std::size_t size, std::align_val_t alignment) {152return alignedNewImpl<false>(size, alignment);153}154155void *156operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t &) noexcept {157return alignedNewImpl<true>(size, alignment);158}159160void *161operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t &) noexcept {162return alignedNewImpl<true>(size, alignment);163}164165#endif // __cpp_aligned_new166167void168operator delete(void *ptr) noexcept {169je_free(ptr);170}171172void173operator delete[](void *ptr) noexcept {174je_free(ptr);175}176177void178operator delete(void *ptr, const std::nothrow_t &) noexcept {179je_free(ptr);180}181182void operator delete[](void *ptr, const std::nothrow_t &) noexcept {183je_free(ptr);184}185186#if __cpp_sized_deallocation >= 201309187188JEMALLOC_ALWAYS_INLINE189void190sizedDeleteImpl(void* ptr, std::size_t size) noexcept {191if (unlikely(ptr == nullptr)) {192return;193}194je_sdallocx_noflags(ptr, size);195}196197void198operator delete(void *ptr, std::size_t size) noexcept {199sizedDeleteImpl(ptr, size);200}201202void203operator delete[](void *ptr, std::size_t size) noexcept {204sizedDeleteImpl(ptr, size);205}206207#endif // __cpp_sized_deallocation208209#if __cpp_aligned_new >= 201606210211JEMALLOC_ALWAYS_INLINE212void213alignedSizedDeleteImpl(void* ptr, std::size_t size, std::align_val_t alignment) noexcept {214if (config_debug) {215assert(((size_t)alignment & ((size_t)alignment - 1)) == 0);216}217if (unlikely(ptr == nullptr)) {218return;219}220je_sdallocx(ptr, size, MALLOCX_ALIGN(alignment));221}222223void224operator delete(void* ptr, std::align_val_t) noexcept {225je_free(ptr);226}227228void229operator delete[](void* ptr, std::align_val_t) noexcept {230je_free(ptr);231}232233void234operator delete(void* ptr, std::align_val_t, const std::nothrow_t&) noexcept {235je_free(ptr);236}237238void239operator delete[](void* ptr, std::align_val_t, const std::nothrow_t&) noexcept {240je_free(ptr);241}242243void244operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept {245alignedSizedDeleteImpl(ptr, size, alignment);246}247248void249operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept {250alignedSizedDeleteImpl(ptr, size, alignment);251}252253#endif // __cpp_aligned_new254255256