1*bf6039f0SWarner Losh #include <mutex> 2*bf6039f0SWarner Losh #include <new> 3*bf6039f0SWarner Losh 4*bf6039f0SWarner Losh #define JEMALLOC_CPP_CPP_ 5*bf6039f0SWarner Losh #ifdef __cplusplus 6*bf6039f0SWarner Losh extern "C" { 7*bf6039f0SWarner Losh #endif 8*bf6039f0SWarner Losh 9*bf6039f0SWarner Losh #include "jemalloc/internal/jemalloc_preamble.h" 10*bf6039f0SWarner Losh #include "jemalloc/internal/jemalloc_internal_includes.h" 11*bf6039f0SWarner Losh 12*bf6039f0SWarner Losh #ifdef __cplusplus 13*bf6039f0SWarner Losh } 14*bf6039f0SWarner Losh #endif 15*bf6039f0SWarner Losh 16*bf6039f0SWarner Losh // All operators in this file are exported. 17*bf6039f0SWarner Losh 18*bf6039f0SWarner Losh // Possibly alias hidden versions of malloc and sdallocx to avoid an extra plt 19*bf6039f0SWarner Losh // thunk? 20*bf6039f0SWarner Losh // 21*bf6039f0SWarner Losh // extern __typeof (sdallocx) sdallocx_int 22*bf6039f0SWarner Losh // __attribute ((alias ("sdallocx"), 23*bf6039f0SWarner Losh // visibility ("hidden"))); 24*bf6039f0SWarner Losh // 25*bf6039f0SWarner Losh // ... but it needs to work with jemalloc namespaces. 26*bf6039f0SWarner Losh 27*bf6039f0SWarner Losh void *operator new(std::size_t size); 28*bf6039f0SWarner Losh void *operator new[](std::size_t size); 29*bf6039f0SWarner Losh void *operator new(std::size_t size, const std::nothrow_t &) noexcept; 30*bf6039f0SWarner Losh void *operator new[](std::size_t size, const std::nothrow_t &) noexcept; 31*bf6039f0SWarner Losh void operator delete(void *ptr) noexcept; 32*bf6039f0SWarner Losh void operator delete[](void *ptr) noexcept; 33*bf6039f0SWarner Losh void operator delete(void *ptr, const std::nothrow_t &) noexcept; 34*bf6039f0SWarner Losh void operator delete[](void *ptr, const std::nothrow_t &) noexcept; 35*bf6039f0SWarner Losh 36*bf6039f0SWarner Losh #if __cpp_sized_deallocation >= 201309 37*bf6039f0SWarner Losh /* C++14's sized-delete operators. */ 38*bf6039f0SWarner Losh void operator delete(void *ptr, std::size_t size) noexcept; 39*bf6039f0SWarner Losh void operator delete[](void *ptr, std::size_t size) noexcept; 40*bf6039f0SWarner Losh #endif 41*bf6039f0SWarner Losh 42*bf6039f0SWarner Losh JEMALLOC_NOINLINE 43*bf6039f0SWarner Losh static void * 44*bf6039f0SWarner Losh handleOOM(std::size_t size, bool nothrow) { 45*bf6039f0SWarner Losh void *ptr = nullptr; 46*bf6039f0SWarner Losh 47*bf6039f0SWarner Losh while (ptr == nullptr) { 48*bf6039f0SWarner Losh std::new_handler handler; 49*bf6039f0SWarner Losh // GCC-4.8 and clang 4.0 do not have std::get_new_handler. 50*bf6039f0SWarner Losh { 51*bf6039f0SWarner Losh static std::mutex mtx; 52*bf6039f0SWarner Losh std::lock_guard<std::mutex> lock(mtx); 53*bf6039f0SWarner Losh 54*bf6039f0SWarner Losh handler = std::set_new_handler(nullptr); 55*bf6039f0SWarner Losh std::set_new_handler(handler); 56*bf6039f0SWarner Losh } 57*bf6039f0SWarner Losh if (handler == nullptr) 58*bf6039f0SWarner Losh break; 59*bf6039f0SWarner Losh 60*bf6039f0SWarner Losh try { 61*bf6039f0SWarner Losh handler(); 62*bf6039f0SWarner Losh } catch (const std::bad_alloc &) { 63*bf6039f0SWarner Losh break; 64*bf6039f0SWarner Losh } 65*bf6039f0SWarner Losh 66*bf6039f0SWarner Losh ptr = je_malloc(size); 67*bf6039f0SWarner Losh } 68*bf6039f0SWarner Losh 69*bf6039f0SWarner Losh if (ptr == nullptr && !nothrow) 70*bf6039f0SWarner Losh std::__throw_bad_alloc(); 71*bf6039f0SWarner Losh return ptr; 72*bf6039f0SWarner Losh } 73*bf6039f0SWarner Losh 74*bf6039f0SWarner Losh template <bool IsNoExcept> 75*bf6039f0SWarner Losh JEMALLOC_ALWAYS_INLINE 76*bf6039f0SWarner Losh void * 77*bf6039f0SWarner Losh newImpl(std::size_t size) noexcept(IsNoExcept) { 78*bf6039f0SWarner Losh void *ptr = je_malloc(size); 79*bf6039f0SWarner Losh if (likely(ptr != nullptr)) 80*bf6039f0SWarner Losh return ptr; 81*bf6039f0SWarner Losh 82*bf6039f0SWarner Losh return handleOOM(size, IsNoExcept); 83*bf6039f0SWarner Losh } 84*bf6039f0SWarner Losh 85*bf6039f0SWarner Losh void * 86*bf6039f0SWarner Losh operator new(std::size_t size) { 87*bf6039f0SWarner Losh return newImpl<false>(size); 88*bf6039f0SWarner Losh } 89*bf6039f0SWarner Losh 90*bf6039f0SWarner Losh void * 91*bf6039f0SWarner Losh operator new[](std::size_t size) { 92*bf6039f0SWarner Losh return newImpl<false>(size); 93*bf6039f0SWarner Losh } 94*bf6039f0SWarner Losh 95*bf6039f0SWarner Losh void * 96*bf6039f0SWarner Losh operator new(std::size_t size, const std::nothrow_t &) noexcept { 97*bf6039f0SWarner Losh return newImpl<true>(size); 98*bf6039f0SWarner Losh } 99*bf6039f0SWarner Losh 100*bf6039f0SWarner Losh void * 101*bf6039f0SWarner Losh operator new[](std::size_t size, const std::nothrow_t &) noexcept { 102*bf6039f0SWarner Losh return newImpl<true>(size); 103*bf6039f0SWarner Losh } 104*bf6039f0SWarner Losh 105*bf6039f0SWarner Losh void 106*bf6039f0SWarner Losh operator delete(void *ptr) noexcept { 107*bf6039f0SWarner Losh je_free(ptr); 108*bf6039f0SWarner Losh } 109*bf6039f0SWarner Losh 110*bf6039f0SWarner Losh void 111*bf6039f0SWarner Losh operator delete[](void *ptr) noexcept { 112*bf6039f0SWarner Losh je_free(ptr); 113*bf6039f0SWarner Losh } 114*bf6039f0SWarner Losh 115*bf6039f0SWarner Losh void 116*bf6039f0SWarner Losh operator delete(void *ptr, const std::nothrow_t &) noexcept { 117*bf6039f0SWarner Losh je_free(ptr); 118*bf6039f0SWarner Losh } 119*bf6039f0SWarner Losh 120*bf6039f0SWarner Losh void operator delete[](void *ptr, const std::nothrow_t &) noexcept { 121*bf6039f0SWarner Losh je_free(ptr); 122*bf6039f0SWarner Losh } 123*bf6039f0SWarner Losh 124*bf6039f0SWarner Losh #if __cpp_sized_deallocation >= 201309 125*bf6039f0SWarner Losh 126*bf6039f0SWarner Losh void 127*bf6039f0SWarner Losh operator delete(void *ptr, std::size_t size) noexcept { 128*bf6039f0SWarner Losh if (unlikely(ptr == nullptr)) { 129*bf6039f0SWarner Losh return; 130*bf6039f0SWarner Losh } 131*bf6039f0SWarner Losh je_sdallocx_noflags(ptr, size); 132*bf6039f0SWarner Losh } 133*bf6039f0SWarner Losh 134*bf6039f0SWarner Losh void operator delete[](void *ptr, std::size_t size) noexcept { 135*bf6039f0SWarner Losh if (unlikely(ptr == nullptr)) { 136*bf6039f0SWarner Losh return; 137*bf6039f0SWarner Losh } 138*bf6039f0SWarner Losh je_sdallocx_noflags(ptr, size); 139*bf6039f0SWarner Losh } 140*bf6039f0SWarner Losh 141*bf6039f0SWarner Losh #endif // __cpp_sized_deallocation 142