From c8456f8c593a0db19bc6827adefa3f3dbf2e9b2d Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 19 Oct 2010 22:15:20 +0000 Subject: [PATCH] Really^2 fix , this time without crashing. Now MICache is a linked list (per the FIXME), where we tradeoff between MacroInfo objects being in MICache and MIChainHead. MacroInfo objects in the MICache chain are already "Destroy()'ed", so they can be reused. When inserting into MICache, we need to remove them from the regular linked list so that they aren't destroyed more than once. llvm-svn: 116869 --- clang/include/clang/Lex/Preprocessor.h | 10 +++--- clang/lib/Lex/PPDirectives.cpp | 44 ++++++++++++++++++-------- clang/lib/Lex/Preprocessor.cpp | 3 +- 3 files changed, 38 insertions(+), 19 deletions(-) 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;