diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 4e3651befe7b5de0ff0125aa2594f3bdfc675143..7c838ff862437ac57d6afc5607fe41bc8766ac4e 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -139,7 +139,7 @@ class Preprocessor { /// CurPPLexer - This is the current top of the stack what we're lexing from /// if not expanding a macro. This is an alias for either CurLexer or /// CurPTHLexer. - PreprocessorLexer* CurPPLexer; + PreprocessorLexer *CurPPLexer; /// CurLookup - The DirectoryLookup structure used to find the current /// FileEntry, if CurLexer is non-null and if applicable. This allows us to @@ -176,8 +176,14 @@ class Preprocessor { llvm::DenseMap Macros; /// MICache - A "freelist" of MacroInfo objects that can be reused for quick - /// allocation. + /// allocation. + /// FIXME: why not use a singly linked list? std::vector MICache; + + /// MacroArgCache - This is a "freelist" of MacroArg objects that can be + /// reused for quick allocation. + MacroArgs *MacroArgCache; + friend class MacroArgs; // Various statistics we track for performance analysis. unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma; diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp index a621854814fbc4a49738f11d3da83b8bf9efce1a..376cce8eb321e5e1b4b499f76e18f942de6c0338 100644 --- a/clang/lib/Lex/MacroArgs.cpp +++ b/clang/lib/Lex/MacroArgs.cpp @@ -48,6 +48,19 @@ void MacroArgs::destroy(Preprocessor &PP) { free(this); } +/// deallocate - This should only be called by the Preprocessor when managing +/// its freelist. +MacroArgs *MacroArgs::deallocate() { + MacroArgs *Next = ArgCache; + + // Run the dtor to deallocate the vectors. + this->~MacroArgs(); + // Release the memory for the object. + free(this); + + return Next; +} + /// getArgLength - Given a pointer to an expanded or unexpanded argument, /// return the number of tokens, not counting the EOF, that make up the diff --git a/clang/lib/Lex/MacroArgs.h b/clang/lib/Lex/MacroArgs.h index 43ce08c26953389af238ee60f51d8e5187541254..fa040c7a4d6f5273a5e3b85c32765c6b596ea393 100644 --- a/clang/lib/Lex/MacroArgs.h +++ b/clang/lib/Lex/MacroArgs.h @@ -46,8 +46,12 @@ class MacroArgs { /// stringified form of an argument has not yet been computed, this is empty. std::vector StringifiedArgs; + /// ArgCache - This is a linked list of MacroArgs objects that the + /// Preprocessor owns which we use to avoid thrashing malloc/free. + MacroArgs *ArgCache; + MacroArgs(unsigned NumToks, bool varargsElided) - : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided) {} + : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(0) {} ~MacroArgs() {} public: /// MacroArgs ctor function - Create a new MacroArgs object with the specified @@ -103,6 +107,11 @@ public: /// static Token StringifyArgument(const Token *ArgToks, Preprocessor &PP, bool Charify = false); + + + /// deallocate - This should only be called by the Preprocessor when managing + /// its freelist. + MacroArgs *deallocate(); }; } // end namespace clang diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 4ab0d3063c42b72fcbccc43a805b328bd0dad456..d4e441b2f18338e9fdcdcf99a42e7d36df18df6f 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -26,6 +26,7 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/Preprocessor.h" +#include "MacroArgs.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Pragma.h" @@ -51,7 +52,7 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()), SourceMgr(SM), HeaderInfo(Headers), Identifiers(opts, IILookup), BuiltinInfo(Target), CodeCompletionFile(0), CurPPLexer(0), CurDirLookup(0), - Callbacks(0) { + Callbacks(0), MacroArgCache(0) { ScratchBuf = new ScratchBuffer(SourceMgr); CounterValue = 0; // __COUNTER__ starts at 0. OwnsHeaderSearch = OwnsHeaders; @@ -111,6 +112,10 @@ Preprocessor::~Preprocessor() { // Free any cached macro expanders. for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i) delete TokenLexerCache[i]; + + // Free any cached MacroArgs. + for (MacroArgs *ArgList = MacroArgCache; ArgList; ) + ArgList = ArgList->deallocate(); // Release pragma information. delete PragmaHandlers;