xref: /freebsd-12.1/contrib/libc++/src/new.cpp (revision b5893f02)
17a984708SDavid Chisnall //===--------------------------- new.cpp ----------------------------------===//
27a984708SDavid Chisnall //
37a984708SDavid Chisnall //                     The LLVM Compiler Infrastructure
47a984708SDavid Chisnall //
57a984708SDavid Chisnall // This file is dual licensed under the MIT and the University of Illinois Open
67a984708SDavid Chisnall // Source Licenses. See LICENSE.TXT for details.
77a984708SDavid Chisnall //
87a984708SDavid Chisnall //===----------------------------------------------------------------------===//
97a984708SDavid Chisnall 
107a984708SDavid Chisnall #include <stdlib.h>
117a984708SDavid Chisnall 
127a984708SDavid Chisnall #include "new"
13b2c7081bSDimitry Andric #include "include/atomic_support.h"
147a984708SDavid Chisnall 
15540d2a8bSDimitry Andric #if defined(_LIBCPP_ABI_MICROSOFT)
16b2c7081bSDimitry Andric #if defined(_LIBCPP_NO_VCRUNTIME)
17b2c7081bSDimitry Andric #include "support/runtime/new_handler_fallback.ipp"
18b2c7081bSDimitry Andric #endif
19540d2a8bSDimitry Andric #elif defined(LIBCXX_BUILDING_LIBCXXABI)
207a984708SDavid Chisnall #include <cxxabi.h>
21540d2a8bSDimitry Andric #elif defined(LIBCXXRT)
22540d2a8bSDimitry Andric #include <cxxabi.h>
23540d2a8bSDimitry Andric #include "support/runtime/new_handler_fallback.ipp"
24540d2a8bSDimitry Andric #elif defined(__GLIBCXX__)
25540d2a8bSDimitry Andric // nothing todo
26540d2a8bSDimitry Andric #else
27540d2a8bSDimitry Andric # if defined(__APPLE__) && !defined(_LIBCPP_BUILDING_HAS_NO_ABI_LIBRARY)
28540d2a8bSDimitry Andric #   include <cxxabi.h> // FIXME: remove this once buildit is gone.
29540d2a8bSDimitry Andric # else
30540d2a8bSDimitry Andric #   include "support/runtime/new_handler_fallback.ipp"
31540d2a8bSDimitry Andric # endif
32540d2a8bSDimitry Andric #endif
3394e3ee44SDavid Chisnall 
34540d2a8bSDimitry Andric namespace std
35540d2a8bSDimitry Andric {
367a984708SDavid Chisnall 
374f7ab58eSDimitry Andric #ifndef __GLIBCXX__
38540d2a8bSDimitry Andric const nothrow_t nothrow = {};
39540d2a8bSDimitry Andric #endif
40540d2a8bSDimitry Andric 
41540d2a8bSDimitry Andric #ifndef LIBSTDCXX
42540d2a8bSDimitry Andric 
43540d2a8bSDimitry Andric void
__throw_bad_alloc()44540d2a8bSDimitry Andric __throw_bad_alloc()
45540d2a8bSDimitry Andric {
46540d2a8bSDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
47540d2a8bSDimitry Andric     throw bad_alloc();
48540d2a8bSDimitry Andric #else
49540d2a8bSDimitry Andric     _VSTD::abort();
50540d2a8bSDimitry Andric #endif
51540d2a8bSDimitry Andric }
52540d2a8bSDimitry Andric 
53540d2a8bSDimitry Andric #endif // !LIBSTDCXX
54540d2a8bSDimitry Andric 
55540d2a8bSDimitry Andric }  // std
56540d2a8bSDimitry Andric 
57b2c7081bSDimitry Andric #if !defined(__GLIBCXX__) &&                                                   \
58*b5893f02SDimitry Andric     !defined(_LIBCPP_DEFER_NEW_TO_VCRUNTIME) &&      \
59540d2a8bSDimitry Andric     !defined(_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS)
604f7ab58eSDimitry Andric 
617a984708SDavid Chisnall // Implement all new and delete operators as weak definitions
629729cf09SDimitry Andric // in this shared library, so that they can be overridden by programs
637a984708SDavid Chisnall // that define non-weak copies of the functions.
647a984708SDavid Chisnall 
65aed8d94eSDimitry Andric _LIBCPP_WEAK
667a984708SDavid Chisnall void *
operator new(std::size_t size)67aed8d94eSDimitry Andric operator new(std::size_t size) _THROW_BAD_ALLOC
687a984708SDavid Chisnall {
697a984708SDavid Chisnall     if (size == 0)
707a984708SDavid Chisnall         size = 1;
717a984708SDavid Chisnall     void* p;
727a984708SDavid Chisnall     while ((p = ::malloc(size)) == 0)
737a984708SDavid Chisnall     {
747a984708SDavid Chisnall         // If malloc fails and there is a new_handler,
757a984708SDavid Chisnall         // call it to try free up memory.
767a984708SDavid Chisnall         std::new_handler nh = std::get_new_handler();
777a984708SDavid Chisnall         if (nh)
787a984708SDavid Chisnall             nh();
797a984708SDavid Chisnall         else
807a984708SDavid Chisnall #ifndef _LIBCPP_NO_EXCEPTIONS
817a984708SDavid Chisnall             throw std::bad_alloc();
827a984708SDavid Chisnall #else
837a984708SDavid Chisnall             break;
847a984708SDavid Chisnall #endif
857a984708SDavid Chisnall     }
867a984708SDavid Chisnall     return p;
877a984708SDavid Chisnall }
887a984708SDavid Chisnall 
89aed8d94eSDimitry Andric _LIBCPP_WEAK
90aed8d94eSDimitry Andric void*
operator new(size_t size,const std::nothrow_t &)91daf78e69SDimitry Andric operator new(size_t size, const std::nothrow_t&) _NOEXCEPT
92daf78e69SDimitry Andric {
93daf78e69SDimitry Andric     void* p = 0;
94daf78e69SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
95daf78e69SDimitry Andric     try
96daf78e69SDimitry Andric     {
97daf78e69SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
98daf78e69SDimitry Andric         p = ::operator new(size);
99daf78e69SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
100daf78e69SDimitry Andric     }
101daf78e69SDimitry Andric     catch (...)
102daf78e69SDimitry Andric     {
103daf78e69SDimitry Andric     }
104daf78e69SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
105daf78e69SDimitry Andric     return p;
106daf78e69SDimitry Andric }
107daf78e69SDimitry Andric 
108daf78e69SDimitry Andric _LIBCPP_WEAK
109daf78e69SDimitry Andric void*
operator new[](size_t size)110daf78e69SDimitry Andric operator new[](size_t size) _THROW_BAD_ALLOC
111daf78e69SDimitry Andric {
112daf78e69SDimitry Andric     return ::operator new(size);
113daf78e69SDimitry Andric }
114daf78e69SDimitry Andric 
115daf78e69SDimitry Andric _LIBCPP_WEAK
116daf78e69SDimitry Andric void*
operator new[](size_t size,const std::nothrow_t &)117daf78e69SDimitry Andric operator new[](size_t size, const std::nothrow_t&) _NOEXCEPT
118daf78e69SDimitry Andric {
119daf78e69SDimitry Andric     void* p = 0;
120daf78e69SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
121daf78e69SDimitry Andric     try
122daf78e69SDimitry Andric     {
123daf78e69SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
124daf78e69SDimitry Andric         p = ::operator new[](size);
125daf78e69SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
126daf78e69SDimitry Andric     }
127daf78e69SDimitry Andric     catch (...)
128daf78e69SDimitry Andric     {
129daf78e69SDimitry Andric     }
130daf78e69SDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
131daf78e69SDimitry Andric     return p;
132daf78e69SDimitry Andric }
133daf78e69SDimitry Andric 
134daf78e69SDimitry Andric _LIBCPP_WEAK
135daf78e69SDimitry Andric void
operator delete(void * ptr)136daf78e69SDimitry Andric operator delete(void* ptr) _NOEXCEPT
137daf78e69SDimitry Andric {
138daf78e69SDimitry Andric     ::free(ptr);
139daf78e69SDimitry Andric }
140daf78e69SDimitry Andric 
141daf78e69SDimitry Andric _LIBCPP_WEAK
142daf78e69SDimitry Andric void
operator delete(void * ptr,const std::nothrow_t &)143daf78e69SDimitry Andric operator delete(void* ptr, const std::nothrow_t&) _NOEXCEPT
144daf78e69SDimitry Andric {
145daf78e69SDimitry Andric     ::operator delete(ptr);
146daf78e69SDimitry Andric }
147daf78e69SDimitry Andric 
148daf78e69SDimitry Andric _LIBCPP_WEAK
149daf78e69SDimitry Andric void
operator delete(void * ptr,size_t)150daf78e69SDimitry Andric operator delete(void* ptr, size_t) _NOEXCEPT
151daf78e69SDimitry Andric {
152daf78e69SDimitry Andric     ::operator delete(ptr);
153daf78e69SDimitry Andric }
154daf78e69SDimitry Andric 
155daf78e69SDimitry Andric _LIBCPP_WEAK
156daf78e69SDimitry Andric void
operator delete[](void * ptr)157daf78e69SDimitry Andric operator delete[] (void* ptr) _NOEXCEPT
158daf78e69SDimitry Andric {
159daf78e69SDimitry Andric     ::operator delete(ptr);
160daf78e69SDimitry Andric }
161daf78e69SDimitry Andric 
162daf78e69SDimitry Andric _LIBCPP_WEAK
163daf78e69SDimitry Andric void
operator delete[](void * ptr,const std::nothrow_t &)164daf78e69SDimitry Andric operator delete[] (void* ptr, const std::nothrow_t&) _NOEXCEPT
165daf78e69SDimitry Andric {
166daf78e69SDimitry Andric     ::operator delete[](ptr);
167daf78e69SDimitry Andric }
168daf78e69SDimitry Andric 
169daf78e69SDimitry Andric _LIBCPP_WEAK
170daf78e69SDimitry Andric void
operator delete[](void * ptr,size_t)171daf78e69SDimitry Andric operator delete[] (void* ptr, size_t) _NOEXCEPT
172daf78e69SDimitry Andric {
173daf78e69SDimitry Andric     ::operator delete[](ptr);
174daf78e69SDimitry Andric }
175daf78e69SDimitry Andric 
176*b5893f02SDimitry Andric #if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
177daf78e69SDimitry Andric 
178daf78e69SDimitry Andric _LIBCPP_WEAK
179daf78e69SDimitry Andric void *
operator new(std::size_t size,std::align_val_t alignment)180aed8d94eSDimitry Andric operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
181aed8d94eSDimitry Andric {
182aed8d94eSDimitry Andric     if (size == 0)
183aed8d94eSDimitry Andric         size = 1;
184aed8d94eSDimitry Andric     if (static_cast<size_t>(alignment) < sizeof(void*))
185aed8d94eSDimitry Andric       alignment = std::align_val_t(sizeof(void*));
186aed8d94eSDimitry Andric     void* p;
187f9448bf3SDimitry Andric #if defined(_LIBCPP_MSVCRT_LIKE)
188aed8d94eSDimitry Andric     while ((p = _aligned_malloc(size, static_cast<size_t>(alignment))) == nullptr)
189aed8d94eSDimitry Andric #else
190aed8d94eSDimitry Andric     while (::posix_memalign(&p, static_cast<size_t>(alignment), size) != 0)
191aed8d94eSDimitry Andric #endif
192aed8d94eSDimitry Andric     {
193aed8d94eSDimitry Andric         // If posix_memalign fails and there is a new_handler,
194aed8d94eSDimitry Andric         // call it to try free up memory.
195aed8d94eSDimitry Andric         std::new_handler nh = std::get_new_handler();
196aed8d94eSDimitry Andric         if (nh)
197aed8d94eSDimitry Andric             nh();
198aed8d94eSDimitry Andric         else {
199aed8d94eSDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
200aed8d94eSDimitry Andric             throw std::bad_alloc();
201aed8d94eSDimitry Andric #else
202aed8d94eSDimitry Andric             p = nullptr; // posix_memalign doesn't initialize 'p' on failure
203aed8d94eSDimitry Andric             break;
204aed8d94eSDimitry Andric #endif
205aed8d94eSDimitry Andric         }
206aed8d94eSDimitry Andric     }
207aed8d94eSDimitry Andric     return p;
208aed8d94eSDimitry Andric }
209aed8d94eSDimitry Andric 
210aed8d94eSDimitry Andric _LIBCPP_WEAK
2117a984708SDavid Chisnall void*
operator new(size_t size,std::align_val_t alignment,const std::nothrow_t &)212aed8d94eSDimitry Andric operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
213aed8d94eSDimitry Andric {
214aed8d94eSDimitry Andric     void* p = 0;
215aed8d94eSDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
216aed8d94eSDimitry Andric     try
217aed8d94eSDimitry Andric     {
218aed8d94eSDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
219aed8d94eSDimitry Andric         p = ::operator new(size, alignment);
220aed8d94eSDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
221aed8d94eSDimitry Andric     }
222aed8d94eSDimitry Andric     catch (...)
223aed8d94eSDimitry Andric     {
224aed8d94eSDimitry Andric     }
225aed8d94eSDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
226aed8d94eSDimitry Andric     return p;
227aed8d94eSDimitry Andric }
228aed8d94eSDimitry Andric 
229aed8d94eSDimitry Andric _LIBCPP_WEAK
230aed8d94eSDimitry Andric void*
operator new[](size_t size,std::align_val_t alignment)231aed8d94eSDimitry Andric operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC
232aed8d94eSDimitry Andric {
233aed8d94eSDimitry Andric     return ::operator new(size, alignment);
234aed8d94eSDimitry Andric }
235aed8d94eSDimitry Andric 
236aed8d94eSDimitry Andric _LIBCPP_WEAK
2377a984708SDavid Chisnall void*
operator new[](size_t size,std::align_val_t alignment,const std::nothrow_t &)238aed8d94eSDimitry Andric operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
239aed8d94eSDimitry Andric {
240aed8d94eSDimitry Andric     void* p = 0;
241aed8d94eSDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
242aed8d94eSDimitry Andric     try
243aed8d94eSDimitry Andric     {
244aed8d94eSDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
245aed8d94eSDimitry Andric         p = ::operator new[](size, alignment);
246aed8d94eSDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS
247aed8d94eSDimitry Andric     }
248aed8d94eSDimitry Andric     catch (...)
249aed8d94eSDimitry Andric     {
250aed8d94eSDimitry Andric     }
251aed8d94eSDimitry Andric #endif  // _LIBCPP_NO_EXCEPTIONS
252aed8d94eSDimitry Andric     return p;
253aed8d94eSDimitry Andric }
254aed8d94eSDimitry Andric 
255aed8d94eSDimitry Andric _LIBCPP_WEAK
2567a984708SDavid Chisnall void
operator delete(void * ptr,std::align_val_t)257aed8d94eSDimitry Andric operator delete(void* ptr, std::align_val_t) _NOEXCEPT
258aed8d94eSDimitry Andric {
259f9448bf3SDimitry Andric #if defined(_LIBCPP_MSVCRT_LIKE)
2607a848d17SDimitry Andric     ::_aligned_free(ptr);
2617a848d17SDimitry Andric #else
262aed8d94eSDimitry Andric     ::free(ptr);
2637a848d17SDimitry Andric #endif
264aed8d94eSDimitry Andric }
265aed8d94eSDimitry Andric 
266aed8d94eSDimitry Andric _LIBCPP_WEAK
2677a984708SDavid Chisnall void
operator delete(void * ptr,std::align_val_t alignment,const std::nothrow_t &)268aed8d94eSDimitry Andric operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
269aed8d94eSDimitry Andric {
270aed8d94eSDimitry Andric     ::operator delete(ptr, alignment);
271aed8d94eSDimitry Andric }
272aed8d94eSDimitry Andric 
273aed8d94eSDimitry Andric _LIBCPP_WEAK
2747a984708SDavid Chisnall void
operator delete(void * ptr,size_t,std::align_val_t alignment)275aed8d94eSDimitry Andric operator delete(void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
276aed8d94eSDimitry Andric {
277aed8d94eSDimitry Andric     ::operator delete(ptr, alignment);
278aed8d94eSDimitry Andric }
279aed8d94eSDimitry Andric 
280aed8d94eSDimitry Andric _LIBCPP_WEAK
281854fa44bSDimitry Andric void
operator delete[](void * ptr,std::align_val_t alignment)282aed8d94eSDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment) _NOEXCEPT
283aed8d94eSDimitry Andric {
284aed8d94eSDimitry Andric     ::operator delete(ptr, alignment);
285aed8d94eSDimitry Andric }
286aed8d94eSDimitry Andric 
287aed8d94eSDimitry Andric _LIBCPP_WEAK
2887a984708SDavid Chisnall void
operator delete[](void * ptr,std::align_val_t alignment,const std::nothrow_t &)289aed8d94eSDimitry Andric operator delete[] (void* ptr, std::align_val_t alignment, const std::nothrow_t&) _NOEXCEPT
290aed8d94eSDimitry Andric {
291aed8d94eSDimitry Andric     ::operator delete[](ptr, alignment);
292aed8d94eSDimitry Andric }
293aed8d94eSDimitry Andric 
294aed8d94eSDimitry Andric _LIBCPP_WEAK
295854fa44bSDimitry Andric void
operator delete[](void * ptr,size_t,std::align_val_t alignment)296aed8d94eSDimitry Andric operator delete[] (void* ptr, size_t, std::align_val_t alignment) _NOEXCEPT
297aed8d94eSDimitry Andric {
298aed8d94eSDimitry Andric     ::operator delete[](ptr, alignment);
299aed8d94eSDimitry Andric }
300aed8d94eSDimitry Andric 
301*b5893f02SDimitry Andric #endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION
302b2c7081bSDimitry Andric #endif // !__GLIBCXX__ && (!_LIBCPP_ABI_MICROSOFT || _LIBCPP_NO_VCRUNTIME) && !_LIBCPP_DISABLE_NEW_DELETE_DEFINITIONS
303