Skip to content

Commit f76cd4d

Browse files
Louis-Yegmarin13
authored andcommitted
Add branch-stack support for Arm SPE-based samples
PiperOrigin-RevId: 684550232
1 parent 50a9b50 commit f76cd4d

File tree

2 files changed

+48
-18
lines changed

2 files changed

+48
-18
lines changed

src/perf_data_handler.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,20 @@ void Normalizer::HandleSample(PerfDataHandler::SampleContext* context) {
579579
context->branch_stack[i].spec = entry.spec();
580580
}
581581

582+
// Add the branch stack pair for SPE sample if it is a branch instruction with
583+
// target branch address.
584+
if (context->spe.is_spe && context->spe.record.tgt_br_ip.addr != 0) {
585+
const auto& record = context->spe.record;
586+
PerfDataHandler::BranchStackPair br;
587+
br.from.ip = context->sample.ip();
588+
br.from.mapping = context->sample_mapping;
589+
br.to.ip = context->spe.record.tgt_br_ip.addr;
590+
br.to.mapping =
591+
GetMappingFromPidAndIP(pid, record.tgt_br_ip.addr, header_context);
592+
br.mispredicted = record.event.br_mis_pred;
593+
context->branch_stack.push_back(br);
594+
}
595+
582596
if (sample.has_cgroup()) {
583597
auto cgrp_it = cgroup_map_.find(sample.cgroup());
584598
if (cgrp_it != cgroup_map_.end()) {

src/perf_data_handler_test.cc

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,11 @@ class PerfDataHandlerTest : public ::testing::Test {
8585

8686
class TestPerfDataHandler : public PerfDataHandler {
8787
public:
88-
TestPerfDataHandler(std::vector<BranchStackEntry> expected_branch_stack,
89-
std::unordered_map<std::string, std::string>
90-
expected_filename_to_build_id)
91-
: expected_branch_stack_(std::move(expected_branch_stack)),
88+
TestPerfDataHandler(
89+
std::vector<std::vector<BranchStackEntry>> expected_branch_stack,
90+
std::unordered_map<std::string, std::string>
91+
expected_filename_to_build_id)
92+
: expected_branch_stack_sequence_(std::move(expected_branch_stack)),
9293
expected_filename_to_build_id_(
9394
std::move(expected_filename_to_build_id)) {}
9495
TestPerfDataHandler(const TestPerfDataHandler&) = delete;
@@ -106,13 +107,22 @@ class TestPerfDataHandler : public PerfDataHandler {
106107
} else {
107108
seen_addr_mappings_.push_back(nullptr);
108109
}
109-
EXPECT_EQ(expected_branch_stack_.size(), sample.branch_stack.size());
110-
for (size_t i = 0; i < sample.branch_stack.size(); i++) {
111-
CheckBranchEquality(expected_branch_stack_[i], sample.branch_stack[i]);
110+
111+
// If the expected branch stack sequence is not empty, then check it for
112+
// each sample.
113+
if (!expected_branch_stack_sequence_.empty()) {
114+
const std::vector<BranchStackEntry>& expected_branch_stack =
115+
expected_branch_stack_sequence_[seen_sample_events_.size() - 1];
116+
EXPECT_EQ(expected_branch_stack.size(), sample.branch_stack.size());
117+
for (size_t i = 0; i < sample.branch_stack.size(); i++) {
118+
CheckBranchEquality(expected_branch_stack[i], sample.branch_stack[i]);
119+
}
112120
}
121+
113122
if (sample.spe.is_spe) {
114123
seen_arm_spe_records_.push_back(sample.spe.record);
115124
}
125+
116126
return true;
117127
}
118128
void Comm(const CommContext& comm) override {}
@@ -170,7 +180,7 @@ class TestPerfDataHandler : public PerfDataHandler {
170180
EXPECT_EQ(expected.abort(), actual.abort);
171181
EXPECT_EQ(expected.cycles(), actual.cycles);
172182
}
173-
std::vector<BranchStackEntry> expected_branch_stack_;
183+
std::vector<std::vector<BranchStackEntry>> expected_branch_stack_sequence_;
174184
std::unordered_map<std::string, std::string> expected_filename_to_build_id_;
175185
std::unordered_set<std::string> seen_filenames_;
176186
std::vector<std::unique_ptr<Mapping>> seen_addr_mappings_;
@@ -257,8 +267,7 @@ TEST(PerfDataHandlerTest, KernelBuildIdWithDifferentFilename) {
257267
expected_filename_to_build_id["[kernel.kallsyms]"] = "17937e648e";
258268
expected_filename_to_build_id["chrome"] = "cac4b36db4d0";
259269

260-
TestPerfDataHandler handler(std::vector<BranchStackEntry>(),
261-
expected_filename_to_build_id);
270+
TestPerfDataHandler handler({}, expected_filename_to_build_id);
262271
PerfDataHandler::Process(proto, &handler);
263272
handler.CheckSeenFilenames();
264273
}
@@ -301,7 +310,7 @@ TEST(PerfDataHandlerTest, SampleBranchStackMatches) {
301310
entry->set_cycles(5);
302311
branch_stack.push_back(*entry);
303312

304-
TestPerfDataHandler handler(branch_stack,
313+
TestPerfDataHandler handler({branch_stack},
305314
std::unordered_map<std::string, std::string>());
306315
PerfDataHandler::Process(proto, &handler);
307316
}
@@ -350,7 +359,7 @@ TEST(PerfDataHandlerTest, AddressMappingIsSet) {
350359
sample_event->set_period(1);
351360
sample_event->set_id(file_attr_id);
352361

353-
TestPerfDataHandler handler(std::vector<BranchStackEntry>{},
362+
TestPerfDataHandler handler({},
354363
std::unordered_map<std::string, std::string>{});
355364
PerfDataHandler::Process(proto, &handler);
356365
auto& addr_mappings = handler.SeenAddrMappings();
@@ -406,7 +415,7 @@ TEST(PerfDataHandlerTest, MappingBuildIdAndSourceAreSet) {
406415
sample_event->set_tid(100);
407416
sample_event->set_addr(0x3010);
408417

409-
TestPerfDataHandler handler(std::vector<BranchStackEntry>{},
418+
TestPerfDataHandler handler({},
410419
std::unordered_map<std::string, std::string>{});
411420
PerfDataHandler::Process(proto, &handler);
412421
auto& mappings = handler.SeenAddrMappings();
@@ -458,7 +467,7 @@ TEST(PerfDataHandlerTest, LostSampleEventsAreHandledInNewerPerf) {
458467
lost_samples_event2->mutable_sample_info()->set_tid(100);
459468
lost_samples_event2->set_num_lost(3);
460469

461-
TestPerfDataHandler handler(std::vector<BranchStackEntry>{},
470+
TestPerfDataHandler handler({},
462471
std::unordered_map<std::string, std::string>{});
463472
PerfDataHandler::Process(proto, &handler);
464473

@@ -497,7 +506,7 @@ TEST(PerfDataHandlerTest, LostEventsAreHandledInOlderPerf) {
497506
lost_event->mutable_sample_info()->set_tid(100);
498507
lost_event->set_lost(10);
499508

500-
TestPerfDataHandler handler(std::vector<BranchStackEntry>{},
509+
TestPerfDataHandler handler({},
501510
std::unordered_map<std::string, std::string>{});
502511
PerfDataHandler::Process(proto, &handler);
503512

@@ -557,7 +566,15 @@ TEST(PerfDataHandlerTest, SpeAuxtraceIntoSamples) {
557566
});
558567
auxtrace_event->set_trace_data(trace_data);
559568

560-
TestPerfDataHandler handler(std::vector<BranchStackEntry>{},
569+
// There record 1 sample is a branch sample, so expecting one branch stack
570+
// entry.
571+
std::vector<BranchStackEntry> expected_br_entries;
572+
BranchStackEntry br;
573+
br.set_from_ip(0xffffba66edefb0e0);
574+
br.set_to_ip(0xffffba66edefb0e4);
575+
expected_br_entries.push_back(br);
576+
577+
TestPerfDataHandler handler({{}, expected_br_entries},
561578
std::unordered_map<std::string, std::string>{});
562579
PerfDataHandler::Process(proto, &handler);
563580

@@ -595,8 +612,7 @@ TEST(PerfDataHandlerTest, KsymbolIntoMappings) {
595612

596613
std::unordered_map<std::string, std::string> expected_filename_to_build_id;
597614
expected_filename_to_build_id[mock_filename] = "";
598-
TestPerfDataHandler handler(std::vector<BranchStackEntry>{},
599-
expected_filename_to_build_id);
615+
TestPerfDataHandler handler({}, expected_filename_to_build_id);
600616
PerfDataHandler::Process(proto, &handler);
601617
handler.CheckSeenFilenames();
602618
}

0 commit comments

Comments
 (0)