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