diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index a1a68dce4517..42e2daac2f26 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -195,11 +195,6 @@ class Preprocessor { /// to the actual definition of the macro. llvm::DenseMap Macros; - /// MICache - A "freelist" of MacroInfo objects that can be reused for quick - /// 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; @@ -255,12 +250,17 @@ private: // Cached tokens state. struct MacroInfoChain { MacroInfo MI; MacroInfoChain *Next; + MacroInfoChain *Prev; }; /// MacroInfos are managed as a chain for easy disposal. This is the head /// of that list. MacroInfoChain *MIChainHead; + /// MICache - A "freelist" of MacroInfo objects that can be reused for quick + /// allocation. + MacroInfoChain *MICache; + public: Preprocessor(Diagnostic &diags, const LangOptions &opts, const TargetInfo &target, diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index b958d9e489fb..8f66d99b187e 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -28,18 +28,23 @@ using namespace clang; //===----------------------------------------------------------------------===// MacroInfo *Preprocessor::AllocateMacroInfo() { - MacroInfo *MI; + MacroInfoChain *MIChain; - if (!MICache.empty()) { - MI = MICache.back(); - MICache.pop_back(); - } else { - MacroInfoChain *MIChain = BP.Allocate(); - MIChain->Next = MIChainHead; - MIChainHead = MIChain; - MI = &(MIChain->MI); + if (MICache) { + MIChain = MICache; + MICache = MICache->Next; } - return MI; + else { + MIChain = BP.Allocate(); + } + + MIChain->Next = MIChainHead; + MIChain->Prev = 0; + if (MIChainHead) + MIChainHead->Prev = MIChain; + MIChainHead = MIChain; + + return &(MIChain->MI); } MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) { @@ -57,10 +62,23 @@ MacroInfo *Preprocessor::CloneMacroInfo(const MacroInfo &MacroToClone) { /// ReleaseMacroInfo - Release the specified MacroInfo. This memory will /// be reused for allocating new MacroInfo objects. void Preprocessor::ReleaseMacroInfo(MacroInfo *MI) { - MICache.push_back(MI); - MI->FreeArgumentList(); -} + MacroInfoChain *MIChain = (MacroInfoChain*) MI; + if (MacroInfoChain *Prev = MIChain->Prev) { + MacroInfoChain *Next = MIChain->Next; + Prev->Next = Next; + if (Next) + Next->Prev = Prev; + } + else { + assert(MIChainHead == MIChain); + MIChainHead = MIChain->Next; + MIChainHead->Prev = 0; + } + MIChain->Next = MICache; + MICache = MIChain; + MI->Destroy(); +} /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the /// current line until the tok::eom token is found. diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index a0782aa86818..1be22df6b1cb 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -56,7 +56,8 @@ Preprocessor::Preprocessor(Diagnostic &diags, const LangOptions &opts, SourceMgr(SM), HeaderInfo(Headers), ExternalSource(0), Identifiers(opts, IILookup), BuiltinInfo(Target), CodeComplete(0), CodeCompletionFile(0), SkipMainFilePreamble(0, true), CurPPLexer(0), - CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0) { + CurDirLookup(0), Callbacks(0), MacroArgCache(0), Record(0), MIChainHead(0), + MICache(0) { ScratchBuf = new ScratchBuffer(SourceMgr); CounterValue = 0; // __COUNTER__ starts at 0. OwnsHeaderSearch = OwnsHeaders;