From: Ted Kremenek Date: Mon, 18 Apr 2011 22:47:10 +0000 (+0000) Subject: Add libclang API to query how much memory is used by a CXTranslationUnit. This is... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=59fc1e55da9c856d1703d3d3ac14a36320d26b30;p=clang Add libclang API to query how much memory is used by a CXTranslationUnit. This is a WIP. Currently we report the amount used for expressions, types, identifiers, and selectors. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129730 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 715a360c4b..11e060b27a 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -1012,7 +1012,56 @@ CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU, unsigned num_unsaved_files, struct CXUnsavedFile *unsaved_files, unsigned options); - + +/** + * \brief Categorizes how memory is being used by a translation unit. + */ +enum CXTUMemoryUsageKind { + CXTUMemoryUsage_AST = 1, + CXTUMemoryUsage_Identifiers = 2, + CXTUMemoryUsage_Selectors = 3, + CXTUMemoryUsage_First = CXTUMemoryUsage_AST, + CXTUMemoryUsage_Last = CXTUMemoryUsage_Selectors +}; + +/** + * \brief Returns the human-readable null-terminated C string that represents + * the name of the memory category. + */ +CINDEX_LINKAGE +const char *clang_getTUMemoryUsageName(enum CXTUMemoryUsageKind kind); + +typedef struct CXTUMemoryUsageEntry { + /* \brief The memory usage category. */ + enum CXTUMemoryUsageKind kind; + /* \brief Memory usage in bytes. */ + unsigned long amount; +} CXTUMemoryUsageEntry; + +/** + * \brief The memory usage of a CXTranslationUnit, broken into categories. + */ +typedef struct CXTUMemoryUsage { + /* \brief Private data member, used for queries. */ + void *data; + + /* \brief The number of entries in the 'entries' array. */ + unsigned numEntries; + + /* \brief An array of key-value pairs, representing the breakdown of memory + usage. */ + CXTUMemoryUsageEntry *entries; + +} CXTUMemoryUsage; + +/** + * \brief Return the memory usage of a translation unit. This object + * should be released with clang_disposeCXTUMemoryUsage(). + */ +CINDEX_LINKAGE CXTUMemoryUsage clang_getCXTUMemoryUsage(CXTranslationUnit TU); + +CINDEX_LINKAGE void clang_disposeCXTUMemoryUsage(CXTUMemoryUsage usage); + /** * @} */ diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index d424e2453a..b2a86b208d 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -370,6 +370,22 @@ void PrintDiagnostics(CXTranslationUnit TU) { } } +void PrintMemoryUsage(CXTranslationUnit TU) { + CXTUMemoryUsage usage = clang_getCXTUMemoryUsage(TU); + fprintf(stderr, "Memory usage:\n"); + unsigned long total = 0.0; + for (unsigned i = 0, n = usage.numEntries; i != n; ++i) { + const char *name = clang_getTUMemoryUsageName(usage.entries[i].kind); + unsigned long amount = usage.entries[i].amount; + total += amount; + fprintf(stderr, " %s : %ld bytes (%lf MBytes)\n", name, amount, + ((double) amount)/(1024*1024)); + } + fprintf(stderr, " TOTAL = %ld bytes (%lf MBytes)\n", total, + ((double) total)/(1024*1024)); + clang_disposeCXTUMemoryUsage(usage); +} + /******************************************************************************/ /* Logic for testing traversal. */ /******************************************************************************/ @@ -1503,6 +1519,8 @@ static CXCursorVisitor GetVisitor(const char *s) { return FilteredPrintingVisitor; if (strcmp(s, "-usrs") == 0) return USRVisitor; + if (strncmp(s, "-memory-usage", 13) == 0) + return GetVisitor(s + 13); return NULL; } @@ -1519,16 +1537,20 @@ static void print_usage(void) { "[FileCheck prefix]\n" " c-index-test -test-load-source {}*\n"); fprintf(stderr, + " c-index-test -test-load-source-memory-usage " + " {}*\n" " c-index-test -test-load-source-reparse " " {}*\n" " c-index-test -test-load-source-usrs {}*\n" + " c-index-test -test-load-source-usrs-memory-usage " + " {}*\n" " c-index-test -test-annotate-tokens= {}*\n" " c-index-test -test-inclusion-stack-source {}*\n" " c-index-test -test-inclusion-stack-tu \n" - " c-index-test -test-print-linkage-source {}*\n" - " c-index-test -test-print-typekind {}*\n" - " c-index-test -print-usr [ {}]*\n"); + " c-index-test -test-print-linkage-source {}*\n"); fprintf(stderr, + " c-index-test -test-print-typekind {}*\n" + " c-index-test -print-usr [ {}]*\n" " c-index-test -print-usr-file \n" " c-index-test -write-pch \n\n"); fprintf(stderr, @@ -1569,8 +1591,14 @@ int cindextest_main(int argc, const char **argv) { } else if (argc >= 4 && strncmp(argv[1], "-test-load-source", 17) == 0) { CXCursorVisitor I = GetVisitor(argv[1] + 17); + + PostVisitTU postVisit = 0; + if (strstr(argv[1], "-memory-usage")) + postVisit = PrintMemoryUsage; + if (I) - return perform_test_load_source(argc - 3, argv + 3, argv[2], I, NULL); + return perform_test_load_source(argc - 3, argv + 3, argv[2], I, + postVisit); } else if (argc >= 4 && strcmp(argv[1], "-test-file-scan") == 0) return perform_file_scan(argv[2], argv[3], diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index f8ca13aab3..2ac57bf208 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -5176,6 +5176,72 @@ CXType clang_getIBOutletCollectionType(CXCursor C) { } } // end: extern "C" +//===----------------------------------------------------------------------===// +// Inspecting memory usage. +//===----------------------------------------------------------------------===// + +typedef std::vector MemUsageEntries; + +static inline void createCXTUMemoryUsageEntry(MemUsageEntries &entries, + enum CXTUMemoryUsageKind k, + double amount) { + CXTUMemoryUsageEntry entry = { k, amount }; + entries.push_back(entry); +} + +extern "C" { + +const char *clang_getTUMemoryUsageName(CXTUMemoryUsageKind kind) { + const char *str = ""; + switch (kind) { + case CXTUMemoryUsage_AST: + str = "ASTContext: expressions, declarations, and types"; + break; + case CXTUMemoryUsage_Identifiers: + str = "ASTContext: identifiers"; + break; + case CXTUMemoryUsage_Selectors: + str = "ASTContext: selectors"; + } + return str; +} + +CXTUMemoryUsage clang_getCXTUMemoryUsage(CXTranslationUnit TU) { + if (!TU) { + CXTUMemoryUsage usage = { (void*) 0, 0, 0 }; + return usage; + } + + ASTUnit *astUnit = static_cast(TU->TUData); + llvm::OwningPtr entries(new MemUsageEntries()); + ASTContext &astContext = astUnit->getASTContext(); + + // How much memory is used by AST nodes and types? + createCXTUMemoryUsageEntry(*entries, CXTUMemoryUsage_AST, + (unsigned long) astContext.getTotalAllocatedMemory()); + + // How much memory is used by identifiers? + createCXTUMemoryUsageEntry(*entries, CXTUMemoryUsage_Identifiers, + (unsigned long) astContext.Idents.getAllocator().getTotalMemory()); + + // How much memory is used for selectors? + createCXTUMemoryUsageEntry(*entries, CXTUMemoryUsage_Selectors, + (unsigned long) astContext.Selectors.getTotalMemory()); + + CXTUMemoryUsage usage = { (void*) entries.get(), + (unsigned) entries->size(), + entries->size() ? &(*entries)[0] : 0 }; + entries.take(); + return usage; +} + +void clang_disposeCXTUMemoryUsage(CXTUMemoryUsage usage) { + if (usage.data) + delete (MemUsageEntries*) usage.data; +} + +} // end extern "C" + //===----------------------------------------------------------------------===// // Misc. utility functions. //===----------------------------------------------------------------------===// @@ -5212,3 +5278,4 @@ CXString clang_getClangVersion() { } } // end: extern "C" + diff --git a/tools/libclang/libclang.darwin.exports b/tools/libclang/libclang.darwin.exports index 0bb463207f..6219d557b3 100644 --- a/tools/libclang/libclang.darwin.exports +++ b/tools/libclang/libclang.darwin.exports @@ -21,6 +21,7 @@ _clang_defaultEditingTranslationUnitOptions _clang_defaultReparseOptions _clang_defaultSaveOptions _clang_disposeCXCursorSet +_clang_disposeCXTUMemoryUsage _clang_disposeCodeCompleteResults _clang_disposeDiagnostic _clang_disposeIndex @@ -35,6 +36,7 @@ _clang_equalTypes _clang_executeOnThread _clang_formatDiagnostic _clang_getCString +_clang_getCXTUMemoryUsage _clang_getCXXAccessSpecifier _clang_getCanonicalCursor _clang_getCanonicalType @@ -98,6 +100,7 @@ _clang_getRangeStart _clang_getResultType _clang_getSpecializedCursorTemplate _clang_getSpellingLocation +_clang_getTUMemoryUsageName _clang_getTemplateCursorKind _clang_getTokenExtent _clang_getTokenKind diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports index ac17b2e74b..2b96053083 100644 --- a/tools/libclang/libclang.exports +++ b/tools/libclang/libclang.exports @@ -21,6 +21,7 @@ clang_defaultEditingTranslationUnitOptions clang_defaultReparseOptions clang_defaultSaveOptions clang_disposeCXCursorSet +clang_disposeCXTUMemoryUsage clang_disposeCodeCompleteResults clang_disposeDiagnostic clang_disposeIndex @@ -35,6 +36,7 @@ clang_equalTypes clang_executeOnThread clang_formatDiagnostic clang_getCString +clang_getCXTUMemoryUsage clang_getCXXAccessSpecifier clang_getCanonicalCursor clang_getCanonicalType @@ -98,6 +100,7 @@ clang_getRangeStart clang_getResultType clang_getSpecializedCursorTemplate clang_getSpellingLocation +clang_getTUMemoryUsageName clang_getTemplateCursorKind clang_getTokenExtent clang_getTokenKind