CursorVisitor: cache worklists created for data-recursion to reduce malloc() traffic.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119290 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 9962bd2..b573c06 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -177,6 +177,10 @@
   DeclContext::decl_iterator *DI_current;
   DeclContext::decl_iterator DE_current;
 
+  // Cache of pre-allocated worklists for data-recursion walk of Stmts.
+  llvm::SmallVector<VisitorWorkList*, 5> WorkListFreeList;
+  llvm::SmallVector<VisitorWorkList*, 5> WorkListCache;
+
   using DeclVisitor<CursorVisitor, bool>::Visit;
   using TypeLocVisitor<CursorVisitor, bool>::Visit;
   using StmtVisitor<CursorVisitor, bool>::Visit;
@@ -223,6 +227,14 @@
     StmtParent = 0;
   }
 
+  ~CursorVisitor() {
+    // Free the pre-allocated worklists for data-recursion.
+    for (llvm::SmallVectorImpl<VisitorWorkList*>::iterator
+          I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
+      delete *I;
+    }
+  }
+
   ASTUnit *getASTUnit() const { return TU; }
 
   bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
@@ -2019,9 +2031,20 @@
 }
 
 bool CursorVisitor::VisitDataRecursive(Stmt *S) {
-  VisitorWorkList WL;
-  EnqueueWorkList(WL, S);
-  return RunVisitorWorkList(WL);
+  VisitorWorkList *WL = 0;
+  if (!WorkListFreeList.empty()) {
+    WL = WorkListFreeList.back();
+    WL->clear();
+    WorkListFreeList.pop_back();
+  }
+  else {
+    WL = new VisitorWorkList();
+    WorkListCache.push_back(WL);
+  }
+  EnqueueWorkList(*WL, S);
+  bool result = RunVisitorWorkList(*WL);
+  WorkListFreeList.push_back(WL);
+  return result;
 }
 
 //===----------------------------------------------------------------------===//