summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2023-05-04 17:33:00 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-05-04 17:33:00 +0000
commit7df8fc592b0559b19d58b13f99426304dde5266f (patch)
tree42649c4032cd0a3c785a6a947231981bcde24084
parente6277023bfceef1cfe824f030ada169d6b486acf (diff)
parentadbb6341047d414fe1f7c373f7d4a246de13471b (diff)
downloadextras-7df8fc592b0559b19d58b13f99426304dde5266f.tar.gz
simpleperf: Store etm branch list in the recording file am: adbb634104
Original change: https://googleplex-android-review.googlesource.com/c/platform/system/extras/+/23008007 Change-Id: I83fd23aff033ab5948fd2d92376ba90edb48d675 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--simpleperf/cmd_dumprecord.cpp30
-rw-r--r--simpleperf/cmd_inject.cpp29
-rw-r--r--simpleperf/cmd_record.cpp17
-rw-r--r--simpleperf/record_file_format.h4
-rw-r--r--simpleperf/record_file_reader.cpp1
5 files changed, 81 insertions, 0 deletions
diff --git a/simpleperf/cmd_dumprecord.cpp b/simpleperf/cmd_dumprecord.cpp
index 4738eef6..0b8df15a 100644
--- a/simpleperf/cmd_dumprecord.cpp
+++ b/simpleperf/cmd_dumprecord.cpp
@@ -26,6 +26,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include "ETMBranchListFile.h"
#include "ETMDecoder.h"
#include "command.h"
#include "dso.h"
@@ -540,6 +541,35 @@ bool DumpRecordCommand::DumpFeatureSection() {
PrintIndented(2, "size: %" PRIu64 "\n", file.size);
}
}
+ } else if (feature == FEAT_ETM_BRANCH_LIST) {
+ std::string data;
+ if (!record_file_reader_->ReadFeatureSection(FEAT_ETM_BRANCH_LIST, &data)) {
+ return false;
+ }
+ BranchListBinaryMap binary_map;
+ if (!StringToBranchListBinaryMap(data, binary_map)) {
+ return false;
+ }
+ PrintIndented(1, "etm_branch_list:\n");
+ for (const auto& [key, binary] : binary_map) {
+ PrintIndented(2, "path: %s\n", key.path.c_str());
+ PrintIndented(2, "build_id: %s\n", key.build_id.ToString().c_str());
+ PrintIndented(2, "binary_type: %s\n", DsoTypeToString(binary.dso_type));
+ if (binary.dso_type == DSO_KERNEL) {
+ PrintIndented(2, "kernel_start_addr: 0x%" PRIx64 "\n", key.kernel_start_addr);
+ }
+ for (const auto& [addr, branches] : binary.GetOrderedBranchMap()) {
+ PrintIndented(3, "addr: 0x%" PRIx64 "\n", addr);
+ for (const auto& [branch, count] : branches) {
+ std::string s = "0b";
+ for (auto it = branch.rbegin(); it != branch.rend(); ++it) {
+ s.push_back(*it ? '1' : '0');
+ }
+ PrintIndented(3, "branch: %s\n", s.c_str());
+ PrintIndented(3, "count: %" PRIu64 "\n", count);
+ }
+ }
+ }
}
}
return true;
diff --git a/simpleperf/cmd_inject.cpp b/simpleperf/cmd_inject.cpp
index f83805ac..d3f66cd7 100644
--- a/simpleperf/cmd_inject.cpp
+++ b/simpleperf/cmd_inject.cpp
@@ -164,6 +164,9 @@ class PerfDataReader {
if (!record_file_reader_) {
return false;
}
+ if (record_file_reader_->HasFeature(PerfFileFormat::FEAT_ETM_BRANCH_LIST)) {
+ return ProcessETMBranchListFeature();
+ }
if (exclude_perf_) {
const auto& info_map = record_file_reader_->GetMetaInfoFeature();
if (auto it = info_map.find("recording_process"); it == info_map.end()) {
@@ -196,6 +199,32 @@ class PerfDataReader {
}
private:
+ bool ProcessETMBranchListFeature() {
+ if (exclude_perf_) {
+ LOG(WARNING) << "--exclude-perf has no effect on perf.data with etm branch list";
+ }
+ if (autofdo_callback_) {
+ LOG(ERROR) << "convert to autofdo format isn't support on perf.data with etm branch list";
+ return false;
+ }
+ CHECK(branch_list_callback_);
+ std::string s;
+ if (!record_file_reader_->ReadFeatureSection(PerfFileFormat::FEAT_ETM_BRANCH_LIST, &s)) {
+ return false;
+ }
+ BranchListBinaryMap binary_map;
+ if (!StringToBranchListBinaryMap(s, binary_map)) {
+ return false;
+ }
+ for (auto& [key, binary] : binary_map) {
+ if (!binary_filter_.Filter(key.path)) {
+ continue;
+ }
+ branch_list_callback_(key, binary);
+ }
+ return true;
+ }
+
bool ProcessRecord(Record* r) {
thread_tree_.GetThreadTree().Update(*r);
if (r->type() == PERF_RECORD_AUXTRACE_INFO) {
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 4ef2b7ff..21b5e50d 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -409,6 +409,7 @@ RECORD_FILTER_OPTION_HELP_MSG_FOR_RECORDING
bool DumpMetaInfoFeature(bool kernel_symbols_available);
bool DumpDebugUnwindFeature(const std::unordered_set<Dso*>& dso_set);
void CollectHitFileInfo(const SampleRecord& r, std::unordered_set<Dso*>* dso_set);
+ bool DumpETMBranchListFeature();
std::unique_ptr<SampleSpeed> sample_speed_;
bool system_wide_collection_;
@@ -1996,6 +1997,9 @@ bool RecordCommand::DumpAdditionalFeatures(const std::vector<std::string>& args)
if (keep_failed_unwinding_debug_info_) {
feature_count += 2;
}
+ if (etm_branch_list_generator_) {
+ feature_count++;
+ }
if (!record_file_writer_->BeginWriteFeatures(feature_count)) {
return false;
}
@@ -2038,6 +2042,9 @@ bool RecordCommand::DumpAdditionalFeatures(const std::vector<std::string>& args)
if (keep_failed_unwinding_debug_info_ && !DumpDebugUnwindFeature(debug_unwinding_files)) {
return false;
}
+ if (etm_branch_list_generator_ && !DumpETMBranchListFeature()) {
+ return false;
+ }
if (!record_file_writer_->EndWriteFeatures()) {
return false;
@@ -2177,6 +2184,16 @@ void RecordCommand::CollectHitFileInfo(const SampleRecord& r, std::unordered_set
}
}
+bool RecordCommand::DumpETMBranchListFeature() {
+ BranchListBinaryMap binary_map = etm_branch_list_generator_->GetBranchListBinaryMap();
+ std::string s;
+ if (!BranchListBinaryMapToString(binary_map, s)) {
+ return false;
+ }
+ return record_file_writer_->WriteFeature(PerfFileFormat::FEAT_ETM_BRANCH_LIST, s.data(),
+ s.size());
+}
+
} // namespace
static bool ConsumeStr(const char*& p, const char* s) {
diff --git a/simpleperf/record_file_format.h b/simpleperf/record_file_format.h
index 53c6719b..0b36f351 100644
--- a/simpleperf/record_file_format.h
+++ b/simpleperf/record_file_format.h
@@ -82,6 +82,9 @@ file2 feature section (used to replace file feature section):
uint32_t file_msg2_size;
FileFeature file_msg2;
...
+
+etm_branch_list feature section:
+ ETMBranchList etm_branch_list; // from etm_branch_list.proto
*/
namespace simpleperf {
@@ -116,6 +119,7 @@ enum {
FEAT_DEBUG_UNWIND,
FEAT_DEBUG_UNWIND_FILE,
FEAT_FILE2,
+ FEAT_ETM_BRANCH_LIST,
FEAT_MAX_NUM = 256,
};
diff --git a/simpleperf/record_file_reader.cpp b/simpleperf/record_file_reader.cpp
index 8f54e65d..1b1bab7e 100644
--- a/simpleperf/record_file_reader.cpp
+++ b/simpleperf/record_file_reader.cpp
@@ -60,6 +60,7 @@ static const std::map<int, std::string> feature_name_map = {
{FEAT_DEBUG_UNWIND, "debug_unwind"},
{FEAT_DEBUG_UNWIND_FILE, "debug_unwind_file"},
{FEAT_FILE2, "file2"},
+ {FEAT_ETM_BRANCH_LIST, "etm_branch_list"},
};
std::string GetFeatureName(int feature_id) {