[llvm] 995c4f3 - [demangler] Fix buffer growth

Nathan Sidwell via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 14 03:59:46 PST 2022


Author: Nathan Sidwell
Date: 2022-02-14T03:59:31-08:00
New Revision: 995c4f306890ad379de19106f053238ce89f1483

URL: https://github.com/llvm/llvm-project/commit/995c4f306890ad379de19106f053238ce89f1483
DIFF: https://github.com/llvm/llvm-project/commit/995c4f306890ad379de19106f053238ce89f1483.diff

LOG: [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

Added: 
    

Modified: 
    libcxxabi/src/demangle/Utility.h
    llvm/include/llvm/Demangle/Utility.h

Removed: 
    


################################################################################
diff  --git a/libcxxabi/src/demangle/Utility.h b/libcxxabi/src/demangle/Utility.h
index 93ef2aae34ba8..97272ae64fb75 100644
--- a/libcxxabi/src/demangle/Utility.h
+++ b/libcxxabi/src/demangle/Utility.h
@@ -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();

diff  --git a/llvm/include/llvm/Demangle/Utility.h b/llvm/include/llvm/Demangle/Utility.h
index 58b1954ec82a5..df520f5cbc96d 100644
--- a/llvm/include/llvm/Demangle/Utility.h
+++ b/llvm/include/llvm/Demangle/Utility.h
@@ -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();


        


More information about the llvm-commits mailing list