Skip to content

Commit e494a96

Browse files
authored
[libc++][NFC] Refactor the core logic of operator new into helper functions (#69407)
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 84f398a commit e494a96

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)