JDevlieghere created this revision. JDevlieghere added reviewers: clayborg, labath. JDevlieghere requested review of this revision.
Add statistics about the memory usage of the string pool. I'm particularly interested in the memory used by the allocator, i.e. the number of bytes actually used by the allocator it self as well as the number of bytes allocated through the allocator. https://reviews.llvm.org/D117914 Files: lldb/include/lldb/Target/Statistics.h lldb/include/lldb/Utility/ConstString.h lldb/source/Target/Statistics.cpp lldb/source/Utility/ConstString.cpp lldb/test/API/commands/statistics/basic/TestStats.py
Index: lldb/test/API/commands/statistics/basic/TestStats.py =================================================================== --- lldb/test/API/commands/statistics/basic/TestStats.py +++ lldb/test/API/commands/statistics/basic/TestStats.py @@ -135,6 +135,7 @@ (lldb) statistics dump { + "strings" : {...}, "modules" : [...], "targets" : [ { @@ -160,6 +161,7 @@ target = self.createTestTarget() debug_stats = self.get_stats() debug_stat_keys = [ + 'strings', 'modules', 'targets', 'totalSymbolTableParseTime', @@ -197,6 +199,7 @@ (lldb) statistics dump { + "strings" : {...}, "modules" : [...], "targets" : [ { @@ -227,6 +230,7 @@ lldb.SBFileSpec("main.c")) debug_stats = self.get_stats() debug_stat_keys = [ + 'strings', 'modules', 'targets', 'totalSymbolTableParseTime', @@ -254,6 +258,36 @@ self.assertGreater(stats['launchOrAttachTime'], 0.0) self.assertGreater(stats['targetCreateTime'], 0.0) + def test_strings(self): + """ + Test "statistics dump" and the string memory information. + """ + exe = self.getBuildArtifact("a.out") + target = self.createTestTarget(file_path=exe) + debug_stats = self.get_stats() + debug_stat_keys = [ + 'strings', + 'modules', + 'targets', + 'totalSymbolTableParseTime', + 'totalSymbolTableIndexTime', + 'totalSymbolTablesLoadedFromCache', + 'totalSymbolTablesSavedToCache', + 'totalDebugInfoParseTime', + 'totalDebugInfoIndexTime', + 'totalDebugInfoIndexLoadedFromCache', + 'totalDebugInfoIndexSavedToCache', + 'totalDebugInfoByteSize' + ] + self.verify_keys(debug_stats, '"debug_stats"', debug_stat_keys, None) + stats = debug_stats['strings'] + keys_exist = [ + 'bytesTotal', + 'bytesAllocated', + 'bytesWasted', + ] + self.verify_keys(stats, '"stats"', keys_exist, None) + def find_module_in_metrics(self, path, stats): modules = stats['modules'] for module in modules: @@ -269,6 +303,7 @@ target = self.createTestTarget(file_path=exe) debug_stats = self.get_stats() debug_stat_keys = [ + 'strings', 'modules', 'targets', 'totalSymbolTableParseTime', @@ -312,6 +347,7 @@ Output expected to be something like: { + "strings" : {...}, "modules" : [...], "targets" : [ { @@ -355,6 +391,7 @@ self.runCmd("b a_function") debug_stats = self.get_stats() debug_stat_keys = [ + 'strings', 'modules', 'targets', 'totalSymbolTableParseTime', Index: lldb/source/Utility/ConstString.cpp =================================================================== --- lldb/source/Utility/ConstString.cpp +++ lldb/source/Utility/ConstString.cpp @@ -171,6 +171,17 @@ return mem_size; } + ConstString::MemoryStats GetMemoryStats() const { + ConstString::MemoryStats stats; + for (const auto &pool : m_string_pools) { + llvm::sys::SmartScopedReader<false> rlock(pool.m_mutex); + const Allocator &alloc = pool.m_string_map.getAllocator(); + stats.total_memory += alloc.getTotalMemory(); + stats.bytes_allocated += alloc.getBytesAllocated(); + } + return stats; + } + protected: uint8_t hash(const llvm::StringRef &s) const { uint32_t h = llvm::djbHash(s); @@ -332,6 +343,10 @@ return StringPool().MemorySize(); } +ConstString::MemoryStats ConstString::GetMemoryStats() { + return StringPool().GetMemoryStats(); +} + void llvm::format_provider<ConstString>::format(const ConstString &CS, llvm::raw_ostream &OS, llvm::StringRef Options) { Index: lldb/source/Target/Statistics.cpp =================================================================== --- lldb/source/Target/Statistics.cpp +++ lldb/source/Target/Statistics.cpp @@ -65,6 +65,14 @@ return module; } +llvm::json::Value StringStats::ToJSON() const { + json::Object obj; + obj.try_emplace<int64_t>("bytesTotal", stats.GetTotalMemory()); + obj.try_emplace<int64_t>("bytesAllocated", stats.GetBytesAllocated()); + obj.try_emplace<int64_t>("bytesWasted", stats.GetBytesWasted()); + return obj; +} + json::Value TargetStats::ToJSON(Target &target) { CollectStats(target); @@ -212,9 +220,12 @@ json_modules.emplace_back(module_stat.ToJSON()); } + StringStats string_stats; + json::Object global_stats{ {"targets", std::move(json_targets)}, {"modules", std::move(json_modules)}, + {"strings", string_stats.ToJSON()}, {"totalSymbolTableParseTime", symtab_parse_time}, {"totalSymbolTableIndexTime", symtab_index_time}, {"totalSymbolTablesLoadedFromCache", symtabs_loaded}, Index: lldb/include/lldb/Utility/ConstString.h =================================================================== --- lldb/include/lldb/Utility/ConstString.h +++ lldb/include/lldb/Utility/ConstString.h @@ -408,6 +408,16 @@ /// in memory. static size_t StaticMemorySize(); + struct MemoryStats { + size_t GetTotalMemory() const { return total_memory; } + size_t GetBytesAllocated() const { return bytes_allocated; } + size_t GetBytesWasted() const { return total_memory - bytes_allocated; } + size_t total_memory; + size_t bytes_allocated; + }; + + static MemoryStats GetMemoryStats(); + protected: template <typename T, typename Enable> friend struct ::llvm::DenseMapInfo; /// Only used by DenseMapInfo. Index: lldb/include/lldb/Target/Statistics.h =================================================================== --- lldb/include/lldb/Target/Statistics.h +++ lldb/include/lldb/Target/Statistics.h @@ -9,6 +9,7 @@ #ifndef LLDB_TARGET_STATISTICS_H #define LLDB_TARGET_STATISTICS_H +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-forward.h" #include "llvm/Support/JSON.h" @@ -110,6 +111,11 @@ bool debug_info_index_saved_to_cache = false; }; +struct StringStats { + llvm::json::Value ToJSON() const; + ConstString::MemoryStats stats = ConstString::GetMemoryStats(); +}; + /// A class that represents statistics for a since lldb_private::Target. class TargetStats { public:
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits