xref: /aosp_15_r20/system/unwinding/libunwindstack/benchmarks/ElfBenchmark.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*eb293b8fSAndroid Build Coastguard Worker  *
4*eb293b8fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*eb293b8fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*eb293b8fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*eb293b8fSAndroid Build Coastguard Worker  *
8*eb293b8fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*eb293b8fSAndroid Build Coastguard Worker  *
10*eb293b8fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*eb293b8fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*eb293b8fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*eb293b8fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*eb293b8fSAndroid Build Coastguard Worker  * limitations under the License.
15*eb293b8fSAndroid Build Coastguard Worker  */
16*eb293b8fSAndroid Build Coastguard Worker 
17*eb293b8fSAndroid Build Coastguard Worker #include <err.h>
18*eb293b8fSAndroid Build Coastguard Worker #include <malloc.h>
19*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h>
20*eb293b8fSAndroid Build Coastguard Worker 
21*eb293b8fSAndroid Build Coastguard Worker #include <string>
22*eb293b8fSAndroid Build Coastguard Worker 
23*eb293b8fSAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
24*eb293b8fSAndroid Build Coastguard Worker 
25*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Elf.h>
26*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Maps.h>
27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Regs.h>
29*eb293b8fSAndroid Build Coastguard Worker 
30*eb293b8fSAndroid Build Coastguard Worker #include "Utils.h"
31*eb293b8fSAndroid Build Coastguard Worker 
32*eb293b8fSAndroid Build Coastguard Worker class ElfCreateBenchmark : public benchmark::Fixture {
33*eb293b8fSAndroid Build Coastguard Worker  public:
RunBenchmark(benchmark::State & state,const std::string & elf_file)34*eb293b8fSAndroid Build Coastguard Worker   void RunBenchmark(benchmark::State& state, const std::string& elf_file) {
35*eb293b8fSAndroid Build Coastguard Worker     MemoryTracker mem_tracker;
36*eb293b8fSAndroid Build Coastguard Worker     for (const auto& _ : state) {
37*eb293b8fSAndroid Build Coastguard Worker       state.PauseTiming();
38*eb293b8fSAndroid Build Coastguard Worker       mem_tracker.StartTrackingAllocations();
39*eb293b8fSAndroid Build Coastguard Worker 
40*eb293b8fSAndroid Build Coastguard Worker       auto file_memory = unwindstack::Memory::CreateFileMemory(elf_file, 0);
41*eb293b8fSAndroid Build Coastguard Worker       state.ResumeTiming();
42*eb293b8fSAndroid Build Coastguard Worker 
43*eb293b8fSAndroid Build Coastguard Worker       unwindstack::Elf elf(file_memory);
44*eb293b8fSAndroid Build Coastguard Worker       if (!elf.Init() || !elf.valid()) {
45*eb293b8fSAndroid Build Coastguard Worker         errx(1, "Internal Error: Cannot open elf: %s", elf_file.c_str());
46*eb293b8fSAndroid Build Coastguard Worker       }
47*eb293b8fSAndroid Build Coastguard Worker 
48*eb293b8fSAndroid Build Coastguard Worker       state.PauseTiming();
49*eb293b8fSAndroid Build Coastguard Worker       mem_tracker.StopTrackingAllocations();
50*eb293b8fSAndroid Build Coastguard Worker       state.ResumeTiming();
51*eb293b8fSAndroid Build Coastguard Worker     }
52*eb293b8fSAndroid Build Coastguard Worker     mem_tracker.SetBenchmarkCounters(state);
53*eb293b8fSAndroid Build Coastguard Worker   }
54*eb293b8fSAndroid Build Coastguard Worker };
55*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(ElfCreateBenchmark,BM_elf_create)56*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(ElfCreateBenchmark, BM_elf_create)(benchmark::State& state) {
57*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, GetElfFile());
58*eb293b8fSAndroid Build Coastguard Worker }
59*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(ElfCreateBenchmark,BM_elf_create_large_compressed)60*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(ElfCreateBenchmark, BM_elf_create_large_compressed)(benchmark::State& state) {
61*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, GetLargeCompressedFrameElfFile());
62*eb293b8fSAndroid Build Coastguard Worker }
63*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(ElfCreateBenchmark,BM_elf_create_large_eh_frame)64*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(ElfCreateBenchmark, BM_elf_create_large_eh_frame)(benchmark::State& state) {
65*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, GetLargeEhFrameElfFile());
66*eb293b8fSAndroid Build Coastguard Worker }
67*eb293b8fSAndroid Build Coastguard Worker 
InitializeBuildId(benchmark::State & state,unwindstack::Maps & maps,unwindstack::MapInfo ** build_id_map_info)68*eb293b8fSAndroid Build Coastguard Worker static void InitializeBuildId(benchmark::State& state, unwindstack::Maps& maps,
69*eb293b8fSAndroid Build Coastguard Worker                               unwindstack::MapInfo** build_id_map_info) {
70*eb293b8fSAndroid Build Coastguard Worker   if (!maps.Parse()) {
71*eb293b8fSAndroid Build Coastguard Worker     state.SkipWithError("Failed to parse local maps.");
72*eb293b8fSAndroid Build Coastguard Worker     return;
73*eb293b8fSAndroid Build Coastguard Worker   }
74*eb293b8fSAndroid Build Coastguard Worker 
75*eb293b8fSAndroid Build Coastguard Worker   // Find the libc.so share library and use that for benchmark purposes.
76*eb293b8fSAndroid Build Coastguard Worker   *build_id_map_info = nullptr;
77*eb293b8fSAndroid Build Coastguard Worker   for (auto& map_info : maps) {
78*eb293b8fSAndroid Build Coastguard Worker     if (map_info->offset() == 0 && map_info->GetBuildID() != "") {
79*eb293b8fSAndroid Build Coastguard Worker       *build_id_map_info = map_info.get();
80*eb293b8fSAndroid Build Coastguard Worker       break;
81*eb293b8fSAndroid Build Coastguard Worker     }
82*eb293b8fSAndroid Build Coastguard Worker   }
83*eb293b8fSAndroid Build Coastguard Worker 
84*eb293b8fSAndroid Build Coastguard Worker   if (*build_id_map_info == nullptr) {
85*eb293b8fSAndroid Build Coastguard Worker     state.SkipWithError("Failed to find a map with a BuildID.");
86*eb293b8fSAndroid Build Coastguard Worker   }
87*eb293b8fSAndroid Build Coastguard Worker }
88*eb293b8fSAndroid Build Coastguard Worker 
BM_elf_get_build_id_from_object(benchmark::State & state)89*eb293b8fSAndroid Build Coastguard Worker static void BM_elf_get_build_id_from_object(benchmark::State& state) {
90*eb293b8fSAndroid Build Coastguard Worker   unwindstack::LocalMaps maps;
91*eb293b8fSAndroid Build Coastguard Worker   unwindstack::MapInfo* build_id_map_info;
92*eb293b8fSAndroid Build Coastguard Worker   InitializeBuildId(state, maps, &build_id_map_info);
93*eb293b8fSAndroid Build Coastguard Worker 
94*eb293b8fSAndroid Build Coastguard Worker   unwindstack::Elf* elf = build_id_map_info->GetElf(std::shared_ptr<unwindstack::Memory>(),
95*eb293b8fSAndroid Build Coastguard Worker                                                     unwindstack::Regs::CurrentArch());
96*eb293b8fSAndroid Build Coastguard Worker   if (!elf->valid()) {
97*eb293b8fSAndroid Build Coastguard Worker     state.SkipWithError("Cannot get valid elf from map.");
98*eb293b8fSAndroid Build Coastguard Worker   }
99*eb293b8fSAndroid Build Coastguard Worker 
100*eb293b8fSAndroid Build Coastguard Worker   for (const auto& _ : state) {
101*eb293b8fSAndroid Build Coastguard Worker     state.PauseTiming();
102*eb293b8fSAndroid Build Coastguard Worker     unwindstack::SharedString* id = build_id_map_info->build_id();
103*eb293b8fSAndroid Build Coastguard Worker     if (id != nullptr) {
104*eb293b8fSAndroid Build Coastguard Worker       delete id;
105*eb293b8fSAndroid Build Coastguard Worker       build_id_map_info->set_build_id(nullptr);
106*eb293b8fSAndroid Build Coastguard Worker     }
107*eb293b8fSAndroid Build Coastguard Worker     state.ResumeTiming();
108*eb293b8fSAndroid Build Coastguard Worker     benchmark::DoNotOptimize(build_id_map_info->GetBuildID());
109*eb293b8fSAndroid Build Coastguard Worker   }
110*eb293b8fSAndroid Build Coastguard Worker }
111*eb293b8fSAndroid Build Coastguard Worker BENCHMARK(BM_elf_get_build_id_from_object);
112*eb293b8fSAndroid Build Coastguard Worker 
BM_elf_get_build_id_from_file(benchmark::State & state)113*eb293b8fSAndroid Build Coastguard Worker static void BM_elf_get_build_id_from_file(benchmark::State& state) {
114*eb293b8fSAndroid Build Coastguard Worker   unwindstack::LocalMaps maps;
115*eb293b8fSAndroid Build Coastguard Worker   unwindstack::MapInfo* build_id_map_info;
116*eb293b8fSAndroid Build Coastguard Worker   InitializeBuildId(state, maps, &build_id_map_info);
117*eb293b8fSAndroid Build Coastguard Worker 
118*eb293b8fSAndroid Build Coastguard Worker   for (const auto& _ : state) {
119*eb293b8fSAndroid Build Coastguard Worker     state.PauseTiming();
120*eb293b8fSAndroid Build Coastguard Worker     unwindstack::SharedString* id = build_id_map_info->build_id();
121*eb293b8fSAndroid Build Coastguard Worker     if (id != nullptr) {
122*eb293b8fSAndroid Build Coastguard Worker       delete id;
123*eb293b8fSAndroid Build Coastguard Worker       build_id_map_info->set_build_id(nullptr);
124*eb293b8fSAndroid Build Coastguard Worker     }
125*eb293b8fSAndroid Build Coastguard Worker     state.ResumeTiming();
126*eb293b8fSAndroid Build Coastguard Worker     benchmark::DoNotOptimize(build_id_map_info->GetBuildID());
127*eb293b8fSAndroid Build Coastguard Worker   }
128*eb293b8fSAndroid Build Coastguard Worker }
129*eb293b8fSAndroid Build Coastguard Worker BENCHMARK(BM_elf_get_build_id_from_file);
130