-
-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support replacing C++ new/delete implementation
This adds support for sanity checks based on sized deallocation and will reduce the overhead of calls through the C++ allocator.
- Loading branch information
1 parent
3dc49f8
commit e6e9ac1
Showing
3 changed files
with
101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#include <stdlib.h> | ||
#include <new> | ||
#include <bits/functexcept.h> | ||
|
||
#define noreturn | ||
|
||
extern "C" { | ||
#include "malloc.h" | ||
#include "util.h" | ||
} | ||
|
||
COLD static void *handle_out_of_memory(size_t size, bool nothrow) { | ||
void *ptr; | ||
|
||
do { | ||
std::new_handler handler = std::get_new_handler(); | ||
if (handler == nullptr) { | ||
break; | ||
} | ||
|
||
try { | ||
handler(); | ||
} catch (const std::bad_alloc &) { | ||
break; | ||
} | ||
|
||
ptr = h_malloc(size); | ||
} while (ptr == nullptr); | ||
|
||
if (ptr == nullptr && !nothrow) { | ||
std::__throw_bad_alloc(); | ||
} | ||
return ptr; | ||
} | ||
|
||
static inline void *new_impl(size_t size, bool nothrow) { | ||
void *ptr = h_malloc(size); | ||
if (likely(ptr != nullptr)) { | ||
return ptr; | ||
} | ||
return handle_out_of_memory(size, nothrow); | ||
} | ||
|
||
void *operator new(size_t size) { | ||
return new_impl(size, false); | ||
} | ||
|
||
void *operator new[](size_t size) { | ||
return new_impl(size, false); | ||
} | ||
|
||
void *operator new(size_t size, const std::nothrow_t &) noexcept { | ||
return new_impl(size, true); | ||
} | ||
|
||
void *operator new[](size_t size, const std::nothrow_t &) noexcept { | ||
return new_impl(size, true); | ||
} | ||
|
||
void operator delete(void *ptr) noexcept { | ||
h_free(ptr); | ||
} | ||
|
||
void operator delete[](void *ptr) noexcept { | ||
h_free(ptr); | ||
} | ||
|
||
void operator delete(void *ptr, const std::nothrow_t &) noexcept { | ||
h_free(ptr); | ||
} | ||
|
||
void operator delete[](void *ptr, const std::nothrow_t &) noexcept { | ||
h_free(ptr); | ||
} | ||
|
||
void operator delete(void *ptr, size_t size) noexcept { | ||
h_free_sized(ptr, size); | ||
} | ||
|
||
void operator delete[](void *ptr, size_t size) noexcept { | ||
h_free_sized(ptr, size); | ||
} |