1*94e3ee44SDavid Chisnall /* 2*94e3ee44SDavid Chisnall * Copyright 2010-2011 PathScale, Inc. All rights reserved. 3*94e3ee44SDavid Chisnall * 4*94e3ee44SDavid Chisnall * Redistribution and use in source and binary forms, with or without 5*94e3ee44SDavid Chisnall * modification, are permitted provided that the following conditions are met: 6*94e3ee44SDavid Chisnall * 7*94e3ee44SDavid Chisnall * 1. Redistributions of source code must retain the above copyright notice, 8*94e3ee44SDavid Chisnall * this list of conditions and the following disclaimer. 9*94e3ee44SDavid Chisnall * 10*94e3ee44SDavid Chisnall * 2. Redistributions in binary form must reproduce the above copyright notice, 11*94e3ee44SDavid Chisnall * this list of conditions and the following disclaimer in the documentation 12*94e3ee44SDavid Chisnall * and/or other materials provided with the distribution. 13*94e3ee44SDavid Chisnall * 14*94e3ee44SDavid Chisnall * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 15*94e3ee44SDavid Chisnall * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16*94e3ee44SDavid Chisnall * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17*94e3ee44SDavid Chisnall * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 18*94e3ee44SDavid Chisnall * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19*94e3ee44SDavid Chisnall * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20*94e3ee44SDavid Chisnall * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21*94e3ee44SDavid Chisnall * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22*94e3ee44SDavid Chisnall * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23*94e3ee44SDavid Chisnall * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24*94e3ee44SDavid Chisnall * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*94e3ee44SDavid Chisnall */ 26*94e3ee44SDavid 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" 397a984708SDavid Chisnall 40*94e3ee44SDavid Chisnall #ifndef __has_builtin 41*94e3ee44SDavid Chisnall #define __has_builtin(x) 0 42*94e3ee44SDavid Chisnall #endif 43*94e3ee44SDavid Chisnall 44db47c4bfSDavid Chisnall #if !__has_builtin(__sync_swap) 45db47c4bfSDavid Chisnall #define __sync_swap __sync_lock_test_and_set 46db47c4bfSDavid Chisnall #endif 47db47c4bfSDavid Chisnall 487a984708SDavid Chisnall namespace std 497a984708SDavid Chisnall { 507a984708SDavid Chisnall struct nothrow_t {}; 517a984708SDavid Chisnall } 527a984708SDavid Chisnall 537a984708SDavid Chisnall 547a984708SDavid Chisnall /// The type of the function called when allocation fails. 557a984708SDavid Chisnall typedef void (*new_handler)(); 567a984708SDavid Chisnall /** 577a984708SDavid Chisnall * The function to call when allocation fails. By default, there is no 587a984708SDavid Chisnall * handler and a bad allocation exception is thrown if an allocation fails. 597a984708SDavid Chisnall */ 607a984708SDavid Chisnall static new_handler new_handl; 617a984708SDavid Chisnall 627a984708SDavid Chisnall namespace std 637a984708SDavid Chisnall { 647a984708SDavid Chisnall /** 657a984708SDavid Chisnall * Sets a function to be called when there is a failure in new. 667a984708SDavid Chisnall */ 677a984708SDavid Chisnall __attribute__((weak)) 687a984708SDavid Chisnall new_handler set_new_handler(new_handler handler) 697a984708SDavid Chisnall { 70db47c4bfSDavid Chisnall return __sync_swap(&new_handl, handler); 717a984708SDavid Chisnall } 727a984708SDavid Chisnall } 737a984708SDavid Chisnall 747a984708SDavid Chisnall 757a984708SDavid Chisnall __attribute__((weak)) 767a984708SDavid Chisnall void* operator new(size_t size) 777a984708SDavid Chisnall { 787a984708SDavid Chisnall void * mem = malloc(size); 797a984708SDavid Chisnall while (0 == mem) 807a984708SDavid Chisnall { 817a984708SDavid Chisnall if (0 != new_handl) 827a984708SDavid Chisnall { 837a984708SDavid Chisnall new_handl(); 847a984708SDavid Chisnall } 857a984708SDavid Chisnall else 867a984708SDavid Chisnall { 877a984708SDavid Chisnall throw std::bad_alloc(); 887a984708SDavid Chisnall } 897a984708SDavid Chisnall mem = malloc(size); 907a984708SDavid Chisnall } 917a984708SDavid Chisnall 927a984708SDavid Chisnall return mem; 937a984708SDavid Chisnall } 947a984708SDavid Chisnall 957a984708SDavid Chisnall __attribute__((weak)) 967a984708SDavid Chisnall void* operator new(size_t size, const std::nothrow_t &) throw() 977a984708SDavid Chisnall { 987a984708SDavid Chisnall void *mem = malloc(size); 997a984708SDavid Chisnall while (0 == mem) 1007a984708SDavid Chisnall { 1017a984708SDavid Chisnall if (0 != new_handl) 1027a984708SDavid Chisnall { 1037a984708SDavid Chisnall try 1047a984708SDavid Chisnall { 1057a984708SDavid Chisnall new_handl(); 1067a984708SDavid Chisnall } 1077a984708SDavid Chisnall catch (...) 1087a984708SDavid Chisnall { 1097a984708SDavid Chisnall // nothrow operator new should return NULL in case of 1107a984708SDavid Chisnall // std::bad_alloc exception in new handler 1117a984708SDavid Chisnall return NULL; 1127a984708SDavid Chisnall } 1137a984708SDavid Chisnall } 1147a984708SDavid Chisnall else 1157a984708SDavid Chisnall { 1167a984708SDavid Chisnall return NULL; 1177a984708SDavid Chisnall } 1187a984708SDavid Chisnall mem = malloc(size); 1197a984708SDavid Chisnall } 1207a984708SDavid Chisnall 1217a984708SDavid Chisnall return mem; 1227a984708SDavid Chisnall } 1237a984708SDavid Chisnall 1247a984708SDavid Chisnall 1257a984708SDavid Chisnall __attribute__((weak)) 1267a984708SDavid Chisnall void operator delete(void * ptr) 1277a984708SDavid Chisnall { 1287a984708SDavid Chisnall free(ptr); 1297a984708SDavid Chisnall } 1307a984708SDavid Chisnall 1317a984708SDavid Chisnall 1327a984708SDavid Chisnall __attribute__((weak)) 1337a984708SDavid Chisnall void * operator new[](size_t size) 1347a984708SDavid Chisnall { 1357a984708SDavid Chisnall return ::operator new(size); 1367a984708SDavid Chisnall } 1377a984708SDavid Chisnall 1387a984708SDavid Chisnall 1397a984708SDavid Chisnall __attribute__((weak)) 140db47c4bfSDavid Chisnall void operator delete[](void * ptr) throw() 1417a984708SDavid Chisnall { 1427a984708SDavid Chisnall ::operator delete(ptr); 1437a984708SDavid Chisnall } 1447a984708SDavid Chisnall 1457a984708SDavid Chisnall 146