//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef _LIBCPP___NEW_ALLOCATE_H #define _LIBCPP___NEW_ALLOCATE_H #include <__config> #include <__cstddef/max_align_t.h> #include <__cstddef/size_t.h> #include <__new/align_val_t.h> #include <__new/global_new_delete.h> // for _LIBCPP_HAS_SIZED_DEALLOCATION #include <__type_traits/type_identity.h> #include <__utility/element_count.h> #include <__configuration/availability.h> #include <__new/global_typed_new_delete.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_CONSTEXPR inline _LIBCPP_HIDE_FROM_ABI bool __is_overaligned_for_new(size_t __align) _NOEXCEPT { #ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__ return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__; #else return __align > _LIBCPP_ALIGNOF(max_align_t); #endif } #if __has_feature(typed_cxx_new_delete) template _LIBCPP_HIDE_FROM_ABI std::__type_descriptor_t __compute_type_descriptor() { // Construct the type descriptor for the given type. We also set a bit in the // type_kind part of the summary indicating this is generated from C++. auto __descriptor = __builtin_tmo_get_type_descriptor(_Tp); auto __from_cxx = 0x00000c0000000000 | __descriptor; return std::__type_descriptor_t(__from_cxx); } # define _LIBCPP_ADD_TYPE_DESCRIPTOR(_Type) , ::std::__compute_type_descriptor<_Type>() #else # define _LIBCPP_ADD_TYPE_DESCRIPTOR(_Type) /* nothing */ #endif template inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _Tp* __libcpp_allocate(__element_count __n, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) { size_t __size = static_cast(__n) * sizeof(_Tp); #if _LIBCPP_HAS_ALIGNED_ALLOCATION if (__is_overaligned_for_new(__align)) return static_cast<_Tp*>(__builtin_operator_new(__size, static_cast(__align))); #endif return static_cast<_Tp*>(__builtin_operator_new(__size _LIBCPP_ADD_TYPE_DESCRIPTOR(_Tp))); } #if _LIBCPP_HAS_SIZED_DEALLOCATION # define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) __VA_ARGS__ #else # define _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(...) /* nothing */ #endif template inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate(__type_identity_t<_Tp>* __ptr, __element_count __n, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT { [[__maybe_unused__]] size_t __size = static_cast(__n) * sizeof(_Tp); #if _LIBCPP_HAS_ALIGNED_ALLOCATION if (__is_overaligned_for_new(__align)) return __builtin_operator_delete( __ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size), static_cast(__align)); #endif return __builtin_operator_delete(__ptr _LIBCPP_ONLY_IF_SIZED_DEALLOCATION(, __size)); } #undef _LIBCPP_ONLY_IF_SIZED_DEALLOCATION template inline _LIBCPP_HIDE_FROM_ABI void __libcpp_deallocate_unsized( __type_identity_t<_Tp>* __ptr, [[__maybe_unused__]] size_t __align = _LIBCPP_ALIGNOF(_Tp)) _NOEXCEPT { #if _LIBCPP_HAS_ALIGNED_ALLOCATION if (__is_overaligned_for_new(__align)) return __builtin_operator_delete(__ptr, static_cast(__align)); #endif return __builtin_operator_delete(__ptr); } _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP___NEW_ALLOCATE_H