]> granicus.if.org Git - clang/commitdiff
Really^2 fix <rdar://problem/8361834>, this time without crashing.
authorTed Kremenek <kremenek@apple.com>
Tue, 19 Oct 2010 22:15:20 +0000 (22:15 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 19 Oct 2010 22:15:20 +0000 (22:15 +0000)
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.

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

include/clang/Lex/Preprocessor.h
lib/Lex/PPDirectives.cpp
lib/Lex/Preprocessor.cpp

index a1a68dce45172876c421f914e90c0a2b7d13173a..42e2daac2f26d8db0f12db5c91420c4d6a71c895 100644 (file)
@@ -195,11 +195,6 @@ class Preprocessor {
   /// to the actual definition of the macro.
   llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
 
-  /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
-  /// allocation.
-  /// FIXME: why not use a singly linked list?
-  std::vector<MacroInfo*> 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,
index b958d9e489fb1d9a09a1b1ffa4a4462667771ceb..8f66d99b187e76437d755f86b3abc91c603a2d4a 100644 (file)
@@ -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<MacroInfoChain>();
-    MIChain->Next = MIChainHead;
-    MIChainHead = MIChain;
-    MI = &(MIChain->MI);
+  if (MICache) {
+    MIChain = MICache;
+    MICache = MICache->Next;
   }
-  return MI;
+  else {
+    MIChain = BP.Allocate<MacroInfoChain>();
+  }
+
+  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.
index a0782aa86818f8f289950fee30a68a1080b2b882..1be22df6b1cbc329f9657f0e736dc41a409f45de 100644 (file)
@@ -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;