000000widow-hackspacecon/fw/HackSpaceCon_AS7/Arduino/megatinycore/new.cpp

181 lines
6.1 KiB
C++

/*
Copyright (c) 2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Updated 2020-21 Spence Konde to support C++ 14 sized
dealocations, and give useful compile errors when aligned
new and delete operators are referenced. I do not think adding
support for them is warranted at this time, though we have
candidates for the simplest of them, both were written by
@henrygab (Henry Gabryjelski, which is fitting because that's
who asked for C++ 17 mode, over on ATTinyCore, but releases
are more frequent for the new parts, and this is equally
applicable to all of the cores.)
*/
#include <stdlib.h>
// For C++11, only need the following:
void *operator new (size_t size) {
return malloc(size);
}
void *operator new[](size_t size) {
return malloc(size);
}
void operator delete (void * ptr) {
free(ptr);
}
void operator delete[](void * ptr) {
free(ptr);
}
void * operator new (size_t size, void * ptr) noexcept {
(void)size;
return ptr;
}
void * operator new[](size_t size, void * ptr) noexcept {
(void)size;
return ptr;
}
// Since C++14, also need two more delete variants...
// Note thnat this CAN break code that compiled amd worked in C++11.
#if (__cpp_sized_deallocation >= 201309L)
void operator delete (void* ptr, size_t size) noexcept {
(void) size;
free(ptr);
}
void operator delete[](void* ptr, size_t size) noexcept {
(void) size;
free(ptr);
}
#endif
// Since C++17, there's four more each for new / delete, to support allocation
// of objects with alignment greater than __STDCPP_DEFAULT_NEW_ALIGNMENT__.
// Almost the entirety of AVR is using C++ 11. Any code that works elsewhere, but NOT on these cores and give these error messages either
// is trying to get alignment that it doesn't actually need, or is - by sheet luck - ending up with the addresses which worked. E
#if (__cpp_aligned_new >= 201606L)
#if !defined(LTODISABLED)
void badAlloc(const char*) __attribute__((error("")));
#endif
void* operator new (size_t size, std::align_val_t al) {
#if !defined(LTODISABLED)
badAlloc("Alignment aware new/delete operators, a C++ 17 feaure, are not supported by this core or any other AVR cores at this point in time");
#endif
(void) al;
return malloc(size);
}
/*
void* operator new (size_t size, std::align_val_t al) {
if (al <= alignof(std::max_align_t)) {
return malloc(size);
}
// how many extra bytes required to ensure can find an aligned pointer?
size_t toAllocate = size + (al - alignof(std::max_align_t)) - 1;
toAllocate += sizeof(uintptr_t); // to store the original pointer
uintptr_t allocated = malloc(toAllocate);
// ensure to save space for the back-pointer.
uintptr_t alignedPtr = allocated + sizeof(uintptr_t);
size_t mask = al 1; // alignment mask ... the bits that must be zero
uintptr_t alignedPtr =
(allocated & mask) == 0 ?
allocated :
(allocated & (~mask)) + al;
// save the original pointer just before the pointer value returned to caller
static_assert(alignof(uintptr_t) <= alignof(std::max_align_t), "" );
uintptr_t* storeOriginalPointerAt = (uintptr_t)(alignedPtr - sizeof(uintptr_t));
*storeOriginalPointerAt = allocated;
return alignedPtr;
}
*/
void* operator new[](size_t size, std::align_val_t al) {
#if !defined(LTODISABLED)
badAlloc("Alignment aware new/delete operators, a C++ 17 feaure, are not supported by this core or any other AVR cores at this point in time");
#endif
(void) al;
return malloc(size);
}
void operator delete (void* ptr, std::align_val_t al) noexcept {
#if !defined(LTODISABLED)
badAlloc("Alignment aware new/delete operators, a C++ 17 feaure, are not supported by this core or any other AVR cores at this point in time");
#endif
(void) al;
free(ptr);
}
/*
void operator delete (void* ptr, std::align_val_t al) noexcept {
if (al <= STDCPP_DEFAULT_NEW_ALIGNMENT) {
free(ptr);
return;
}
// Get the original pointer value from just prior to the provided pointer.
uintptr_t aligned = ptr;
uintptr_t tmp = aligned - sizeof(uintptr_t); // go back 2 bytes
uintptr_t original = *((uintptr_t *)tmp); // extract the original pointer
// sanity check the original value... for iot, infinite loop recommended
// as it's better than memory corruption!rhy
size_t overhead = (al - STDCPP_DEFAULT_NEW_ALIGNMENT) + sizeof(uintptr_t);
assert(original < aligned);
assert(original + overhead <= aligned);
// and finally free the original memory
free(original);
}
*/
void operator delete[](void* ptr, std::align_val_t al) noexcept {
#if !defined(LTODISABLED)
badAlloc("Alignment aware new/delete operators, a C++ 17 feaure, are not supported by this core or any other AVR cores at this point in time");
#endif
(void) al;
free(ptr);
}
void operator delete (void* ptr, size_t size, std::align_val_t al) noexcept{
#if !defined(LTODISABLED)
badAlloc("Alignment aware new/delete operators, a C++ 17 feaure, are not supported by this core or any other AVR cores at this point in time");
#endif
(void) al;
(void) size;
free(ptr);
}
void operator delete[](void* ptr, size_t size, std::align_val_t al) noexcept {
#if !defined(LTODISABLED)
badAlloc("Overaligned allocation/deallocation is a C++ 17 feature, and is not supported by this or other AVR cores at this point in time");
#endif
(void) al;
(void) size;
free(ptr);
}
#endif