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