2020#include < assert.h>
2121#include < Arduino.h>
2222#include < cxxabi.h>
23+ #include < bits/c++config.h>
24+ #include < bit>
2325
2426using __cxxabiv1::__guard;
2527
@@ -29,21 +31,29 @@ extern "C" void* _heap_abi_malloc(size_t size, bool unhandled, const void* const
2931extern " C" void __cxa_pure_virtual (void ) __attribute__ ((__noreturn__));
3032extern " C" void __cxa_deleted_virtual (void ) __attribute__ ((__noreturn__));
3133
32- #if defined(__cpp_exceptions) && (defined(DEBUG_ESP_OOM) || defined(DEBUG_ESP_PORT) || defined(DEBUG_ESP_WITHINISR))
34+ #if defined(__cpp_exceptions) && (defined(DEBUG_ESP_OOM) \
35+ || defined (DEBUG_ESP_PORT) || defined (DEBUG_ESP_WITHINISR) || defined (MIN_ESP_OOM))
3336/*
3437 When built with C++ Exceptions: "enabled", track caller address of Last OOM.
3538 * For debug build, force enable Last OOM tracking.
3639 * With the option "DEBUG_ESP_OOM," always do Last OOM tracking.
3740 * Otherwise, disable Last OOM tracking. The build relies on the weak link to
38- the default C++ exception handler.
39- This saves about 136 bytes of IROM, code in flash.
41+ the default C++ exception handler. This saves about 232 bytes of IROM, when
42+ using C++ exceptions.
43+
44+ //C C++ Exception "enabled" already adds 28,868 bytes to the build does another
45+ //C 232 matter that much? Added define MIN_ESP_OOM for experimention.
46+
47+ If desired, define MIN_ESP_OOM to continue with a minimum OOM tracking for
48+ C++ exception builds.
4049*/
4150
51+
4252// Debug replacement adaptation from ".../new_op.cc".
4353using std::new_handler;
4454using std::bad_alloc;
4555
46- void * operator new (std::size_t size)
56+ static void * _heap_new (std::size_t size, const void * caller )
4757{
4858 void * p;
4959
@@ -52,7 +62,7 @@ void* operator new (std::size_t size)
5262 size = 1 ;
5363 }
5464
55- while (0 == (p = _heap_abi_malloc (size, false , __builtin_return_address ( 0 ) ))) {
65+ while (0 == (p = _heap_abi_malloc (size, false , caller ))) {
5666 new_handler handler = std::get_new_handler ();
5767 if (!handler) {
5868 throw (bad_alloc ());
@@ -63,18 +73,54 @@ void* operator new (std::size_t size)
6373 return p;
6474}
6575
76+ void * operator new (std::size_t size)
77+ {
78+ return _heap_new (size, __builtin_return_address (0 ));
79+ }
80+
81+ void * operator new [] (std::size_t size)
82+ {
83+ return _heap_new (size, __builtin_return_address (0 ));
84+ }
85+
86+ void * operator new (size_t size, const std::nothrow_t &) noexcept
87+ {
88+ __try {
89+ return _heap_new (size, __builtin_return_address (0 ));
90+ }
91+ __catch (...) {
92+ return nullptr ;
93+ }
94+ }
95+
96+ void * operator new [] (size_t size, const std::nothrow_t &) noexcept
97+ {
98+ __try {
99+ return _heap_new (size, __builtin_return_address (0 ));
100+ }
101+ __catch (...) {
102+ return nullptr ;
103+ }
104+ }
105+ /*
106+ TODO:
107+ Current master does not support "new" align operations. Compiler reports:
108+ "/workdir/repo/gcc-gnu/libstdc++-v3/libsupc++/new_opa.cc:86: undefined reference to `memalign'"
109+ Look at enhancement to umm_malloc for an alignment option.
110+ */
111+
66112#elif !defined(__cpp_exceptions)
67113// When doing builds with C++ Exceptions "disabled", always save details of
68114// the last OOM event.
69115
70116// overwrite weak operators new/new[] definitions
71117
72- void * operator new (size_t size)
118+ void * operator new (size_t size)
73119{
74120 return _heap_abi_malloc (size, true , __builtin_return_address (0 ));
75121}
76122
77- void * operator new [](size_t size)
123+ void * operator new [] (size_t size)
78124{
79125 return _heap_abi_malloc (size, true , __builtin_return_address (0 ));
80126}
0 commit comments