Path: blob/main/contrib/llvm-project/libcxx/src/new.cpp
35154 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "include/overridable_function.h"9#include <__assert>10#include <__memory/aligned_alloc.h>11#include <cstddef>12#include <cstdlib>13#include <new>1415#if !defined(__GLIBCXX__) && !defined(_LIBCPP_ABI_VCRUNTIME)1617// The code below is copied as-is into libc++abi's libcxxabi/src/stdlib_new_delete.cpp18// file. The version in this file is the canonical one.1920inline void __throw_bad_alloc_shim() { std::__throw_bad_alloc(); }2122# define _LIBCPP_ASSERT_SHIM(expr, str) _LIBCPP_ASSERT(expr, str)2324// ------------------ BEGIN COPY ------------------25// Implement all new and delete operators as weak definitions26// in this shared library, so that they can be overridden by programs27// that define non-weak copies of the functions.2829static void* operator_new_impl(std::size_t size) {30if (size == 0)31size = 1;32void* p;33while ((p = std::malloc(size)) == nullptr) {34// If malloc fails and there is a new_handler,35// call it to try free up memory.36std::new_handler nh = std::get_new_handler();37if (nh)38nh();39else40break;41}42return p;43}4445_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC {46void* p = operator_new_impl(size);47if (p == nullptr)48__throw_bad_alloc_shim();49return p;50}5152_LIBCPP_WEAK void* operator new(size_t size, const std::nothrow_t&) noexcept {53# ifdef _LIBCPP_HAS_NO_EXCEPTIONS54# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION55_LIBCPP_ASSERT_SHIM(56!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)),57"libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, "58"but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because "59"`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case "60"it fails to allocate, making it impossible for `operator new(size_t, nothrow_t)` to fulfill its "61"contract (since it should return nullptr upon failure). Please make sure you override "62"`operator new(size_t, nothrow_t)` as well.");63# endif6465return operator_new_impl(size);66# else67void* p = nullptr;68try {69p = ::operator new(size);70} catch (...) {71}72return p;73# endif74}7576_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC {77return ::operator new(size);78}7980_LIBCPP_WEAK void* operator new[](size_t size, const std::nothrow_t&) noexcept {81# ifdef _LIBCPP_HAS_NO_EXCEPTIONS82# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION83_LIBCPP_ASSERT_SHIM(84!std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])),85"libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, "86"but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because "87"`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case "88"it fails to allocate, making it impossible for `operator new[](size_t, nothrow_t)` to fulfill its "89"contract (since it should return nullptr upon failure). Please make sure you override "90"`operator new[](size_t, nothrow_t)` as well.");91# endif9293return operator_new_impl(size);94# else95void* p = nullptr;96try {97p = ::operator new[](size);98} catch (...) {99}100return p;101# endif102}103104_LIBCPP_WEAK void operator delete(void* ptr) noexcept { std::free(ptr); }105106_LIBCPP_WEAK void operator delete(void* ptr, const std::nothrow_t&) noexcept { ::operator delete(ptr); }107108_LIBCPP_WEAK void operator delete(void* ptr, size_t) noexcept { ::operator delete(ptr); }109110_LIBCPP_WEAK void operator delete[](void* ptr) noexcept { ::operator delete(ptr); }111112_LIBCPP_WEAK void operator delete[](void* ptr, const std::nothrow_t&) noexcept { ::operator delete[](ptr); }113114_LIBCPP_WEAK void operator delete[](void* ptr, size_t) noexcept { ::operator delete[](ptr); }115116# if !defined(_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION)117118static void* operator_new_aligned_impl(std::size_t size, std::align_val_t alignment) {119if (size == 0)120size = 1;121if (static_cast<size_t>(alignment) < sizeof(void*))122alignment = std::align_val_t(sizeof(void*));123124// Try allocating memory. If allocation fails and there is a new_handler,125// call it to try free up memory, and try again until it succeeds, or until126// the new_handler decides to terminate.127void* p;128while ((p = std::__libcpp_aligned_alloc(static_cast<std::size_t>(alignment), size)) == nullptr) {129std::new_handler nh = std::get_new_handler();130if (nh)131nh();132else133break;134}135return p;136}137138_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*139operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {140void* p = operator_new_aligned_impl(size, alignment);141if (p == nullptr)142__throw_bad_alloc_shim();143return p;144}145146_LIBCPP_WEAK void* operator new(size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {147# ifdef _LIBCPP_HAS_NO_EXCEPTIONS148# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION149_LIBCPP_ASSERT_SHIM(150!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)),151"libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, "152"but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "153"`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will "154"terminate in case it fails to allocate, making it impossible for `operator new(size_t, align_val_t, nothrow_t)` "155"to fulfill its contract (since it should return nullptr upon failure). Please make sure you override "156"`operator new(size_t, align_val_t, nothrow_t)` as well.");157# endif158159return operator_new_aligned_impl(size, alignment);160# else161void* p = nullptr;162try {163p = ::operator new(size, alignment);164} catch (...) {165}166return p;167# endif168}169170_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void*171operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC {172return ::operator new(size, alignment);173}174175_LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept {176# ifdef _LIBCPP_HAS_NO_EXCEPTIONS177# if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION178_LIBCPP_ASSERT_SHIM(179!std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])),180"libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, "181"but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because "182"`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will "183"terminate in case it fails to allocate, making it impossible for `operator new[](size_t, align_val_t, "184"nothrow_t)` to fulfill its contract (since it should return nullptr upon failure). Please make sure you "185"override "186"`operator new[](size_t, align_val_t, nothrow_t)` as well.");187# endif188189return operator_new_aligned_impl(size, alignment);190# else191void* p = nullptr;192try {193p = ::operator new[](size, alignment);194} catch (...) {195}196return p;197# endif198}199200_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t) noexcept { std::__libcpp_aligned_free(ptr); }201202_LIBCPP_WEAK void operator delete(void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {203::operator delete(ptr, alignment);204}205206_LIBCPP_WEAK void operator delete(void* ptr, size_t, std::align_val_t alignment) noexcept {207::operator delete(ptr, alignment);208}209210_LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment) noexcept {211::operator delete(ptr, alignment);212}213214_LIBCPP_WEAK void operator delete[](void* ptr, std::align_val_t alignment, const std::nothrow_t&) noexcept {215::operator delete[](ptr, alignment);216}217218_LIBCPP_WEAK void operator delete[](void* ptr, size_t, std::align_val_t alignment) noexcept {219::operator delete[](ptr, alignment);220}221222# endif // !_LIBCPP_HAS_NO_LIBRARY_ALIGNED_ALLOCATION223// ------------------ END COPY ------------------224225#endif // !__GLIBCXX__ && !_LIBCPP_ABI_VCRUNTIME226227228