blob: 73088dab090199088c4d9b3dc6e473a48564d53d [file] [log] [blame]
Christopher Ferrisa9e19092020-04-14 11:59:15 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <err.h>
18#include <inttypes.h>
19#include <malloc.h>
20#include <stdint.h>
21
22#include <string>
23#include <vector>
24
Christopher Ferrisa9e19092020-04-14 11:59:15 -070025#include <benchmark/benchmark.h>
26
27#include <unwindstack/Elf.h>
28#include <unwindstack/Memory.h>
29
David Srbeckya17c2b62020-04-14 16:59:27 +010030#include "Utils.h"
Christopher Ferrisa9e19092020-04-14 11:59:15 -070031
32static void BenchmarkSymbolLookup(benchmark::State& state, std::vector<uint64_t> offsets,
33 std::string elf_file, bool expect_found) {
34#if defined(__BIONIC__)
35 uint64_t rss_bytes = 0;
36#endif
37 uint64_t alloc_bytes = 0;
38 for (auto _ : state) {
39 state.PauseTiming();
40 unwindstack::Elf elf(unwindstack::Memory::CreateFileMemory(elf_file, 0).release());
41 if (!elf.Init() || !elf.valid()) {
42 errx(1, "Internal Error: Cannot open elf.");
43 }
44
45#if defined(__BIONIC__)
46 mallopt(M_PURGE, 0);
47 uint64_t rss_bytes_before = 0;
David Srbeckya17c2b62020-04-14 16:59:27 +010048 GatherRss(&rss_bytes_before);
Christopher Ferrisa9e19092020-04-14 11:59:15 -070049#endif
50 uint64_t alloc_bytes_before = mallinfo().uordblks;
51 state.ResumeTiming();
52
53 for (auto pc : offsets) {
54 std::string name;
55 uint64_t offset;
56 bool found = elf.GetFunctionName(pc, &name, &offset);
57 if (expect_found && !found) {
58 errx(1, "expected pc 0x%" PRIx64 " present, but not found.", pc);
59 } else if (!expect_found && found) {
60 errx(1, "expected pc 0x%" PRIx64 " not present, but found.", pc);
61 }
62 }
63
64 state.PauseTiming();
65#if defined(__BIONIC__)
66 mallopt(M_PURGE, 0);
67#endif
68 alloc_bytes += mallinfo().uordblks - alloc_bytes_before;
69#if defined(__BIONIC__)
David Srbeckya17c2b62020-04-14 16:59:27 +010070 GatherRss(&rss_bytes);
Christopher Ferrisa9e19092020-04-14 11:59:15 -070071 rss_bytes -= rss_bytes_before;
72#endif
73 state.ResumeTiming();
74 }
75
76#if defined(__BIONIC__)
77 state.counters["RSS_BYTES"] = rss_bytes / static_cast<double>(state.iterations());
78#endif
79 state.counters["ALLOCATED_BYTES"] = alloc_bytes / static_cast<double>(state.iterations());
80}
81
82static void BenchmarkSymbolLookup(benchmark::State& state, uint64_t pc, std::string elf_file,
83 bool expect_found) {
84 BenchmarkSymbolLookup(state, std::vector<uint64_t>{pc}, elf_file, expect_found);
85}
86
Christopher Ferrisa9e19092020-04-14 11:59:15 -070087void BM_symbol_not_present(benchmark::State& state) {
88 BenchmarkSymbolLookup(state, 0, GetElfFile(), false);
89}
90BENCHMARK(BM_symbol_not_present);
91
92void BM_symbol_find_single(benchmark::State& state) {
93 BenchmarkSymbolLookup(state, 0x22b2bc, GetElfFile(), true);
94}
95BENCHMARK(BM_symbol_find_single);
96
97void BM_symbol_find_single_many_times(benchmark::State& state) {
98 BenchmarkSymbolLookup(state, std::vector<uint64_t>(15, 0x22b2bc), GetElfFile(), true);
99}
100BENCHMARK(BM_symbol_find_single_many_times);
101
102void BM_symbol_find_multiple(benchmark::State& state) {
103 BenchmarkSymbolLookup(state,
104 std::vector<uint64_t>{0x22b2bc, 0xd5d30, 0x1312e8, 0x13582e, 0x1389c8},
105 GetElfFile(), true);
106}
107BENCHMARK(BM_symbol_find_multiple);
108
109void BM_symbol_not_present_from_sorted(benchmark::State& state) {
David Srbeckya17c2b62020-04-14 16:59:27 +0100110 BenchmarkSymbolLookup(state, 0, GetSymbolSortedElfFile(), false);
Christopher Ferrisa9e19092020-04-14 11:59:15 -0700111}
112BENCHMARK(BM_symbol_not_present_from_sorted);
113
114void BM_symbol_find_single_from_sorted(benchmark::State& state) {
David Srbeckya17c2b62020-04-14 16:59:27 +0100115 BenchmarkSymbolLookup(state, 0x138638, GetSymbolSortedElfFile(), true);
Christopher Ferrisa9e19092020-04-14 11:59:15 -0700116}
117BENCHMARK(BM_symbol_find_single_from_sorted);
118
119void BM_symbol_find_single_many_times_from_sorted(benchmark::State& state) {
David Srbeckya17c2b62020-04-14 16:59:27 +0100120 BenchmarkSymbolLookup(state, std::vector<uint64_t>(15, 0x138638), GetSymbolSortedElfFile(), true);
Christopher Ferrisa9e19092020-04-14 11:59:15 -0700121}
122BENCHMARK(BM_symbol_find_single_many_times_from_sorted);
123
124void BM_symbol_find_multiple_from_sorted(benchmark::State& state) {
125 BenchmarkSymbolLookup(state,
126 std::vector<uint64_t>{0x138638, 0x84350, 0x14df18, 0x1f3a38, 0x1f3ca8},
David Srbeckya17c2b62020-04-14 16:59:27 +0100127 GetSymbolSortedElfFile(), true);
Christopher Ferrisa9e19092020-04-14 11:59:15 -0700128}
129BENCHMARK(BM_symbol_find_multiple_from_sorted);