• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
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  * http://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 
16 #include "runtime/tooling/sampler/stack_walker_base.h"
17 
18 namespace ark {
19 
20 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
StackWalkerBase(void * fp,bool isFrameCompiled)21 StackWalkerBase::StackWalkerBase(void *fp, bool isFrameCompiled)
22 {
23     frame_ = GetTopFrameFromFp(fp, isFrameCompiled);
24 }
25 
GetTopFrameFromFp(void * ptr,bool isFrameCompiled)26 StackWalkerBase::FrameVariant StackWalkerBase::GetTopFrameFromFp(void *ptr, bool isFrameCompiled)
27 {
28     if (isFrameCompiled) {
29         if (IsBoundaryFrame<FrameKind::INTERPRETER>(ptr)) {
30             auto bp = GetPrevFromBoundary<FrameKind::INTERPRETER>(ptr);
31             if (GetBoundaryFrameMethod<FrameKind::COMPILER>(bp) == BYPASS) {
32                 return CreateCFrame(GetPrevFromBoundary<FrameKind::COMPILER>(bp));
33             }
34             return CreateCFrame(GetPrevFromBoundary<FrameKind::INTERPRETER>(ptr));  // NOLINT
35         }
36         return CreateCFrame(reinterpret_cast<SlotType *>(ptr));
37     }
38     return reinterpret_cast<Frame *>(ptr);
39 }
40 
CreateCFrame(SlotType * ptr)41 StackWalkerBase::CFrameType StackWalkerBase::CreateCFrame(SlotType *ptr)
42 {
43     CFrameType cframe(ptr);
44     return cframe;
45 }
46 
NextFrame()47 void StackWalkerBase::NextFrame()
48 {
49     if (IsCFrame()) {
50         NextFromCFrame();
51     } else {
52         NextFromIFrame();
53     }
54 }
55 
CreateCFrameForC2IBridge(Frame * frame)56 StackWalkerBase::CFrameType StackWalkerBase::CreateCFrameForC2IBridge(Frame *frame)
57 {
58     auto prev = GetPrevFromBoundary<FrameKind::INTERPRETER>(frame);
59     ASSERT(GetBoundaryFrameMethod<FrameKind::COMPILER>(prev) != FrameBridgeKind::BYPASS);
60     return CreateCFrame(reinterpret_cast<SlotType *>(prev));
61 }
62 
NextFromCFrame()63 void StackWalkerBase::NextFromCFrame()
64 {
65     auto prev = GetCFrame().GetPrevFrame();
66     if (prev == nullptr) {
67         frame_ = nullptr;
68         return;
69     }
70     auto frameMethod = GetBoundaryFrameMethod<FrameKind::COMPILER>(prev);
71     switch (frameMethod) {
72         case FrameBridgeKind::INTERPRETER_TO_COMPILED_CODE: {
73             auto prevFrame = reinterpret_cast<Frame *>(GetPrevFromBoundary<FrameKind::COMPILER>(prev));
74             if (prevFrame != nullptr && IsBoundaryFrame<FrameKind::INTERPRETER>(prevFrame)) {
75                 frame_ = CreateCFrameForC2IBridge(prevFrame);
76                 break;
77             }
78             frame_ = reinterpret_cast<Frame *>(prevFrame);
79             break;
80         }
81         case FrameBridgeKind::BYPASS: {
82             auto prevFrame = reinterpret_cast<Frame *>(GetPrevFromBoundary<FrameKind::COMPILER>(prev));
83             if (prevFrame != nullptr && IsBoundaryFrame<FrameKind::INTERPRETER>(prevFrame)) {
84                 frame_ = CreateCFrameForC2IBridge(prevFrame);
85                 break;
86             }
87             frame_ = CreateCFrame(reinterpret_cast<SlotType *>(GetPrevFromBoundary<FrameKind::COMPILER>(prev)));
88             break;
89         }
90         default:
91             frame_ = CreateCFrame(reinterpret_cast<SlotType *>(prev));
92             break;
93     }
94 }
95 
NextFromIFrame()96 void StackWalkerBase::NextFromIFrame()
97 {
98     auto prev = GetIFrame()->GetPrevFrame();
99     if (prev == nullptr) {
100         frame_ = nullptr;
101         return;
102     }
103     if (IsBoundaryFrame<FrameKind::INTERPRETER>(prev)) {
104         auto bp = GetPrevFromBoundary<FrameKind::INTERPRETER>(prev);
105         if (GetBoundaryFrameMethod<FrameKind::COMPILER>(bp) == BYPASS) {
106             frame_ = CreateCFrame(GetPrevFromBoundary<FrameKind::COMPILER>(bp));
107         } else {
108             frame_ = CreateCFrameForC2IBridge(prev);
109         }
110     } else {
111         frame_ = reinterpret_cast<Frame *>(prev);
112     }
113 }
114 
115 }  // namespace ark
116