The pmr::monotonic_buffer_resource ("pmr::mbr") strategy can only
allocate buffers; deallocation is a no-op. I chose it for
QDuplicateTracker because the tool was only used one-off: build it,
then destroy it. There were no other operations.
That changed when 090c7e3262 added
clear().
Calling pmr::unordered_set::clear() will deallocate the nodes (but not
the bucket array), but due to pmr::mbr, nothing is actually
deallocated, so memory that was freed by the container isn't actually
reused by it, later. IOW: repeated grow-clear-grow-clear cycles would
forever grow the monotonic_muffer_resource, using more and more memory
and thus appear to be leaking it.
This isn't exactly optimal behavior, so try to shed the pmr::mbr's
extra memory with a call to mbr::release().
Unfortunately, C++17 originally failed to nail down the semantics of
pmr::mbr::release(), prompting LWG 3120 in response to observed
implementation divergence. In particular, MSSTL, at the time of LWG
3120 filing, didn't appear to allow to allocate() after release(). In
our tests, it does allow it, it just never falls back to the original
(stack) buffer, and, looking at the implementation, it doesn't look
like it can do so anytime soon (it doesn't remember the buffer, and
everything is inline, so they would seem to need a BC break to fix it.
We tried to work-around the problem by hard-resetting 'res' by going
through a destroy-recreate cycle. pmr::mbr is neither copy- nor
move-constructible, so that blunt instrument is, unfortunately,
necessary (std::optional would be an alternative, but has overhead
that affects all platforms). This crashed, though, so just call
release() and handle MSSTL's failure to reuse the initial buffer as a
QoI issue.
For all platforms, before release(), we also need to make sure that
`set` no longer holds any references into it, and, since clear()
doesn't shed capacity, we need to use the C++11 version of the
swap-trick (swap is actually UB here, because the allocators differ):
move-assign a default-constructed set.
Amends 090c7e3262.
Fixes: QTBUG-132945
Pick-to: 6.5 6.2
Change-Id: I4796806e427602255439dcb1518aa9b661c7933e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 9f4325e67354ce6c4c98e7a206f17729b378dc04)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit d2c4f6df21629495ce6fe32653037b35a989d6f4)