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(),