Skip to content

Commit

Permalink
Deallocate at least (microsoft#3819)
Browse files Browse the repository at this point in the history
Co-authored-by: Stephan T. Lavavej <[email protected]>
  • Loading branch information
CaseyCarter and StephanTLavavej authored Jun 23, 2023
1 parent c5f1960 commit 40640c6
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 210 deletions.
5 changes: 2 additions & 3 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -1557,13 +1557,12 @@ private:

_Newsize *= 2;
}
_Count = _Newsize - _Mapsize();

size_type _Myboff = _Myoff() / _Block_size;
_Mapptr _Newmap = _Allocate_at_least_helper(_Almap, _Newsize);
_Mapptr _Newmap = _Almap.allocate(_Mapsize() + _Count);
_Mapptr _Myptr = _Newmap + _Myboff;

_Count = _Newsize - _Mapsize();

_Myptr = _STD uninitialized_copy(_Map() + _Myboff, _Map() + _Mapsize(), _Myptr); // copy initial to end
if (_Myboff <= _Count) { // increment greater than offset of initial block
_Myptr = _STD uninitialized_copy(_Map(), _Map() + _Myboff, _Myptr); // copy rest of old
Expand Down
9 changes: 4 additions & 5 deletions stl/inc/sstream
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ protected:
return _Traits::eof();
}

const auto _Newptr = _Unfancy(_Allocate_at_least_helper(_Al, _Newsize));
const auto _Newptr = _Unfancy(_Al.allocate(_Newsize));
_Traits::copy(_Newptr, _Oldptr, _Oldsize);

const auto _New_pnext = _Newptr + _Oldsize;
Expand Down Expand Up @@ -430,7 +430,7 @@ protected:
return pos_type{_Off};
}

void _Init(const _Elem* _Ptr, const _Mysize_type _Count, int _State) {
void _Init(const _Elem* _Ptr, _Mysize_type _Count, int _State) {
// initialize buffer to [_Ptr, _Ptr + _Count), set state
_State &= ~_From_rvalue;

Expand All @@ -440,10 +440,9 @@ protected:

if (_Count != 0 && (_State & (_Noread | _Constant)) != (_Noread | _Constant)) {
// finite buffer that can be read or written, set it up
_Mysize_type _Newsize = _Count;
const auto _Pnew = _Unfancy(_Allocate_at_least_helper(_Al, _Newsize));
const auto _Pnew = _Unfancy(_Al.allocate(_Count));
_Traits::copy(_Pnew, _Ptr, _Count);
_Seekhigh = _Pnew + _Newsize;
_Seekhigh = _Pnew + _Count;

if (!(_State & _Noread)) {
_Mysb::setg(_Pnew, _Pnew, _Seekhigh); // setup read buffer
Expand Down
13 changes: 6 additions & 7 deletions stl/inc/syncstream
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ public:
if (_Al != _Right_al) {
_Tidy();

_Size_type _Right_buf_size = _Right._Get_buffer_size();
const _Size_type _Right_buf_size = _Right._Get_buffer_size();
const _Size_type _Right_data_size = _Right._Get_data_size();

_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Al, _Right_buf_size));
_Elem* const _New_ptr = _Unfancy(_Al.allocate(_Right_buf_size));
_Traits::copy(_New_ptr, _Right.pbase(), _Right_data_size);

streambuf_type::setp(_New_ptr, _New_ptr + _Right_data_size, _New_ptr + _Right_buf_size);
Expand Down Expand Up @@ -217,11 +217,11 @@ protected:
return _Traits::eof();
}

_Size_type _New_capacity = _Calculate_growth(_Buf_size, _Buf_size + 1, _Max_allocation);
const _Size_type _New_capacity = _Calculate_growth(_Buf_size, _Buf_size + 1, _Max_allocation);
_Elem* const _Old_ptr = streambuf_type::pbase();
const _Size_type _Old_data_size = _Get_data_size();

_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Al, _New_capacity));
_Elem* const _New_ptr = _Unfancy(_Al.allocate(_New_capacity));
_Traits::copy(_New_ptr, _Old_ptr, _Old_data_size);
if (0 < _Buf_size) {
_Al.deallocate(_Refancy<_Pointer>(_Old_ptr), _Buf_size);
Expand All @@ -237,9 +237,8 @@ private:
static constexpr _Size_type _Min_size = 32; // constant for minimum buffer size

void _Init() {
_Size_type _New_capacity = _Min_size;
_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Getal(), _New_capacity));
streambuf_type::setp(_New_ptr, _New_ptr + _New_capacity);
_Elem* const _New_ptr = _Unfancy(_Getal().allocate(_Min_size));
streambuf_type::setp(_New_ptr, _New_ptr + _Min_size);
}

void _Tidy() noexcept {
Expand Down
60 changes: 25 additions & 35 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -825,10 +825,10 @@ private:
_Xlength();
}

const size_type _Newsize = _Oldsize + 1;
size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + 1;
const size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Constructed_last = _Newvec + _Whereoff + 1;
pointer _Constructed_first = _Constructed_last;

Expand Down Expand Up @@ -912,10 +912,10 @@ private:
_Xlength();
}

const size_type _Newsize = _Oldsize + _Count;
size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + _Count;
const size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Constructed_last = _Newvec + _Oldsize + _Count;
pointer _Constructed_first = _Constructed_last;

Expand Down Expand Up @@ -1033,10 +1033,10 @@ public:
_Xlength();
}

const size_type _Newsize = _Oldsize + _Count;
size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + _Count;
const size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
pointer _Constructed_first = _Constructed_last;

Expand Down Expand Up @@ -1128,10 +1128,10 @@ private:
_Xlength();
}

const size_type _Newsize = _Oldsize + _Count;
size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + _Count;
const size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Newvec = _Al.allocate(_Newcapacity);
const auto _Whereoff = static_cast<size_type>(_Whereptr - _Oldfirst);
const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
pointer _Constructed_first = _Constructed_last;
Expand Down Expand Up @@ -1518,10 +1518,10 @@ private:
pointer& _Myfirst = _My_data._Myfirst;
pointer& _Mylast = _My_data._Mylast;

const auto _Oldsize = static_cast<size_type>(_Mylast - _Myfirst);
size_type _Newcapacity = _Calculate_growth(_Newsize);
const auto _Oldsize = static_cast<size_type>(_Mylast - _Myfirst);
const size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Appended_first = _Newvec + _Oldsize;
pointer _Appended_last = _Appended_first;

Expand Down Expand Up @@ -1598,10 +1598,7 @@ public:
}

private:
enum class _Reallocation_policy { _At_least, _Exactly };

template <_Reallocation_policy _Policy>
_CONSTEXPR20 void _Reallocate(size_type& _Newcapacity) {
_CONSTEXPR20 void _Reallocate_exactly(const size_type _Newcapacity) {
// set capacity to _Newcapacity (without geometric growth), provide strong guarantee
auto& _Al = _Getal();
auto& _My_data = _Mypair._Myval2;
Expand All @@ -1610,13 +1607,7 @@ private:

const auto _Size = static_cast<size_type>(_Mylast - _Myfirst);

pointer _Newvec;
if constexpr (_Policy == _Reallocation_policy::_At_least) {
_Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
} else {
_STL_INTERNAL_STATIC_ASSERT(_Policy == _Reallocation_policy::_Exactly);
_Newvec = _Al.allocate(_Newcapacity);
}
const pointer _Newvec = _Al.allocate(_Newcapacity);

_TRY_BEGIN
if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) {
Expand Down Expand Up @@ -1684,14 +1675,14 @@ private:
}

public:
_CONSTEXPR20 void reserve(_CRT_GUARDOVERFLOW size_type _Newcapacity) {
_CONSTEXPR20 void reserve(_CRT_GUARDOVERFLOW const size_type _Newcapacity) {
// increase capacity to _Newcapacity (without geometric growth), provide strong guarantee
if (_Newcapacity > capacity()) { // something to do (reserve() never shrinks)
if (_Newcapacity > max_size()) {
_Xlength();
}

_Reallocate<_Reallocation_policy::_At_least>(_Newcapacity);
_Reallocate_exactly(_Newcapacity);
}
}

Expand All @@ -1703,8 +1694,7 @@ public:
if (_Oldfirst == _Oldlast) {
_Tidy();
} else {
size_type _Newcapacity = static_cast<size_type>(_Oldlast - _Oldfirst);
_Reallocate<_Reallocation_policy::_Exactly>(_Newcapacity);
_Reallocate_exactly(static_cast<size_type>(_Oldlast - _Oldfirst));
}
}
}
Expand Down Expand Up @@ -1986,7 +1976,7 @@ private:
return _Geometric; // geometric growth is sufficient
}

_CONSTEXPR20 void _Buy_raw(size_type _Newcapacity) {
_CONSTEXPR20 void _Buy_raw(const size_type _Newcapacity) {
// allocate array with _Newcapacity elements
auto& _My_data = _Mypair._Myval2;
pointer& _Myfirst = _My_data._Myfirst;
Expand All @@ -1996,10 +1986,10 @@ private:
_STL_INTERNAL_CHECK(!_Myfirst && !_Mylast && !_Myend); // check that *this is tidy
_STL_INTERNAL_CHECK(0 < _Newcapacity && _Newcapacity <= max_size());

const pointer _Newvec = _Allocate_at_least_helper(_Getal(), _Newcapacity);
_Myfirst = _Newvec;
_Mylast = _Newvec;
_Myend = _Newvec + _Newcapacity;
const auto _Newvec = _Getal().allocate(_Newcapacity);
_Myfirst = _Newvec;
_Mylast = _Newvec;
_Myend = _Newvec + _Newcapacity;
}

_CONSTEXPR20 void _Buy_nonzero(const size_type _Newcapacity) {
Expand Down
12 changes: 0 additions & 12 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2174,18 +2174,6 @@ _NODISCARD constexpr bool _Allocators_equal(const _Alloc& _Lhs, const _Alloc& _R
}
}

template <class _Alloc>
_NODISCARD_RAW_PTR_ALLOC _CONSTEXPR20 typename allocator_traits<_Alloc>::pointer _Allocate_at_least_helper(
_Alloc& _Al, _CRT_GUARDOVERFLOW typename allocator_traits<_Alloc>::size_type& _Count) {
#if _HAS_CXX23
auto [_Ptr, _Allocated] = allocator_traits<_Alloc>::allocate_at_least(_Al, _Count);
_Count = _Allocated;
return _Ptr;
#else // _HAS_CXX23
return _Al.allocate(_Count);
#endif // _HAS_CXX23
}

_EXPORT_STD template <class _FwdIt, class _Ty>
_NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val) {
// remove each matching _Val
Expand Down
61 changes: 22 additions & 39 deletions stl/inc/xstring
Original file line number Diff line number Diff line change
Expand Up @@ -2647,11 +2647,9 @@ private:
return;
}

_My_data._Myres = _BUF_SIZE - 1;
size_type _New_capacity = _Calculate_growth(_Count);
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
_My_data._Myres = _BUF_SIZE - 1;
const size_type _New_capacity = _Calculate_growth(_Count);
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
_Construct_in_place(_My_data._Bx._Ptr, _New_ptr);

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
Expand Down Expand Up @@ -2693,10 +2691,8 @@ private:
}

if (_Count >= _BUF_SIZE) {
size_type _New_capacity = _Calculate_growth(_Count);
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
const size_type _New_capacity = _Calculate_growth(_Count);
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
_Construct_in_place(_My_data._Bx._Ptr, _New_ptr);
_My_data._Myres = _New_capacity;

Expand All @@ -2712,11 +2708,9 @@ private:
_Xlen_string(); // result too long
}

const auto _Old_ptr = _My_data._Myptr();
size_type _New_capacity = _Calculate_growth(_My_data._Mysize);
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
const auto _Old_ptr = _My_data._Myptr();
const size_type _New_capacity = _Calculate_growth(_My_data._Mysize);
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
_Traits::copy(_Unfancy(_New_ptr), _Old_ptr, _My_data._Mysize);
Expand Down Expand Up @@ -2798,11 +2792,9 @@ public:
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); // throws

if (_New_capacity < _New_size) {
_New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, max_size());
++_New_capacity;
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
--_New_capacity;
_Ptr = _Unfancy(_Fancyptr);
_New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, max_size());
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
_Ptr = _Unfancy(_Fancyptr);
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);

_Start_element_lifetimes(_Ptr, _New_capacity + 1);
Expand Down Expand Up @@ -2871,12 +2863,10 @@ public:
_Xlen_string();
}

auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
const auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); // throws
++_New_capacity;
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
--_New_capacity;
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
// nothrow hereafter
_Start_element_lifetimes(_Unfancy(_Fancyptr), _New_capacity + 1);
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);
Expand Down Expand Up @@ -2956,10 +2946,9 @@ public:
_Result._Res = _My_data._Myres + 1;
} else {
// use _BUF_SIZE + 1 to avoid SSO, if the buffer is assigned back
size_type _Allocated = _BUF_SIZE + 1;
_Result._Ptr = _Allocate_at_least_helper(_Al, _Allocated);
_Result._Ptr = _Al.allocate(_BUF_SIZE + 1);
_Traits::copy(_Unfancy(_Result._Ptr), _My_data._Bx._Buf, _BUF_SIZE);
_Result._Res = _Allocated;
_Result._Res = _BUF_SIZE + 1;
}
_My_data._Orphan_all();
_Tidy_init();
Expand Down Expand Up @@ -3178,11 +3167,9 @@ public:

if (_Right._Mypair._Myval2._Large_string_engaged()) {
const auto _New_size = _Right._Mypair._Myval2._Mysize;
auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
const auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
auto _Right_al_non_const = _Right_al;
++_New_capacity;
const auto _New_ptr = _Allocate_at_least_helper(_Right_al_non_const, _New_capacity); // throws
--_New_capacity;
const auto _New_ptr = _Right_al_non_const.allocate(_New_capacity + 1); // throws

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);

Expand Down Expand Up @@ -4749,11 +4736,9 @@ private:
}

const size_type _Old_capacity = _Mypair._Myval2._Myres;
size_type _New_capacity = _Calculate_growth(_New_size);
const size_type _New_capacity = _Calculate_growth(_New_size);
auto& _Al = _Getal();
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
_Mypair._Myval2._Orphan_all();
Expand Down Expand Up @@ -4784,11 +4769,9 @@ private:

const size_type _New_size = _Old_size + _Size_increase;
const size_type _Old_capacity = _My_data._Myres;
size_type _New_capacity = _Calculate_growth(_New_size);
const size_type _New_capacity = _Calculate_growth(_New_size);
auto& _Al = _Getal();
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
_My_data._Orphan_all();
Expand Down
1 change: 0 additions & 1 deletion tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ tests\GH_003022_substr_allocator
tests\GH_003105_piecewise_densities
tests\GH_003119_error_category_ctor
tests\GH_003246_cmath_narrowing
tests\GH_003570_allocate_at_least
tests\GH_003572_fstream_seekp_0_cur
tests\GH_003617_vectorized_meow_element
tests\GH_003676_format_large_hh_mm_ss_values
Expand Down
4 changes: 0 additions & 4 deletions tests/std/tests/GH_003570_allocate_at_least/env.lst

This file was deleted.

Loading

0 comments on commit 40640c6

Please sign in to comment.