• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 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 panda::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)92     ALWAYS_INLINE inline State(ManagedThread *thread, const uint8_t *pc, Frame *frame) : StateIface(frame)
93     {
94         SetInst(BytecodeInstruction(pc));
95         SetFrame(frame);
96         SetThread(thread);
97     }
98 
UpdateState(const uint8_t * pc,Frame * frame)99     ALWAYS_INLINE inline void UpdateState(const uint8_t *pc, Frame *frame)
100     {
101         SetInst(BytecodeInstruction(pc));
102         SetFrame(frame);
103     }
104 
GetInst()105     ALWAYS_INLINE inline BytecodeInstruction GetInst() const
106     {
107         return BytecodeInstruction(arch::regs::GetPc());
108     }
109 
SetInst(BytecodeInstruction inst)110     ALWAYS_INLINE inline void SetInst(BytecodeInstruction inst)
111     {
112         arch::regs::SetPc(inst.GetAddress());
113     }
114 
GetFrame()115     ALWAYS_INLINE inline Frame *GetFrame() const
116     {
117         return arch::regs::GetFrame();
118     }
119 
SetFrame(Frame * frame)120     ALWAYS_INLINE inline void SetFrame(Frame *frame)
121     {
122         arch::regs::SetFrame(frame);
123         arch::regs::SetMirrorFp(
124             reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(frame) + Frame::GetVregsOffset() + frame->GetSize()));
125     }
126 
GetDispatchTable()127     ALWAYS_INLINE inline const void *const *GetDispatchTable() const
128     {
129         return arch::regs::GetDispatchTable();
130     }
131 
SetDispatchTable(const void * const * dispatch_table)132     ALWAYS_INLINE inline void SetDispatchTable(const void *const *dispatch_table)
133     {
134         return arch::regs::SetDispatchTable(dispatch_table);
135     }
136 
GetThread()137     ALWAYS_INLINE inline ManagedThread *GetThread() const
138     {
139         return arch::regs::GetThread();
140     }
141 
SetThread(ManagedThread * thread)142     ALWAYS_INLINE inline void SetThread(ManagedThread *thread)
143     {
144         arch::regs::SetThread(thread);
145     }
146 
SaveState()147     ALWAYS_INLINE inline void SaveState()
148     {
149         inst_spill_ = GetInst();
150         acc_spill_ = GetAcc();
151         fp_spill_ = arch::regs::GetFp();
152         m_fp_spill_ = arch::regs::GetMirrorFp();
153         thread_spill_ = GetThread();
154     }
155 
RestoreState()156     ALWAYS_INLINE inline void RestoreState()
157     {
158         SetInst(inst_spill_);
159         GetAcc() = acc_spill_;
160         arch::regs::SetFp(fp_spill_);
161         arch::regs::SetMirrorFp(m_fp_spill_);
162         SetThread(thread_spill_);
163     }
164 
165 private:
166     BytecodeInstruction inst_spill_;
167     void *fp_spill_ {nullptr};
168     void *m_fp_spill_ {nullptr};
169     ManagedThread *thread_spill_ {nullptr};
170     AccVRegister acc_spill_;
171 };
172 
173 #else
174 
175 class State : public StateIface<State> {
176 public:
State(ManagedThread * thread,const uint8_t * pc,Frame * frame)177     ALWAYS_INLINE inline State(ManagedThread *thread, const uint8_t *pc, Frame *frame) : StateIface(frame)
178     {
179         SetInst(BytecodeInstruction(pc));
180         SetFrame(frame);
181         SetThread(thread);
182     }
183 
UpdateState(const uint8_t * pc,Frame * frame)184     ALWAYS_INLINE inline void UpdateState(const uint8_t *pc, Frame *frame)
185     {
186         SetInst(BytecodeInstruction(pc));
187         SetFrame(frame);
188     }
189 
GetInst()190     ALWAYS_INLINE inline BytecodeInstruction GetInst() const
191     {
192         return inst_;
193     }
194 
SetInst(BytecodeInstruction inst)195     ALWAYS_INLINE inline void SetInst(BytecodeInstruction inst)
196     {
197         inst_ = inst;
198     }
199 
GetFrame()200     ALWAYS_INLINE inline Frame *GetFrame() const
201     {
202         return frame_;
203     }
204 
SetFrame(Frame * frame)205     ALWAYS_INLINE inline void SetFrame(Frame *frame)
206     {
207         frame_ = frame;
208     }
209 
GetDispatchTable()210     ALWAYS_INLINE inline const void *const *GetDispatchTable() const
211     {
212         return nullptr;
213     }
214 
GetThread()215     ALWAYS_INLINE inline ManagedThread *GetThread() const
216     {
217         return thread_;
218     }
219 
SetThread(ManagedThread * thread)220     ALWAYS_INLINE inline void SetThread(ManagedThread *thread)
221     {
222         thread_ = thread;
223     }
224 
SetDispatchTable(const void * const * dispatch_table)225     void SetDispatchTable([[maybe_unused]] const void *const *dispatch_table) {}
226 
SaveState()227     void SaveState() {}
228 
RestoreState()229     void RestoreState() {}
230 
231 private:
232     BytecodeInstruction inst_;
233     Frame *frame_ {nullptr};
234     ManagedThread *thread_ {nullptr};
235 };
236 
237 #endif  // PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
238 
239 }  // namespace panda::interpreter
240 
241 #endif  // PANDA_INTERPRETER_VREGISTER_H_
242