Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Utilize allocate_at_least #3712

Merged
merged 15 commits into from
Jun 15, 2023
Merged

Utilize allocate_at_least #3712

merged 15 commits into from
Jun 15, 2023

Conversation

Saalvage
Copy link
Contributor

@Saalvage Saalvage commented May 17, 2023

Considerations

shrink_to_fit

I have opted to not utilize allocate_at_least for shrink_to_fit (for vectors and strings), as overallocation in combination with repeated calls to shrink_to_fit would result in continuous reallocations without changing the capacity (worst case).

_Hash_vec

The internally used type _Hash_vec from xhash uses a similar system differentiating size from capacity as other containers, but documentation seems to suggest that "This implementation never has capacity() differ from size(), but the previous implementation could" (l. 281). I have assumed this is by design, if not, it can be adjusted similarly to the allocations elsewhere (probably in combination with adjusting that comment).

Tests

I think the existing tests passing is probably good enough to ascertain that no functionality is impeded, although I will be looking into writing tests to ascertain that the proper allocate_at_least method is called.

Closes #3570

@Saalvage Saalvage requested a review from a team as a code owner May 17, 2023 18:11
@CaseyCarter CaseyCarter added the performance Must go faster label May 17, 2023
@StephanTLavavej StephanTLavavej changed the title Utilize allocate_at_least #3570 Utilize allocate_at_least May 17, 2023
stl/inc/xstring Outdated Show resolved Hide resolved
@StephanTLavavej StephanTLavavej self-assigned this Jun 11, 2023
tests/std/tests/GH_003570_allocate_at_least/test.cpp Outdated Show resolved Hide resolved
tests/std/tests/GH_003570_allocate_at_least/test.cpp Outdated Show resolved Hide resolved
tests/std/tests/GH_003570_allocate_at_least/test.cpp Outdated Show resolved Hide resolved
tests/std/tests/GH_003570_allocate_at_least/test.cpp Outdated Show resolved Hide resolved
tests/std/tests/GH_003570_allocate_at_least/test.cpp Outdated Show resolved Hide resolved
stl/inc/vector Outdated Show resolved Hide resolved
stl/inc/xstring Outdated Show resolved Hide resolved
stl/inc/xstring Outdated Show resolved Hide resolved
stl/inc/xstring Show resolved Hide resolved
@StephanTLavavej

This comment was marked as resolved.

@StephanTLavavej StephanTLavavej removed their assignment Jun 13, 2023
stl/inc/xstring Outdated Show resolved Hide resolved
@StephanTLavavej StephanTLavavej self-requested a review June 14, 2023 06:44
@StephanTLavavej StephanTLavavej self-assigned this Jun 14, 2023
@StephanTLavavej StephanTLavavej removed their assignment Jun 14, 2023
@StephanTLavavej StephanTLavavej self-assigned this Jun 14, 2023
@StephanTLavavej
Copy link
Member

I'm speculatively mirroring this to the MSVC-internal repo - please notify me if any further changes are pushed.

Copy link
Member

@CaseyCarter CaseyCarter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicky things that we should defer to a cleanup PR to avoid resetting testing.

_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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we _STL_ASSERT(_Allocated >= _Count); here?


signalling_allocator() = default;

template <typename U>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with line 32 (and because tests should follow product code conventions):

Suggested change
template <typename U>
template <class U>

signalling_allocator(const signalling_allocator<U>&) {}

T* allocate(size_t count) {
T* const ptr = static_cast<T*>(malloc(count * sizeof(T)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We conventionally use auto when the initializer is a cast to avoid repeating the type:

Suggested change
T* const ptr = static_cast<T*>(malloc(count * sizeof(T)));
const auto ptr = static_cast<T*>(malloc(count * sizeof(T)));

friend bool operator==(const signalling_allocator&, const signalling_allocator&) = default;
};

template <typename T>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
template <typename T>
template <class T>

@CaseyCarter CaseyCarter removed their assignment Jun 15, 2023
@StephanTLavavej StephanTLavavej merged commit e37227e into microsoft:main Jun 15, 2023
35 checks passed
@StephanTLavavej
Copy link
Member

Thanks for helping STL containers light up with this new allocator machinery! 💡 🎉 ⚙️

@Saalvage Saalvage deleted the feature/allocate_at_least-utilization branch June 15, 2023 14:59
CaseyCarter added a commit to CaseyCarter/STL that referenced this pull request Jun 21, 2023
This reverts commit e37227e.

This broke BitCoin in Microsoft's internal Real World Code (RWC) test
suite. They publicy derive an allocator from `std::allocate`,
implementing `allocate` and `deallocate` but not `allocate_at_least`
(https://github.com/bitcoin/bitcoin/blob/f1b4975461364d5d40d2bfafc6b165dd5d7eec30/src/support/allocators/secure.h#L19-L56).
When `vector` allocates memory with `std::allocator::allocate_at_least`
and tries to free it with `secure_allocator::deallocate`, terrible
things happen.

We suspect this pattern is widespread, so we're reverting the change for now.
CaseyCarter added a commit to CaseyCarter/STL that referenced this pull request Jun 22, 2023
CaseyCarter added a commit to CaseyCarter/STL that referenced this pull request Jul 11, 2023
@CaseyCarter CaseyCarter mentioned this pull request Jul 11, 2023
achow101 added a commit to bitcoin-core/gui that referenced this pull request Jul 25, 2023
… std::allocator

07c59ed Don't derive secure_allocator from std::allocator (Casey Carter)

Pull request description:

  Giving the C++ Standard Committee control of the public interface of your type means they will break it. C++23 adds a new `allocate_at_least` member to `std::allocator`. Very bad things happen when, say, `std::vector` uses `allocate_at_least` from `secure_allocator`'s base to allocate memory which it then tries to free with `secure_allocator::deallocate`.

  (Discovered by microsoft/STL#3712, which will be reverted by microsoft/STL#3819 before it ships.)

ACKs for top commit:
  jonatack:
    re-ACK 07c59ed no change since my previous ACK apart from squashing the commits
  achow101:
    ACK 07c59ed
  john-moffett:
    ACK 07c59ed Reviewed and tested. Performance appears unaffected in my environment.

Tree-SHA512: 23606c40414d325f5605a9244d4dd50907fdf5f2fbf70f336accb3a2cb98baa8acd2972f46eab1b7fdec1d28a843a96b06083cd2d09791cda7c90ee218e5bbd5
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Aug 9, 2023
…locator

07c59ed Don't derive secure_allocator from std::allocator (Casey Carter)

Pull request description:

  Giving the C++ Standard Committee control of the public interface of your type means they will break it. C++23 adds a new `allocate_at_least` member to `std::allocator`. Very bad things happen when, say, `std::vector` uses `allocate_at_least` from `secure_allocator`'s base to allocate memory which it then tries to free with `secure_allocator::deallocate`.

  (Discovered by microsoft/STL#3712, which will be reverted by microsoft/STL#3819 before it ships.)

ACKs for top commit:
  jonatack:
    re-ACK 07c59ed no change since my previous ACK apart from squashing the commits
  achow101:
    ACK 07c59ed
  john-moffett:
    ACK 07c59ed Reviewed and tested. Performance appears unaffected in my environment.

Tree-SHA512: 23606c40414d325f5605a9244d4dd50907fdf5f2fbf70f336accb3a2cb98baa8acd2972f46eab1b7fdec1d28a843a96b06083cd2d09791cda7c90ee218e5bbd5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Must go faster
Projects
None yet
Development

Successfully merging this pull request may close these issues.

<string>, <vector>: Contiguous containers should benefit from allocate_at_least
5 participants