From: Chris Lattner Date: Tue, 15 Dec 2009 20:48:12 +0000 (+0000) Subject: enable reuse of MacroArgs objects. This is a small (2.5%) win X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4608459d918261275af147b4c22351469f7ebea1;p=clang enable reuse of MacroArgs objects. This is a small (2.5%) win 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 --- diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp index 376cce8eb3..34b1ef8fc0 100644 --- a/lib/Lex/MacroArgs.cpp +++ b/lib/Lex/MacroArgs.cpp @@ -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