/*1* Copyright 2010-2011 PathScale, Inc. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions are met:5*6* 1. Redistributions of source code must retain the above copyright notice,7* this list of conditions and the following disclaimer.8*9* 2. Redistributions in binary form must reproduce the above copyright notice,10* this list of conditions and the following disclaimer in the documentation11* and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS14* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,15* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR16* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR17* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,18* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,19* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;20* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,21* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR22* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF23* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/2526/**27* memory.cc - Contains stub definition of C++ new/delete operators.28*29* These definitions are intended to be used for testing and are weak symbols30* to allow them to be replaced by definitions from a STL implementation.31* These versions simply wrap malloc() and free(), they do not provide a32* C++-specific allocator.33*/3435#include <stddef.h>36#include <stdlib.h>37#include "stdexcept.h"38#include "atomic.h"394041namespace std42{43struct nothrow_t {};44}454647/// The type of the function called when allocation fails.48typedef void (*new_handler)();49/**50* The function to call when allocation fails. By default, there is no51* handler and a bad allocation exception is thrown if an allocation fails.52*/53static atomic<new_handler> new_handl{nullptr};5455namespace std56{57/**58* Sets a function to be called when there is a failure in new.59*/60__attribute__((weak))61new_handler set_new_handler(new_handler handler)62{63return new_handl.exchange(handler);64}6566__attribute__((weak))67new_handler get_new_handler(void)68{69return new_handl.load();70}71}727374#if __cplusplus < 201103L75#define BADALLOC throw(std::bad_alloc)76#else77#define BADALLOC78#endif7980namespace81{82/**83* Helper for forwarding from no-throw operators to versions that can84* return nullptr. Catches any exception and converts it into a nullptr85* return.86*/87template<void*(New)(size_t)>88void *noexcept_new(size_t size)89{90#if !defined(_CXXRT_NO_EXCEPTIONS)91try92{93return New(size);94} catch (...)95{96// nothrow operator new should return NULL in case of97// std::bad_alloc exception in new handler98return nullptr;99}100#else101return New(size);102#endif103}104}105106107__attribute__((weak))108void* operator new(size_t size) BADALLOC109{110if (0 == size)111{112size = 1;113}114void * mem = malloc(size);115while (0 == mem)116{117new_handler h = std::get_new_handler();118if (0 != h)119{120h();121}122else123{124#if !defined(_CXXRT_NO_EXCEPTIONS)125throw std::bad_alloc();126#else127break;128#endif129}130mem = malloc(size);131}132133return mem;134}135136137__attribute__((weak))138void* operator new(size_t size, const std::nothrow_t &) _LIBCXXRT_NOEXCEPT139{140return noexcept_new<(::operator new)>(size);141}142143144__attribute__((weak))145void operator delete(void * ptr) _LIBCXXRT_NOEXCEPT146{147free(ptr);148}149150151__attribute__((weak))152void * operator new[](size_t size) BADALLOC153{154return ::operator new(size);155}156157158__attribute__((weak))159void * operator new[](size_t size, const std::nothrow_t &) _LIBCXXRT_NOEXCEPT160{161return noexcept_new<(::operator new[])>(size);162}163164165__attribute__((weak))166void operator delete[](void * ptr) _LIBCXXRT_NOEXCEPT167{168::operator delete(ptr);169}170171// C++14 additional delete operators172173#if __cplusplus >= 201402L174175__attribute__((weak))176void operator delete(void * ptr, size_t) _LIBCXXRT_NOEXCEPT177{178::operator delete(ptr);179}180181182__attribute__((weak))183void operator delete[](void * ptr, size_t) _LIBCXXRT_NOEXCEPT184{185::operator delete(ptr);186}187188#endif189190191