From e9b5f3d4acfc2ad6e8b65a4072464e997dea9ed3 Mon Sep 17 00:00:00 2001
From: Ted Kremenek <kremenek@apple.com>
Date: Thu, 28 Apr 2011 23:46:20 +0000
Subject: [PATCH] Enhance clang_getCXTUResourceUsage() to report the sizes of
 the memory buffers used by PCH.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130460 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang-c/Index.h                       |  9 ++++----
 include/clang/AST/ExternalASTSource.h         | 22 +++++++++++++++++++
 include/clang/Serialization/ASTReader.h       |  4 ++++
 .../Serialization/ChainedIncludesSource.h     |  5 ++++-
 lib/Serialization/ASTReader.cpp               | 17 ++++++++++++++
 lib/Serialization/ChainedIncludesSource.cpp   | 10 +++++++++
 tools/libclang/CIndex.cpp                     | 21 +++++++++++++++++-
 7 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 0ce57723697..d89a903e411 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -1024,14 +1024,15 @@ enum CXTUResourceUsageKind {
   CXTUResourceUsage_SourceManagerContentCache = 5,
   CXTUResourceUsage_AST_SideTables = 6,
   CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7,
-  CXTUResourceUsage_SourceManager_Membuffer_MMap = 8,  
-
+  CXTUResourceUsage_SourceManager_Membuffer_MMap = 8,
+  CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9, 
+  CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, 
   CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST,
   CXTUResourceUsage_MEMORY_IN_BYTES_END =
-    CXTUResourceUsage_SourceManager_Membuffer_MMap,
+    CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
 
   CXTUResourceUsage_First = CXTUResourceUsage_AST,
-  CXTUResourceUsage_Last = CXTUResourceUsage_SourceManager_Membuffer_MMap
+  CXTUResourceUsage_Last = CXTUResourceUsage_ExternalASTSource_Membuffer_MMap
 };
 
 /**
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index bb47aff9c07..6db23364122 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -190,6 +190,28 @@ public:
   ///
   /// The default implementation of this method is a no-op.
   virtual void PrintStats();
+  
+  //===--------------------------------------------------------------------===//
+  // Queries for performance analysis.
+  //===--------------------------------------------------------------------===//
+  
+  struct MemoryBufferSizes {
+    size_t malloc_bytes;
+    size_t mmap_bytes;
+    
+    MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes)
+    : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {}
+  };
+  
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  MemoryBufferSizes getMemoryBufferSizes() const {
+    MemoryBufferSizes sizes(0, 0);
+    getMemoryBufferSizes(sizes);
+    return sizes;
+  }
+
+  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const = 0;
 
 protected:
   static DeclContextLookupResult
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index c821df85ff9..25e6949ecd1 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -1066,6 +1066,10 @@ public:
   /// \brief Print some statistics about AST usage.
   virtual void PrintStats();
 
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+
   /// \brief Initialize the semantic source with the Sema instance
   /// being used to perform semantic analysis on the abstract syntax
   /// tree.
diff --git a/include/clang/Serialization/ChainedIncludesSource.h b/include/clang/Serialization/ChainedIncludesSource.h
index ceef4f2e345..0c3e86faf41 100644
--- a/include/clang/Serialization/ChainedIncludesSource.h
+++ b/include/clang/Serialization/ChainedIncludesSource.h
@@ -57,6 +57,10 @@ protected:
   virtual void StartTranslationUnit(ASTConsumer *Consumer);
   virtual void PrintStats();
 
+  /// Return the amount of memory used by memory buffers, breaking down
+  /// by heap-backed versus mmap'ed memory.
+  virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
+
 //===----------------------------------------------------------------------===//
 // ExternalSemaSource interface.
 //===----------------------------------------------------------------------===//
@@ -65,7 +69,6 @@ protected:
   virtual void ForgetSema();
   virtual std::pair<ObjCMethodList,ObjCMethodList> ReadMethodPool(Selector Sel);
   virtual bool LookupUnqualified(LookupResult &R, Scope *S);
-
 };
 
 }
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 65ff731d3a8..b362aa43bea 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4053,6 +4053,23 @@ void ASTReader::PrintStats() {
   std::fprintf(stderr, "\n");
 }
 
+/// Return the amount of memory used by memory buffers, breaking down
+/// by heap-backed versus mmap'ed memory.
+void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
+  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+    if (llvm::MemoryBuffer *buf = Chain[i]->Buffer.get()) {
+      size_t bytes = buf->getBufferSize();
+      switch (buf->getBufferKind()) {
+        case llvm::MemoryBuffer::MemoryBuffer_Malloc:
+          sizes.malloc_bytes += bytes;
+          break;
+        case llvm::MemoryBuffer::MemoryBuffer_MMap:
+          sizes.mmap_bytes += bytes;
+          break;
+      }
+    }
+}
+
 void ASTReader::InitializeSema(Sema &S) {
   SemaObj = &S;
   S.ExternalSource = this;
diff --git a/lib/Serialization/ChainedIncludesSource.cpp b/lib/Serialization/ChainedIncludesSource.cpp
index 4b954191fce..da5be957a53 100644
--- a/lib/Serialization/ChainedIncludesSource.cpp
+++ b/lib/Serialization/ChainedIncludesSource.cpp
@@ -208,6 +208,16 @@ void ChainedIncludesSource::StartTranslationUnit(ASTConsumer *Consumer) {
 void ChainedIncludesSource::PrintStats() {
   return getFinalReader().PrintStats();
 }
+void ChainedIncludesSource::getMemoryBufferSizes(MemoryBufferSizes &sizes)const{
+  for (unsigned i = 0, e = CIs.size(); i != e; ++i) {
+    if (const ExternalASTSource *eSrc =
+        CIs[i]->getASTContext().getExternalSource()) {
+      eSrc->getMemoryBufferSizes(sizes);
+    }
+  }
+
+  getFinalReader().getMemoryBufferSizes(sizes);
+}
 
 void ChainedIncludesSource::InitializeSema(Sema &S) {
   return getFinalReader().InitializeSema(S);
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 364120c61b3..1379ee19fc8 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -5232,6 +5232,12 @@ const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
     case CXTUResourceUsage_SourceManager_Membuffer_MMap:
       str = "SourceManager: mmap'ed memory buffers";
       break;
+    case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
+      str = "ExternalASTSource: malloc'ed memory buffers";
+      break;
+    case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
+      str = "ExternalASTSource: mmap'ed memory buffers";
+      break;
   }
   return str;
 }
@@ -5284,9 +5290,22 @@ CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
   createCXTUResourceUsageEntry(*entries,
                                CXTUResourceUsage_SourceManager_Membuffer_Malloc,
                                (unsigned long) srcBufs.malloc_bytes);
-  createCXTUResourceUsageEntry(*entries,
+    createCXTUResourceUsageEntry(*entries,
                                CXTUResourceUsage_SourceManager_Membuffer_MMap,
                                (unsigned long) srcBufs.mmap_bytes);
+  
+  // How much memory is being used by the ExternalASTSource?
+  if (ExternalASTSource *esrc = astContext.getExternalSource()) {
+    const ExternalASTSource::MemoryBufferSizes &sizes =
+      esrc->getMemoryBufferSizes();
+    
+    createCXTUResourceUsageEntry(*entries,
+      CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
+                                 (unsigned long) sizes.malloc_bytes);
+    createCXTUResourceUsageEntry(*entries,
+      CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
+                                 (unsigned long) sizes.mmap_bytes);
+  }
 
   CXTUResourceUsage usage = { (void*) entries.get(),
                             (unsigned) entries->size(),
-- 
GitLab