194e3ee44SDavid Chisnall /* 294e3ee44SDavid Chisnall * Copyright 2010-2011 PathScale, Inc. All rights reserved. 394e3ee44SDavid Chisnall * 494e3ee44SDavid Chisnall * Redistribution and use in source and binary forms, with or without 594e3ee44SDavid Chisnall * modification, are permitted provided that the following conditions are met: 694e3ee44SDavid Chisnall * 794e3ee44SDavid Chisnall * 1. Redistributions of source code must retain the above copyright notice, 894e3ee44SDavid Chisnall * this list of conditions and the following disclaimer. 994e3ee44SDavid Chisnall * 1094e3ee44SDavid Chisnall * 2. Redistributions in binary form must reproduce the above copyright notice, 1194e3ee44SDavid Chisnall * this list of conditions and the following disclaimer in the documentation 1294e3ee44SDavid Chisnall * and/or other materials provided with the distribution. 1394e3ee44SDavid Chisnall * 1494e3ee44SDavid Chisnall * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 1594e3ee44SDavid Chisnall * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1694e3ee44SDavid Chisnall * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1794e3ee44SDavid Chisnall * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 1894e3ee44SDavid Chisnall * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1994e3ee44SDavid Chisnall * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2094e3ee44SDavid Chisnall * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2194e3ee44SDavid Chisnall * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2294e3ee44SDavid Chisnall * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2394e3ee44SDavid Chisnall * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2494e3ee44SDavid Chisnall * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2594e3ee44SDavid Chisnall */ 2694e3ee44SDavid Chisnall 277a984708SDavid Chisnall /** 287a984708SDavid Chisnall * memory.cc - Contains stub definition of C++ new/delete operators. 297a984708SDavid Chisnall * 307a984708SDavid Chisnall * These definitions are intended to be used for testing and are weak symbols 317a984708SDavid Chisnall * to allow them to be replaced by definitions from a STL implementation. 327a984708SDavid Chisnall * These versions simply wrap malloc() and free(), they do not provide a 337a984708SDavid Chisnall * C++-specific allocator. 347a984708SDavid Chisnall */ 357a984708SDavid Chisnall 367a984708SDavid Chisnall #include <stddef.h> 377a984708SDavid Chisnall #include <stdlib.h> 387a984708SDavid Chisnall #include "stdexcept.h" 39f7cb1657SDavid Chisnall #include "atomic.h" 407a984708SDavid Chisnall 41db47c4bfSDavid Chisnall 427a984708SDavid Chisnall namespace std 437a984708SDavid Chisnall { 447a984708SDavid Chisnall struct nothrow_t {}; 457a984708SDavid Chisnall } 467a984708SDavid Chisnall 477a984708SDavid Chisnall 487a984708SDavid Chisnall /// The type of the function called when allocation fails. 497a984708SDavid Chisnall typedef void (*new_handler)(); 507a984708SDavid Chisnall /** 517a984708SDavid Chisnall * The function to call when allocation fails. By default, there is no 527a984708SDavid Chisnall * handler and a bad allocation exception is thrown if an allocation fails. 537a984708SDavid Chisnall */ 547a984708SDavid Chisnall static new_handler new_handl; 557a984708SDavid Chisnall 567a984708SDavid Chisnall namespace std 577a984708SDavid Chisnall { 587a984708SDavid Chisnall /** 597a984708SDavid Chisnall * Sets a function to be called when there is a failure in new. 607a984708SDavid Chisnall */ 617a984708SDavid Chisnall __attribute__((weak)) 627a984708SDavid Chisnall new_handler set_new_handler(new_handler handler) 637a984708SDavid Chisnall { 64f7cb1657SDavid Chisnall return ATOMIC_SWAP(&new_handl, handler); 65f7cb1657SDavid Chisnall } 66f7cb1657SDavid Chisnall __attribute__((weak)) 67f7cb1657SDavid Chisnall new_handler get_new_handler(void) 68f7cb1657SDavid Chisnall { 69f7cb1657SDavid Chisnall return ATOMIC_LOAD(&new_handl); 707a984708SDavid Chisnall } 717a984708SDavid Chisnall } 727a984708SDavid Chisnall 737a984708SDavid Chisnall 747a984708SDavid Chisnall __attribute__((weak)) 757a984708SDavid Chisnall void* operator new(size_t size) 767a984708SDavid Chisnall { 77f7cb1657SDavid Chisnall if (0 == size) 78f7cb1657SDavid Chisnall { 79f7cb1657SDavid Chisnall size = 1; 80f7cb1657SDavid Chisnall } 817a984708SDavid Chisnall void * mem = malloc(size); 827a984708SDavid Chisnall while (0 == mem) 837a984708SDavid Chisnall { 84f7cb1657SDavid Chisnall new_handler h = std::get_new_handler(); 85f7cb1657SDavid Chisnall if (0 != h) 867a984708SDavid Chisnall { 87f7cb1657SDavid Chisnall h(); 887a984708SDavid Chisnall } 897a984708SDavid Chisnall else 907a984708SDavid Chisnall { 917a984708SDavid Chisnall throw std::bad_alloc(); 927a984708SDavid Chisnall } 937a984708SDavid Chisnall mem = malloc(size); 947a984708SDavid Chisnall } 957a984708SDavid Chisnall 967a984708SDavid Chisnall return mem; 977a984708SDavid Chisnall } 987a984708SDavid Chisnall 997a984708SDavid Chisnall __attribute__((weak)) 1007a984708SDavid Chisnall void* operator new(size_t size, const std::nothrow_t &) throw() 1017a984708SDavid Chisnall { 102*4bab9fd9SDavid Chisnall try { 103*4bab9fd9SDavid Chisnall return :: operator new(size); 104*4bab9fd9SDavid Chisnall } catch (...) { 1057a984708SDavid Chisnall // nothrow operator new should return NULL in case of 1067a984708SDavid Chisnall // std::bad_alloc exception in new handler 1077a984708SDavid Chisnall return NULL; 1087a984708SDavid Chisnall } 1097a984708SDavid Chisnall } 1107a984708SDavid Chisnall 1117a984708SDavid Chisnall 1127a984708SDavid Chisnall __attribute__((weak)) 1137a984708SDavid Chisnall void operator delete(void * ptr) 114*4bab9fd9SDavid Chisnall #if __cplusplus < 201000L 115*4bab9fd9SDavid Chisnall throw() 116*4bab9fd9SDavid Chisnall #endif 1177a984708SDavid Chisnall { 1187a984708SDavid Chisnall free(ptr); 1197a984708SDavid Chisnall } 1207a984708SDavid Chisnall 1217a984708SDavid Chisnall 1227a984708SDavid Chisnall __attribute__((weak)) 1237a984708SDavid Chisnall void * operator new[](size_t size) 124*4bab9fd9SDavid Chisnall #if __cplusplus < 201000L 125*4bab9fd9SDavid Chisnall throw(std::bad_alloc) 126*4bab9fd9SDavid Chisnall #endif 1277a984708SDavid Chisnall { 1287a984708SDavid Chisnall return ::operator new(size); 1297a984708SDavid Chisnall } 1307a984708SDavid Chisnall 1317a984708SDavid Chisnall 1327a984708SDavid Chisnall __attribute__((weak)) 133*4bab9fd9SDavid Chisnall void * operator new[](size_t size, const std::nothrow_t &) throw() 134*4bab9fd9SDavid Chisnall { 135*4bab9fd9SDavid Chisnall try { 136*4bab9fd9SDavid Chisnall return ::operator new[](size); 137*4bab9fd9SDavid Chisnall } catch (...) { 138*4bab9fd9SDavid Chisnall // nothrow operator new should return NULL in case of 139*4bab9fd9SDavid Chisnall // std::bad_alloc exception in new handler 140*4bab9fd9SDavid Chisnall return NULL; 141*4bab9fd9SDavid Chisnall } 142*4bab9fd9SDavid Chisnall } 143*4bab9fd9SDavid Chisnall 144*4bab9fd9SDavid Chisnall 145*4bab9fd9SDavid Chisnall __attribute__((weak)) 146*4bab9fd9SDavid Chisnall void operator delete[](void * ptr) 147*4bab9fd9SDavid Chisnall #if __cplusplus < 201000L 148*4bab9fd9SDavid Chisnall throw() 149*4bab9fd9SDavid Chisnall #endif 1507a984708SDavid Chisnall { 1517a984708SDavid Chisnall ::operator delete(ptr); 1527a984708SDavid Chisnall } 1537a984708SDavid Chisnall 1547a984708SDavid Chisnall 155