xref: /aosp_15_r20/external/jemalloc_new/src/jemalloc_cpp.cpp (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
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