Skip to content

Commit fc787ff

Browse files
committed
[libc++][NFC] Refactor the core logic of operator new into helper functions
This will make it easier to implement new(nothrow) without calling the throwing version of new when exceptions are disabled. See https://llvm.org/D150610 for the full discussion.
1 parent f362be5 commit fc787ff

File tree

2 files changed

+44
-32
lines changed

2 files changed

+44
-32
lines changed

libcxx/src/new.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
// in this shared library, so that they can be overridden by programs
2121
// that define non-weak copies of the functions.
2222

23-
_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
23+
static void* operator_new_impl(std::size_t size) noexcept {
2424
if (size == 0)
2525
size = 1;
2626
void* p;
@@ -31,15 +31,20 @@ _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
3131
if (nh)
3232
nh();
3333
else
34-
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
35-
throw std::bad_alloc();
36-
# else
3734
break;
38-
# endif
3935
}
4036
return p;
4137
}
4238

39+
_LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {
40+
void* p = operator_new_impl(size);
41+
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
42+
if (p == nullptr)
43+
throw std::bad_alloc();
44+
# endif
45+
return p;
46+
}
47+
4348
_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {
4449
void* p = nullptr;
4550
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
@@ -82,7 +87,7 @@ _LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator del
8287

8388
# if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
8489

85-
_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
90+
static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept {
8691
if (size == 0)
8792
size = 1;
8893
if (static_cast<size_t>(alignment) < sizeof(void*))
@@ -91,25 +96,26 @@ _LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _T
9196
// Try allocating memory. If allocation fails and there is a new_handler,
9297
// call it to try free up memory, and try again until it succeeds, or until
9398
// the new_handler decides to terminate.
94-
//
95-
// If allocation fails and there is no new_handler, we throw bad_alloc
96-
// (or return nullptr if exceptions are disabled).
9799
void* p;
98100
while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
99101
std::new_handler nh = std::get_new_handler();
100102
if (nh)
101103
nh();
102-
else {
103-
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
104-
throw std::bad_alloc();
105-
# else
104+
else
106105
break;
107-
# endif
108-
}
109106
}
110107
return p;
111108
}
112109

110+
_LIBCPP_WEAK void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
111+
void* p = operator_new_aligned_impl(size, alignment);
112+
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
113+
if (p == nullptr)
114+
throw std::bad_alloc();
115+
# endif
116+
return p;
117+
}
118+
113119
_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
114120
void* p = nullptr;
115121
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS

libcxxabi/src/stdlib_new_delete.cpp

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
// in this shared library, so that they can be overridden by programs
3131
// that define non-weak copies of the functions.
3232

33-
_LIBCPP_WEAK
34-
void* operator new(std::size_t size) _THROW_BAD_ALLOC {
33+
static void* operator_new_impl(std::size_t size) noexcept {
3534
if (size == 0)
3635
size = 1;
3736
void* p;
@@ -42,15 +41,21 @@ void* operator new(std::size_t size) _THROW_BAD_ALLOC {
4241
if (nh)
4342
nh();
4443
else
45-
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
46-
throw std::bad_alloc();
47-
#else
4844
break;
49-
#endif
5045
}
5146
return p;
5247
}
5348

49+
_LIBCPP_WEAK
50+
void* operator new(std::size_t size) _THROW_BAD_ALLOC {
51+
void* p = operator_new_impl(size);
52+
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
53+
if (p == nullptr)
54+
throw std::bad_alloc();
55+
#endif
56+
return p;
57+
}
58+
5459
_LIBCPP_WEAK
5560
void* operator new(size_t size, const std::nothrow_t&) noexcept {
5661
void* p = nullptr;
@@ -102,8 +107,7 @@ void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }
102107

103108
#if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)
104109

105-
_LIBCPP_WEAK
106-
void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
110+
static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) noexcept {
107111
if (size == 0)
108112
size = 1;
109113
if (static_cast<size_t>(alignment) < sizeof(void*))
@@ -112,25 +116,27 @@ void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLO
112116
// Try allocating memory. If allocation fails and there is a new_handler,
113117
// call it to try free up memory, and try again until it succeeds, or until
114118
// the new_handler decides to terminate.
115-
//
116-
// If allocation fails and there is no new_handler, we throw bad_alloc
117-
// (or return nullptr if exceptions are disabled).
118119
void* p;
119120
while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {
120121
std::new_handler nh = std::get_new_handler();
121122
if (nh)
122123
nh();
123-
else {
124-
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
125-
throw std::bad_alloc();
126-
# else
124+
else
127125
break;
128-
# endif
129-
}
130126
}
131127
return p;
132128
}
133129

130+
_LIBCPP_WEAK
131+
void* operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {
132+
void* p = operator_new_aligned_impl(size, alignment);
133+
# ifndef _LIBCPP_HAS_NO_EXCEPTIONS
134+
if (p == nullptr)
135+
throw std::bad_alloc();
136+
# endif
137+
return p;
138+
}
139+
134140
_LIBCPP_WEAK
135141
void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {
136142
void* p = nullptr;

0 commit comments

Comments
 (0)