diff --git a/tools/sampler/aspt_convert.cpp b/tools/sampler/aspt_convert.cpp index 0363631a558727e27a14164f03d378b14f41673e..7beebe4b9b34bcc7dccecab748b4385adeed6013 100644 --- a/tools/sampler/aspt_convert.cpp +++ b/tools/sampler/aspt_convert.cpp @@ -45,6 +45,7 @@ int Main(int argc, const char **argv) if (!conv.CollectModules()) { LOG(ERROR, PROFILER) << "No modules found in file, names would not be resolved"; } + conv.BuildMethodsMap(); conv.DumpResolvedTracesAsCSV(out_filename); return 0; } @@ -54,4 +55,4 @@ int Main(int argc, const char **argv) int main(int argc, const char **argv) { return panda::tooling::sampler::Main(argc, argv); -} \ No newline at end of file +} diff --git a/tools/sampler/aspt_converter.h b/tools/sampler/aspt_converter.h index fec1f1c473612e8d6150b3947c8dc81108fb047b..0843d1bdca3355937f51dc00d1193b81ecc38dad 100644 --- a/tools/sampler/aspt_converter.h +++ b/tools/sampler/aspt_converter.h @@ -32,6 +32,7 @@ class AsptConverter { public: using StackTraceMap = std::unordered_map; using ModuleMap = std::unordered_map>; + using MethodMap = std::unordered_map>; explicit AsptConverter(const char *filename) : reader_(filename) {} ~AsptConverter() = default; @@ -96,47 +97,53 @@ public: return true; } - std::string ResolveName(const panda_file::File *pf, uint64_t file_id) + std::string ResolveName(const panda_file::File *pf, uint64_t file_id) const { if (pf == nullptr) { return std::string("__unknown_module::" + std::to_string(file_id)); } - // TODO(m.strizhak): make a hash map to avoid of O(N^2) - std::string result; - auto classes_span = pf->GetClasses(); - for (auto id : classes_span) { - if (pf->IsExternal(panda_file::File::EntityId(id))) { - continue; - } - panda_file::ClassDataAccessor cda(*pf, panda_file::File::EntityId(id)); - cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) { - if (panda_file::File::EntityId(file_id) == mda.GetMethodId()) { + + auto it = methods_map_.find(pf); + if (it != methods_map_.end()) { + return it->second.at(file_id); + } + return pf->GetFilename() + "::__unknown_" + std::to_string(file_id); + } + + void BuildMethodsMap() + { + for (const auto &pf_pair : modules_map_) { + const panda_file::File *pf = pf_pair.second.get(); + auto classes_span = pf->GetClasses(); + for (auto id : classes_span) { + if (pf->IsExternal(panda_file::File::EntityId(id))) { + continue; + } + panda_file::ClassDataAccessor cda(*pf, panda_file::File::EntityId(id)); + cda.EnumerateMethods([&](panda_file::MethodDataAccessor &mda) { std::string method_name = utf::Mutf8AsCString(mda.GetName().data); std::string class_name = utf::Mutf8AsCString(cda.GetDescriptor()); if (class_name[class_name.length() - 1] == ';') { class_name.pop_back(); } - result = class_name; - result += "::"; - result += method_name; - } - }); - } - if (result.empty()) { - return std::string(pf->GetFilename() + "::__unknown_" + std::to_string(file_id)); + std::string full_name = class_name + "::"; + full_name += method_name; + methods_map_[pf][mda.GetMethodId().GetOffset()] = std::move(full_name); + }); + } } - return result; } NO_COPY_SEMANTIC(AsptConverter); NO_MOVE_SEMANTIC(AsptConverter); private: - ModuleMap modules_map_; SampleReader reader_; + ModuleMap modules_map_; + MethodMap methods_map_; StackTraceMap stack_traces_; }; } // namespace panda::tooling::sampler -#endif // PANDA_TOOLS_SAMPLER_CONVERTER_IMPL_H \ No newline at end of file +#endif // PANDA_TOOLS_SAMPLER_CONVERTER_IMPL_H