diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 0ce57723697b..d89a903e4112 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/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/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index bb47aff9c07f..6db233641220 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/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/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index c821df85ff91..25e6949ecd1d 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/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/clang/include/clang/Serialization/ChainedIncludesSource.h b/clang/include/clang/Serialization/ChainedIncludesSource.h index ceef4f2e3459..0c3e86faf414 100644 --- a/clang/include/clang/Serialization/ChainedIncludesSource.h +++ b/clang/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 ReadMethodPool(Selector Sel); virtual bool LookupUnqualified(LookupResult &R, Scope *S); - }; } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 65ff731d3a8c..b362aa43beaa 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/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/clang/lib/Serialization/ChainedIncludesSource.cpp b/clang/lib/Serialization/ChainedIncludesSource.cpp index 4b954191fcee..da5be957a530 100644 --- a/clang/lib/Serialization/ChainedIncludesSource.cpp +++ b/clang/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/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 364120c61b3c..1379ee19fc8d 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/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(),