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