summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2015-08-20 15:04:39 -0700
committerYabin Cui <yabinc@google.com>2015-08-21 11:42:23 -0700
commitc84856093e8bf4350d30fc521dc0f1c800c5270b (patch)
tree202c91d997d583c7f503cfec8d300f6c11d837a5
parentb84ee6cd81da6a0929035c589f1c0450e8d10902 (diff)
downloadextras-c84856093e8bf4350d30fc521dc0f1c800c5270b.tar.gz
Simpleperf: refactor dso.
Having DsoEntry and DsoFactory confuses me which part code should belong to. This change merges the two into class Dso and makes things clear. It is also a preparation for performance optimization in Dso. Bug: 23387541 Change-Id: I41e773406a7f1582a11a18859df252ce8ea3acfa
-rw-r--r--simpleperf/cmd_record.cpp4
-rw-r--r--simpleperf/cmd_report.cpp25
-rw-r--r--simpleperf/dso.cpp223
-rw-r--r--simpleperf/dso.h75
-rw-r--r--simpleperf/environment.cpp7
-rw-r--r--simpleperf/sample_tree.cpp10
-rw-r--r--simpleperf/sample_tree.h6
-rw-r--r--simpleperf/sample_tree_test.cpp6
-rw-r--r--simpleperf/thread_tree.cpp31
-rw-r--r--simpleperf/thread_tree.h36
10 files changed, 223 insertions, 200 deletions
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 5b7bec24..bed957b2 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -600,9 +600,9 @@ bool RecordCommand::GetHitFiles(std::set<std::string>* kernel_modules,
const ThreadEntry* thread = thread_tree.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid);
const MapEntry* map = thread_tree.FindMap(thread, r.ip_data.ip, in_kernel);
if (in_kernel) {
- kernel_modules->insert(map->dso->path);
+ kernel_modules->insert(map->dso->Path());
} else {
- user_files->insert(map->dso->path);
+ user_files->insert(map->dso->Path());
}
}
}
diff --git a/simpleperf/cmd_report.cpp b/simpleperf/cmd_report.cpp
index 5d08993c..9c2f6062 100644
--- a/simpleperf/cmd_report.cpp
+++ b/simpleperf/cmd_report.cpp
@@ -165,11 +165,11 @@ class DsoItem : public Displayable, public Comparable {
}
int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override {
- return strcmp(sample1.map->dso->path.c_str(), sample2.map->dso->path.c_str());
+ return strcmp(sample1.map->dso->Path().c_str(), sample2.map->dso->Path().c_str());
}
std::string Show(const SampleEntry& sample) const override {
- return sample.map->dso->path;
+ return sample.map->dso->Path();
}
};
@@ -194,12 +194,12 @@ class DsoFromItem : public Displayable, public Comparable {
}
int Compare(const SampleEntry& sample1, const SampleEntry& sample2) const override {
- return strcmp(sample1.branch_from.map->dso->path.c_str(),
- sample2.branch_from.map->dso->path.c_str());
+ return strcmp(sample1.branch_from.map->dso->Path().c_str(),
+ sample2.branch_from.map->dso->Path().c_str());
}
std::string Show(const SampleEntry& sample) const override {
- return sample.branch_from.map->dso->path;
+ return sample.branch_from.map->dso->Path();
}
};
@@ -424,12 +424,12 @@ bool ReportCommand::ParseOptions(const std::vector<std::string>& args) {
}
}
- DsoFactory::GetInstance()->SetDemangle(demangle);
- if (!DsoFactory::GetInstance()->SetSymFsDir(symfs_dir)) {
+ Dso::SetDemangle(demangle);
+ if (!Dso::SetSymFsDir(symfs_dir)) {
return false;
}
if (!vmlinux.empty()) {
- DsoFactory::GetInstance()->SetVmlinux(vmlinux);
+ Dso::SetVmlinux(vmlinux);
}
if (!accumulate_callchain_) {
@@ -590,7 +590,7 @@ bool ReportCommand::ReadFeaturesFromRecordFile() {
for (auto& r : records) {
build_ids.push_back(std::make_pair(r.filename, r.build_id));
}
- DsoFactory::GetInstance()->SetBuildIds(build_ids);
+ Dso::SetBuildIds(build_ids);
std::string arch = record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH);
if (!arch.empty()) {
@@ -695,10 +695,11 @@ static void PrintCallGraphEntry(size_t depth, std::string prefix,
double percentage = 100.0 * (node->period + node->children_period) / parent_period;
percentage_s = android::base::StringPrintf("--%.2lf%%-- ", percentage);
}
- printf("%s%s%s\n", prefix.c_str(), percentage_s.c_str(), node->chain[0]->symbol->name.c_str());
+ printf("%s%s%s\n", prefix.c_str(), percentage_s.c_str(),
+ node->chain[0]->symbol->GetDemangledName().c_str());
prefix.append(percentage_s.size(), ' ');
for (size_t i = 1; i < node->chain.size(); ++i) {
- printf("%s%s\n", prefix.c_str(), node->chain[i]->symbol->name.c_str());
+ printf("%s%s\n", prefix.c_str(), node->chain[i]->symbol->GetDemangledName().c_str());
}
for (size_t i = 0; i < node->children.size(); ++i) {
@@ -710,7 +711,7 @@ static void PrintCallGraphEntry(size_t depth, std::string prefix,
void ReportCommand::PrintCallGraph(const SampleEntry& sample) {
std::string prefix = " ";
printf("%s|\n", prefix.c_str());
- printf("%s-- %s\n", prefix.c_str(), sample.symbol->name.c_str());
+ printf("%s-- %s\n", prefix.c_str(), sample.symbol->GetDemangledName().c_str());
prefix.append(3, ' ');
for (size_t i = 0; i < sample.callchain.children.size(); ++i) {
PrintCallGraphEntry(1, prefix, sample.callchain.children[i], sample.callchain.children_period,
diff --git a/simpleperf/dso.cpp b/simpleperf/dso.cpp
index 55963c2a..0ac44640 100644
--- a/simpleperf/dso.cpp
+++ b/simpleperf/dso.cpp
@@ -17,61 +17,64 @@
#include "dso.h"
#include <stdlib.h>
+
+#include <limits>
+
#include <base/logging.h>
+
#include "environment.h"
#include "read_elf.h"
#include "utils.h"
-const std::string& SymbolEntry::GetDemangledName() const {
+const std::string& Symbol::GetDemangledName() const {
if (demangled_name_.empty()) {
- demangled_name_ = DsoFactory::GetInstance()->Demangle(name);
+ demangled_name_ = Dso::Demangle(name);
}
return demangled_name_;
}
-bool SymbolComparator::operator()(const std::unique_ptr<SymbolEntry>& symbol1,
- const std::unique_ptr<SymbolEntry>& symbol2) {
+bool SymbolComparator::operator()(const std::unique_ptr<Symbol>& symbol1,
+ const std::unique_ptr<Symbol>& symbol2) {
return symbol1->addr < symbol2->addr;
}
-DsoEntry::DsoEntry(DsoType type, const std::string& path)
- : type(type), path(path), is_loaded(false) {
+bool Dso::demangle_ = true;
+std::string Dso::symfs_dir_;
+std::string Dso::vmlinux_;
+std::unordered_map<std::string, BuildId> Dso::build_id_map_;
+
+void Dso::SetDemangle(bool demangle) {
+ demangle_ = demangle;
}
-const SymbolEntry* DsoEntry::FindSymbol(uint64_t offset_in_dso) {
- if (!is_loaded) {
- DsoFactory::GetInstance()->LoadDso(this);
- is_loaded = true;
- }
- std::unique_ptr<SymbolEntry> symbol(new SymbolEntry{
- "", // name
- offset_in_dso, // addr
- 0, // len
- });
+extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status);
- auto it = symbols.upper_bound(symbol);
- if (it != symbols.begin()) {
- --it;
- if ((*it)->addr <= offset_in_dso && (*it)->addr + (*it)->len > offset_in_dso) {
- return (*it).get();
+std::string Dso::Demangle(const std::string& name) {
+ if (!demangle_) {
+ return name;
+ }
+ int status;
+ bool is_linker_symbol = (name.find(linker_prefix) == 0);
+ const char* mangled_str = name.c_str();
+ if (is_linker_symbol) {
+ mangled_str += linker_prefix.size();
+ }
+ std::string result = name;
+ char* demangled_name = __cxa_demangle(mangled_str, nullptr, nullptr, &status);
+ if (status == 0) {
+ if (is_linker_symbol) {
+ result = std::string("[linker]") + demangled_name;
+ } else {
+ result = demangled_name;
}
+ free(demangled_name);
+ } else if (is_linker_symbol) {
+ result = std::string("[linker]") + mangled_str;
}
- return nullptr;
-}
-
-DsoFactory* DsoFactory::GetInstance() {
- static DsoFactory dso_factory;
- return &dso_factory;
-}
-
-DsoFactory::DsoFactory() : demangle_(true) {
-}
-
-void DsoFactory::SetDemangle(bool demangle) {
- demangle_ = demangle;
+ return result;
}
-bool DsoFactory::SetSymFsDir(const std::string& symfs_dir) {
+bool Dso::SetSymFsDir(const std::string& symfs_dir) {
std::string dirname = symfs_dir;
if (!dirname.empty()) {
if (dirname.back() != '/') {
@@ -89,11 +92,11 @@ bool DsoFactory::SetSymFsDir(const std::string& symfs_dir) {
return true;
}
-void DsoFactory::SetVmlinux(const std::string& vmlinux) {
+void Dso::SetVmlinux(const std::string& vmlinux) {
vmlinux_ = vmlinux;
}
-void DsoFactory::SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids) {
+void Dso::SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids) {
std::unordered_map<std::string, BuildId> map;
for (auto& pair : build_ids) {
LOG(DEBUG) << "build_id_map: " << pair.first << ", " << pair.second.ToString();
@@ -102,91 +105,90 @@ void DsoFactory::SetBuildIds(const std::vector<std::pair<std::string, BuildId>>&
build_id_map_ = std::move(map);
}
-std::unique_ptr<DsoEntry> DsoFactory::CreateDso(DsoType dso_type, const std::string& dso_path) {
+BuildId Dso::GetExpectedBuildId(const std::string& filename) {
+ auto it = build_id_map_.find(filename);
+ if (it != build_id_map_.end()) {
+ return it->second;
+ }
+ return BuildId();
+}
+
+std::unique_ptr<Dso> Dso::CreateDso(DsoType dso_type, const std::string& dso_path) {
std::string path = dso_path;
if (dso_type == DSO_KERNEL) {
path = "[kernel.kallsyms]";
}
- return std::unique_ptr<DsoEntry>(new DsoEntry(dso_type, path));
+ return std::unique_ptr<Dso>(new Dso(dso_type, path));
}
-extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status);
+Dso::Dso(DsoType type, const std::string& path) : type_(type), path_(path), is_loaded_(false) {
+}
-std::string DsoFactory::Demangle(const std::string& name) {
- if (!demangle_) {
- return name;
- }
- int status;
- bool is_linker_symbol = (name.find(linker_prefix) == 0);
- const char* mangled_str = name.c_str();
- if (is_linker_symbol) {
- mangled_str += linker_prefix.size();
+const Symbol* Dso::FindSymbol(uint64_t offset_in_dso) {
+ if (!is_loaded_) {
+ is_loaded_ = true;
+ if (!Load()) {
+ LOG(DEBUG) << "failed to load dso: " << path_;
+ return nullptr;
+ }
}
- std::string result = name;
- char* demangled_name = __cxa_demangle(mangled_str, nullptr, nullptr, &status);
- if (status == 0) {
- if (is_linker_symbol) {
- result = std::string("[linker]") + demangled_name;
- } else {
- result = demangled_name;
+ std::unique_ptr<Symbol> symbol(new Symbol{
+ "", // name
+ offset_in_dso, // addr
+ 0, // len
+ });
+
+ auto it = symbols_.upper_bound(symbol);
+ if (it != symbols_.begin()) {
+ --it;
+ if ((*it)->addr <= offset_in_dso && (*it)->addr + (*it)->len > offset_in_dso) {
+ return (*it).get();
}
- free(demangled_name);
- } else if (is_linker_symbol) {
- result = std::string("[linker]") + mangled_str;
}
- return result;
+ return nullptr;
}
-bool DsoFactory::LoadDso(DsoEntry* dso) {
- switch (dso->type) {
+bool Dso::Load() {
+ bool result = false;
+ switch (type_) {
case DSO_KERNEL:
- return LoadKernel(dso);
+ result = LoadKernel();
+ break;
case DSO_KERNEL_MODULE:
- return LoadKernelModule(dso);
+ result = LoadKernelModule();
+ break;
case DSO_ELF_FILE:
- return LoadElfFile(dso);
- default:
- return false;
+ result = LoadElfFile();
+ break;
+ }
+ if (result) {
+ FixupSymbolLength();
}
+ return result;
}
static bool IsKernelFunctionSymbol(const KernelSymbol& symbol) {
return (symbol.type == 'T' || symbol.type == 't' || symbol.type == 'W' || symbol.type == 'w');
}
-static bool KernelSymbolCallback(const KernelSymbol& kernel_symbol, DsoEntry* dso) {
+bool Dso::KernelSymbolCallback(const KernelSymbol& kernel_symbol, Dso* dso) {
if (IsKernelFunctionSymbol(kernel_symbol)) {
- dso->symbols.insert(
- std::unique_ptr<SymbolEntry>(new SymbolEntry(kernel_symbol.name, kernel_symbol.addr, 0)));
+ dso->InsertSymbol(Symbol(kernel_symbol.name, kernel_symbol.addr, 0));
}
return false;
}
-static void VmlinuxSymbolCallback(const ElfFileSymbol& elf_symbol, DsoEntry* dso) {
+void Dso::VmlinuxSymbolCallback(const ElfFileSymbol& elf_symbol, Dso* dso) {
if (elf_symbol.is_func) {
- dso->symbols.insert(std::unique_ptr<SymbolEntry>(
- new SymbolEntry(elf_symbol.name, elf_symbol.vaddr, elf_symbol.len)));
- }
-}
-
-static void FixupSymbolLength(DsoEntry* dso) {
- SymbolEntry* prev_symbol = nullptr;
- for (auto& symbol : dso->symbols) {
- if (prev_symbol != nullptr && prev_symbol->len == 0) {
- prev_symbol->len = symbol->addr - prev_symbol->addr;
- }
- prev_symbol = symbol.get();
- }
- if (prev_symbol != nullptr && prev_symbol->len == 0) {
- prev_symbol->len = ULLONG_MAX - prev_symbol->addr;
+ dso->InsertSymbol(Symbol(elf_symbol.name, elf_symbol.vaddr, elf_symbol.len));
}
}
-bool DsoFactory::LoadKernel(DsoEntry* dso) {
+bool Dso::LoadKernel() {
BuildId build_id = GetExpectedBuildId(DEFAULT_KERNEL_FILENAME_FOR_BUILD_ID);
if (!vmlinux_.empty()) {
ParseSymbolsFromElfFile(vmlinux_, build_id,
- std::bind(VmlinuxSymbolCallback, std::placeholders::_1, dso));
+ std::bind(VmlinuxSymbolCallback, std::placeholders::_1, this));
} else {
if (!build_id.IsEmpty()) {
BuildId real_build_id;
@@ -199,17 +201,15 @@ bool DsoFactory::LoadKernel(DsoEntry* dso) {
}
}
ProcessKernelSymbols("/proc/kallsyms",
- std::bind(&KernelSymbolCallback, std::placeholders::_1, dso));
+ std::bind(&KernelSymbolCallback, std::placeholders::_1, this));
}
- FixupSymbolLength(dso);
return true;
}
-static void ParseSymbolCallback(const ElfFileSymbol& elf_symbol, DsoEntry* dso,
+void Dso::ElfFileSymbolCallback(const ElfFileSymbol& elf_symbol, Dso* dso,
bool (*filter)(const ElfFileSymbol&)) {
if (filter(elf_symbol)) {
- dso->symbols.insert(std::unique_ptr<SymbolEntry>(
- new SymbolEntry(elf_symbol.name, elf_symbol.start_in_file, elf_symbol.len)));
+ dso->InsertSymbol(Symbol(elf_symbol.name, elf_symbol.start_in_file, elf_symbol.len));
}
}
@@ -218,12 +218,11 @@ static bool SymbolFilterForKernelModule(const ElfFileSymbol& elf_symbol) {
return (elf_symbol.is_func && elf_symbol.is_in_text_section);
}
-bool DsoFactory::LoadKernelModule(DsoEntry* dso) {
- BuildId build_id = GetExpectedBuildId(dso->path);
+bool Dso::LoadKernelModule() {
+ BuildId build_id = GetExpectedBuildId(path_);
ParseSymbolsFromElfFile(
- symfs_dir_ + dso->path, build_id,
- std::bind(ParseSymbolCallback, std::placeholders::_1, dso, SymbolFilterForKernelModule));
- FixupSymbolLength(dso);
+ symfs_dir_ + path_, build_id,
+ std::bind(ElfFileSymbolCallback, std::placeholders::_1, this, SymbolFilterForKernelModule));
return true;
}
@@ -231,19 +230,27 @@ static bool SymbolFilterForDso(const ElfFileSymbol& elf_symbol) {
return elf_symbol.is_func || (elf_symbol.is_label && elf_symbol.is_in_text_section);
}
-bool DsoFactory::LoadElfFile(DsoEntry* dso) {
- BuildId build_id = GetExpectedBuildId(dso->path);
+bool Dso::LoadElfFile() {
+ BuildId build_id = GetExpectedBuildId(path_);
ParseSymbolsFromElfFile(
- symfs_dir_ + dso->path, build_id,
- std::bind(ParseSymbolCallback, std::placeholders::_1, dso, SymbolFilterForDso));
- FixupSymbolLength(dso);
+ symfs_dir_ + path_, build_id,
+ std::bind(ElfFileSymbolCallback, std::placeholders::_1, this, SymbolFilterForDso));
return true;
}
-BuildId DsoFactory::GetExpectedBuildId(const std::string& filename) {
- auto it = build_id_map_.find(filename);
- if (it != build_id_map_.end()) {
- return it->second;
+void Dso::InsertSymbol(const Symbol& symbol) {
+ symbols_.insert(std::unique_ptr<Symbol>(new Symbol(symbol)));
+}
+
+void Dso::FixupSymbolLength() {
+ Symbol* prev_symbol = nullptr;
+ for (auto& symbol : symbols_) {
+ if (prev_symbol != nullptr && prev_symbol->len == 0) {
+ prev_symbol->len = symbol->addr - prev_symbol->addr;
+ }
+ prev_symbol = symbol.get();
+ }
+ if (prev_symbol != nullptr && prev_symbol->len == 0) {
+ prev_symbol->len = std::numeric_limits<unsigned long long>::max() - prev_symbol->addr;
}
- return BuildId();
}
diff --git a/simpleperf/dso.h b/simpleperf/dso.h
index 5e44a994..148a47c8 100644
--- a/simpleperf/dso.h
+++ b/simpleperf/dso.h
@@ -25,13 +25,12 @@
#include "build_id.h"
-struct SymbolEntry {
+struct Symbol {
std::string name;
uint64_t addr;
uint64_t len;
- SymbolEntry(const std::string& name, uint64_t addr, uint64_t len)
- : name(name), addr(addr), len(len) {
+ Symbol(const std::string& name, uint64_t addr, uint64_t len) : name(name), addr(addr), len(len) {
}
const std::string& GetDemangledName() const;
@@ -41,8 +40,7 @@ struct SymbolEntry {
};
struct SymbolComparator {
- bool operator()(const std::unique_ptr<SymbolEntry>& symbol1,
- const std::unique_ptr<SymbolEntry>& symbol2);
+ bool operator()(const std::unique_ptr<Symbol>& symbol1, const std::unique_ptr<Symbol>& symbol2);
};
enum DsoType {
@@ -51,42 +49,49 @@ enum DsoType {
DSO_ELF_FILE,
};
-struct DsoEntry {
- DsoType type;
- std::string path;
- std::set<std::unique_ptr<SymbolEntry>, SymbolComparator> symbols;
+struct KernelSymbol;
+struct ElfFileSymbol;
- DsoEntry(DsoType type, const std::string& path);
- const SymbolEntry* FindSymbol(uint64_t offset_in_dso);
-
- private:
- bool is_loaded;
-};
-
-class DsoFactory {
+struct Dso {
public:
- static DsoFactory* GetInstance();
+ static void SetDemangle(bool demangle);
+ static std::string Demangle(const std::string& name);
+ static bool SetSymFsDir(const std::string& symfs_dir);
+ static void SetVmlinux(const std::string& vmlinux);
+ static void SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids);
+
+ static std::unique_ptr<Dso> CreateDso(DsoType dso_type, const std::string& dso_path = "");
- void SetDemangle(bool demangle);
- bool SetSymFsDir(const std::string& symfs_dir);
- void SetVmlinux(const std::string& vmlinux);
- void SetBuildIds(const std::vector<std::pair<std::string, BuildId>>& build_ids);
+ const std::string& Path() const {
+ return path_;
+ }
- std::unique_ptr<DsoEntry> CreateDso(DsoType dso_type, const std::string& dso_path = "");
- std::string Demangle(const std::string& name);
- bool LoadDso(DsoEntry* dso);
+ const Symbol* FindSymbol(uint64_t offset_in_dso);
private:
- DsoFactory();
- bool LoadKernel(DsoEntry* dso);
- bool LoadKernelModule(DsoEntry* dso);
- bool LoadElfFile(DsoEntry* dso);
- BuildId GetExpectedBuildId(const std::string& filename);
-
- bool demangle_;
- std::string symfs_dir_;
- std::string vmlinux_;
- std::unordered_map<std::string, BuildId> build_id_map_;
+ static BuildId GetExpectedBuildId(const std::string& filename);
+ static bool KernelSymbolCallback(const KernelSymbol& kernel_symbol, Dso* dso);
+ static void VmlinuxSymbolCallback(const ElfFileSymbol& elf_symbol, Dso* dso);
+ static void ElfFileSymbolCallback(const ElfFileSymbol& elf_symbol, Dso* dso,
+ bool (*filter)(const ElfFileSymbol&));
+
+ static bool demangle_;
+ static std::string symfs_dir_;
+ static std::string vmlinux_;
+ static std::unordered_map<std::string, BuildId> build_id_map_;
+
+ Dso(DsoType type, const std::string& path);
+ bool Load();
+ bool LoadKernel();
+ bool LoadKernelModule();
+ bool LoadElfFile();
+ void InsertSymbol(const Symbol& symbol);
+ void FixupSymbolLength();
+
+ const DsoType type_;
+ const std::string path_;
+ std::set<std::unique_ptr<Symbol>, SymbolComparator> symbols_;
+ bool is_loaded_;
};
#endif // SIMPLE_PERF_DSO_H_
diff --git a/simpleperf/environment.cpp b/simpleperf/environment.cpp
index 4d63530d..4e3c212e 100644
--- a/simpleperf/environment.cpp
+++ b/simpleperf/environment.cpp
@@ -19,6 +19,8 @@
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
+
+#include <limits>
#include <unordered_map>
#include <vector>
@@ -218,7 +220,7 @@ bool GetKernelAndModuleMmaps(KernelMmap* kernel_mmap, std::vector<ModuleMmap>* m
kernel_mmap->name = DEFAULT_KERNEL_MMAP_NAME;
*module_mmaps = GetModulesInUse();
if (module_mmaps->size() == 0) {
- kernel_mmap->len = ULLONG_MAX - kernel_mmap->start_addr;
+ kernel_mmap->len = std::numeric_limits<unsigned long long>::max() - kernel_mmap->start_addr;
} else {
std::sort(
module_mmaps->begin(), module_mmaps->end(),
@@ -238,7 +240,8 @@ bool GetKernelAndModuleMmaps(KernelMmap* kernel_mmap, std::vector<ModuleMmap>* m
(*module_mmaps)[i + 1].start_addr - (*module_mmaps)[i].start_addr - 1;
}
}
- module_mmaps->back().len = ULLONG_MAX - module_mmaps->back().start_addr;
+ module_mmaps->back().len =
+ std::numeric_limits<unsigned long long>::max() - module_mmaps->back().start_addr;
}
return true;
}
diff --git a/simpleperf/sample_tree.cpp b/simpleperf/sample_tree.cpp
index 29bffdac..a55fd64e 100644
--- a/simpleperf/sample_tree.cpp
+++ b/simpleperf/sample_tree.cpp
@@ -34,7 +34,7 @@ SampleEntry* SampleTree::AddSample(int pid, int tid, uint64_t ip, uint64_t time,
bool in_kernel) {
const ThreadEntry* thread = thread_tree_->FindThreadOrNew(pid, tid);
const MapEntry* map = thread_tree_->FindMap(thread, ip, in_kernel);
- const SymbolEntry* symbol = thread_tree_->FindSymbol(map, ip);
+ const Symbol* symbol = thread_tree_->FindSymbol(map, ip);
SampleEntry value(ip, time, period, 0, 1, thread, map, symbol);
@@ -51,12 +51,12 @@ void SampleTree::AddBranchSample(int pid, int tid, uint64_t from_ip, uint64_t to
if (from_map == thread_tree_->UnknownMap()) {
from_map = thread_tree_->FindMap(thread, from_ip, true);
}
- const SymbolEntry* from_symbol = thread_tree_->FindSymbol(from_map, from_ip);
+ const Symbol* from_symbol = thread_tree_->FindSymbol(from_map, from_ip);
const MapEntry* to_map = thread_tree_->FindMap(thread, to_ip, false);
if (to_map == thread_tree_->UnknownMap()) {
to_map = thread_tree_->FindMap(thread, to_ip, true);
}
- const SymbolEntry* to_symbol = thread_tree_->FindSymbol(to_map, to_ip);
+ const Symbol* to_symbol = thread_tree_->FindSymbol(to_map, to_ip);
SampleEntry value(to_ip, time, period, 0, 1, thread, to_map, to_symbol);
value.branch_from.ip = from_ip;
@@ -75,7 +75,7 @@ SampleEntry* SampleTree::AddCallChainSample(int pid, int tid, uint64_t ip, uint6
const std::vector<SampleEntry*>& callchain) {
const ThreadEntry* thread = thread_tree_->FindThreadOrNew(pid, tid);
const MapEntry* map = thread_tree_->FindMap(thread, ip, in_kernel);
- const SymbolEntry* symbol = thread_tree_->FindSymbol(map, ip);
+ const Symbol* symbol = thread_tree_->FindSymbol(map, ip);
SampleEntry value(ip, time, 0, period, 0, thread, map, symbol);
@@ -111,7 +111,7 @@ bool SampleTree::IsFilteredOut(const SampleEntry& value) {
if (!comm_filter_.empty() && comm_filter_.find(value.thread_comm) == comm_filter_.end()) {
return true;
}
- if (!dso_filter_.empty() && dso_filter_.find(value.map->dso->path) == dso_filter_.end()) {
+ if (!dso_filter_.empty() && dso_filter_.find(value.map->dso->Path()) == dso_filter_.end()) {
return true;
}
return false;
diff --git a/simpleperf/sample_tree.h b/simpleperf/sample_tree.h
index 5227af20..6eb73722 100644
--- a/simpleperf/sample_tree.h
+++ b/simpleperf/sample_tree.h
@@ -31,7 +31,7 @@
struct BranchFromEntry {
uint64_t ip;
const MapEntry* map;
- const SymbolEntry* symbol;
+ const Symbol* symbol;
uint64_t flags;
BranchFromEntry() : ip(0), map(nullptr), symbol(nullptr), flags(0) {
@@ -47,13 +47,13 @@ struct SampleEntry {
const ThreadEntry* thread;
const char* thread_comm; // It refers to the thread comm when the sample happens.
const MapEntry* map;
- const SymbolEntry* symbol;
+ const Symbol* symbol;
BranchFromEntry branch_from;
CallChainRoot callchain; // A callchain tree representing all callchains in the sample records.
SampleEntry(uint64_t ip, uint64_t time, uint64_t period, uint64_t accumulated_period,
uint64_t sample_count, const ThreadEntry* thread, const MapEntry* map,
- const SymbolEntry* symbol)
+ const Symbol* symbol)
: ip(ip),
time(time),
period(period),
diff --git a/simpleperf/sample_tree_test.cpp b/simpleperf/sample_tree_test.cpp
index cb590832..8e14a8b8 100644
--- a/simpleperf/sample_tree_test.cpp
+++ b/simpleperf/sample_tree_test.cpp
@@ -35,7 +35,7 @@ static void SampleMatchExpectation(const SampleEntry& sample, const ExpectedSamp
ASSERT_EQ(expected.tid, sample.thread->tid);
ASSERT_STREQ(expected.comm, sample.thread_comm);
ASSERT_TRUE(sample.map != nullptr);
- ASSERT_EQ(expected.dso_name, sample.map->dso->path);
+ ASSERT_EQ(expected.dso_name, sample.map->dso->Path());
ASSERT_EQ(expected.map_start_addr, sample.map->start_addr);
ASSERT_EQ(expected.sample_count, sample.sample_count);
*has_error = false;
@@ -60,8 +60,8 @@ static int CompareSampleFunction(const SampleEntry& sample1, const SampleEntry&
if (strcmp(sample1.thread_comm, sample2.thread_comm) != 0) {
return strcmp(sample1.thread_comm, sample2.thread_comm);
}
- if (sample1.map->dso->path != sample2.map->dso->path) {
- return sample1.map->dso->path > sample2.map->dso->path ? 1 : -1;
+ if (sample1.map->dso->Path() != sample2.map->dso->Path()) {
+ return sample1.map->dso->Path() > sample2.map->dso->Path() ? 1 : -1;
}
if (sample1.map->start_addr != sample2.map->start_addr) {
return sample1.map->start_addr - sample2.map->start_addr;
diff --git a/simpleperf/thread_tree.cpp b/simpleperf/thread_tree.cpp
index 9407733a..27b8583d 100644
--- a/simpleperf/thread_tree.cpp
+++ b/simpleperf/thread_tree.cpp
@@ -16,7 +16,10 @@
#include "thread_tree.h"
+#include <limits>
+
#include <base/logging.h>
+
#include "environment.h"
#include "perf_event.h"
#include "record.h"
@@ -91,7 +94,7 @@ void ThreadTree::AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff,
if (len == 0) {
return;
}
- DsoEntry* dso = FindKernelDsoOrNew(filename);
+ Dso* dso = FindKernelDsoOrNew(filename);
MapEntry* map = new MapEntry{
start_addr, len, pgoff, time, dso,
};
@@ -101,16 +104,16 @@ void ThreadTree::AddKernelMap(uint64_t start_addr, uint64_t len, uint64_t pgoff,
CHECK(pair.second);
}
-DsoEntry* ThreadTree::FindKernelDsoOrNew(const std::string& filename) {
+Dso* ThreadTree::FindKernelDsoOrNew(const std::string& filename) {
if (filename == DEFAULT_KERNEL_MMAP_NAME) {
if (kernel_dso_ == nullptr) {
- kernel_dso_ = DsoFactory::GetInstance()->CreateDso(DSO_KERNEL);
+ kernel_dso_ = Dso::CreateDso(DSO_KERNEL);
}
return kernel_dso_.get();
}
auto it = module_dso_tree_.find(filename);
if (it == module_dso_tree_.end()) {
- module_dso_tree_[filename] = DsoFactory::GetInstance()->CreateDso(DSO_KERNEL_MODULE, filename);
+ module_dso_tree_[filename] = Dso::CreateDso(DSO_KERNEL_MODULE, filename);
it = module_dso_tree_.find(filename);
}
return it->second.get();
@@ -119,7 +122,7 @@ DsoEntry* ThreadTree::FindKernelDsoOrNew(const std::string& filename) {
void ThreadTree::AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, uint64_t pgoff,
uint64_t time, const std::string& filename) {
ThreadEntry* thread = FindThreadOrNew(pid, tid);
- DsoEntry* dso = FindUserDsoOrNew(filename);
+ Dso* dso = FindUserDsoOrNew(filename);
MapEntry* map = new MapEntry{
start_addr, len, pgoff, time, dso,
};
@@ -129,10 +132,10 @@ void ThreadTree::AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t le
CHECK(pair.second);
}
-DsoEntry* ThreadTree::FindUserDsoOrNew(const std::string& filename) {
+Dso* ThreadTree::FindUserDsoOrNew(const std::string& filename) {
auto it = user_dso_tree_.find(filename);
if (it == user_dso_tree_.end()) {
- user_dso_tree_[filename] = DsoFactory::GetInstance()->CreateDso(DSO_ELF_FILE, filename);
+ user_dso_tree_[filename] = Dso::CreateDso(DSO_ELF_FILE, filename);
it = user_dso_tree_.find(filename);
}
return it->second.get();
@@ -145,11 +148,11 @@ static bool IsAddrInMap(uint64_t addr, const MapEntry* map) {
static MapEntry* FindMapByAddr(const std::set<MapEntry*, MapComparator>& maps, uint64_t addr) {
// Construct a map_entry which is strictly after the searched map_entry, based on MapComparator.
MapEntry find_map = {
- addr, // start_addr
- ULLONG_MAX, // len
- 0, // pgoff
- ULLONG_MAX, // time
- nullptr, // dso
+ addr, // start_addr
+ std::numeric_limits<unsigned long long>::max(), // len
+ 0, // pgoff
+ std::numeric_limits<unsigned long long>::max(), // time
+ nullptr, // dso
};
auto it = maps.upper_bound(&find_map);
if (it != maps.begin() && IsAddrInMap(addr, *--it)) {
@@ -168,14 +171,14 @@ const MapEntry* ThreadTree::FindMap(const ThreadEntry* thread, uint64_t ip, bool
return result != nullptr ? result : &unknown_map_;
}
-const SymbolEntry* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip) {
+const Symbol* ThreadTree::FindSymbol(const MapEntry* map, uint64_t ip) {
uint64_t offset_in_file;
if (map->dso == kernel_dso_.get()) {
offset_in_file = ip;
} else {
offset_in_file = ip - map->start_addr + map->pgoff;
}
- const SymbolEntry* symbol = map->dso->FindSymbol(offset_in_file);
+ const Symbol* symbol = map->dso->FindSymbol(offset_in_file);
if (symbol == nullptr) {
symbol = &unknown_symbol_;
}
diff --git a/simpleperf/thread_tree.h b/simpleperf/thread_tree.h
index c0ec3ea4..7abfdfc3 100644
--- a/simpleperf/thread_tree.h
+++ b/simpleperf/thread_tree.h
@@ -17,9 +17,12 @@
#ifndef SIMPLE_PERF_THREAD_TREE_H_
#define SIMPLE_PERF_THREAD_TREE_H_
-#include <limits.h>
#include <stdint.h>
+
+#include <limits>
+#include <memory>
#include <set>
+
#include "dso.h"
struct MapEntry {
@@ -27,7 +30,7 @@ struct MapEntry {
uint64_t len;
uint64_t pgoff;
uint64_t time; // Map creation time.
- DsoEntry* dso;
+ Dso* dso;
};
struct MapComparator {
@@ -43,13 +46,14 @@ struct ThreadEntry {
class ThreadTree {
public:
- ThreadTree() : unknown_dso_(DSO_ELF_FILE, "unknown"), unknown_symbol_("unknown", 0, ULLONG_MAX) {
+ ThreadTree() : unknown_symbol_("unknown", 0, std::numeric_limits<unsigned long long>::max()) {
+ unknown_dso_ = Dso::CreateDso(DSO_ELF_FILE, "unknown");
unknown_map_ = MapEntry{
- 0, // start_addr
- ULLONG_MAX, // len
- 0, // pgoff
- 0, // time
- &unknown_dso_, // dso
+ 0, // start_addr
+ std::numeric_limits<unsigned long long>::max(), // len
+ 0, // pgoff
+ 0, // time
+ unknown_dso_.get(), // dso
};
}
@@ -61,14 +65,14 @@ class ThreadTree {
void AddThreadMap(int pid, int tid, uint64_t start_addr, uint64_t len, uint64_t pgoff,
uint64_t time, const std::string& filename);
const MapEntry* FindMap(const ThreadEntry* thread, uint64_t ip, bool in_kernel);
- const SymbolEntry* FindSymbol(const MapEntry* map, uint64_t ip);
+ const Symbol* FindSymbol(const MapEntry* map, uint64_t ip);
const MapEntry* UnknownMap() const {
return &unknown_map_;
}
private:
- DsoEntry* FindKernelDsoOrNew(const std::string& filename);
- DsoEntry* FindUserDsoOrNew(const std::string& filename);
+ Dso* FindKernelDsoOrNew(const std::string& filename);
+ Dso* FindUserDsoOrNew(const std::string& filename);
std::unordered_map<int, std::unique_ptr<ThreadEntry>> thread_tree_;
std::vector<std::unique_ptr<std::string>> thread_comm_storage_;
@@ -77,11 +81,11 @@ class ThreadTree {
std::vector<std::unique_ptr<MapEntry>> map_storage_;
MapEntry unknown_map_;
- std::unique_ptr<DsoEntry> kernel_dso_;
- std::unordered_map<std::string, std::unique_ptr<DsoEntry>> module_dso_tree_;
- std::unordered_map<std::string, std::unique_ptr<DsoEntry>> user_dso_tree_;
- DsoEntry unknown_dso_;
- SymbolEntry unknown_symbol_;
+ std::unique_ptr<Dso> kernel_dso_;
+ std::unordered_map<std::string, std::unique_ptr<Dso>> module_dso_tree_;
+ std::unordered_map<std::string, std::unique_ptr<Dso>> user_dso_tree_;
+ std::unique_ptr<Dso> unknown_dso_;
+ Symbol unknown_symbol_;
};
struct Record;