• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef PANDA_RUNTIME_INTERPRETER_STATE_H_
17 #define PANDA_RUNTIME_INTERPRETER_STATE_H_
18 
19 #include "libpandafile/bytecode_instruction-inl.h"
20 #include "runtime/interpreter/frame.h"
21 
22 #ifdef PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
23 #include "arch/global_regs.h"
24 #endif
25 
26 namespace panda::interpreter {
27 
28 template <class T>
29 class StateIface {
30 public:
StateIface(Frame * frame)31     ALWAYS_INLINE inline StateIface(Frame *frame) : acc_(frame->GetAcc()) {}
32 
GetInst()33     ALWAYS_INLINE inline BytecodeInstruction GetInst() const
34     {
35         return static_cast<const T *>(this)->GetInst();
36     }
37 
SetInst(BytecodeInstruction inst)38     ALWAYS_INLINE inline void SetInst(BytecodeInstruction inst)
39     {
40         static_cast<T *>(this)->SetInst(inst);
41     }
42 
GetFrame()43     ALWAYS_INLINE inline Frame *GetFrame() const
44     {
45         return static_cast<const T *>(this)->GetFrame();
46     }
47 
SetFrame(Frame * frame)48     ALWAYS_INLINE inline void SetFrame(Frame *frame)
49     {
50         static_cast<T *>(this)->SetFrame(frame);
51     }
52 
GetThread()53     ALWAYS_INLINE inline ManagedThread *GetThread() const
54     {
55         return static_cast<const T *>(this)->GetThread();
56     }
57 
SetThread(ManagedThread * thread)58     ALWAYS_INLINE inline void SetThread(ManagedThread *thread)
59     {
60         static_cast<T *>(this)->SetThread(thread);
61     }
62 
SaveState()63     ALWAYS_INLINE inline void SaveState()
64     {
65         static_cast<T *>(this)->SaveState();
66     }
67 
RestoreState()68     ALWAYS_INLINE inline void RestoreState()
69     {
70         static_cast<T *>(this)->RestoreState();
71     }
72 
GetAcc()73     ALWAYS_INLINE inline AccVRegister &GetAcc()
74     {
75         return acc_;
76     }
77 
GetAcc()78     ALWAYS_INLINE inline const AccVRegister &GetAcc() const
79     {
80         return acc_;
81     }
82 
83 private:
84     AccVRegister acc_;
85 };
86 
87 #ifdef PANDA_ENABLE_GLOBAL_REGISTER_VARIABLES
88 
89 class State : public StateIface<State> {
90 public:
State(ManagedThread * thread,const uint8_t * pc,Frame * frame)91     ALWAYS_INLINE inline State(ManagedThread *thread, const uint8_t *pc, Frame *frame) : StateIface(frame)
92     {
93         SetInst(BytecodeInstruction(pc));
94         SetFrame(frame);
95         SetThread(thread);
96     }
97     ~State() = default;
98     DEFAULT_MOVE_SEMANTIC(State);
99     DEFAULT_COPY_SEMANTIC(State);
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     }
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         frame_spill_ = GetFrame();
152         thread_spill_ = GetThread();
153     }
154 
RestoreState()155     ALWAYS_INLINE inline void RestoreState()
156     {
157         SetInst(inst_spill_);
158         GetAcc() = acc_spill_;
159         SetFrame(frame_spill_);
160         SetThread(thread_spill_);
161     }
162 
163 private:
164     BytecodeInstruction inst_spill_;
165     Frame *frame_spill_ {nullptr};
166     ManagedThread *thread_spill_ {nullptr};
167     Frame::VRegister acc_spill_;
168 };
169 
170 #else
171 
172 class State : public StateIface<State> {
173 public:
State(ManagedThread * thread,const uint8_t * pc,Frame * frame)174     ALWAYS_INLINE inline State(ManagedThread *thread, const uint8_t *pc, Frame *frame) : StateIface(frame)
175     {
176         SetInst(BytecodeInstruction(pc));
177         SetFrame(frame);
178         SetThread(thread);
179     }
180     ~State() = default;
181     DEFAULT_MOVE_SEMANTIC(State);
182     DEFAULT_COPY_SEMANTIC(State);
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_RUNTIME_INTERPRETER_STATE_H_
242