[demangler] Fix buffer growth

The output buffer growth algorithm had a few issues:

a) An off-by-one error in the initial size check, which uses
'>='. This error was safe, but could cause us to reallocate when there
was no need.

b) An inconsistency between the initial size check (>=) and the
post-doubling check (>).  The latter was somewhat obscured by the
swapped operands.

c) There would be many reallocs with an initially-small buffer.  Add a
little initialization hysteresis.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D119177
This commit is contained in:
Nathan Sidwell 2022-02-07 11:33:08 -08:00
parent 5a43a278f7
commit 995c4f3068
2 changed files with 14 additions and 10 deletions

View File

@ -33,12 +33,14 @@ class OutputBuffer {
size_t CurrentPosition = 0;
size_t BufferCapacity = 0;
// Ensure there is at least n more positions in buffer.
// Ensure there are at least N more positions in the buffer.
void grow(size_t N) {
if (N + CurrentPosition >= BufferCapacity) {
BufferCapacity *= 2;
if (BufferCapacity < N + CurrentPosition)
BufferCapacity = N + CurrentPosition;
size_t Need = N + CurrentPosition;
if (Need > BufferCapacity) {
// Avoid many reallocations during startup, with a bit of hysteresis.
constexpr size_t MinInitAlloc = 1024;
Need = std::max(Need, MinInitAlloc);
BufferCapacity = std::max(Need, BufferCapacity * 2);
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
if (Buffer == nullptr)
std::terminate();

View File

@ -33,12 +33,14 @@ class OutputBuffer {
size_t CurrentPosition = 0;
size_t BufferCapacity = 0;
// Ensure there is at least n more positions in buffer.
// Ensure there are at least N more positions in the buffer.
void grow(size_t N) {
if (N + CurrentPosition >= BufferCapacity) {
BufferCapacity *= 2;
if (BufferCapacity < N + CurrentPosition)
BufferCapacity = N + CurrentPosition;
size_t Need = N + CurrentPosition;
if (Need > BufferCapacity) {
// Avoid many reallocations during startup, with a bit of hysteresis.
constexpr size_t MinInitAlloc = 1024;
Need = std::max(Need, MinInitAlloc);
BufferCapacity = std::max(Need, BufferCapacity * 2);
Buffer = static_cast<char *>(std::realloc(Buffer, BufferCapacity));
if (Buffer == nullptr)
std::terminate();