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