Loading libunwindstack/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -411,6 +411,7 @@ cc_benchmark { srcs: [ "benchmarks/unwind_benchmarks.cpp", "benchmarks/ElfBenchmark.cpp", "benchmarks/MapsBenchmark.cpp", "benchmarks/SymbolBenchmark.cpp", "benchmarks/Utils.cpp", ], Loading libunwindstack/benchmarks/ElfBenchmark.cpp +65 −0 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ #include <benchmark/benchmark.h> #include <unwindstack/Elf.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Regs.h> #include "Utils.h" Loading Loading @@ -75,3 +77,66 @@ void BM_elf_create_compressed(benchmark::State& state) { BenchmarkElfCreate(state, GetCompressedElfFile()); } BENCHMARK(BM_elf_create_compressed); static void InitializeBuildId(benchmark::State& state, unwindstack::Maps& maps, unwindstack::MapInfo** build_id_map_info) { if (!maps.Parse()) { state.SkipWithError("Failed to parse local maps."); return; } // Find the libc.so share library and use that for benchmark purposes. *build_id_map_info = nullptr; for (auto& map_info : maps) { if (map_info->offset == 0 && map_info->GetBuildID() != "") { *build_id_map_info = map_info.get(); break; } } if (*build_id_map_info == nullptr) { state.SkipWithError("Failed to find a map with a BuildID."); } } static void BM_elf_get_build_id_from_object(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; InitializeBuildId(state, maps, &build_id_map_info); unwindstack::Elf* elf = build_id_map_info->GetElf(std::shared_ptr<unwindstack::Memory>(), unwindstack::Regs::CurrentArch()); if (!elf->valid()) { state.SkipWithError("Cannot get valid elf from map."); } for (auto _ : state) { state.PauseTiming(); uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } state.ResumeTiming(); benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_elf_get_build_id_from_object); static void BM_elf_get_build_id_from_file(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; InitializeBuildId(state, maps, &build_id_map_info); for (auto _ : state) { state.PauseTiming(); uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } state.ResumeTiming(); benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_elf_get_build_id_from_file); libunwindstack/benchmarks/MapsBenchmark.cpp 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <err.h> #include <stdint.h> #include <string> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <benchmark/benchmark.h> #include <unwindstack/Maps.h> class BenchmarkLocalUpdatableMaps : public unwindstack::LocalUpdatableMaps { public: BenchmarkLocalUpdatableMaps() : unwindstack::LocalUpdatableMaps() {} virtual ~BenchmarkLocalUpdatableMaps() = default; const std::string GetMapsFile() const override { return maps_file_; } void BenchmarkSetMapsFile(const std::string& maps_file) { maps_file_ = maps_file; } private: std::string maps_file_; }; constexpr size_t kNumMaps = 10000; static void CreateInitialMap(const char* filename) { std::string maps; for (size_t i = 0; i < kNumMaps; i += 2) { maps += android::base::StringPrintf("%zu-%zu r-xp 0000 00:00 0 name%zu\n", i * 1000, (i + 1) * 1000, i); } if (!android::base::WriteStringToFile(maps, filename)) { errx(1, "WriteStringToFile failed"); } } static void CreateReparseMap(const char* filename) { std::string maps; for (size_t i = 0; i < kNumMaps; i++) { maps += android::base::StringPrintf("%zu-%zu r-xp 0000 00:00 0 name%zu\n", i * 2000, (i + 1) * 2000, 2 * i); } if (!android::base::WriteStringToFile(maps, filename)) { errx(1, "WriteStringToFile failed"); } } void BM_local_updatable_maps_reparse(benchmark::State& state) { TemporaryFile initial_map; CreateInitialMap(initial_map.path); TemporaryFile reparse_map; CreateReparseMap(reparse_map.path); for (auto _ : state) { BenchmarkLocalUpdatableMaps maps; maps.BenchmarkSetMapsFile(initial_map.path); if (!maps.Reparse()) { errx(1, "Internal Error: reparse of initial maps filed."); } if (maps.Total() != (kNumMaps / 2)) { errx(1, "Internal Error: Incorrect total number of maps %zu, expected %zu.", maps.Total(), kNumMaps / 2); } maps.BenchmarkSetMapsFile(reparse_map.path); if (!maps.Reparse()) { errx(1, "Internal Error: reparse of second set of maps filed."); } if (maps.Total() != kNumMaps) { errx(1, "Internal Error: Incorrect total number of maps %zu, expected %zu.", maps.Total(), kNumMaps); } } } BENCHMARK(BM_local_updatable_maps_reparse); libunwindstack/benchmarks/unwind_benchmarks.cpp +0 −60 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ #include <android-base/strings.h> #include <unwindstack/Elf.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Regs.h> Loading Loading @@ -83,63 +82,4 @@ static void BM_cached_unwind(benchmark::State& state) { } BENCHMARK(BM_cached_unwind); static void Initialize(benchmark::State& state, unwindstack::Maps& maps, unwindstack::MapInfo** build_id_map_info) { if (!maps.Parse()) { state.SkipWithError("Failed to parse local maps."); return; } // Find the libc.so share library and use that for benchmark purposes. *build_id_map_info = nullptr; for (auto& map_info : maps) { if (map_info->offset == 0 && map_info->GetBuildID() != "") { *build_id_map_info = map_info.get(); break; } } if (*build_id_map_info == nullptr) { state.SkipWithError("Failed to find a map with a BuildID."); } } static void BM_get_build_id_from_elf(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; Initialize(state, maps, &build_id_map_info); unwindstack::Elf* elf = build_id_map_info->GetElf(std::shared_ptr<unwindstack::Memory>(), unwindstack::Regs::CurrentArch()); if (!elf->valid()) { state.SkipWithError("Cannot get valid elf from map."); } for (auto _ : state) { uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_get_build_id_from_elf); static void BM_get_build_id_from_file(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; Initialize(state, maps, &build_id_map_info); for (auto _ : state) { uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_get_build_id_from_file); BENCHMARK_MAIN(); Loading
libunwindstack/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -411,6 +411,7 @@ cc_benchmark { srcs: [ "benchmarks/unwind_benchmarks.cpp", "benchmarks/ElfBenchmark.cpp", "benchmarks/MapsBenchmark.cpp", "benchmarks/SymbolBenchmark.cpp", "benchmarks/Utils.cpp", ], Loading
libunwindstack/benchmarks/ElfBenchmark.cpp +65 −0 Original line number Diff line number Diff line Loading @@ -23,7 +23,9 @@ #include <benchmark/benchmark.h> #include <unwindstack/Elf.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Regs.h> #include "Utils.h" Loading Loading @@ -75,3 +77,66 @@ void BM_elf_create_compressed(benchmark::State& state) { BenchmarkElfCreate(state, GetCompressedElfFile()); } BENCHMARK(BM_elf_create_compressed); static void InitializeBuildId(benchmark::State& state, unwindstack::Maps& maps, unwindstack::MapInfo** build_id_map_info) { if (!maps.Parse()) { state.SkipWithError("Failed to parse local maps."); return; } // Find the libc.so share library and use that for benchmark purposes. *build_id_map_info = nullptr; for (auto& map_info : maps) { if (map_info->offset == 0 && map_info->GetBuildID() != "") { *build_id_map_info = map_info.get(); break; } } if (*build_id_map_info == nullptr) { state.SkipWithError("Failed to find a map with a BuildID."); } } static void BM_elf_get_build_id_from_object(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; InitializeBuildId(state, maps, &build_id_map_info); unwindstack::Elf* elf = build_id_map_info->GetElf(std::shared_ptr<unwindstack::Memory>(), unwindstack::Regs::CurrentArch()); if (!elf->valid()) { state.SkipWithError("Cannot get valid elf from map."); } for (auto _ : state) { state.PauseTiming(); uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } state.ResumeTiming(); benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_elf_get_build_id_from_object); static void BM_elf_get_build_id_from_file(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; InitializeBuildId(state, maps, &build_id_map_info); for (auto _ : state) { state.PauseTiming(); uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } state.ResumeTiming(); benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_elf_get_build_id_from_file);
libunwindstack/benchmarks/MapsBenchmark.cpp 0 → 100644 +93 −0 Original line number Diff line number Diff line /* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <err.h> #include <stdint.h> #include <string> #include <android-base/file.h> #include <android-base/stringprintf.h> #include <benchmark/benchmark.h> #include <unwindstack/Maps.h> class BenchmarkLocalUpdatableMaps : public unwindstack::LocalUpdatableMaps { public: BenchmarkLocalUpdatableMaps() : unwindstack::LocalUpdatableMaps() {} virtual ~BenchmarkLocalUpdatableMaps() = default; const std::string GetMapsFile() const override { return maps_file_; } void BenchmarkSetMapsFile(const std::string& maps_file) { maps_file_ = maps_file; } private: std::string maps_file_; }; constexpr size_t kNumMaps = 10000; static void CreateInitialMap(const char* filename) { std::string maps; for (size_t i = 0; i < kNumMaps; i += 2) { maps += android::base::StringPrintf("%zu-%zu r-xp 0000 00:00 0 name%zu\n", i * 1000, (i + 1) * 1000, i); } if (!android::base::WriteStringToFile(maps, filename)) { errx(1, "WriteStringToFile failed"); } } static void CreateReparseMap(const char* filename) { std::string maps; for (size_t i = 0; i < kNumMaps; i++) { maps += android::base::StringPrintf("%zu-%zu r-xp 0000 00:00 0 name%zu\n", i * 2000, (i + 1) * 2000, 2 * i); } if (!android::base::WriteStringToFile(maps, filename)) { errx(1, "WriteStringToFile failed"); } } void BM_local_updatable_maps_reparse(benchmark::State& state) { TemporaryFile initial_map; CreateInitialMap(initial_map.path); TemporaryFile reparse_map; CreateReparseMap(reparse_map.path); for (auto _ : state) { BenchmarkLocalUpdatableMaps maps; maps.BenchmarkSetMapsFile(initial_map.path); if (!maps.Reparse()) { errx(1, "Internal Error: reparse of initial maps filed."); } if (maps.Total() != (kNumMaps / 2)) { errx(1, "Internal Error: Incorrect total number of maps %zu, expected %zu.", maps.Total(), kNumMaps / 2); } maps.BenchmarkSetMapsFile(reparse_map.path); if (!maps.Reparse()) { errx(1, "Internal Error: reparse of second set of maps filed."); } if (maps.Total() != kNumMaps) { errx(1, "Internal Error: Incorrect total number of maps %zu, expected %zu.", maps.Total(), kNumMaps); } } } BENCHMARK(BM_local_updatable_maps_reparse);
libunwindstack/benchmarks/unwind_benchmarks.cpp +0 −60 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ #include <android-base/strings.h> #include <unwindstack/Elf.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Regs.h> Loading Loading @@ -83,63 +82,4 @@ static void BM_cached_unwind(benchmark::State& state) { } BENCHMARK(BM_cached_unwind); static void Initialize(benchmark::State& state, unwindstack::Maps& maps, unwindstack::MapInfo** build_id_map_info) { if (!maps.Parse()) { state.SkipWithError("Failed to parse local maps."); return; } // Find the libc.so share library and use that for benchmark purposes. *build_id_map_info = nullptr; for (auto& map_info : maps) { if (map_info->offset == 0 && map_info->GetBuildID() != "") { *build_id_map_info = map_info.get(); break; } } if (*build_id_map_info == nullptr) { state.SkipWithError("Failed to find a map with a BuildID."); } } static void BM_get_build_id_from_elf(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; Initialize(state, maps, &build_id_map_info); unwindstack::Elf* elf = build_id_map_info->GetElf(std::shared_ptr<unwindstack::Memory>(), unwindstack::Regs::CurrentArch()); if (!elf->valid()) { state.SkipWithError("Cannot get valid elf from map."); } for (auto _ : state) { uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_get_build_id_from_elf); static void BM_get_build_id_from_file(benchmark::State& state) { unwindstack::LocalMaps maps; unwindstack::MapInfo* build_id_map_info; Initialize(state, maps, &build_id_map_info); for (auto _ : state) { uintptr_t id = build_id_map_info->build_id; if (id != 0) { delete reinterpret_cast<std::string*>(id); build_id_map_info->build_id = 0; } benchmark::DoNotOptimize(build_id_map_info->GetBuildID()); } } BENCHMARK(BM_get_build_id_from_file); BENCHMARK_MAIN();