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