]> granicus.if.org Git - clang/commitdiff
enable reuse of MacroArgs objects. This is a small (2.5%) win
authorChris Lattner <sabre@nondot.org>
Tue, 15 Dec 2009 20:48:12 +0000 (20:48 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 15 Dec 2009 20:48:12 +0000 (20:48 +0000)
on PR5610 (2.185 -> 2.130s).  The big issue is that this is making
insanely huge macro argument lists with over a million tokens in it.
The reason that mallco and free are so expensive is that we are
actually going to the kernel to get it, and switching to a bump
pointer allocator won't change this in an interesting way.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91449 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/MacroArgs.cpp

index 376cce8eb321e5e1b4b499f76e18f942de6c0338..34b1ef8fc0f074c808e76a7a9fa1aa449e3e6872 100644 (file)
@@ -24,12 +24,28 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI,
                              Preprocessor &PP) {
   assert(MI->isFunctionLike() &&
          "Can't have args for an object-like macro!");
-
-  // Allocate memory for the MacroArgs object with the lexer tokens at the end.
-  MacroArgs *Result = (MacroArgs*)malloc(sizeof(MacroArgs) +
-                                         NumToks*sizeof(Token));
-  // Construct the macroargs object.
-  new (Result) MacroArgs(NumToks, VarargsElided);
+  MacroArgs *Result = 0;
+  
+  // See if we have an entry with a big enough argument list to reuse on the
+  // free list.  If so, reuse it.
+  for (MacroArgs **Entry = &PP.MacroArgCache; *Entry;
+       Entry = &(*Entry)->ArgCache)
+    if ((*Entry)->NumUnexpArgTokens >= NumToks) {
+      Result = *Entry;
+      // Unlink this node from the preprocessors singly linked list.
+      *Entry = Result->ArgCache;
+      break;
+    }
+  
+  if (Result == 0) {
+    // Allocate memory for a MacroArgs object with the lexer tokens at the end.
+    Result = (MacroArgs*)malloc(sizeof(MacroArgs) + NumToks*sizeof(Token));
+    // Construct the MacroArgs object.
+    new (Result) MacroArgs(NumToks, VarargsElided);
+  } else {
+    Result->NumUnexpArgTokens = NumToks;
+    Result->VarargsElided = VarargsElided;
+  }
 
   // Copy the actual unexpanded tokens to immediately after the result ptr.
   if (NumToks)
@@ -42,10 +58,16 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI,
 /// destroy - Destroy and deallocate the memory for this object.
 ///
 void MacroArgs::destroy(Preprocessor &PP) {
-  // Run the dtor to deallocate the vectors.
-  this->~MacroArgs();
-  // Release the memory for the object.
-  free(this);
+  StringifiedArgs.clear();
+
+  // Don't clear PreExpArgTokens, just clear the entries.  Clearing the entries
+  // would deallocate the element vectors.
+  for (unsigned i = 0, e = PreExpArgTokens.size(); i != e; ++i)
+    PreExpArgTokens[i].clear();
+  
+  // Add this to the preprocessor's free list.
+  ArgCache = PP.MacroArgCache;
+  PP.MacroArgCache = this;
 }
 
 /// deallocate - This should only be called by the Preprocessor when managing