1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License.
5800b99b8Sopenharmony_ci * You may obtain a copy of the License at
6800b99b8Sopenharmony_ci *
7800b99b8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8800b99b8Sopenharmony_ci *
9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and
13800b99b8Sopenharmony_ci * limitations under the License.
14800b99b8Sopenharmony_ci */
15800b99b8Sopenharmony_ci
16800b99b8Sopenharmony_ci#include <benchmark/benchmark.h>
17800b99b8Sopenharmony_ci#include <string>
18800b99b8Sopenharmony_ci#include <vector>
19800b99b8Sopenharmony_ci#include <unistd.h>
20800b99b8Sopenharmony_ci#include "dfx_log.h"
21800b99b8Sopenharmony_ci#include "dfx_regs_get.h"
22800b99b8Sopenharmony_ci#include "dfx_regs_qut.h"
23800b99b8Sopenharmony_ci#include "dfx_test_util.h"
24800b99b8Sopenharmony_ci#include "fp_unwinder.h"
25800b99b8Sopenharmony_ci#include "unwinder.h"
26800b99b8Sopenharmony_ci#include "unwinder_config.h"
27800b99b8Sopenharmony_ci
28800b99b8Sopenharmony_ciusing namespace OHOS::HiviewDFX;
29800b99b8Sopenharmony_ciusing namespace std;
30800b99b8Sopenharmony_ci
31800b99b8Sopenharmony_ci#undef LOG_DOMAIN
32800b99b8Sopenharmony_ci#undef LOG_TAG
33800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11
34800b99b8Sopenharmony_ci#define LOG_TAG "DfxUnwinderLocal"
35800b99b8Sopenharmony_ci
36800b99b8Sopenharmony_cistatic constexpr size_t TEST_MIN_UNWIND_FRAMES = 5;
37800b99b8Sopenharmony_ci
38800b99b8Sopenharmony_cistruct UnwindData {
39800b99b8Sopenharmony_ci    std::shared_ptr<Unwinder> unwinder = nullptr;
40800b99b8Sopenharmony_ci    bool isCache = false;
41800b99b8Sopenharmony_ci    bool isFillFrames = false;
42800b99b8Sopenharmony_ci    bool isFp = false;
43800b99b8Sopenharmony_ci};
44800b99b8Sopenharmony_ci
45800b99b8Sopenharmony_ciNOINLINE static size_t TestFunc5(size_t (*func)(void*), void* data)
46800b99b8Sopenharmony_ci{
47800b99b8Sopenharmony_ci    return func(data);
48800b99b8Sopenharmony_ci}
49800b99b8Sopenharmony_ci
50800b99b8Sopenharmony_ciNOINLINE static size_t TestFunc4(size_t (*func)(void*), void* data)
51800b99b8Sopenharmony_ci{
52800b99b8Sopenharmony_ci    return TestFunc5(func, data);
53800b99b8Sopenharmony_ci}
54800b99b8Sopenharmony_ci
55800b99b8Sopenharmony_ciNOINLINE static size_t TestFunc3(size_t (*func)(void*), void* data)
56800b99b8Sopenharmony_ci{
57800b99b8Sopenharmony_ci    return TestFunc4(func, data);
58800b99b8Sopenharmony_ci}
59800b99b8Sopenharmony_ci
60800b99b8Sopenharmony_ciNOINLINE static size_t TestFunc2(size_t (*func)(void*), void* data)
61800b99b8Sopenharmony_ci{
62800b99b8Sopenharmony_ci    return TestFunc3(func, data);
63800b99b8Sopenharmony_ci}
64800b99b8Sopenharmony_ci
65800b99b8Sopenharmony_ciNOINLINE static size_t TestFunc1(size_t (*func)(void*), void* data)
66800b99b8Sopenharmony_ci{
67800b99b8Sopenharmony_ci    return TestFunc2(func, data);
68800b99b8Sopenharmony_ci}
69800b99b8Sopenharmony_ci
70800b99b8Sopenharmony_cistatic bool GetUnwinder(void* data, std::shared_ptr<Unwinder>& unwinder, bool& isFp)
71800b99b8Sopenharmony_ci{
72800b99b8Sopenharmony_ci    UnwindData* dataPtr = reinterpret_cast<UnwindData*>(data);
73800b99b8Sopenharmony_ci    if ((dataPtr != nullptr) && (dataPtr->unwinder != nullptr)) {
74800b99b8Sopenharmony_ci        unwinder = dataPtr->unwinder;
75800b99b8Sopenharmony_ci        unwinder->EnableFillFrames(dataPtr->isFillFrames);
76800b99b8Sopenharmony_ci        unwinder->EnableUnwindCache(dataPtr->isCache);
77800b99b8Sopenharmony_ci        isFp = dataPtr->isFp;
78800b99b8Sopenharmony_ci        return true;
79800b99b8Sopenharmony_ci    }
80800b99b8Sopenharmony_ci    DFXLOGE("Failed to get unwinder");
81800b99b8Sopenharmony_ci    return false;
82800b99b8Sopenharmony_ci}
83800b99b8Sopenharmony_ci
84800b99b8Sopenharmony_cistatic size_t UnwinderLocal(MAYBE_UNUSED void* data)
85800b99b8Sopenharmony_ci{
86800b99b8Sopenharmony_ci    std::shared_ptr<Unwinder> unwinder = nullptr;
87800b99b8Sopenharmony_ci    bool isFp = false;
88800b99b8Sopenharmony_ci    if (!GetUnwinder(data, unwinder, isFp)) {
89800b99b8Sopenharmony_ci        return 0;
90800b99b8Sopenharmony_ci    }
91800b99b8Sopenharmony_ci    MAYBE_UNUSED bool unwRet = unwinder->UnwindLocal(false, isFp);
92800b99b8Sopenharmony_ci    size_t unwSize = 0;
93800b99b8Sopenharmony_ci    if (isFp) {
94800b99b8Sopenharmony_ci        unwSize = unwinder->GetPcs().size();
95800b99b8Sopenharmony_ci    } else {
96800b99b8Sopenharmony_ci        unwSize = unwinder->GetFrames().size();
97800b99b8Sopenharmony_ci    }
98800b99b8Sopenharmony_ci    DFXLOGU("%{public}s frames.size: %{public}zu", __func__, unwSize);
99800b99b8Sopenharmony_ci    return unwSize;
100800b99b8Sopenharmony_ci}
101800b99b8Sopenharmony_ci
102800b99b8Sopenharmony_ci#if defined(__aarch64__)
103800b99b8Sopenharmony_cistatic size_t UnwinderLocalFp(MAYBE_UNUSED void* data) {
104800b99b8Sopenharmony_ci    UnwindData* dataPtr = reinterpret_cast<UnwindData*>(data);
105800b99b8Sopenharmony_ci    if ((dataPtr == nullptr) || (dataPtr->unwinder == nullptr)) {
106800b99b8Sopenharmony_ci        return 0;
107800b99b8Sopenharmony_ci    }
108800b99b8Sopenharmony_ci
109800b99b8Sopenharmony_ci    uintptr_t stackBottom = 1, stackTop = static_cast<uintptr_t>(-1);
110800b99b8Sopenharmony_ci    if (!dataPtr->unwinder->GetStackRange(stackBottom, stackTop)) {
111800b99b8Sopenharmony_ci        return 0;
112800b99b8Sopenharmony_ci    }
113800b99b8Sopenharmony_ci    uintptr_t miniRegs[FP_MINI_REGS_SIZE] = {0};
114800b99b8Sopenharmony_ci    GetFramePointerMiniRegs(miniRegs, sizeof(miniRegs) / sizeof(miniRegs[0]));
115800b99b8Sopenharmony_ci    auto regs = DfxRegs::CreateFromRegs(UnwindMode::FRAMEPOINTER_UNWIND, miniRegs,
116800b99b8Sopenharmony_ci                                        sizeof(miniRegs) / sizeof(miniRegs[0]));
117800b99b8Sopenharmony_ci    dataPtr->unwinder->SetRegs(regs);
118800b99b8Sopenharmony_ci    UnwindContext context;
119800b99b8Sopenharmony_ci    context.pid = UNWIND_TYPE_LOCAL;
120800b99b8Sopenharmony_ci    context.regs = regs;
121800b99b8Sopenharmony_ci    context.stackCheck = false;
122800b99b8Sopenharmony_ci    context.stackBottom = stackBottom;
123800b99b8Sopenharmony_ci    context.stackTop = stackTop;
124800b99b8Sopenharmony_ci    dataPtr->unwinder->EnableFpCheckMapExec(false);
125800b99b8Sopenharmony_ci    dataPtr->unwinder->UnwindByFp(&context);
126800b99b8Sopenharmony_ci    auto unwSize = dataPtr->unwinder->GetPcs().size();
127800b99b8Sopenharmony_ci    DFXLOGU("%{public}s frames.size: %{public}zu", __func__, unwSize);
128800b99b8Sopenharmony_ci
129800b99b8Sopenharmony_ci    if (dataPtr->isFillFrames) {
130800b99b8Sopenharmony_ci        auto& pcs = dataPtr->unwinder->GetPcs();
131800b99b8Sopenharmony_ci        std::vector<DfxFrame> frames;
132800b99b8Sopenharmony_ci        for (size_t i = 0; i < unwSize; ++i) {
133800b99b8Sopenharmony_ci            DfxFrame frame;
134800b99b8Sopenharmony_ci            frame.index = i;
135800b99b8Sopenharmony_ci            frame.pc = static_cast<uint64_t>(pcs[i]);
136800b99b8Sopenharmony_ci            frames.emplace_back(frame);
137800b99b8Sopenharmony_ci        }
138800b99b8Sopenharmony_ci        Unwinder::FillLocalFrames(frames);
139800b99b8Sopenharmony_ci        DFXLOGU(Unwinder::GetFramesStr(frames).c_str());
140800b99b8Sopenharmony_ci    }
141800b99b8Sopenharmony_ci    return unwSize;
142800b99b8Sopenharmony_ci}
143800b99b8Sopenharmony_ci
144800b99b8Sopenharmony_cistatic size_t FpUnwinderLocal(MAYBE_UNUSED void* data) {
145800b99b8Sopenharmony_ci    uintptr_t regs[2]; // 2: pc and fp reg
146800b99b8Sopenharmony_ci    FpUnwinder::GetPcFpRegs(regs);
147800b99b8Sopenharmony_ci    const size_t maxSize = 32;
148800b99b8Sopenharmony_ci    uintptr_t pcs[maxSize] = {0};
149800b99b8Sopenharmony_ci    auto unwSize = FpUnwinder::GetPtr()->Unwind(regs[0], regs[1], pcs, maxSize);
150800b99b8Sopenharmony_ci    DFXLOGU("%{public}s frames.size: %{public}zu", __func__, unwSize);
151800b99b8Sopenharmony_ci
152800b99b8Sopenharmony_ci    UnwindData* dataPtr = reinterpret_cast<UnwindData*>(data);
153800b99b8Sopenharmony_ci    if (dataPtr != nullptr && dataPtr->isFillFrames) {
154800b99b8Sopenharmony_ci        std::vector<DfxFrame> frames;
155800b99b8Sopenharmony_ci        for (auto i = 0; i < unwSize; ++i) {
156800b99b8Sopenharmony_ci            DfxFrame frame;
157800b99b8Sopenharmony_ci            frame.index = i;
158800b99b8Sopenharmony_ci            frame.pc = static_cast<uint64_t>(pcs[i]);
159800b99b8Sopenharmony_ci            frames.emplace_back(frame);
160800b99b8Sopenharmony_ci        }
161800b99b8Sopenharmony_ci        Unwinder::FillLocalFrames(frames);
162800b99b8Sopenharmony_ci        DFXLOGU(Unwinder::GetFramesStr(frames).c_str());
163800b99b8Sopenharmony_ci    }
164800b99b8Sopenharmony_ci    return unwSize;
165800b99b8Sopenharmony_ci}
166800b99b8Sopenharmony_ci
167800b99b8Sopenharmony_cistatic size_t FpUnwinderLocalSafe(MAYBE_UNUSED void* data) {
168800b99b8Sopenharmony_ci    uintptr_t regs[2]; // 2: pc and fp reg
169800b99b8Sopenharmony_ci    FpUnwinder::GetPcFpRegs(regs);
170800b99b8Sopenharmony_ci    const size_t maxSize = 32;
171800b99b8Sopenharmony_ci    uintptr_t pcs[maxSize] = {0};
172800b99b8Sopenharmony_ci    auto unwSize = FpUnwinder::GetPtr()->UnwindSafe(regs[0], regs[1], pcs, maxSize);
173800b99b8Sopenharmony_ci    DFXLOGU("%{public}s frames.size: %{public}zu", __func__, unwSize);
174800b99b8Sopenharmony_ci
175800b99b8Sopenharmony_ci    UnwindData* dataPtr = reinterpret_cast<UnwindData*>(data);
176800b99b8Sopenharmony_ci    if (dataPtr != nullptr && dataPtr->isFillFrames) {
177800b99b8Sopenharmony_ci        std::vector<DfxFrame> frames;
178800b99b8Sopenharmony_ci        for (auto i = 0; i < unwSize; ++i) {
179800b99b8Sopenharmony_ci            DfxFrame frame;
180800b99b8Sopenharmony_ci            frame.index = i;
181800b99b8Sopenharmony_ci            frame.pc = static_cast<uint64_t>(pcs[i]);
182800b99b8Sopenharmony_ci            frames.emplace_back(frame);
183800b99b8Sopenharmony_ci        }
184800b99b8Sopenharmony_ci        Unwinder::FillLocalFrames(frames);
185800b99b8Sopenharmony_ci        DFXLOGU(Unwinder::GetFramesStr(frames).c_str());
186800b99b8Sopenharmony_ci    }
187800b99b8Sopenharmony_ci    return unwSize;
188800b99b8Sopenharmony_ci}
189800b99b8Sopenharmony_ci#endif
190800b99b8Sopenharmony_ci
191800b99b8Sopenharmony_cistatic void Run(benchmark::State& state, size_t (*func)(void*), void* data)
192800b99b8Sopenharmony_ci{
193800b99b8Sopenharmony_ci    DFXLOGU("++++++pid: %{public}d", getpid());
194800b99b8Sopenharmony_ci    for (const auto& _ : state) {
195800b99b8Sopenharmony_ci        if (TestFunc1(func, data) < TEST_MIN_UNWIND_FRAMES) {
196800b99b8Sopenharmony_ci            state.SkipWithError("Failed to unwind.");
197800b99b8Sopenharmony_ci        }
198800b99b8Sopenharmony_ci    }
199800b99b8Sopenharmony_ci    DFXLOGU("------pid: %{public}d", getpid());
200800b99b8Sopenharmony_ci}
201800b99b8Sopenharmony_ci
202800b99b8Sopenharmony_ci/**
203800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalFull
204800b99b8Sopenharmony_ci* @tc.desc: Unwind local full
205800b99b8Sopenharmony_ci* @tc.type: FUNC
206800b99b8Sopenharmony_ci*/
207800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalFull(benchmark::State& state)
208800b99b8Sopenharmony_ci{
209800b99b8Sopenharmony_ci    std::vector<uint16_t> qutRegs;
210800b99b8Sopenharmony_ci    for (uint16_t i = REG_EH; i < REG_LAST; ++i) {
211800b99b8Sopenharmony_ci        qutRegs.emplace_back(i);
212800b99b8Sopenharmony_ci    }
213800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(qutRegs);
214800b99b8Sopenharmony_ci    UnwindData data;
215800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
216800b99b8Sopenharmony_ci    data.isCache = false;
217800b99b8Sopenharmony_ci    data.isFillFrames = false;
218800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
219800b99b8Sopenharmony_ci}
220800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalFull);
221800b99b8Sopenharmony_ci
222800b99b8Sopenharmony_ci/**
223800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalQut
224800b99b8Sopenharmony_ci* @tc.desc: Unwind local qut
225800b99b8Sopenharmony_ci* @tc.type: FUNC
226800b99b8Sopenharmony_ci*/
227800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalQut(benchmark::State& state)
228800b99b8Sopenharmony_ci{
229800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
230800b99b8Sopenharmony_ci    UnwindData data;
231800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
232800b99b8Sopenharmony_ci    data.isCache = false;
233800b99b8Sopenharmony_ci    data.isFillFrames = false;
234800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
235800b99b8Sopenharmony_ci}
236800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalQut);
237800b99b8Sopenharmony_ci
238800b99b8Sopenharmony_ci/**
239800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalQutCache
240800b99b8Sopenharmony_ci* @tc.desc: Unwind local qut cache
241800b99b8Sopenharmony_ci* @tc.type: FUNC
242800b99b8Sopenharmony_ci*/
243800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalQutCache(benchmark::State& state)
244800b99b8Sopenharmony_ci{
245800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
246800b99b8Sopenharmony_ci    UnwindData data;
247800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
248800b99b8Sopenharmony_ci    data.isCache = true;
249800b99b8Sopenharmony_ci    data.isFillFrames = false;
250800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
251800b99b8Sopenharmony_ci}
252800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalQutCache);
253800b99b8Sopenharmony_ci
254800b99b8Sopenharmony_ci/**
255800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalQutFrames
256800b99b8Sopenharmony_ci* @tc.desc: Unwind local qut frames
257800b99b8Sopenharmony_ci* @tc.type: FUNC
258800b99b8Sopenharmony_ci*/
259800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalQutFrames(benchmark::State& state)
260800b99b8Sopenharmony_ci{
261800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
262800b99b8Sopenharmony_ci    UnwindData data;
263800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
264800b99b8Sopenharmony_ci    data.isCache = false;
265800b99b8Sopenharmony_ci    data.isFillFrames = true;
266800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
267800b99b8Sopenharmony_ci}
268800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalQutFrames);
269800b99b8Sopenharmony_ci
270800b99b8Sopenharmony_ci/**
271800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalQutFramesCache
272800b99b8Sopenharmony_ci* @tc.desc: Unwind local qut Frames cache
273800b99b8Sopenharmony_ci* @tc.type: FUNC
274800b99b8Sopenharmony_ci*/
275800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalQutFramesCache(benchmark::State& state)
276800b99b8Sopenharmony_ci{
277800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
278800b99b8Sopenharmony_ci    UnwindData data;
279800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
280800b99b8Sopenharmony_ci    data.isCache = true;
281800b99b8Sopenharmony_ci    data.isFillFrames = true;
282800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
283800b99b8Sopenharmony_ci}
284800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalQutFramesCache);
285800b99b8Sopenharmony_ci
286800b99b8Sopenharmony_ci/**
287800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalQutMiniDebugInfos
288800b99b8Sopenharmony_ci* @tc.desc: Unwind local qut minidebuginfo
289800b99b8Sopenharmony_ci* @tc.type: FUNC
290800b99b8Sopenharmony_ci*/
291800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalQutMiniDebugInfos(benchmark::State& state)
292800b99b8Sopenharmony_ci{
293800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
294800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableMiniDebugInfo(true);
295800b99b8Sopenharmony_ci    UnwindData data;
296800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
297800b99b8Sopenharmony_ci    data.isCache = true;
298800b99b8Sopenharmony_ci    data.isFillFrames = true;
299800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
300800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableMiniDebugInfo(false);
301800b99b8Sopenharmony_ci}
302800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalQutMiniDebugInfos);
303800b99b8Sopenharmony_ci
304800b99b8Sopenharmony_ci/**
305800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalQutMiniDebugInfosLazily
306800b99b8Sopenharmony_ci* @tc.desc: Unwind local qut minidebuginfo lazily
307800b99b8Sopenharmony_ci* @tc.type: FUNC
308800b99b8Sopenharmony_ci*/
309800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalQutMiniDebugInfosLazily(benchmark::State& state)
310800b99b8Sopenharmony_ci{
311800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
312800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableMiniDebugInfo(true);
313800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableLoadSymbolLazily(true);
314800b99b8Sopenharmony_ci    UnwindData data;
315800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>();
316800b99b8Sopenharmony_ci    data.isCache = true;
317800b99b8Sopenharmony_ci    data.isFillFrames = true;
318800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
319800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableMiniDebugInfo(false);
320800b99b8Sopenharmony_ci    UnwinderConfig::SetEnableLoadSymbolLazily(false);
321800b99b8Sopenharmony_ci}
322800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalQutMiniDebugInfosLazily);
323800b99b8Sopenharmony_ci
324800b99b8Sopenharmony_ci#if defined(__aarch64__)
325800b99b8Sopenharmony_ci/**
326800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalByFp
327800b99b8Sopenharmony_ci* @tc.desc: Unwind local by fp
328800b99b8Sopenharmony_ci* @tc.type: FUNC
329800b99b8Sopenharmony_ci*/
330800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalByFp(benchmark::State& state)
331800b99b8Sopenharmony_ci{
332800b99b8Sopenharmony_ci    DfxRegsQut::SetQutRegs(QUT_REGS);
333800b99b8Sopenharmony_ci    UnwindData data;
334800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>(false);
335800b99b8Sopenharmony_ci    data.isCache = true;
336800b99b8Sopenharmony_ci    data.isFillFrames = false;
337800b99b8Sopenharmony_ci    data.isFp = true;
338800b99b8Sopenharmony_ci    Run(state, UnwinderLocal, &data);
339800b99b8Sopenharmony_ci}
340800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalByFp);
341800b99b8Sopenharmony_ci
342800b99b8Sopenharmony_ci/**
343800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalFp
344800b99b8Sopenharmony_ci* @tc.desc: Unwind local fp
345800b99b8Sopenharmony_ci* @tc.type: FUNC
346800b99b8Sopenharmony_ci*/
347800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalFp(benchmark::State& state)
348800b99b8Sopenharmony_ci{
349800b99b8Sopenharmony_ci    UnwindData data;
350800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>(false);
351800b99b8Sopenharmony_ci    data.isFp = true;
352800b99b8Sopenharmony_ci    data.isFillFrames = false;
353800b99b8Sopenharmony_ci    Run(state, UnwinderLocalFp, &data);
354800b99b8Sopenharmony_ci}
355800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalFp);
356800b99b8Sopenharmony_ci
357800b99b8Sopenharmony_ci/**
358800b99b8Sopenharmony_ci* @tc.name: BenchmarkUnwinderLocalFpFrames
359800b99b8Sopenharmony_ci* @tc.desc: Unwind local fp Frames
360800b99b8Sopenharmony_ci* @tc.type: FUNC
361800b99b8Sopenharmony_ci*/
362800b99b8Sopenharmony_cistatic void BenchmarkUnwinderLocalFpFrames(benchmark::State& state)
363800b99b8Sopenharmony_ci{
364800b99b8Sopenharmony_ci    UnwindData data;
365800b99b8Sopenharmony_ci    data.unwinder = std::make_shared<Unwinder>(false);
366800b99b8Sopenharmony_ci    data.isFp = true;
367800b99b8Sopenharmony_ci    data.isFillFrames = true;
368800b99b8Sopenharmony_ci    Run(state, UnwinderLocalFp, &data);
369800b99b8Sopenharmony_ci}
370800b99b8Sopenharmony_ciBENCHMARK(BenchmarkUnwinderLocalFpFrames);
371800b99b8Sopenharmony_ci
372800b99b8Sopenharmony_ci/**
373800b99b8Sopenharmony_ci* @tc.name: BenchmarkFpUnwinderLocal
374800b99b8Sopenharmony_ci* @tc.desc: FpUnwinder Unwind
375800b99b8Sopenharmony_ci* @tc.type: FUNC
376800b99b8Sopenharmony_ci*/
377800b99b8Sopenharmony_cistatic void BenchmarkFpUnwinderLocal(benchmark::State& state)
378800b99b8Sopenharmony_ci{
379800b99b8Sopenharmony_ci    UnwindData data;
380800b99b8Sopenharmony_ci    data.isFillFrames = false;
381800b99b8Sopenharmony_ci    Run(state, FpUnwinderLocal, &data);
382800b99b8Sopenharmony_ci}
383800b99b8Sopenharmony_ciBENCHMARK(BenchmarkFpUnwinderLocal);
384800b99b8Sopenharmony_ci
385800b99b8Sopenharmony_ci/**
386800b99b8Sopenharmony_ci* @tc.name: BenchmarkFpUnwinderLocalFrames
387800b99b8Sopenharmony_ci* @tc.desc: FpUnwinder Unwind Frames
388800b99b8Sopenharmony_ci* @tc.type: FUNC
389800b99b8Sopenharmony_ci*/
390800b99b8Sopenharmony_cistatic void BenchmarkFpUnwinderLocalFrames(benchmark::State& state)
391800b99b8Sopenharmony_ci{
392800b99b8Sopenharmony_ci    UnwindData data;
393800b99b8Sopenharmony_ci    data.isFillFrames = true;
394800b99b8Sopenharmony_ci    Run(state, FpUnwinderLocal, &data);
395800b99b8Sopenharmony_ci}
396800b99b8Sopenharmony_ciBENCHMARK(BenchmarkFpUnwinderLocalFrames);
397800b99b8Sopenharmony_ci
398800b99b8Sopenharmony_ci/**
399800b99b8Sopenharmony_ci* @tc.name: BenchmarkFpUnwinderLocalSafe
400800b99b8Sopenharmony_ci* @tc.desc: FpUnwinder UnwindSafe
401800b99b8Sopenharmony_ci* @tc.type: FUNC
402800b99b8Sopenharmony_ci*/
403800b99b8Sopenharmony_cistatic void BenchmarkFpUnwinderLocalSafe(benchmark::State& state)
404800b99b8Sopenharmony_ci{
405800b99b8Sopenharmony_ci    UnwindData data;
406800b99b8Sopenharmony_ci    data.isFillFrames = false;
407800b99b8Sopenharmony_ci    Run(state, FpUnwinderLocalSafe, &data);
408800b99b8Sopenharmony_ci}
409800b99b8Sopenharmony_ciBENCHMARK(BenchmarkFpUnwinderLocalSafe);
410800b99b8Sopenharmony_ci
411800b99b8Sopenharmony_ci/**
412800b99b8Sopenharmony_ci* @tc.name: BenchmarkFpUnwinderLocalSafeFrames
413800b99b8Sopenharmony_ci* @tc.desc: FpUnwinder UnwindSafe Frames
414800b99b8Sopenharmony_ci* @tc.type: FUNC
415800b99b8Sopenharmony_ci*/
416800b99b8Sopenharmony_cistatic void BenchmarkFpUnwinderLocalSafeFrames(benchmark::State& state)
417800b99b8Sopenharmony_ci{
418800b99b8Sopenharmony_ci    UnwindData data;
419800b99b8Sopenharmony_ci    data.isFillFrames = true;
420800b99b8Sopenharmony_ci    Run(state, FpUnwinderLocalSafe, &data);
421800b99b8Sopenharmony_ci}
422800b99b8Sopenharmony_ciBENCHMARK(BenchmarkFpUnwinderLocalSafeFrames);
423800b99b8Sopenharmony_ci#endif