12061Sjkh/* 221673Sjkh * Copyright 2010-2011 PathScale, Inc. All rights reserved. 32061Sjkh * 42061Sjkh * Redistribution and use in source and binary forms, with or without 515603Smarkm * modification, are permitted provided that the following conditions are met: 62061Sjkh * 72061Sjkh * 1. Redistributions of source code must retain the above copyright notice, 83197Scsgr * this list of conditions and the following disclaimer. 920710Sasami * 1020710Sasami * 2. Redistributions in binary form must reproduce the above copyright notice, 113197Scsgr * this list of conditions and the following disclaimer in the documentation 122061Sjkh * and/or other materials provided with the distribution. 1312483Speter * 142160Scsgr * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 152834Swollman * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 162061Sjkh * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 172061Sjkh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 182160Scsgr * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1917308Speter * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2019320Sadam * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2121536Sjmacd * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 221594Srgrimes * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2317308Speter * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2417308Speter * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2517308Speter */ 2617308Speter 2717308Speter/** 2817308Speter * memory.cc - Contains stub definition of C++ new/delete operators. 2917308Speter * 3019175Sbde * These definitions are intended to be used for testing and are weak symbols 3119175Sbde * to allow them to be replaced by definitions from a STL implementation. 3219175Sbde * These versions simply wrap malloc() and free(), they do not provide a 3319175Sbde * C++-specific allocator. 3417308Speter */ 3517308Speter 362061Sjkh#include <stddef.h> 372061Sjkh#include <stdlib.h> 381594Srgrimes#include "stdexcept.h" 397407Srgrimes#include "atomic.h" 407407Srgrimes 417108Sphk 427108Sphknamespace std 437108Sphk{ 447407Srgrimes struct nothrow_t {}; 457407Srgrimes} 467407Srgrimes 477108Sphk 482061Sjkh/// The type of the function called when allocation fails. 492061Sjkhtypedef void (*new_handler)(); 502061Sjkh/** 5117308Speter * The function to call when allocation fails. By default, there is no 522061Sjkh * handler and a bad allocation exception is thrown if an allocation fails. 532061Sjkh */ 542061Sjkhstatic new_handler new_handl; 552061Sjkh 562061Sjkhnamespace std 573197Scsgr{ 582626Scsgr /** 592626Scsgr * Sets a function to be called when there is a failure in new. 602061Sjkh */ 612061Sjkh __attribute__((weak)) 622061Sjkh new_handler set_new_handler(new_handler handler) 632061Sjkh { 642061Sjkh return ATOMIC_SWAP(&new_handl, handler); 652061Sjkh } 6619320Sadam __attribute__((weak)) 672061Sjkh new_handler get_new_handler(void) 682061Sjkh { 692061Sjkh return ATOMIC_LOAD(&new_handl); 702061Sjkh } 712061Sjkh} 722061Sjkh 732061Sjkh 742061Sjkh__attribute__((weak)) 752061Sjkhvoid* operator new(size_t size) 762061Sjkh{ 772061Sjkh if (0 == size) 782834Swollman { 792834Swollman size = 1; 802834Swollman } 812834Swollman void * mem = malloc(size); 822834Swollman while (0 == mem) 832834Swollman { 841594Srgrimes new_handler h = std::get_new_handler(); 854486Sphk if (0 != h) 864486Sphk { 874486Sphk h(); 884486Sphk } 894486Sphk else 902061Sjkh { 912061Sjkh throw std::bad_alloc(); 922061Sjkh } 932061Sjkh mem = malloc(size); 942061Sjkh } 952061Sjkh 962061Sjkh return mem; 972061Sjkh} 982061Sjkh 9917308Speter__attribute__((weak)) 1002061Sjkhvoid* operator new(size_t size, const std::nothrow_t &) throw() 1012061Sjkh{ 1022061Sjkh try { 1032061Sjkh return :: operator new(size); 1042061Sjkh } catch (...) { 10512483Speter // nothrow operator new should return NULL in case of 10612483Speter // std::bad_alloc exception in new handler 10712483Speter return NULL; 10812483Speter } 1092061Sjkh} 1102061Sjkh 1118854Srgrimes 1122061Sjkh__attribute__((weak)) 1132061Sjkhvoid operator delete(void * ptr) 11412483Speter#if __cplusplus < 201000L 1152061Sjkhthrow() 11618714Sache#endif 11718714Sache{ 11818714Sache free(ptr); 11917308Speter} 12017308Speter 12117308Speter 12217308Speter__attribute__((weak)) 12321536Sjmacdvoid * operator new[](size_t size) 12415603Smarkm#if __cplusplus < 201000L 12517308Speterthrow(std::bad_alloc) 12617308Speter#endif 12717308Speter{ 12817308Speter return ::operator new(size); 12917308Speter} 13017308Speter 13117308Speter 13217308Speter__attribute__((weak)) 13317308Spetervoid * operator new[](size_t size, const std::nothrow_t &) throw() 13418362Sjkh{ 13519966Sache try { 13618362Sjkh return ::operator new[](size); 13717308Speter } catch (...) { 13817308Speter // nothrow operator new should return NULL in case of 13917308Speter // std::bad_alloc exception in new handler 14017308Speter return NULL; 14117308Speter } 14217308Speter} 14316550Sjkh 1442061Sjkh 14517308Speter__attribute__((weak)) 1462061Sjkhvoid operator delete[](void * ptr) 14717308Speter#if __cplusplus < 201000L 1482061Sjkhthrow() 14917308Speter#endif 15017308Speter{ 15117308Speter ::operator delete(ptr); 15217308Speter} 15317308Speter 15417308Speter 15517308Speter