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