diff options
author | Eric Fiselier <eric@efcs.ca> | 2018-10-25 17:21:30 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2018-10-25 17:21:30 +0000 |
commit | f25b75b91b2d5906609bb609d39cf0ee3dcc746b (patch) | |
tree | 2e9ef3bba902796aa4763c731b857b545f2c4343 /libcxx/include/valarray | |
parent | 1e6d0aad7e90744dcaa5d9be8644dafd5181834d (diff) | |
download | bcm5719-llvm-f25b75b91b2d5906609bb609d39cf0ee3dcc746b.tar.gz bcm5719-llvm-f25b75b91b2d5906609bb609d39cf0ee3dcc746b.zip |
Implement sized deallocation for std::allocator and friends.
Summary:
C++14 sized deallocation is disabled by default due to ABI concerns. However, when a user manually enables it then libc++ should take advantage of it since sized deallocation can provide a significant performance win depending on the underlying malloc implementation. (Note that libc++'s definitions of sized delete don't do anything special yet, but users are free to provide their own).
This patch updates __libcpp_deallocate to selectively call sized operator delete when it's available. `__libcpp_deallocate_unsized` should be used when the size of the allocation is unknown.
On Apple this patch makes no attempt to determine if the sized operator delete is unavailable, only that the language feature is enabled. This could cause a compile error when using `std::allocator`, but the same compile error would occur whenever the user calls `new`, so I don't think it's a problem.
Reviewers: ldionne, mclow.lists
Reviewed By: ldionne
Subscribers: rsmith, ckennelly, libcxx-commits, christof
Differential Revision: https://reviews.llvm.org/D53120
llvm-svn: 345281
Diffstat (limited to 'libcxx/include/valarray')
-rw-r--r-- | libcxx/include/valarray | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/libcxx/include/valarray b/libcxx/include/valarray index a941e3ec441..027436dce9b 100644 --- a/libcxx/include/valarray +++ b/libcxx/include/valarray @@ -1054,7 +1054,7 @@ private: const _Up* end(const valarray<_Up>& __v); - void __clear(); + void __clear(size_t __capacity); valarray& __assign_range(const value_type* __f, const value_type* __l); }; @@ -2762,13 +2762,13 @@ valarray<_Tp>::valarray(size_t __n) try { #endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; --__n, ++__end_) + for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) ::new (__end_) value_type(); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2797,13 +2797,13 @@ valarray<_Tp>::valarray(const value_type* __p, size_t __n) try { #endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; ++__end_, ++__p, --__n) + for (size_t __n_left = __n; __n_left; ++__end_, ++__p, --__n_left) ::new (__end_) value_type(*__p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2829,7 +2829,7 @@ valarray<_Tp>::valarray(const valarray& __v) } catch (...) { - __clear(); + __clear(__v.size()); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2852,7 +2852,7 @@ valarray<_Tp>::valarray(initializer_list<value_type> __il) : __begin_(0), __end_(0) { - size_t __n = __il.size(); + const size_t __n = __il.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( @@ -2861,13 +2861,14 @@ _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); try { #endif // _LIBCPP_NO_EXCEPTIONS - for (const value_type* __p = __il.begin(); __n; ++__end_, ++__p, --__n) + size_t __n_left = __n; + for (const value_type* __p = __il.begin(); __n_left; ++__end_, ++__p, --__n_left) ::new (__end_) value_type(*__p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2881,7 +2882,7 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) : __begin_(0), __end_(0) { - size_t __n = __sa.__size_; + const size_t __n = __sa.__size_; if (__n) { __begin_ = __end_ = static_cast<value_type*>( @@ -2890,13 +2891,14 @@ valarray<_Tp>::valarray(const slice_array<value_type>& __sa) try { #endif // _LIBCPP_NO_EXCEPTIONS - for (const value_type* __p = __sa.__vp_; __n; ++__end_, __p += __sa.__stride_, --__n) + size_t __n_left = __n; + for (const value_type* __p = __sa.__vp_; __n_left; ++__end_, __p += __sa.__stride_, --__n_left) ::new (__end_) value_type(*__p); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2908,7 +2910,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) : __begin_(0), __end_(0) { - size_t __n = __ga.__1d_.size(); + const size_t __n = __ga.__1d_.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( @@ -2926,7 +2928,7 @@ valarray<_Tp>::valarray(const gslice_array<value_type>& __ga) } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2938,7 +2940,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) : __begin_(0), __end_(0) { - size_t __n = __ma.__1d_.size(); + const size_t __n = __ma.__1d_.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( @@ -2956,7 +2958,7 @@ valarray<_Tp>::valarray(const mask_array<value_type>& __ma) } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2968,7 +2970,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) : __begin_(0), __end_(0) { - size_t __n = __ia.__1d_.size(); + const size_t __n = __ia.__1d_.size(); if (__n) { __begin_ = __end_ = static_cast<value_type*>( @@ -2986,7 +2988,7 @@ valarray<_Tp>::valarray(const indirect_array<value_type>& __ia) } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS @@ -2997,7 +2999,7 @@ template <class _Tp> inline valarray<_Tp>::~valarray() { - __clear(); + __clear(size()); } template <class _Tp> @@ -3007,7 +3009,7 @@ valarray<_Tp>::__assign_range(const value_type* __f, const value_type* __l) size_t __n = __l - __f; if (size() != __n) { - __clear(); + __clear(size()); __begin_ = static_cast<value_type*>( _VSTD::__libcpp_allocate(__n * sizeof(value_type), __alignof(value_type))); __end_ = __begin_ + __n; @@ -3034,7 +3036,7 @@ inline valarray<_Tp>& valarray<_Tp>::operator=(valarray&& __v) _NOEXCEPT { - __clear(); + __clear(size()); __begin_ = __v.__begin_; __end_ = __v.__end_; __v.__begin_ = nullptr; @@ -3726,23 +3728,23 @@ valarray<_Tp>::apply(value_type __f(const value_type&)) const } template <class _Tp> -void -valarray<_Tp>::__clear() +inline _LIBCPP_INLINE_VISIBILITY +void valarray<_Tp>::__clear(size_t __capacity) { - if (__begin_ != nullptr) - { - while (__end_ != __begin_) - (--__end_)->~value_type(); - _VSTD::__libcpp_deallocate(__begin_, __alignof(value_type)); - __begin_ = __end_ = nullptr; - } + if (__begin_ != nullptr) + { + while (__end_ != __begin_) + (--__end_)->~value_type(); + _VSTD::__libcpp_deallocate(__begin_, __capacity * sizeof(value_type), __alignof(value_type)); + __begin_ = __end_ = nullptr; + } } template <class _Tp> void valarray<_Tp>::resize(size_t __n, value_type __x) { - __clear(); + __clear(size()); if (__n) { __begin_ = __end_ = static_cast<value_type*>( @@ -3751,13 +3753,13 @@ valarray<_Tp>::resize(size_t __n, value_type __x) try { #endif // _LIBCPP_NO_EXCEPTIONS - for (; __n; --__n, ++__end_) + for (size_t __n_left = __n; __n_left; --__n_left, ++__end_) ::new (__end_) value_type(__x); #ifndef _LIBCPP_NO_EXCEPTIONS } catch (...) { - __clear(); + __clear(__n); throw; } #endif // _LIBCPP_NO_EXCEPTIONS |