xref: /aosp_15_r20/system/unwinding/libunwindstack/benchmarks/OfflineUnwindBenchmarks.cpp (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
1*eb293b8fSAndroid Build Coastguard Worker /*
2*eb293b8fSAndroid Build Coastguard Worker  * Copyright (C) 2021 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 <cstddef>
18*eb293b8fSAndroid Build Coastguard Worker #include <cstdint>
19*eb293b8fSAndroid Build Coastguard Worker #include <filesystem>
20*eb293b8fSAndroid Build Coastguard Worker #include <memory>
21*eb293b8fSAndroid Build Coastguard Worker #include <sstream>
22*eb293b8fSAndroid Build Coastguard Worker #include <unordered_map>
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/Arch.h>
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Unwinder.h>
29*eb293b8fSAndroid Build Coastguard Worker 
30*eb293b8fSAndroid Build Coastguard Worker #include "Utils.h"
31*eb293b8fSAndroid Build Coastguard Worker #include "utils/OfflineUnwindUtils.h"
32*eb293b8fSAndroid Build Coastguard Worker 
33*eb293b8fSAndroid Build Coastguard Worker // This collection of benchmarks exercises Unwinder::Unwind for offline unwinds.
34*eb293b8fSAndroid Build Coastguard Worker //
35*eb293b8fSAndroid Build Coastguard Worker // See `libunwindstack/utils/OfflineUnwindUtils.h` for more info on offline unwinds
36*eb293b8fSAndroid Build Coastguard Worker // and b/192012600 for additional information regarding these benchmarks.
37*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
38*eb293b8fSAndroid Build Coastguard Worker namespace {
39*eb293b8fSAndroid Build Coastguard Worker 
40*eb293b8fSAndroid Build Coastguard Worker static constexpr char kStartup[] = "startup_case";
41*eb293b8fSAndroid Build Coastguard Worker static constexpr char kSteadyState[] = "steady_state_case";
42*eb293b8fSAndroid Build Coastguard Worker 
43*eb293b8fSAndroid Build Coastguard Worker class OfflineUnwindBenchmark : public benchmark::Fixture {
44*eb293b8fSAndroid Build Coastguard Worker  public:
SetUp(benchmark::State & state)45*eb293b8fSAndroid Build Coastguard Worker   void SetUp(benchmark::State& state) override {
46*eb293b8fSAndroid Build Coastguard Worker     // Ensure each benchmarks has a fresh ELF cache at the start.
47*eb293b8fSAndroid Build Coastguard Worker     unwind_case_ = state.range(0) ? kSteadyState : kStartup;
48*eb293b8fSAndroid Build Coastguard Worker     resolve_names_ = state.range(1);
49*eb293b8fSAndroid Build Coastguard Worker     Elf::SetCachingEnabled(false);
50*eb293b8fSAndroid Build Coastguard Worker   }
51*eb293b8fSAndroid Build Coastguard Worker 
TearDown(const benchmark::State &)52*eb293b8fSAndroid Build Coastguard Worker   void TearDown(const benchmark::State&) override {
53*eb293b8fSAndroid Build Coastguard Worker     offline_utils_.ReturnToCurrentWorkingDirectory();
54*eb293b8fSAndroid Build Coastguard Worker   }
55*eb293b8fSAndroid Build Coastguard Worker 
SingleUnwindBenchmark(benchmark::State & state,const UnwindSampleInfo & sample_info)56*eb293b8fSAndroid Build Coastguard Worker   void SingleUnwindBenchmark(benchmark::State& state, const UnwindSampleInfo& sample_info) {
57*eb293b8fSAndroid Build Coastguard Worker     std::string error_msg;
58*eb293b8fSAndroid Build Coastguard Worker     if (!offline_utils_.Init(sample_info, &error_msg)) {
59*eb293b8fSAndroid Build Coastguard Worker       state.SkipWithError(error_msg.c_str());
60*eb293b8fSAndroid Build Coastguard Worker       return;
61*eb293b8fSAndroid Build Coastguard Worker     }
62*eb293b8fSAndroid Build Coastguard Worker     BenchmarkOfflineUnwindMultipleSamples(state, std::vector<UnwindSampleInfo>{sample_info});
63*eb293b8fSAndroid Build Coastguard Worker   }
64*eb293b8fSAndroid Build Coastguard Worker 
ConsecutiveUnwindBenchmark(benchmark::State & state,const std::vector<UnwindSampleInfo> & sample_infos)65*eb293b8fSAndroid Build Coastguard Worker   void ConsecutiveUnwindBenchmark(benchmark::State& state,
66*eb293b8fSAndroid Build Coastguard Worker                                   const std::vector<UnwindSampleInfo>& sample_infos) {
67*eb293b8fSAndroid Build Coastguard Worker     std::string error_msg;
68*eb293b8fSAndroid Build Coastguard Worker     if (!offline_utils_.Init(sample_infos, &error_msg)) {
69*eb293b8fSAndroid Build Coastguard Worker       state.SkipWithError(error_msg.c_str());
70*eb293b8fSAndroid Build Coastguard Worker       return;
71*eb293b8fSAndroid Build Coastguard Worker     }
72*eb293b8fSAndroid Build Coastguard Worker     BenchmarkOfflineUnwindMultipleSamples(state, sample_infos);
73*eb293b8fSAndroid Build Coastguard Worker   }
74*eb293b8fSAndroid Build Coastguard Worker 
75*eb293b8fSAndroid Build Coastguard Worker  private:
BenchmarkOfflineUnwindMultipleSamples(benchmark::State & state,const std::vector<UnwindSampleInfo> & sample_infos)76*eb293b8fSAndroid Build Coastguard Worker   void BenchmarkOfflineUnwindMultipleSamples(benchmark::State& state,
77*eb293b8fSAndroid Build Coastguard Worker                                              const std::vector<UnwindSampleInfo>& sample_infos) {
78*eb293b8fSAndroid Build Coastguard Worker     std::string error_msg;
79*eb293b8fSAndroid Build Coastguard Worker     MemoryTracker mem_tracker;
80*eb293b8fSAndroid Build Coastguard Worker     auto offline_unwind_multiple_samples = [&](bool benchmarking_unwind) {
81*eb293b8fSAndroid Build Coastguard Worker       // The benchmark should only measure the time / memory usage for the creation of
82*eb293b8fSAndroid Build Coastguard Worker       // each Unwinder object and the corresponding unwind as close as possible.
83*eb293b8fSAndroid Build Coastguard Worker       if (benchmarking_unwind) state.PauseTiming();
84*eb293b8fSAndroid Build Coastguard Worker 
85*eb293b8fSAndroid Build Coastguard Worker       std::unordered_map<std::string_view, std::unique_ptr<Regs>> regs_copies;
86*eb293b8fSAndroid Build Coastguard Worker       for (const auto& sample_info : sample_infos) {
87*eb293b8fSAndroid Build Coastguard Worker         const std::string& sample_name = sample_info.offline_files_dir;
88*eb293b8fSAndroid Build Coastguard Worker 
89*eb293b8fSAndroid Build Coastguard Worker         // Need to init unwinder with new copy of regs each iteration because unwinding changes
90*eb293b8fSAndroid Build Coastguard Worker         // the attributes of the regs object.
91*eb293b8fSAndroid Build Coastguard Worker         regs_copies.emplace(sample_name,
92*eb293b8fSAndroid Build Coastguard Worker                             std::unique_ptr<Regs>(offline_utils_.GetRegs(sample_name)->Clone()));
93*eb293b8fSAndroid Build Coastguard Worker 
94*eb293b8fSAndroid Build Coastguard Worker         // The Maps object will still hold the parsed maps from the previous unwinds. So reset them
95*eb293b8fSAndroid Build Coastguard Worker         // unless we want to assume all Maps are cached.
96*eb293b8fSAndroid Build Coastguard Worker         if (!sample_info.create_maps) {
97*eb293b8fSAndroid Build Coastguard Worker           if (!offline_utils_.CreateMaps(&error_msg, sample_name)) {
98*eb293b8fSAndroid Build Coastguard Worker             state.SkipWithError(error_msg.c_str());
99*eb293b8fSAndroid Build Coastguard Worker             return;
100*eb293b8fSAndroid Build Coastguard Worker           }
101*eb293b8fSAndroid Build Coastguard Worker 
102*eb293b8fSAndroid Build Coastguard Worker           // Since this maps object will be cached, need to make sure that
103*eb293b8fSAndroid Build Coastguard Worker           // all of the names are fully qualified paths. This allows the
104*eb293b8fSAndroid Build Coastguard Worker           // caching mechanism to properly cache elf files that are
105*eb293b8fSAndroid Build Coastguard Worker           // actually the same.
106*eb293b8fSAndroid Build Coastguard Worker           if (!offline_utils_.ChangeToSampleDirectory(&error_msg, sample_name)) {
107*eb293b8fSAndroid Build Coastguard Worker             state.SkipWithError(error_msg.c_str());
108*eb293b8fSAndroid Build Coastguard Worker             return;
109*eb293b8fSAndroid Build Coastguard Worker           }
110*eb293b8fSAndroid Build Coastguard Worker           for (auto& map_info : *offline_utils_.GetMaps(sample_name)) {
111*eb293b8fSAndroid Build Coastguard Worker             auto& name = map_info->name();
112*eb293b8fSAndroid Build Coastguard Worker             if (!name.empty()) {
113*eb293b8fSAndroid Build Coastguard Worker               std::filesystem::path path;
114*eb293b8fSAndroid Build Coastguard Worker               if (std::filesystem::is_symlink(name.c_str())) {
115*eb293b8fSAndroid Build Coastguard Worker                 path = std::filesystem::read_symlink(name.c_str());
116*eb293b8fSAndroid Build Coastguard Worker               } else {
117*eb293b8fSAndroid Build Coastguard Worker                 path = std::filesystem::current_path();
118*eb293b8fSAndroid Build Coastguard Worker                 path /= name.c_str();
119*eb293b8fSAndroid Build Coastguard Worker               }
120*eb293b8fSAndroid Build Coastguard Worker               name = path.lexically_normal().c_str();
121*eb293b8fSAndroid Build Coastguard Worker             }
122*eb293b8fSAndroid Build Coastguard Worker           }
123*eb293b8fSAndroid Build Coastguard Worker         }
124*eb293b8fSAndroid Build Coastguard Worker       }
125*eb293b8fSAndroid Build Coastguard Worker 
126*eb293b8fSAndroid Build Coastguard Worker       if (benchmarking_unwind) mem_tracker.StartTrackingAllocations();
127*eb293b8fSAndroid Build Coastguard Worker       for (const auto& sample_info : sample_infos) {
128*eb293b8fSAndroid Build Coastguard Worker         const std::string& sample_name = sample_info.offline_files_dir;
129*eb293b8fSAndroid Build Coastguard Worker         // Need to change to sample directory for Unwinder to properly init ELF objects.
130*eb293b8fSAndroid Build Coastguard Worker         // See more info at OfflineUnwindUtils::ChangeToSampleDirectory.
131*eb293b8fSAndroid Build Coastguard Worker         if (!offline_utils_.ChangeToSampleDirectory(&error_msg, sample_name)) {
132*eb293b8fSAndroid Build Coastguard Worker           state.SkipWithError(error_msg.c_str());
133*eb293b8fSAndroid Build Coastguard Worker           return;
134*eb293b8fSAndroid Build Coastguard Worker         }
135*eb293b8fSAndroid Build Coastguard Worker         if (benchmarking_unwind) state.ResumeTiming();
136*eb293b8fSAndroid Build Coastguard Worker 
137*eb293b8fSAndroid Build Coastguard Worker         Unwinder unwinder(128, offline_utils_.GetMaps(sample_name),
138*eb293b8fSAndroid Build Coastguard Worker                           regs_copies.at(sample_name).get(),
139*eb293b8fSAndroid Build Coastguard Worker                           offline_utils_.GetProcessMemory(sample_name));
140*eb293b8fSAndroid Build Coastguard Worker         if (sample_info.memory_flag == ProcessMemoryFlag::kIncludeJitMemory) {
141*eb293b8fSAndroid Build Coastguard Worker           unwinder.SetJitDebug(offline_utils_.GetJitDebug(sample_name));
142*eb293b8fSAndroid Build Coastguard Worker         }
143*eb293b8fSAndroid Build Coastguard Worker         unwinder.SetResolveNames(resolve_names_);
144*eb293b8fSAndroid Build Coastguard Worker         unwinder.Unwind();
145*eb293b8fSAndroid Build Coastguard Worker 
146*eb293b8fSAndroid Build Coastguard Worker         if (benchmarking_unwind) state.PauseTiming();
147*eb293b8fSAndroid Build Coastguard Worker         size_t expected_num_frames;
148*eb293b8fSAndroid Build Coastguard Worker         if (!offline_utils_.GetExpectedNumFrames(&expected_num_frames, &error_msg, sample_name)) {
149*eb293b8fSAndroid Build Coastguard Worker           state.SkipWithError(error_msg.c_str());
150*eb293b8fSAndroid Build Coastguard Worker           return;
151*eb293b8fSAndroid Build Coastguard Worker         }
152*eb293b8fSAndroid Build Coastguard Worker         if (unwinder.NumFrames() != expected_num_frames) {
153*eb293b8fSAndroid Build Coastguard Worker           std::stringstream err_stream;
154*eb293b8fSAndroid Build Coastguard Worker           err_stream << "Failed to unwind sample " << sample_name << " properly.Expected "
155*eb293b8fSAndroid Build Coastguard Worker                      << expected_num_frames << " frames, but unwinder contained "
156*eb293b8fSAndroid Build Coastguard Worker                      << unwinder.NumFrames() << " frames. Unwind:\n"
157*eb293b8fSAndroid Build Coastguard Worker                      << DumpFrames(unwinder);
158*eb293b8fSAndroid Build Coastguard Worker           state.SkipWithError(err_stream.str().c_str());
159*eb293b8fSAndroid Build Coastguard Worker           return;
160*eb293b8fSAndroid Build Coastguard Worker         }
161*eb293b8fSAndroid Build Coastguard Worker       }
162*eb293b8fSAndroid Build Coastguard Worker       if (benchmarking_unwind) {
163*eb293b8fSAndroid Build Coastguard Worker         mem_tracker.StopTrackingAllocations();
164*eb293b8fSAndroid Build Coastguard Worker         state.ResumeTiming();
165*eb293b8fSAndroid Build Coastguard Worker       }
166*eb293b8fSAndroid Build Coastguard Worker     };
167*eb293b8fSAndroid Build Coastguard Worker 
168*eb293b8fSAndroid Build Coastguard Worker     if (unwind_case_ == kSteadyState) {
169*eb293b8fSAndroid Build Coastguard Worker       WarmUpUnwindCaches(offline_unwind_multiple_samples);
170*eb293b8fSAndroid Build Coastguard Worker     }
171*eb293b8fSAndroid Build Coastguard Worker 
172*eb293b8fSAndroid Build Coastguard Worker     for (const auto& _ : state) {
173*eb293b8fSAndroid Build Coastguard Worker       offline_unwind_multiple_samples(/*benchmarking_unwind=*/true);
174*eb293b8fSAndroid Build Coastguard Worker     }
175*eb293b8fSAndroid Build Coastguard Worker     mem_tracker.SetBenchmarkCounters(state);
176*eb293b8fSAndroid Build Coastguard Worker   }
177*eb293b8fSAndroid Build Coastguard Worker 
178*eb293b8fSAndroid Build Coastguard Worker   // This functions main purpose is to enable ELF caching for the steady state unwind case
179*eb293b8fSAndroid Build Coastguard Worker   // and then perform one unwind to warm up the cache for subsequent unwinds.
180*eb293b8fSAndroid Build Coastguard Worker   //
181*eb293b8fSAndroid Build Coastguard Worker   // Another reason for pulling this functionality out of the main benchmarking function is
182*eb293b8fSAndroid Build Coastguard Worker   // to add an additional call stack frame in between the cache warm-up unwinds and
183*eb293b8fSAndroid Build Coastguard Worker   // BenchmarkOfflineUnwindMultipleSamples so that it is easy to filter this set of unwinds out
184*eb293b8fSAndroid Build Coastguard Worker   // when profiling.
WarmUpUnwindCaches(const std::function<void (bool)> & offline_unwind_multiple_samples)185*eb293b8fSAndroid Build Coastguard Worker   void WarmUpUnwindCaches(const std::function<void(bool)>& offline_unwind_multiple_samples) {
186*eb293b8fSAndroid Build Coastguard Worker     Elf::SetCachingEnabled(true);
187*eb293b8fSAndroid Build Coastguard Worker     offline_unwind_multiple_samples(/*benchmarking_unwind=*/false);
188*eb293b8fSAndroid Build Coastguard Worker   }
189*eb293b8fSAndroid Build Coastguard Worker 
190*eb293b8fSAndroid Build Coastguard Worker   std::string unwind_case_;
191*eb293b8fSAndroid Build Coastguard Worker   bool resolve_names_;
192*eb293b8fSAndroid Build Coastguard Worker   OfflineUnwindUtils offline_utils_;
193*eb293b8fSAndroid Build Coastguard Worker };
194*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_DEFINE_F(OfflineUnwindBenchmark,BM_offline_straddle_arm64)195*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_DEFINE_F(OfflineUnwindBenchmark, BM_offline_straddle_arm64)(benchmark::State& state) {
196*eb293b8fSAndroid Build Coastguard Worker   SingleUnwindBenchmark(
197*eb293b8fSAndroid Build Coastguard Worker       state, {.offline_files_dir = "straddle_arm64/", .arch = ARCH_ARM64, .create_maps = false});
198*eb293b8fSAndroid Build Coastguard Worker }
199*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_REGISTER_F(OfflineUnwindBenchmark, BM_offline_straddle_arm64)
200*eb293b8fSAndroid Build Coastguard Worker     ->ArgNames({"is_steady_state_case", "resolve_names"})
201*eb293b8fSAndroid Build Coastguard Worker     ->Ranges({{false, true}, {false, true}});
202*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_DEFINE_F(OfflineUnwindBenchmark,BM_offline_straddle_arm64_cached_maps)203*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_DEFINE_F(OfflineUnwindBenchmark, BM_offline_straddle_arm64_cached_maps)
204*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
205*eb293b8fSAndroid Build Coastguard Worker   SingleUnwindBenchmark(state, {.offline_files_dir = "straddle_arm64/", .arch = ARCH_ARM64});
206*eb293b8fSAndroid Build Coastguard Worker }
207*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_REGISTER_F(OfflineUnwindBenchmark, BM_offline_straddle_arm64_cached_maps)
208*eb293b8fSAndroid Build Coastguard Worker     ->ArgNames({"is_steady_state_case", "resolve_names"})
209*eb293b8fSAndroid Build Coastguard Worker     ->Ranges({{false, true}, {false, true}});
210*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_DEFINE_F(OfflineUnwindBenchmark,BM_offline_jit_debug_arm)211*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_DEFINE_F(OfflineUnwindBenchmark, BM_offline_jit_debug_arm)(benchmark::State& state) {
212*eb293b8fSAndroid Build Coastguard Worker   SingleUnwindBenchmark(state, {.offline_files_dir = "jit_debug_arm/",
213*eb293b8fSAndroid Build Coastguard Worker                                 .arch = ARCH_ARM,
214*eb293b8fSAndroid Build Coastguard Worker                                 .memory_flag = ProcessMemoryFlag::kIncludeJitMemory,
215*eb293b8fSAndroid Build Coastguard Worker                                 .create_maps = false});
216*eb293b8fSAndroid Build Coastguard Worker }
217*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_REGISTER_F(OfflineUnwindBenchmark, BM_offline_jit_debug_arm)
218*eb293b8fSAndroid Build Coastguard Worker     ->ArgNames({"is_steady_state_case", "resolve_names"})
219*eb293b8fSAndroid Build Coastguard Worker     ->Ranges({{false, true}, {false, true}});
220*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_DEFINE_F(OfflineUnwindBenchmark,BM_offline_profiler_like_multi_process)221*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_DEFINE_F(OfflineUnwindBenchmark, BM_offline_profiler_like_multi_process)
222*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
223*eb293b8fSAndroid Build Coastguard Worker   ConsecutiveUnwindBenchmark(
224*eb293b8fSAndroid Build Coastguard Worker       state,
225*eb293b8fSAndroid Build Coastguard Worker       std::vector<UnwindSampleInfo>{
226*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "bluetooth_arm64/pc_1/", .arch = ARCH_ARM64, .create_maps = false},
227*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "jit_debug_arm/",
228*eb293b8fSAndroid Build Coastguard Worker            .arch = ARCH_ARM,
229*eb293b8fSAndroid Build Coastguard Worker            .memory_flag = ProcessMemoryFlag::kIncludeJitMemory,
230*eb293b8fSAndroid Build Coastguard Worker            .create_maps = false},
231*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "photos_reset_arm64/", .arch = ARCH_ARM64, .create_maps = false},
232*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "youtube_compiled_arm64/",
233*eb293b8fSAndroid Build Coastguard Worker            .arch = ARCH_ARM64,
234*eb293b8fSAndroid Build Coastguard Worker            .create_maps = false},
235*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "yt_music_arm64/", .arch = ARCH_ARM64, .create_maps = false},
236*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "maps_compiled_arm64/28656_oat_odex_jar/",
237*eb293b8fSAndroid Build Coastguard Worker            .arch = ARCH_ARM64,
238*eb293b8fSAndroid Build Coastguard Worker            .create_maps = false}});
239*eb293b8fSAndroid Build Coastguard Worker }
240*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_REGISTER_F(OfflineUnwindBenchmark, BM_offline_profiler_like_multi_process)
241*eb293b8fSAndroid Build Coastguard Worker     ->ArgNames({"is_steady_state_case", "resolve_names"})
242*eb293b8fSAndroid Build Coastguard Worker     ->Ranges({{false, true}, {false, true}});
243*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_DEFINE_F(OfflineUnwindBenchmark,BM_offline_profiler_like_single_process_multi_thread)244*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_DEFINE_F(OfflineUnwindBenchmark, BM_offline_profiler_like_single_process_multi_thread)
245*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
246*eb293b8fSAndroid Build Coastguard Worker   ConsecutiveUnwindBenchmark(
247*eb293b8fSAndroid Build Coastguard Worker       state,
248*eb293b8fSAndroid Build Coastguard Worker       std::vector<UnwindSampleInfo>{{.offline_files_dir = "maps_compiled_arm64/28656_oat_odex_jar/",
249*eb293b8fSAndroid Build Coastguard Worker                                      .arch = ARCH_ARM64,
250*eb293b8fSAndroid Build Coastguard Worker                                      .create_maps = false},
251*eb293b8fSAndroid Build Coastguard Worker                                     {.offline_files_dir = "maps_compiled_arm64/28613_main-thread/",
252*eb293b8fSAndroid Build Coastguard Worker                                      .arch = ARCH_ARM64,
253*eb293b8fSAndroid Build Coastguard Worker                                      .create_maps = false},
254*eb293b8fSAndroid Build Coastguard Worker                                     {.offline_files_dir = "maps_compiled_arm64/28644/",
255*eb293b8fSAndroid Build Coastguard Worker                                      .arch = ARCH_ARM64,
256*eb293b8fSAndroid Build Coastguard Worker                                      .create_maps = false},
257*eb293b8fSAndroid Build Coastguard Worker                                     {.offline_files_dir = "maps_compiled_arm64/28648/",
258*eb293b8fSAndroid Build Coastguard Worker                                      .arch = ARCH_ARM64,
259*eb293b8fSAndroid Build Coastguard Worker                                      .create_maps = false},
260*eb293b8fSAndroid Build Coastguard Worker                                     {.offline_files_dir = "maps_compiled_arm64/28667/",
261*eb293b8fSAndroid Build Coastguard Worker                                      .arch = ARCH_ARM64,
262*eb293b8fSAndroid Build Coastguard Worker                                      .create_maps = false}});
263*eb293b8fSAndroid Build Coastguard Worker }
264*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_REGISTER_F(OfflineUnwindBenchmark, BM_offline_profiler_like_single_process_multi_thread)
265*eb293b8fSAndroid Build Coastguard Worker     ->ArgNames({"is_steady_state_case", "resolve_names"})
266*eb293b8fSAndroid Build Coastguard Worker     ->Ranges({{false, true}, {false, true}});
267*eb293b8fSAndroid Build Coastguard Worker 
BENCHMARK_DEFINE_F(OfflineUnwindBenchmark,BM_offline_profiler_like_single_thread_diverse_pcs)268*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_DEFINE_F(OfflineUnwindBenchmark, BM_offline_profiler_like_single_thread_diverse_pcs)
269*eb293b8fSAndroid Build Coastguard Worker (benchmark::State& state) {
270*eb293b8fSAndroid Build Coastguard Worker   ConsecutiveUnwindBenchmark(
271*eb293b8fSAndroid Build Coastguard Worker       state,
272*eb293b8fSAndroid Build Coastguard Worker       std::vector<UnwindSampleInfo>{
273*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "bluetooth_arm64/pc_1/", .arch = ARCH_ARM64, .create_maps = false},
274*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "bluetooth_arm64/pc_2/", .arch = ARCH_ARM64, .create_maps = false},
275*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "bluetooth_arm64/pc_3/", .arch = ARCH_ARM64, .create_maps = false},
276*eb293b8fSAndroid Build Coastguard Worker           {.offline_files_dir = "bluetooth_arm64/pc_4/",
277*eb293b8fSAndroid Build Coastguard Worker            .arch = ARCH_ARM64,
278*eb293b8fSAndroid Build Coastguard Worker            .create_maps = false}});
279*eb293b8fSAndroid Build Coastguard Worker }
280*eb293b8fSAndroid Build Coastguard Worker BENCHMARK_REGISTER_F(OfflineUnwindBenchmark, BM_offline_profiler_like_single_thread_diverse_pcs)
281*eb293b8fSAndroid Build Coastguard Worker     ->ArgNames({"is_steady_state_case", "resolve_names"})
282*eb293b8fSAndroid Build Coastguard Worker     ->Ranges({{false, true}, {false, true}});
283*eb293b8fSAndroid Build Coastguard Worker 
284*eb293b8fSAndroid Build Coastguard Worker }  // namespace
285*eb293b8fSAndroid Build Coastguard Worker }  // namespace unwindstack
286