Skip to content

Commit 7c4bbdc

Browse files
yabincAndroid (Google) Code Review
authored and
Android (Google) Code Review
committed
Merge "Simpleperf: remove dependency on global current_arch." into nyc-dev
2 parents 9fbb28c + e435e7d commit 7c4bbdc

10 files changed

+72
-49
lines changed

Diff for: simpleperf/cmd_dumprecord.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class DumpRecordCommand : public Command {
3939
: Command("dump", "dump perf record file",
4040
"Usage: simpleperf dumprecord [options] [perf_record_file]\n"
4141
" Dump different parts of a perf record file. Default file is perf.data.\n"),
42-
record_filename_("perf.data") {
42+
record_filename_("perf.data"), record_file_arch_(GetBuildArch()) {
4343
}
4444

4545
bool Run(const std::vector<std::string>& args);
@@ -53,6 +53,7 @@ class DumpRecordCommand : public Command {
5353

5454
std::string record_filename_;
5555
std::unique_ptr<RecordFileReader> record_file_reader_;
56+
ArchType record_file_arch_;
5657
};
5758

5859
bool DumpRecordCommand::Run(const std::vector<std::string>& args) {
@@ -65,10 +66,12 @@ bool DumpRecordCommand::Run(const std::vector<std::string>& args) {
6566
}
6667
std::string arch = record_file_reader_->ReadFeatureString(FEAT_ARCH);
6768
if (!arch.empty()) {
68-
if (!SetCurrentArch(arch)) {
69+
record_file_arch_ = GetArchType(arch);
70+
if (record_file_arch_ == ARCH_UNSUPPORTED) {
6971
return false;
7072
}
7173
}
74+
ScopedCurrentArch scoped_arch(record_file_arch_);
7275
DumpFileHeader();
7376
DumpAttrSection();
7477
DumpDataSection();

Diff for: simpleperf/cmd_record.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ void RecordCommand::UnwindRecord(Record* record) {
688688
ThreadEntry* thread = thread_tree_.FindThreadOrNew(r.tid_data.pid, r.tid_data.tid);
689689
RegSet regs = CreateRegSet(r.regs_user_data.reg_mask, r.regs_user_data.regs);
690690
std::vector<char>& stack = r.stack_user_data.data;
691-
std::vector<uint64_t> unwind_ips = UnwindCallChain(*thread, regs, stack);
691+
std::vector<uint64_t> unwind_ips = UnwindCallChain(GetBuildArch(), *thread, regs, stack);
692692
r.callchain_data.ips.push_back(PERF_CONTEXT_USER);
693693
r.callchain_data.ips.insert(r.callchain_data.ips.end(), unwind_ips.begin(), unwind_ips.end());
694694
r.regs_user_data.abi = 0;

Diff for: simpleperf/cmd_report.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ class ReportCommand : public Command {
270270
" --vmlinux <file>\n"
271271
" Parse kernel symbols from <file>.\n"),
272272
record_filename_("perf.data"),
273+
record_file_arch_(GetBuildArch()),
273274
use_branch_address_(false),
274275
accumulate_callchain_(false),
275276
print_callgraph_(false),
@@ -302,6 +303,7 @@ class ReportCommand : public Command {
302303
uint64_t parent_period, bool last);
303304

304305
std::string record_filename_;
306+
ArchType record_file_arch_;
305307
std::unique_ptr<RecordFileReader> record_file_reader_;
306308
perf_event_attr event_attr_;
307309
std::vector<std::unique_ptr<Displayable>> displayable_items_;
@@ -336,6 +338,7 @@ bool ReportCommand::Run(const std::vector<std::string>& args) {
336338
if (!ReadFeaturesFromRecordFile()) {
337339
return false;
338340
}
341+
ScopedCurrentArch scoped_arch(record_file_arch_);
339342
ReadSampleTreeFromRecordFile();
340343

341344
// 3. Show collected information.
@@ -565,7 +568,8 @@ void ReportCommand::ProcessSampleRecord(const SampleRecord& r) {
565568
RegSet regs = CreateRegSet(r.regs_user_data.reg_mask, r.regs_user_data.regs);
566569
std::vector<char> stack(r.stack_user_data.data.begin(),
567570
r.stack_user_data.data.begin() + r.stack_user_data.data.size());
568-
std::vector<uint64_t> unwind_ips = UnwindCallChain(*sample->thread, regs, stack);
571+
std::vector<uint64_t> unwind_ips =
572+
UnwindCallChain(ScopedCurrentArch::GetCurrentArch(), *sample->thread, regs, stack);
569573
if (!unwind_ips.empty()) {
570574
ips.push_back(PERF_CONTEXT_USER);
571575
ips.insert(ips.end(), unwind_ips.begin(), unwind_ips.end());
@@ -633,7 +637,8 @@ bool ReportCommand::ReadFeaturesFromRecordFile() {
633637

634638
std::string arch = record_file_reader_->ReadFeatureString(PerfFileFormat::FEAT_ARCH);
635639
if (!arch.empty()) {
636-
if (!SetCurrentArch(arch)) {
640+
record_file_arch_ = GetArchType(arch);
641+
if (record_file_arch_ == ARCH_UNSUPPORTED) {
637642
return false;
638643
}
639644
}

Diff for: simpleperf/dwarf_unwind.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,15 @@ static ucontext_t BuildUContextFromRegs(const RegSet& regs __attribute__((unused
9494
return ucontext;
9595
}
9696

97-
std::vector<uint64_t> UnwindCallChain(const ThreadEntry& thread, const RegSet& regs,
98-
const std::vector<char>& stack) {
97+
std::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread,
98+
const RegSet& regs, const std::vector<char>& stack) {
9999
std::vector<uint64_t> result;
100-
if (GetCurrentArch() != GetBuildArch()) {
100+
if (arch != GetBuildArch()) {
101101
LOG(ERROR) << "can't unwind data recorded on a different architecture";
102102
return result;
103103
}
104104
uint64_t sp_reg_value;
105-
if (!GetSpRegValue(regs, &sp_reg_value)) {
105+
if (!GetSpRegValue(regs, arch, &sp_reg_value)) {
106106
LOG(ERROR) << "can't get sp reg value";
107107
return result;
108108
}

Diff for: simpleperf/dwarf_unwind.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
struct ThreadEntry;
2525

26-
std::vector<uint64_t> UnwindCallChain(const ThreadEntry& thread, const RegSet& regs,
26+
std::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread, const RegSet& regs,
2727
const std::vector<char>& stack);
2828

2929
#endif // SIMPLE_PERF_DWARF_UNWIND_H_

Diff for: simpleperf/event_selection_set.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ bool IsDwarfCallChainSamplingSupported() {
4545
perf_event_attr attr = CreateDefaultPerfEventAttr(*type);
4646
attr.sample_type |= PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER;
4747
attr.exclude_callchain_user = 1;
48-
attr.sample_regs_user = GetSupportedRegMask();
48+
attr.sample_regs_user = GetSupportedRegMask(GetBuildArch());
4949
attr.sample_stack_user = 8192;
5050
return IsEventAttrSupportedByKernel(attr);
5151
}
@@ -166,7 +166,7 @@ bool EventSelectionSet::EnableDwarfCallChainSampling(uint32_t dump_stack_size) {
166166
selection.event_attr.sample_type |=
167167
PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_STACK_USER;
168168
selection.event_attr.exclude_callchain_user = 1;
169-
selection.event_attr.sample_regs_user = GetSupportedRegMask();
169+
selection.event_attr.sample_regs_user = GetSupportedRegMask(GetBuildArch());
170170
selection.event_attr.sample_stack_user = dump_stack_size;
171171
}
172172
return true;

Diff for: simpleperf/nonlinux_support/nonlinux_support.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
#include "dwarf_unwind.h"
2121
#include "environment.h"
2222

23-
std::vector<uint64_t> UnwindCallChain(const ThreadEntry&, const RegSet&, const std::vector<char>&) {
23+
std::vector<uint64_t> UnwindCallChain(ArchType, const ThreadEntry&, const RegSet&,
24+
const std::vector<char>&) {
2425
return std::vector<uint64_t>();
2526
}
2627

Diff for: simpleperf/perf_regs.cpp

+29-30
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,24 @@
2121
#include <android-base/stringprintf.h>
2222
#include <android-base/strings.h>
2323

24-
static ArchType current_arch = GetBuildArch();
24+
ArchType ScopedCurrentArch::current_arch = GetBuildArch();
2525

26-
ArchType GetCurrentArch() {
27-
return current_arch;
28-
}
29-
30-
bool SetCurrentArch(const std::string& arch) {
26+
ArchType GetArchType(const std::string& arch) {
3127
if (arch == "x86" || arch == "i686") {
32-
current_arch = ARCH_X86_32;
28+
return ARCH_X86_32;
3329
} else if (arch == "x86_64") {
34-
current_arch = ARCH_X86_64;
30+
return ARCH_X86_64;
3531
} else if (arch == "aarch64") {
36-
current_arch = ARCH_ARM64;
32+
return ARCH_ARM64;
3733
} else if (android::base::StartsWith(arch, "arm")) {
38-
current_arch = ARCH_ARM;
39-
} else {
40-
LOG(ERROR) << "unsupported arch: " << arch;
41-
return false;
34+
return ARCH_ARM;
4235
}
43-
return true;
36+
LOG(ERROR) << "unsupported arch: " << arch;
37+
return ARCH_UNSUPPORTED;
4438
}
4539

46-
uint64_t GetSupportedRegMask() {
47-
switch (GetCurrentArch()) {
40+
uint64_t GetSupportedRegMask(ArchType arch) {
41+
switch (arch) {
4842
case ARCH_X86_32:
4943
return ((1ULL << PERF_REG_X86_32_MAX) - 1);
5044
case ARCH_X86_64:
@@ -78,10 +72,10 @@ static std::unordered_map<size_t, std::string> arm64_reg_map = {
7872
{PERF_REG_ARM64_LR, "lr"}, {PERF_REG_ARM64_SP, "sp"}, {PERF_REG_ARM64_PC, "pc"},
7973
};
8074

81-
std::string GetRegName(size_t regno) {
75+
std::string GetRegName(size_t regno, ArchType arch) {
8276
// Cast regno to int type to avoid -Werror=type-limits.
8377
int reg = static_cast<int>(regno);
84-
switch (GetCurrentArch()) {
78+
switch (arch) {
8579
case ARCH_X86_64: {
8680
if (reg >= PERF_REG_X86_R8 && reg <= PERF_REG_X86_R15) {
8781
return android::base::StringPrintf("r%d", reg - PERF_REG_X86_R8 + 8);
@@ -133,18 +127,23 @@ bool GetRegValue(const RegSet& regs, size_t regno, uint64_t* value) {
133127
return false;
134128
}
135129

136-
bool GetSpRegValue(const RegSet& regs, uint64_t* value) {
130+
bool GetSpRegValue(const RegSet& regs, ArchType arch, uint64_t* value) {
137131
size_t regno;
138-
#if defined(__i386__)
139-
regno = PERF_REG_X86_SP;
140-
#elif defined(__x86_64__)
141-
regno = PERF_REG_X86_SP;
142-
#elif defined(__aarch64__)
143-
regno = PERF_REG_ARM64_SP;
144-
#elif defined(__arm__)
145-
regno = PERF_REG_ARM_SP;
146-
#else
147-
return false;
148-
#endif
132+
switch (arch) {
133+
case ARCH_X86_32:
134+
regno = PERF_REG_X86_SP;
135+
break;
136+
case ARCH_X86_64:
137+
regno = PERF_REG_X86_SP;
138+
break;
139+
case ARCH_ARM:
140+
regno = PERF_REG_ARM_SP;
141+
break;
142+
case ARCH_ARM64:
143+
regno = PERF_REG_ARM64_SP;
144+
break;
145+
default:
146+
return false;
147+
}
149148
return GetRegValue(regs, regno, value);
150149
}

Diff for: simpleperf/perf_regs.h

+19-5
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,26 @@ constexpr ArchType GetBuildArch() {
5555
#endif
5656
}
5757

58-
ArchType GetCurrentArch();
59-
bool SetCurrentArch(const std::string& arch);
58+
ArchType GetArchType(const std::string& arch);
59+
uint64_t GetSupportedRegMask(ArchType arch);
60+
std::string GetRegName(size_t regno, ArchType arch);
6061

61-
uint64_t GetSupportedRegMask();
62+
class ScopedCurrentArch {
63+
public:
64+
ScopedCurrentArch(ArchType arch) : saved_arch(current_arch) {
65+
current_arch = arch;
66+
}
67+
~ScopedCurrentArch() {
68+
current_arch = saved_arch;
69+
}
70+
static ArchType GetCurrentArch() {
71+
return current_arch;
72+
}
6273

63-
std::string GetRegName(size_t regno);
74+
private:
75+
ArchType saved_arch;
76+
static ArchType current_arch;
77+
};
6478

6579
struct RegSet {
6680
uint64_t valid_mask;
@@ -70,6 +84,6 @@ struct RegSet {
7084
RegSet CreateRegSet(uint64_t valid_mask, const std::vector<uint64_t>& valid_regs);
7185

7286
bool GetRegValue(const RegSet& regs, size_t regno, uint64_t* value);
73-
bool GetSpRegValue(const RegSet& regs, uint64_t* value);
87+
bool GetSpRegValue(const RegSet& regs, ArchType arch, uint64_t* value);
7488

7589
#endif // SIMPLE_PERF_PERF_REGS_H_

Diff for: simpleperf/record.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,8 @@ void SampleRecord::DumpData(size_t indent) const {
505505
PrintIndented(indent, "user regs: abi=%" PRId64 "\n", regs_user_data.abi);
506506
for (size_t i = 0, pos = 0; i < 64; ++i) {
507507
if ((regs_user_data.reg_mask >> i) & 1) {
508-
PrintIndented(indent + 1, "reg (%s) 0x%016" PRIx64 "\n", GetRegName(i).c_str(),
508+
PrintIndented(indent + 1, "reg (%s) 0x%016" PRIx64 "\n",
509+
GetRegName(i, ScopedCurrentArch::GetCurrentArch()).c_str(),
509510
regs_user_data.regs[pos++]);
510511
}
511512
}

0 commit comments

Comments
 (0)