• 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 #ifndef PANDA_INTERPRETER_STATE_H_
16 #define PANDA_INTERPRETER_STATE_H_
17 
18 #include "libpandafile/bytecode_instruction-inl.h"
19 #include "runtime/interpreter/acc_vregister.h"
20 #include "runtime/interpreter/acc_vregister-inl.h"
21 #include "runtime/interpreter/frame.h"
22 
23 #ifdef PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
24 #include "arch/global_regs.h"
25 #endif
26 
27 namespace ark::interpreter {
28 
29 template <class T>
30 class StateIface {
31 public:
StateIface(Frame * frame)32     ALWAYS_INLINE inline explicit StateIface(Frame *frame) : acc_(frame->GetAcc()) {}
33 
GetInst()34     ALWAYS_INLINE inline BytecodeInstruction GetInst() const
35     {
36         return static_cast<const T *>(this)->GetInst();
37     }
38 
SetInst(BytecodeInstruction inst)39     ALWAYS_INLINE inline void SetInst(BytecodeInstruction inst)
40     {
41         static_cast<T *>(this)->SetInst(inst);
42     }
43 
GetFrame()44     ALWAYS_INLINE inline Frame *GetFrame() const
45     {
46         return static_cast<const T *>(this)->GetFrame();
47     }
48 
SetFrame(Frame * frame)49     ALWAYS_INLINE inline void SetFrame(Frame *frame)
50     {
51         static_cast<T *>(this)->SetFrame(frame);
52     }
53 
GetThread()54     ALWAYS_INLINE inline ManagedThread *GetThread() const
55     {
56         return static_cast<const T *>(this)->GetThread();
57     }
58 
SetThread(ManagedThread * thread)59     ALWAYS_INLINE inline void SetThread(ManagedThread *thread)
60     {
61         static_cast<T *>(this)->SetThread(thread);
62     }
63 
SaveState()64     ALWAYS_INLINE inline void SaveState()
65     {
66         static_cast<T *>(this)->SaveState();
67     }
68 
RestoreState()69     ALWAYS_INLINE inline void RestoreState()
70     {
71         static_cast<T *>(this)->RestoreState();
72     }
73 
GetAcc()74     ALWAYS_INLINE inline AccVRegisterT &GetAcc()
75     {
76         return acc_;
77     }
78 
GetAcc()79     ALWAYS_INLINE inline const AccVRegisterT &GetAcc() const
80     {
81         return acc_;
82     }
83 
84 private:
85     AccVRegisterT acc_;
86 };
87 
88 #ifdef PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
89 
90 class State : public StateIface<State> {
91 public:
State(ManagedThread * thread,const uint8_t * pc,Frame * frame,const void * const * dispatchTable)92     ALWAYS_INLINE inline State(ManagedThread *thread, const uint8_t *pc, Frame *frame, const void *const *dispatchTable)
93         : StateIface(frame)
94     {
95         SetInst(BytecodeInstruction(pc));
96         SetFrame(frame);
97         SetThread(thread);
98         SetDispatchTable(dispatchTable);
99     }
100 
UpdateState(const uint8_t * pc,Frame * frame)101     ALWAYS_INLINE inline void UpdateState(const uint8_t *pc, Frame *frame)
102     {
103         SetInst(BytecodeInstruction(pc));
104         SetFrame(frame);
105     }
106 
GetInst()107     ALWAYS_INLINE inline BytecodeInstruction GetInst() const
108     {
109         return BytecodeInstruction(arch::regs::GetPc());
110     }
111 
SetInst(BytecodeInstruction inst)112     ALWAYS_INLINE inline void SetInst(BytecodeInstruction inst)
113     {
114         arch::regs::SetPc(inst.GetAddress());
115     }
116 
GetFrame()117     ALWAYS_INLINE inline Frame *GetFrame() const
118     {
119         return arch::regs::GetFrame();
120     }
121 
SetFrame(Frame * frame)122     ALWAYS_INLINE inline void SetFrame(Frame *frame)
123     {
124         arch::regs::SetFrame(frame);
125         arch::regs::SetMirrorFp(
126             reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(frame) + Frame::GetVregsOffset() + frame->GetSize()));
127     }
128 
GetDispatchTable()129     ALWAYS_INLINE inline const void *const *GetDispatchTable() const
130     {
131         return arch::regs::GetDispatchTable();
132     }
133 
SetDispatchTable(const void * const * dispatchTable)134     ALWAYS_INLINE inline void SetDispatchTable(const void *const *dispatchTable)
135     {
136         return arch::regs::SetDispatchTable(dispatchTable);
137     }
138 
GetThread()139     ALWAYS_INLINE inline ManagedThread *GetThread() const
140     {
141         return arch::regs::GetThread();
142     }
143 
SetThread(ManagedThread * thread)144     ALWAYS_INLINE inline void SetThread(ManagedThread *thread)
145     {
146         arch::regs::SetThread(thread);
147     }
148 
SaveState()149     ALWAYS_INLINE inline void SaveState()
150     {
151         instSpill_ = GetInst();
152         accSpill_ = GetAcc();
153         fpSpill_ = arch::regs::GetFp();
154         mFpSpill_ = arch::regs::GetMirrorFp();
155         threadSpill_ = GetThread();
156     }
157 
RestoreState()158     ALWAYS_INLINE inline void RestoreState()
159     {
160         SetInst(instSpill_);
161         GetAcc() = accSpill_;
162         arch::regs::SetFp(fpSpill_);
163         arch::regs::SetMirrorFp(mFpSpill_);
164         SetThread(threadSpill_);
165     }
166 
167 private:
168     BytecodeInstruction instSpill_;
169     void *fpSpill_ {nullptr};
170     void *mFpSpill_ {nullptr};
171     ManagedThread *threadSpill_ {nullptr};
172     AccVRegister accSpill_;
173 };
174 
175 #else
176 
177 class State : public StateIface<State> {
178 public:
State(ManagedThread * thread,const uint8_t * pc,Frame * frame,const void * const * dispatchTable)179     ALWAYS_INLINE inline State(ManagedThread *thread, const uint8_t *pc, Frame *frame, const void *const *dispatchTable)
180         : StateIface(frame)
181     {
182         SetInst(BytecodeInstruction(pc));
183         SetFrame(frame);
184         SetThread(thread);
185         SetDispatchTable(dispatchTable);
186     }
187 
UpdateState(const uint8_t * pc,Frame * frame)188     ALWAYS_INLINE inline void UpdateState(const uint8_t *pc, Frame *frame)
189     {
190         SetInst(BytecodeInstruction(pc));
191         SetFrame(frame);
192     }
193 
GetInst()194     ALWAYS_INLINE inline BytecodeInstruction GetInst() const
195     {
196         return inst_;
197     }
198 
SetInst(BytecodeInstruction inst)199     ALWAYS_INLINE inline void SetInst(BytecodeInstruction inst)
200     {
201         inst_ = inst;
202     }
203 
GetFrame()204     ALWAYS_INLINE inline Frame *GetFrame() const
205     {
206         return frame_;
207     }
208 
SetFrame(Frame * frame)209     ALWAYS_INLINE inline void SetFrame(Frame *frame)
210     {
211         frame_ = frame;
212     }
213 
GetDispatchTable()214     ALWAYS_INLINE inline const void *const *GetDispatchTable() const
215     {
216         return dispatchTable_;
217     }
218 
GetThread()219     ALWAYS_INLINE inline ManagedThread *GetThread() const
220     {
221         return thread_;
222     }
223 
SetThread(ManagedThread * thread)224     ALWAYS_INLINE inline void SetThread(ManagedThread *thread)
225     {
226         thread_ = thread;
227     }
228 
SetDispatchTable(const void * const * dispatchTable)229     void SetDispatchTable(const void *const *dispatchTable)
230     {
231         dispatchTable_ = dispatchTable;
232     }
233 
SaveState()234     void SaveState() {}
235 
RestoreState()236     void RestoreState() {}
237 
238 private:
239     BytecodeInstruction inst_;
240     Frame *frame_ {nullptr};
241     ManagedThread *thread_ {nullptr};
242     const void *const *dispatchTable_ {nullptr};
243 };
244 
245 #endif  // PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
246 
247 }  // namespace ark::interpreter
248 
249 #endif  // PANDA_INTERPRETER_VREGISTER_H_
250