[demangler] Improve buffer hysteresis
authorNathan Sidwell <nathan@acm.org>
Wed, 16 Feb 2022 16:03:24 +0000 (08:03 -0800)
committerNathan Sidwell <nathan@acm.org>
Tue, 1 Mar 2022 12:37:24 +0000 (04:37 -0800)
Improve demangler buffer hysteresis.  If we needed more than double
the buffer, the original code would allocate exactly the amount
needed, and thus consequently the next request would also realloc.
We're very unlikely to get into wanting more than double, after the
first allocation, as it would require the user to have used an
identifier larger than the hysteresis.  With machine generated code
that's possible, but unlikely.

Reviewed By: ChuanqiXu

Differential Revision: https://reviews.llvm.org/D119972

libcxxabi/src/demangle/Utility.h
llvm/include/llvm/Demangle/Utility.h
llvm/unittests/Demangle/OutputBufferTest.cpp

index f8190b8..0cf70bd 100644 (file)
@@ -37,10 +37,10 @@ class OutputBuffer {
   void grow(size_t N) {
     size_t Need = N + CurrentPosition;
     if (Need > BufferCapacity) {
-      // Avoid many reallocations during startup, with a bit of hysteresis.
-      constexpr size_t MinInitAlloc = 1024;
-      if (Need < MinInitAlloc)
-        Need = MinInitAlloc;
+      // Reduce the number of reallocations, with a bit of hysteresis. The
+      // number here is chosen so the first allocation will more-than-likely not
+      // allocate more than 1K.
+      Need += 1024 - 32;
       BufferCapacity *= 2;
       if (BufferCapacity < Need)
         BufferCapacity = Need;
index c7cf456..f3537c1 100644 (file)
@@ -37,10 +37,10 @@ class OutputBuffer {
   void grow(size_t N) {
     size_t Need = N + CurrentPosition;
     if (Need > BufferCapacity) {
-      // Avoid many reallocations during startup, with a bit of hysteresis.
-      constexpr size_t MinInitAlloc = 1024;
-      if (Need < MinInitAlloc)
-        Need = MinInitAlloc;
+      // Reduce the number of reallocations, with a bit of hysteresis. The
+      // number here is chosen so the first allocation will more-than-likely not
+      // allocate more than 1K.
+      Need += 1024 - 32;
       BufferCapacity *= 2;
       if (BufferCapacity < Need)
         BufferCapacity = Need;
index 1d37f56..9fc572b 100644 (file)
@@ -78,3 +78,16 @@ TEST(OutputBufferTest, Prepend) {
 
   std::free(OB.getBuffer());
 }
+
+// Test when initial needed size is larger than the default.
+TEST(OutputBufferTest, Extend) {
+  OutputBuffer OB;
+
+  char Massive[2000];
+  std::memset(Massive, 'a', sizeof(Massive));
+  Massive[sizeof(Massive) - 1] = 0;
+  OB << Massive;
+  EXPECT_EQ(Massive, toString(OB));
+
+  std::free(OB.getBuffer());
+}