1*c43cad87SWarner Losh <<<<<<< HEAD 2*c43cad87SWarner Losh #include <mutex> 3*c43cad87SWarner Losh #include <new> 4*c43cad87SWarner Losh 5*c43cad87SWarner Losh #define JEMALLOC_CPP_CPP_ 6*c43cad87SWarner Losh #ifdef __cplusplus 7*c43cad87SWarner Losh extern "C" { 8*c43cad87SWarner Losh #endif 9*c43cad87SWarner Losh 10*c43cad87SWarner Losh #include "jemalloc/internal/jemalloc_preamble.h" 11*c43cad87SWarner Losh #include "jemalloc/internal/jemalloc_internal_includes.h" 12*c43cad87SWarner Losh 13*c43cad87SWarner Losh #ifdef __cplusplus 14*c43cad87SWarner Losh } 15*c43cad87SWarner Losh #endif 16*c43cad87SWarner Losh 17*c43cad87SWarner Losh // All operators in this file are exported. 18*c43cad87SWarner Losh 19*c43cad87SWarner Losh // Possibly alias hidden versions of malloc and sdallocx to avoid an extra plt 20*c43cad87SWarner Losh // thunk? 21*c43cad87SWarner Losh // 22*c43cad87SWarner Losh // extern __typeof (sdallocx) sdallocx_int 23*c43cad87SWarner Losh // __attribute ((alias ("sdallocx"), 24*c43cad87SWarner Losh // visibility ("hidden"))); 25*c43cad87SWarner Losh // 26*c43cad87SWarner Losh // ... but it needs to work with jemalloc namespaces. 27*c43cad87SWarner Losh 28*c43cad87SWarner Losh void *operator new(std::size_t size); 29*c43cad87SWarner Losh void *operator new[](std::size_t size); 30*c43cad87SWarner Losh void *operator new(std::size_t size, const std::nothrow_t &) noexcept; 31*c43cad87SWarner Losh void *operator new[](std::size_t size, const std::nothrow_t &) noexcept; 32*c43cad87SWarner Losh void operator delete(void *ptr) noexcept; 33*c43cad87SWarner Losh void operator delete[](void *ptr) noexcept; 34*c43cad87SWarner Losh void operator delete(void *ptr, const std::nothrow_t &) noexcept; 35*c43cad87SWarner Losh void operator delete[](void *ptr, const std::nothrow_t &) noexcept; 36*c43cad87SWarner Losh 37*c43cad87SWarner Losh #if __cpp_sized_deallocation >= 201309 38*c43cad87SWarner Losh /* C++14's sized-delete operators. */ 39*c43cad87SWarner Losh void operator delete(void *ptr, std::size_t size) noexcept; 40*c43cad87SWarner Losh void operator delete[](void *ptr, std::size_t size) noexcept; 41*c43cad87SWarner Losh #endif 42*c43cad87SWarner Losh 43*c43cad87SWarner Losh #if __cpp_aligned_new >= 201606 44*c43cad87SWarner Losh /* C++17's over-aligned operators. */ 45*c43cad87SWarner Losh void *operator new(std::size_t size, std::align_val_t); 46*c43cad87SWarner Losh void *operator new(std::size_t size, std::align_val_t, const std::nothrow_t &) noexcept; 47*c43cad87SWarner Losh void *operator new[](std::size_t size, std::align_val_t); 48*c43cad87SWarner Losh void *operator new[](std::size_t size, std::align_val_t, const std::nothrow_t &) noexcept; 49*c43cad87SWarner Losh void operator delete(void* ptr, std::align_val_t) noexcept; 50*c43cad87SWarner Losh void operator delete(void* ptr, std::align_val_t, const std::nothrow_t &) noexcept; 51*c43cad87SWarner Losh void operator delete(void* ptr, std::size_t size, std::align_val_t al) noexcept; 52*c43cad87SWarner Losh void operator delete[](void* ptr, std::align_val_t) noexcept; 53*c43cad87SWarner Losh void operator delete[](void* ptr, std::align_val_t, const std::nothrow_t &) noexcept; 54*c43cad87SWarner Losh void operator delete[](void* ptr, std::size_t size, std::align_val_t al) noexcept; 55*c43cad87SWarner Losh #endif 56*c43cad87SWarner Losh 57*c43cad87SWarner Losh JEMALLOC_NOINLINE 58*c43cad87SWarner Losh static void * 59*c43cad87SWarner Losh handleOOM(std::size_t size, bool nothrow) { 60*c43cad87SWarner Losh if (opt_experimental_infallible_new) { 61*c43cad87SWarner Losh safety_check_fail("<jemalloc>: Allocation failed and " 62*c43cad87SWarner Losh "opt.experimental_infallible_new is true. Aborting.\n"); 63*c43cad87SWarner Losh return nullptr; 64*c43cad87SWarner Losh } 65*c43cad87SWarner Losh 66*c43cad87SWarner Losh void *ptr = nullptr; 67*c43cad87SWarner Losh 68*c43cad87SWarner Losh while (ptr == nullptr) { 69*c43cad87SWarner Losh std::new_handler handler; 70*c43cad87SWarner Losh // GCC-4.8 and clang 4.0 do not have std::get_new_handler. 71*c43cad87SWarner Losh { 72*c43cad87SWarner Losh static std::mutex mtx; 73*c43cad87SWarner Losh std::lock_guard<std::mutex> lock(mtx); 74*c43cad87SWarner Losh 75*c43cad87SWarner Losh handler = std::set_new_handler(nullptr); 76*c43cad87SWarner Losh std::set_new_handler(handler); 77*c43cad87SWarner Losh } 78*c43cad87SWarner Losh if (handler == nullptr) 79*c43cad87SWarner Losh break; 80*c43cad87SWarner Losh 81*c43cad87SWarner Losh try { 82*c43cad87SWarner Losh handler(); 83*c43cad87SWarner Losh } catch (const std::bad_alloc &) { 84*c43cad87SWarner Losh break; 85*c43cad87SWarner Losh } 86*c43cad87SWarner Losh 87*c43cad87SWarner Losh ptr = je_malloc(size); 88*c43cad87SWarner Losh } 89*c43cad87SWarner Losh 90*c43cad87SWarner Losh if (ptr == nullptr && !nothrow) 91*c43cad87SWarner Losh std::__throw_bad_alloc(); 92*c43cad87SWarner Losh return ptr; 93*c43cad87SWarner Losh } 94*c43cad87SWarner Losh 95*c43cad87SWarner Losh template <bool IsNoExcept> 96*c43cad87SWarner Losh JEMALLOC_NOINLINE 97*c43cad87SWarner Losh static void * 98*c43cad87SWarner Losh fallback_impl(std::size_t size) noexcept(IsNoExcept) { 99*c43cad87SWarner Losh void *ptr = malloc_default(size); 100*c43cad87SWarner Losh if (likely(ptr != nullptr)) { 101*c43cad87SWarner Losh return ptr; 102*c43cad87SWarner Losh } 103*c43cad87SWarner Losh return handleOOM(size, IsNoExcept); 104*c43cad87SWarner Losh } 105*c43cad87SWarner Losh 106*c43cad87SWarner Losh template <bool IsNoExcept> 107*c43cad87SWarner Losh JEMALLOC_ALWAYS_INLINE 108*c43cad87SWarner Losh void * 109*c43cad87SWarner Losh newImpl(std::size_t size) noexcept(IsNoExcept) { 110*c43cad87SWarner Losh return imalloc_fastpath(size, &fallback_impl<IsNoExcept>); 111*c43cad87SWarner Losh } 112*c43cad87SWarner Losh 113*c43cad87SWarner Losh void * 114*c43cad87SWarner Losh operator new(std::size_t size) { 115*c43cad87SWarner Losh return newImpl<false>(size); 116*c43cad87SWarner Losh } 117*c43cad87SWarner Losh 118*c43cad87SWarner Losh void * 119*c43cad87SWarner Losh operator new[](std::size_t size) { 120*c43cad87SWarner Losh return newImpl<false>(size); 121*c43cad87SWarner Losh } 122*c43cad87SWarner Losh 123*c43cad87SWarner Losh void * 124*c43cad87SWarner Losh operator new(std::size_t size, const std::nothrow_t &) noexcept { 125*c43cad87SWarner Losh return newImpl<true>(size); 126*c43cad87SWarner Losh } 127*c43cad87SWarner Losh 128*c43cad87SWarner Losh void * 129*c43cad87SWarner Losh operator new[](std::size_t size, const std::nothrow_t &) noexcept { 130*c43cad87SWarner Losh return newImpl<true>(size); 131*c43cad87SWarner Losh } 132*c43cad87SWarner Losh 133*c43cad87SWarner Losh #if __cpp_aligned_new >= 201606 134*c43cad87SWarner Losh 135*c43cad87SWarner Losh template <bool IsNoExcept> 136*c43cad87SWarner Losh JEMALLOC_ALWAYS_INLINE 137*c43cad87SWarner Losh void * 138*c43cad87SWarner Losh alignedNewImpl(std::size_t size, std::align_val_t alignment) noexcept(IsNoExcept) { 139*c43cad87SWarner Losh void *ptr = je_aligned_alloc(static_cast<std::size_t>(alignment), size); 140*c43cad87SWarner Losh if (likely(ptr != nullptr)) { 141*c43cad87SWarner Losh return ptr; 142*c43cad87SWarner Losh } 143*c43cad87SWarner Losh 144*c43cad87SWarner Losh return handleOOM(size, IsNoExcept); 145*c43cad87SWarner Losh } 146*c43cad87SWarner Losh 147*c43cad87SWarner Losh void * 148*c43cad87SWarner Losh operator new(std::size_t size, std::align_val_t alignment) { 149*c43cad87SWarner Losh return alignedNewImpl<false>(size, alignment); 150*c43cad87SWarner Losh } 151*c43cad87SWarner Losh 152*c43cad87SWarner Losh void * 153*c43cad87SWarner Losh operator new[](std::size_t size, std::align_val_t alignment) { 154*c43cad87SWarner Losh return alignedNewImpl<false>(size, alignment); 155*c43cad87SWarner Losh } 156*c43cad87SWarner Losh 157*c43cad87SWarner Losh void * 158*c43cad87SWarner Losh operator new(std::size_t size, std::align_val_t alignment, const std::nothrow_t &) noexcept { 159*c43cad87SWarner Losh return alignedNewImpl<true>(size, alignment); 160*c43cad87SWarner Losh } 161*c43cad87SWarner Losh 162*c43cad87SWarner Losh void * 163*c43cad87SWarner Losh operator new[](std::size_t size, std::align_val_t alignment, const std::nothrow_t &) noexcept { 164*c43cad87SWarner Losh return alignedNewImpl<true>(size, alignment); 165*c43cad87SWarner Losh } 166*c43cad87SWarner Losh 167*c43cad87SWarner Losh #endif // __cpp_aligned_new 168*c43cad87SWarner Losh 169*c43cad87SWarner Losh void 170*c43cad87SWarner Losh operator delete(void *ptr) noexcept { 171*c43cad87SWarner Losh je_free(ptr); 172*c43cad87SWarner Losh } 173*c43cad87SWarner Losh 174*c43cad87SWarner Losh void 175*c43cad87SWarner Losh operator delete[](void *ptr) noexcept { 176*c43cad87SWarner Losh je_free(ptr); 177*c43cad87SWarner Losh } 178*c43cad87SWarner Losh 179*c43cad87SWarner Losh void 180*c43cad87SWarner Losh operator delete(void *ptr, const std::nothrow_t &) noexcept { 181*c43cad87SWarner Losh je_free(ptr); 182*c43cad87SWarner Losh } 183*c43cad87SWarner Losh 184*c43cad87SWarner Losh void operator delete[](void *ptr, const std::nothrow_t &) noexcept { 185*c43cad87SWarner Losh je_free(ptr); 186*c43cad87SWarner Losh } 187*c43cad87SWarner Losh 188*c43cad87SWarner Losh #if __cpp_sized_deallocation >= 201309 189*c43cad87SWarner Losh 190*c43cad87SWarner Losh JEMALLOC_ALWAYS_INLINE 191*c43cad87SWarner Losh void 192*c43cad87SWarner Losh sizedDeleteImpl(void* ptr, std::size_t size) noexcept { 193*c43cad87SWarner Losh if (unlikely(ptr == nullptr)) { 194*c43cad87SWarner Losh return; 195*c43cad87SWarner Losh } 196*c43cad87SWarner Losh je_sdallocx_noflags(ptr, size); 197*c43cad87SWarner Losh } 198*c43cad87SWarner Losh 199*c43cad87SWarner Losh void 200*c43cad87SWarner Losh operator delete(void *ptr, std::size_t size) noexcept { 201*c43cad87SWarner Losh sizedDeleteImpl(ptr, size); 202*c43cad87SWarner Losh } 203*c43cad87SWarner Losh 204*c43cad87SWarner Losh void 205*c43cad87SWarner Losh operator delete[](void *ptr, std::size_t size) noexcept { 206*c43cad87SWarner Losh sizedDeleteImpl(ptr, size); 207*c43cad87SWarner Losh } 208*c43cad87SWarner Losh 209*c43cad87SWarner Losh #endif // __cpp_sized_deallocation 210*c43cad87SWarner Losh 211*c43cad87SWarner Losh #if __cpp_aligned_new >= 201606 212*c43cad87SWarner Losh 213*c43cad87SWarner Losh JEMALLOC_ALWAYS_INLINE 214*c43cad87SWarner Losh void 215*c43cad87SWarner Losh alignedSizedDeleteImpl(void* ptr, std::size_t size, std::align_val_t alignment) noexcept { 216*c43cad87SWarner Losh if (config_debug) { 217*c43cad87SWarner Losh assert(((size_t)alignment & ((size_t)alignment - 1)) == 0); 218*c43cad87SWarner Losh } 219*c43cad87SWarner Losh if (unlikely(ptr == nullptr)) { 220*c43cad87SWarner Losh return; 221*c43cad87SWarner Losh } 222*c43cad87SWarner Losh je_sdallocx(ptr, size, MALLOCX_ALIGN(alignment)); 223*c43cad87SWarner Losh } 224*c43cad87SWarner Losh 225*c43cad87SWarner Losh void 226*c43cad87SWarner Losh operator delete(void* ptr, std::align_val_t) noexcept { 227*c43cad87SWarner Losh je_free(ptr); 228*c43cad87SWarner Losh } 229*c43cad87SWarner Losh 230*c43cad87SWarner Losh void 231*c43cad87SWarner Losh operator delete[](void* ptr, std::align_val_t) noexcept { 232*c43cad87SWarner Losh je_free(ptr); 233*c43cad87SWarner Losh } 234*c43cad87SWarner Losh 235*c43cad87SWarner Losh void 236*c43cad87SWarner Losh operator delete(void* ptr, std::align_val_t, const std::nothrow_t&) noexcept { 237*c43cad87SWarner Losh je_free(ptr); 238*c43cad87SWarner Losh } 239*c43cad87SWarner Losh 240*c43cad87SWarner Losh void 241*c43cad87SWarner Losh operator delete[](void* ptr, std::align_val_t, const std::nothrow_t&) noexcept { 242*c43cad87SWarner Losh je_free(ptr); 243*c43cad87SWarner Losh } 244*c43cad87SWarner Losh 245*c43cad87SWarner Losh void 246*c43cad87SWarner Losh operator delete(void* ptr, std::size_t size, std::align_val_t alignment) noexcept { 247*c43cad87SWarner Losh alignedSizedDeleteImpl(ptr, size, alignment); 248*c43cad87SWarner Losh } 249*c43cad87SWarner Losh 250*c43cad87SWarner Losh void 251*c43cad87SWarner Losh operator delete[](void* ptr, std::size_t size, std::align_val_t alignment) noexcept { 252*c43cad87SWarner Losh alignedSizedDeleteImpl(ptr, size, alignment); 253*c43cad87SWarner Losh } 254*c43cad87SWarner Losh 255*c43cad87SWarner Losh #endif // __cpp_aligned_new 256*c43cad87SWarner Losh ||||||| dec341af7695 257*c43cad87SWarner Losh ======= 258bf6039f0SWarner Losh #include <mutex> 259bf6039f0SWarner Losh #include <new> 260bf6039f0SWarner Losh 261bf6039f0SWarner Losh #define JEMALLOC_CPP_CPP_ 262bf6039f0SWarner Losh #ifdef __cplusplus 263bf6039f0SWarner Losh extern "C" { 264bf6039f0SWarner Losh #endif 265bf6039f0SWarner Losh 266bf6039f0SWarner Losh #include "jemalloc/internal/jemalloc_preamble.h" 267bf6039f0SWarner Losh #include "jemalloc/internal/jemalloc_internal_includes.h" 268bf6039f0SWarner Losh 269bf6039f0SWarner Losh #ifdef __cplusplus 270bf6039f0SWarner Losh } 271bf6039f0SWarner Losh #endif 272bf6039f0SWarner Losh 273bf6039f0SWarner Losh // All operators in this file are exported. 274bf6039f0SWarner Losh 275bf6039f0SWarner Losh // Possibly alias hidden versions of malloc and sdallocx to avoid an extra plt 276bf6039f0SWarner Losh // thunk? 277bf6039f0SWarner Losh // 278bf6039f0SWarner Losh // extern __typeof (sdallocx) sdallocx_int 279bf6039f0SWarner Losh // __attribute ((alias ("sdallocx"), 280bf6039f0SWarner Losh // visibility ("hidden"))); 281bf6039f0SWarner Losh // 282bf6039f0SWarner Losh // ... but it needs to work with jemalloc namespaces. 283bf6039f0SWarner Losh 284bf6039f0SWarner Losh void *operator new(std::size_t size); 285bf6039f0SWarner Losh void *operator new[](std::size_t size); 286bf6039f0SWarner Losh void *operator new(std::size_t size, const std::nothrow_t &) noexcept; 287bf6039f0SWarner Losh void *operator new[](std::size_t size, const std::nothrow_t &) noexcept; 288bf6039f0SWarner Losh void operator delete(void *ptr) noexcept; 289bf6039f0SWarner Losh void operator delete[](void *ptr) noexcept; 290bf6039f0SWarner Losh void operator delete(void *ptr, const std::nothrow_t &) noexcept; 291bf6039f0SWarner Losh void operator delete[](void *ptr, const std::nothrow_t &) noexcept; 292bf6039f0SWarner Losh 293bf6039f0SWarner Losh #if __cpp_sized_deallocation >= 201309 294bf6039f0SWarner Losh /* C++14's sized-delete operators. */ 295bf6039f0SWarner Losh void operator delete(void *ptr, std::size_t size) noexcept; 296bf6039f0SWarner Losh void operator delete[](void *ptr, std::size_t size) noexcept; 297bf6039f0SWarner Losh #endif 298bf6039f0SWarner Losh 299bf6039f0SWarner Losh JEMALLOC_NOINLINE 300bf6039f0SWarner Losh static void * 301bf6039f0SWarner Losh handleOOM(std::size_t size, bool nothrow) { 302bf6039f0SWarner Losh void *ptr = nullptr; 303bf6039f0SWarner Losh 304bf6039f0SWarner Losh while (ptr == nullptr) { 305bf6039f0SWarner Losh std::new_handler handler; 306bf6039f0SWarner Losh // GCC-4.8 and clang 4.0 do not have std::get_new_handler. 307bf6039f0SWarner Losh { 308bf6039f0SWarner Losh static std::mutex mtx; 309bf6039f0SWarner Losh std::lock_guard<std::mutex> lock(mtx); 310bf6039f0SWarner Losh 311bf6039f0SWarner Losh handler = std::set_new_handler(nullptr); 312bf6039f0SWarner Losh std::set_new_handler(handler); 313bf6039f0SWarner Losh } 314bf6039f0SWarner Losh if (handler == nullptr) 315bf6039f0SWarner Losh break; 316bf6039f0SWarner Losh 317bf6039f0SWarner Losh try { 318bf6039f0SWarner Losh handler(); 319bf6039f0SWarner Losh } catch (const std::bad_alloc &) { 320bf6039f0SWarner Losh break; 321bf6039f0SWarner Losh } 322bf6039f0SWarner Losh 323bf6039f0SWarner Losh ptr = je_malloc(size); 324bf6039f0SWarner Losh } 325bf6039f0SWarner Losh 326bf6039f0SWarner Losh if (ptr == nullptr && !nothrow) 327bf6039f0SWarner Losh std::__throw_bad_alloc(); 328bf6039f0SWarner Losh return ptr; 329bf6039f0SWarner Losh } 330bf6039f0SWarner Losh 331bf6039f0SWarner Losh template <bool IsNoExcept> 332bf6039f0SWarner Losh JEMALLOC_ALWAYS_INLINE 333bf6039f0SWarner Losh void * 334bf6039f0SWarner Losh newImpl(std::size_t size) noexcept(IsNoExcept) { 335bf6039f0SWarner Losh void *ptr = je_malloc(size); 336bf6039f0SWarner Losh if (likely(ptr != nullptr)) 337bf6039f0SWarner Losh return ptr; 338bf6039f0SWarner Losh 339bf6039f0SWarner Losh return handleOOM(size, IsNoExcept); 340bf6039f0SWarner Losh } 341bf6039f0SWarner Losh 342bf6039f0SWarner Losh void * 343bf6039f0SWarner Losh operator new(std::size_t size) { 344bf6039f0SWarner Losh return newImpl<false>(size); 345bf6039f0SWarner Losh } 346bf6039f0SWarner Losh 347bf6039f0SWarner Losh void * 348bf6039f0SWarner Losh operator new[](std::size_t size) { 349bf6039f0SWarner Losh return newImpl<false>(size); 350bf6039f0SWarner Losh } 351bf6039f0SWarner Losh 352bf6039f0SWarner Losh void * 353bf6039f0SWarner Losh operator new(std::size_t size, const std::nothrow_t &) noexcept { 354bf6039f0SWarner Losh return newImpl<true>(size); 355bf6039f0SWarner Losh } 356bf6039f0SWarner Losh 357bf6039f0SWarner Losh void * 358bf6039f0SWarner Losh operator new[](std::size_t size, const std::nothrow_t &) noexcept { 359bf6039f0SWarner Losh return newImpl<true>(size); 360bf6039f0SWarner Losh } 361bf6039f0SWarner Losh 362bf6039f0SWarner Losh void 363bf6039f0SWarner Losh operator delete(void *ptr) noexcept { 364bf6039f0SWarner Losh je_free(ptr); 365bf6039f0SWarner Losh } 366bf6039f0SWarner Losh 367bf6039f0SWarner Losh void 368bf6039f0SWarner Losh operator delete[](void *ptr) noexcept { 369bf6039f0SWarner Losh je_free(ptr); 370bf6039f0SWarner Losh } 371bf6039f0SWarner Losh 372bf6039f0SWarner Losh void 373bf6039f0SWarner Losh operator delete(void *ptr, const std::nothrow_t &) noexcept { 374bf6039f0SWarner Losh je_free(ptr); 375bf6039f0SWarner Losh } 376bf6039f0SWarner Losh 377bf6039f0SWarner Losh void operator delete[](void *ptr, const std::nothrow_t &) noexcept { 378bf6039f0SWarner Losh je_free(ptr); 379bf6039f0SWarner Losh } 380bf6039f0SWarner Losh 381bf6039f0SWarner Losh #if __cpp_sized_deallocation >= 201309 382bf6039f0SWarner Losh 383bf6039f0SWarner Losh void 384bf6039f0SWarner Losh operator delete(void *ptr, std::size_t size) noexcept { 385bf6039f0SWarner Losh if (unlikely(ptr == nullptr)) { 386bf6039f0SWarner Losh return; 387bf6039f0SWarner Losh } 388bf6039f0SWarner Losh je_sdallocx_noflags(ptr, size); 389bf6039f0SWarner Losh } 390bf6039f0SWarner Losh 391bf6039f0SWarner Losh void operator delete[](void *ptr, std::size_t size) noexcept { 392bf6039f0SWarner Losh if (unlikely(ptr == nullptr)) { 393bf6039f0SWarner Losh return; 394bf6039f0SWarner Losh } 395bf6039f0SWarner Losh je_sdallocx_noflags(ptr, size); 396bf6039f0SWarner Losh } 397bf6039f0SWarner Losh 398bf6039f0SWarner Losh #endif // __cpp_sized_deallocation 399*c43cad87SWarner Losh >>>>>>> main 400