17a984708SDavid Chisnall /** 27a984708SDavid Chisnall * memory.cc - Contains stub definition of C++ new/delete operators. 37a984708SDavid Chisnall * 47a984708SDavid Chisnall * These definitions are intended to be used for testing and are weak symbols 57a984708SDavid Chisnall * to allow them to be replaced by definitions from a STL implementation. 67a984708SDavid Chisnall * These versions simply wrap malloc() and free(), they do not provide a 77a984708SDavid Chisnall * C++-specific allocator. 87a984708SDavid Chisnall */ 97a984708SDavid Chisnall 107a984708SDavid Chisnall #include <stddef.h> 117a984708SDavid Chisnall #include <stdlib.h> 127a984708SDavid Chisnall #include "stdexcept.h" 137a984708SDavid Chisnall 14*db47c4bfSDavid Chisnall #if !__has_builtin(__sync_swap) 15*db47c4bfSDavid Chisnall #define __sync_swap __sync_lock_test_and_set 16*db47c4bfSDavid Chisnall #endif 17*db47c4bfSDavid Chisnall 187a984708SDavid Chisnall namespace std 197a984708SDavid Chisnall { 207a984708SDavid Chisnall struct nothrow_t {}; 217a984708SDavid Chisnall } 227a984708SDavid Chisnall 237a984708SDavid Chisnall 247a984708SDavid Chisnall /// The type of the function called when allocation fails. 257a984708SDavid Chisnall typedef void (*new_handler)(); 267a984708SDavid Chisnall /** 277a984708SDavid Chisnall * The function to call when allocation fails. By default, there is no 287a984708SDavid Chisnall * handler and a bad allocation exception is thrown if an allocation fails. 297a984708SDavid Chisnall */ 307a984708SDavid Chisnall static new_handler new_handl; 317a984708SDavid Chisnall 327a984708SDavid Chisnall namespace std 337a984708SDavid Chisnall { 347a984708SDavid Chisnall /** 357a984708SDavid Chisnall * Sets a function to be called when there is a failure in new. 367a984708SDavid Chisnall */ 377a984708SDavid Chisnall __attribute__((weak)) 387a984708SDavid Chisnall new_handler set_new_handler(new_handler handler) 397a984708SDavid Chisnall { 40*db47c4bfSDavid Chisnall return __sync_swap(&new_handl, handler); 417a984708SDavid Chisnall } 427a984708SDavid Chisnall } 437a984708SDavid Chisnall 447a984708SDavid Chisnall 457a984708SDavid Chisnall __attribute__((weak)) 467a984708SDavid Chisnall void* operator new(size_t size) 477a984708SDavid Chisnall { 487a984708SDavid Chisnall void * mem = malloc(size); 497a984708SDavid Chisnall while (0 == mem) 507a984708SDavid Chisnall { 517a984708SDavid Chisnall if (0 != new_handl) 527a984708SDavid Chisnall { 537a984708SDavid Chisnall new_handl(); 547a984708SDavid Chisnall } 557a984708SDavid Chisnall else 567a984708SDavid Chisnall { 577a984708SDavid Chisnall throw std::bad_alloc(); 587a984708SDavid Chisnall } 597a984708SDavid Chisnall mem = malloc(size); 607a984708SDavid Chisnall } 617a984708SDavid Chisnall 627a984708SDavid Chisnall return mem; 637a984708SDavid Chisnall } 647a984708SDavid Chisnall 657a984708SDavid Chisnall __attribute__((weak)) 667a984708SDavid Chisnall void* operator new(size_t size, const std::nothrow_t &) throw() 677a984708SDavid Chisnall { 687a984708SDavid Chisnall void *mem = malloc(size); 697a984708SDavid Chisnall while (0 == mem) 707a984708SDavid Chisnall { 717a984708SDavid Chisnall if (0 != new_handl) 727a984708SDavid Chisnall { 737a984708SDavid Chisnall try 747a984708SDavid Chisnall { 757a984708SDavid Chisnall new_handl(); 767a984708SDavid Chisnall } 777a984708SDavid Chisnall catch (...) 787a984708SDavid Chisnall { 797a984708SDavid Chisnall // nothrow operator new should return NULL in case of 807a984708SDavid Chisnall // std::bad_alloc exception in new handler 817a984708SDavid Chisnall return NULL; 827a984708SDavid Chisnall } 837a984708SDavid Chisnall } 847a984708SDavid Chisnall else 857a984708SDavid Chisnall { 867a984708SDavid Chisnall return NULL; 877a984708SDavid Chisnall } 887a984708SDavid Chisnall mem = malloc(size); 897a984708SDavid Chisnall } 907a984708SDavid Chisnall 917a984708SDavid Chisnall return mem; 927a984708SDavid Chisnall } 937a984708SDavid Chisnall 947a984708SDavid Chisnall 957a984708SDavid Chisnall __attribute__((weak)) 967a984708SDavid Chisnall void operator delete(void * ptr) 977a984708SDavid Chisnall { 987a984708SDavid Chisnall free(ptr); 997a984708SDavid Chisnall } 1007a984708SDavid Chisnall 1017a984708SDavid Chisnall 1027a984708SDavid Chisnall __attribute__((weak)) 1037a984708SDavid Chisnall void * operator new[](size_t size) 1047a984708SDavid Chisnall { 1057a984708SDavid Chisnall return ::operator new(size); 1067a984708SDavid Chisnall } 1077a984708SDavid Chisnall 1087a984708SDavid Chisnall 1097a984708SDavid Chisnall __attribute__((weak)) 110*db47c4bfSDavid Chisnall void operator delete[](void * ptr) throw() 1117a984708SDavid Chisnall { 1127a984708SDavid Chisnall ::operator delete(ptr); 1137a984708SDavid Chisnall } 1147a984708SDavid Chisnall 1157a984708SDavid Chisnall 116