xref: /freebsd/contrib/libcxxrt/memory.cc (revision db47c4bf212fedd87006f4949bcbacb6c58dd064)
17a984708SDavid Chisnall /**
27a984708SDavid Chisnall  * memory.cc - Contains stub definition of C++ new/delete operators.
37a984708SDavid Chisnall  *
47a984708SDavid Chisnall  * These definitions are intended to be used for testing and are weak symbols
57a984708SDavid Chisnall  * to allow them to be replaced by definitions from a STL implementation.
67a984708SDavid Chisnall  * These versions simply wrap malloc() and free(), they do not provide a
77a984708SDavid Chisnall  * C++-specific allocator.
87a984708SDavid Chisnall  */
97a984708SDavid Chisnall 
107a984708SDavid Chisnall #include <stddef.h>
117a984708SDavid Chisnall #include <stdlib.h>
127a984708SDavid Chisnall #include "stdexcept.h"
137a984708SDavid Chisnall 
14*db47c4bfSDavid Chisnall #if !__has_builtin(__sync_swap)
15*db47c4bfSDavid Chisnall #define __sync_swap __sync_lock_test_and_set
16*db47c4bfSDavid Chisnall #endif
17*db47c4bfSDavid Chisnall 
187a984708SDavid Chisnall namespace std
197a984708SDavid Chisnall {
207a984708SDavid Chisnall 	struct nothrow_t {};
217a984708SDavid Chisnall }
227a984708SDavid Chisnall 
237a984708SDavid Chisnall 
247a984708SDavid Chisnall /// The type of the function called when allocation fails.
257a984708SDavid Chisnall typedef void (*new_handler)();
267a984708SDavid Chisnall /**
277a984708SDavid Chisnall  * The function to call when allocation fails.  By default, there is no
287a984708SDavid Chisnall  * handler and a bad allocation exception is thrown if an allocation fails.
297a984708SDavid Chisnall  */
307a984708SDavid Chisnall static new_handler new_handl;
317a984708SDavid Chisnall 
327a984708SDavid Chisnall namespace std
337a984708SDavid Chisnall {
347a984708SDavid Chisnall 	/**
357a984708SDavid Chisnall 	 * Sets a function to be called when there is a failure in new.
367a984708SDavid Chisnall 	 */
377a984708SDavid Chisnall 	__attribute__((weak))
387a984708SDavid Chisnall 	new_handler set_new_handler(new_handler handler)
397a984708SDavid Chisnall 	{
40*db47c4bfSDavid Chisnall 		return __sync_swap(&new_handl, handler);
417a984708SDavid Chisnall 	}
427a984708SDavid Chisnall }
437a984708SDavid Chisnall 
447a984708SDavid Chisnall 
457a984708SDavid Chisnall __attribute__((weak))
467a984708SDavid Chisnall void* operator new(size_t size)
477a984708SDavid Chisnall {
487a984708SDavid Chisnall 	void * mem = malloc(size);
497a984708SDavid Chisnall 	while (0 == mem)
507a984708SDavid Chisnall 	{
517a984708SDavid Chisnall 		if (0 != new_handl)
527a984708SDavid Chisnall 		{
537a984708SDavid Chisnall 			new_handl();
547a984708SDavid Chisnall 		}
557a984708SDavid Chisnall 		else
567a984708SDavid Chisnall 		{
577a984708SDavid Chisnall 			throw std::bad_alloc();
587a984708SDavid Chisnall 		}
597a984708SDavid Chisnall 		mem = malloc(size);
607a984708SDavid Chisnall 	}
617a984708SDavid Chisnall 
627a984708SDavid Chisnall 	return mem;
637a984708SDavid Chisnall }
647a984708SDavid Chisnall 
657a984708SDavid Chisnall __attribute__((weak))
667a984708SDavid Chisnall void* operator new(size_t size, const std::nothrow_t &) throw()
677a984708SDavid Chisnall {
687a984708SDavid Chisnall 	void *mem = malloc(size);
697a984708SDavid Chisnall 	while (0 == mem)
707a984708SDavid Chisnall 	{
717a984708SDavid Chisnall 		if (0 != new_handl)
727a984708SDavid Chisnall 		{
737a984708SDavid Chisnall 			try
747a984708SDavid Chisnall 			{
757a984708SDavid Chisnall 				new_handl();
767a984708SDavid Chisnall 			}
777a984708SDavid Chisnall 			catch (...)
787a984708SDavid Chisnall 			{
797a984708SDavid Chisnall 				// nothrow operator new should return NULL in case of
807a984708SDavid Chisnall 				// std::bad_alloc exception in new handler
817a984708SDavid Chisnall 				return NULL;
827a984708SDavid Chisnall 			}
837a984708SDavid Chisnall 		}
847a984708SDavid Chisnall 		else
857a984708SDavid Chisnall 		{
867a984708SDavid Chisnall 			return NULL;
877a984708SDavid Chisnall 		}
887a984708SDavid Chisnall 		mem = malloc(size);
897a984708SDavid Chisnall 	}
907a984708SDavid Chisnall 
917a984708SDavid Chisnall 	return mem;
927a984708SDavid Chisnall }
937a984708SDavid Chisnall 
947a984708SDavid Chisnall 
957a984708SDavid Chisnall __attribute__((weak))
967a984708SDavid Chisnall void operator delete(void * ptr)
977a984708SDavid Chisnall {
987a984708SDavid Chisnall 	free(ptr);
997a984708SDavid Chisnall }
1007a984708SDavid Chisnall 
1017a984708SDavid Chisnall 
1027a984708SDavid Chisnall __attribute__((weak))
1037a984708SDavid Chisnall void * operator new[](size_t size)
1047a984708SDavid Chisnall {
1057a984708SDavid Chisnall 	return ::operator new(size);
1067a984708SDavid Chisnall }
1077a984708SDavid Chisnall 
1087a984708SDavid Chisnall 
1097a984708SDavid Chisnall __attribute__((weak))
110*db47c4bfSDavid Chisnall void operator delete[](void * ptr) throw()
1117a984708SDavid Chisnall {
1127a984708SDavid Chisnall 	::operator delete(ptr);
1137a984708SDavid Chisnall }
1147a984708SDavid Chisnall 
1157a984708SDavid Chisnall 
116