1 // Copyright 2022 The Abseil Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "absl/base/attributes.h"
16 #include "absl/base/config.h"
17 #include "absl/base/optimization.h"
18 #include "absl/debugging/stacktrace.h"
19 #include "benchmark/benchmark.h"
20
21 namespace absl {
22 ABSL_NAMESPACE_BEGIN
23 namespace {
24
25 static constexpr int kMaxStackDepth = 100;
26 static constexpr int kCacheSize = (1 << 16);
27 void* pcs[kMaxStackDepth];
28
func(benchmark::State & state,int x,int depth)29 ABSL_ATTRIBUTE_NOINLINE void func(benchmark::State& state, int x, int depth) {
30 if (x <= 0) {
31 // Touch a significant amount of memory so that the stack is likely to be
32 // not cached in the L1 cache.
33 state.PauseTiming();
34 int* arr = new int[kCacheSize];
35 for (int i = 0; i < kCacheSize; ++i) benchmark::DoNotOptimize(arr[i] = 100);
36 delete[] arr;
37 state.ResumeTiming();
38 benchmark::DoNotOptimize(absl::GetStackTrace(pcs, depth, 0));
39 return;
40 }
41 ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
42 func(state, --x, depth);
43 }
44
BM_GetStackTrace(benchmark::State & state)45 void BM_GetStackTrace(benchmark::State& state) {
46 int depth = state.range(0);
47 for (auto s : state) {
48 func(state, depth, depth);
49 }
50 }
51
52 BENCHMARK(BM_GetStackTrace)->DenseRange(10, kMaxStackDepth, 10);
53 } // namespace
54 ABSL_NAMESPACE_END
55 } // namespace absl
56