implement trivial scope caching.  This reduces malloc traffic in the common
case, speeding up parsing of this contrived example:

#define A {{}}
#define B A A A A A A A A A A
#define C B B B B B B B B B B
#define D C C C C C C C C C C
#define E D D D D D D D D D D
#define F E E E E E E E E E E
#define G F F F F F F F F F F
#define H G G G G G G G G G G

void foo() {
  H
}

from 7.478s to 4.321s.  GCC requires 8.2s.

llvm-svn: 39138
diff --git a/clang/Parse/Parser.cpp b/clang/Parse/Parser.cpp
index dc1909a..3e991ba 100644
--- a/clang/Parse/Parser.cpp
+++ b/clang/Parse/Parser.cpp
@@ -37,11 +37,6 @@
   ParenCount = BracketCount = BraceCount = 0;
 }
 
-Parser::~Parser() {
-  // If we still have scopes active, delete the scope tree.
-  delete CurScope;
-}
-
 ///  Out-of-line virtual destructor to provide home for Action class.
 Action::~Action() {}
 
@@ -186,9 +181,19 @@
 // Scope manipulation
 //===----------------------------------------------------------------------===//
 
+/// ScopeCache - Cache scopes to avoid malloc traffic.
+static SmallVector<Scope*, 16> ScopeCache;
+
 /// EnterScope - Start a new scope.
 void Parser::EnterScope(unsigned ScopeFlags) {
-  CurScope = new Scope(CurScope, ScopeFlags);
+  if (!ScopeCache.empty()) {
+    Scope *N = ScopeCache.back();
+    ScopeCache.pop_back();
+    N->Init(CurScope, ScopeFlags);
+    CurScope = N;
+  } else {
+    CurScope = new Scope(CurScope, ScopeFlags);
+  }
 }
 
 /// ExitScope - Pop a scope off the scope stack.
@@ -200,7 +205,11 @@
   
   Scope *Old = CurScope;
   CurScope = Old->getParent();
-  delete Old;
+  
+  if (ScopeCache.size() == 16)
+    delete Old;
+  else
+    ScopeCache.push_back(Old);
 }
 
 
@@ -210,6 +219,17 @@
 // C99 6.9: External Definitions.
 //===----------------------------------------------------------------------===//
 
+Parser::~Parser() {
+  // If we still have scopes active, delete the scope tree.
+  delete CurScope;
+  
+  // Free the scope cache.
+  while (!ScopeCache.empty()) {
+    delete ScopeCache.back();
+    ScopeCache.pop_back();
+  }
+}
+
 /// Initialize - Warm up the parser.
 ///
 void Parser::Initialize() {