xref: /aosp_15_r20/system/unwinding/libunwindstack/benchmarks/SymbolBenchmark.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 <inttypes.h>
19*eb293b8fSAndroid Build Coastguard Worker #include <malloc.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h>
21*eb293b8fSAndroid Build Coastguard Worker 
22*eb293b8fSAndroid Build Coastguard Worker #include <string>
23*eb293b8fSAndroid Build Coastguard Worker #include <vector>
24*eb293b8fSAndroid Build Coastguard Worker 
25*eb293b8fSAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
26*eb293b8fSAndroid Build Coastguard Worker 
27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Elf.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.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 SymbolLookupBenchmark : public benchmark::Fixture {
33*eb293b8fSAndroid Build Coastguard Worker  public:
RunBenchmark(benchmark::State & state,const std::vector<uint64_t> & offsets,const std::string & elf_file,bool expect_found,uint32_t runs=1)34*eb293b8fSAndroid Build Coastguard Worker   void RunBenchmark(benchmark::State& state, const std::vector<uint64_t>& offsets,
35*eb293b8fSAndroid Build Coastguard Worker                     const std::string& elf_file, bool expect_found, uint32_t runs = 1) {
36*eb293b8fSAndroid Build Coastguard Worker     MemoryTracker mem_tracker;
37*eb293b8fSAndroid Build Coastguard Worker     for (const auto& _ : state) {
38*eb293b8fSAndroid Build Coastguard Worker       state.PauseTiming();
39*eb293b8fSAndroid Build Coastguard Worker       mem_tracker.StartTrackingAllocations();
40*eb293b8fSAndroid Build Coastguard Worker       state.ResumeTiming();
41*eb293b8fSAndroid Build Coastguard Worker 
42*eb293b8fSAndroid Build Coastguard Worker       auto elf_memory = unwindstack::Memory::CreateFileMemory(elf_file, 0);
43*eb293b8fSAndroid Build Coastguard Worker       unwindstack::Elf elf(elf_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       unwindstack::SharedString name;
49*eb293b8fSAndroid Build Coastguard Worker       uint64_t offset;
50*eb293b8fSAndroid Build Coastguard Worker       for (size_t i = 0; i < runs; i++) {
51*eb293b8fSAndroid Build Coastguard Worker         for (auto pc : offsets) {
52*eb293b8fSAndroid Build Coastguard Worker           bool found = elf.GetFunctionName(pc, &name, &offset);
53*eb293b8fSAndroid Build Coastguard Worker           if (expect_found && !found) {
54*eb293b8fSAndroid Build Coastguard Worker             errx(1, "expected pc 0x%" PRIx64 " present, but not found.", pc);
55*eb293b8fSAndroid Build Coastguard Worker           } else if (!expect_found && found) {
56*eb293b8fSAndroid Build Coastguard Worker             errx(1, "expected pc 0x%" PRIx64 " not present, but found.", pc);
57*eb293b8fSAndroid Build Coastguard Worker           }
58*eb293b8fSAndroid Build Coastguard Worker         }
59*eb293b8fSAndroid Build Coastguard Worker       }
60*eb293b8fSAndroid Build Coastguard Worker 
61*eb293b8fSAndroid Build Coastguard Worker       state.PauseTiming();
62*eb293b8fSAndroid Build Coastguard Worker       mem_tracker.StopTrackingAllocations();
63*eb293b8fSAndroid Build Coastguard Worker       state.ResumeTiming();
64*eb293b8fSAndroid Build Coastguard Worker     }
65*eb293b8fSAndroid Build Coastguard Worker     mem_tracker.SetBenchmarkCounters(state);
66*eb293b8fSAndroid Build Coastguard Worker   }
67*eb293b8fSAndroid Build Coastguard Worker 
RunBenchmark(benchmark::State & state,uint64_t pc,const std::string & elf_file,bool expect_found,uint32_t runs=1)68*eb293b8fSAndroid Build Coastguard Worker   void RunBenchmark(benchmark::State& state, uint64_t pc, const std::string& elf_file,
69*eb293b8fSAndroid Build Coastguard Worker                     bool expect_found, uint32_t runs = 1) {
70*eb293b8fSAndroid Build Coastguard Worker     RunBenchmark(state, std::vector<uint64_t>{pc}, elf_file, expect_found, runs);
71*eb293b8fSAndroid Build Coastguard Worker   }
72*eb293b8fSAndroid Build Coastguard Worker };
73*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_not_present)74*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_not_present)(benchmark::State& state) {
75*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0, GetElfFile(), false);
76*eb293b8fSAndroid Build Coastguard Worker }
77*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_single)78*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_single)(benchmark::State& state) {
79*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0x22b2bc, GetElfFile(), true);
80*eb293b8fSAndroid Build Coastguard Worker }
81*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_single_many_times)82*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_single_many_times)
83*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
84*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0x22b2bc, GetElfFile(), true, 4096);
85*eb293b8fSAndroid Build Coastguard Worker }
86*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_multiple)87*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_multiple)(benchmark::State& state) {
88*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, std::vector<uint64_t>{0x22b2bc, 0xd5d30, 0x1312e8, 0x13582e, 0x1389c8},
89*eb293b8fSAndroid Build Coastguard Worker                GetElfFile(), true);
90*eb293b8fSAndroid Build Coastguard Worker }
91*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_not_present_from_sorted)92*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_not_present_from_sorted)
93*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
94*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0, GetSymbolSortedElfFile(), false);
95*eb293b8fSAndroid Build Coastguard Worker }
96*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_single_from_sorted)97*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_single_from_sorted)
98*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
99*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0x138638, GetSymbolSortedElfFile(), true);
100*eb293b8fSAndroid Build Coastguard Worker }
101*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_single_many_times_from_sorted)102*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_single_many_times_from_sorted)
103*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
104*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0x138638, GetSymbolSortedElfFile(), true, 4096);
105*eb293b8fSAndroid Build Coastguard Worker }
106*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_multiple_from_sorted)107*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_multiple_from_sorted)
108*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
109*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, std::vector<uint64_t>{0x138638, 0x84350, 0x14df18, 0x1f3a38, 0x1f3ca8},
110*eb293b8fSAndroid Build Coastguard Worker                GetSymbolSortedElfFile(), true);
111*eb293b8fSAndroid Build Coastguard Worker }
112*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_not_present_from_large_compressed_frame)113*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_not_present_from_large_compressed_frame)
114*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
115*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0, GetLargeCompressedFrameElfFile(), false);
116*eb293b8fSAndroid Build Coastguard Worker }
117*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_single_from_large_compressed_frame)118*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_single_from_large_compressed_frame)
119*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
120*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0x202aec, GetLargeCompressedFrameElfFile(), true);
121*eb293b8fSAndroid Build Coastguard Worker }
122*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_single_many_times_from_large_compressed_frame)123*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark,
124*eb293b8fSAndroid Build Coastguard Worker             BM_symbol_lookup_find_single_many_times_from_large_compressed_frame)
125*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
126*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, 0x202aec, GetLargeCompressedFrameElfFile(), true, 4096);
127*eb293b8fSAndroid Build Coastguard Worker }
128*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_F(SymbolLookupBenchmark,BM_symbol_lookup_find_multiple_from_large_compressed_frame)129*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_F(SymbolLookupBenchmark, BM_symbol_lookup_find_multiple_from_large_compressed_frame)
130*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
131*eb293b8fSAndroid Build Coastguard Worker   RunBenchmark(state, std::vector<uint64_t>{0x202aec, 0x23e74c, 0xd000c, 0x201b10, 0x183060},
132*eb293b8fSAndroid Build Coastguard Worker                GetLargeCompressedFrameElfFile(), true);
133*eb293b8fSAndroid Build Coastguard Worker }
134