diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 0ce57723697b21df0f46fbdaa7343a4dfb1da6ad..d89a903e4112172f47277b53f3fbd7898949a981 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 bb47aff9c07f9ab54b3f1603a12ef2c54bc141e3..6db233641220e751c6987c262c15fb2af2c51a92 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 c821df85ff9111beafd22a364294e44eb533d193..25e6949ecd1df76b61dd358532593d93dcf9ff87 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 ceef4f2e34598e33d52676f42baef8354be2ba60..0c3e86faf414f50614a129260e71c0402ead4346 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 65ff731d3a8c482b00fad0d9294f7fa59556e61f..b362aa43beaaaec6fe61ea91955b0236a83b2d69 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 4b954191fceee1de462dac09755136d6425bcd30..da5be957a530f993a10cf6628cfa38915fa520ae 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 364120c61b3c5fef626713e21352a0e30d609566..1379ee19fc8d372b53cd5f2aea689ec9579775a3 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(),