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_RUNTIME_COMPILER_INTERFACE_H_ 16 #define PANDA_RUNTIME_COMPILER_INTERFACE_H_ 17 18 #include <cstdint> 19 #include <atomic> 20 21 #include "libpandabase/macros.h" 22 #include "libpandafile/file.h" 23 #include "runtime/interpreter/frame.h" 24 #include "runtime/thread_pool_queue.h" 25 26 namespace panda { 27 28 namespace coretypes { 29 class Array; 30 } // namespace coretypes 31 32 class PandaVM; 33 class CompilerTask : public TaskInterface { 34 public: 35 explicit CompilerTask(Method *method = nullptr, bool is_osr = false, PandaVM *vm = nullptr) method_(method)36 : method_(method), is_osr_(is_osr), vm_(vm) 37 { 38 } GetMethod()39 Method *GetMethod() const 40 { 41 return method_; 42 } IsOsr()43 bool IsOsr() const 44 { 45 return is_osr_; 46 } 47 IsEmpty()48 bool IsEmpty() const 49 { 50 return method_ == nullptr; 51 } 52 GetVM()53 PandaVM *GetVM() const 54 { 55 return vm_; 56 } 57 58 private: 59 Method *method_ {nullptr}; 60 bool is_osr_ {false}; 61 PandaVM *vm_ {nullptr}; 62 }; 63 64 class Method; 65 class CompilerInterface { 66 public: 67 enum class ReturnReason { RET_OK = 0, RET_DEOPTIMIZATION = 1 }; 68 69 class ExecState { 70 public: ExecState(const uint8_t * pc,Frame * frame,Method * callee,size_t num_args,const bool * sp_flag)71 ExecState(const uint8_t *pc, Frame *frame, Method *callee, size_t num_args, const bool *sp_flag) 72 : pc_(pc), frame_(frame), callee_method_(callee), num_args_(num_args), sp_flag_(sp_flag) 73 { 74 } 75 GetPc()76 const uint8_t *GetPc() const 77 { 78 return pc_; 79 } 80 SetPc(const uint8_t * pc)81 void SetPc(const uint8_t *pc) 82 { 83 pc_ = pc; 84 } 85 GetFrame()86 Frame *GetFrame() const 87 { 88 return frame_; 89 } 90 SetFrame(Frame * frame)91 void SetFrame(Frame *frame) 92 { 93 frame_ = frame; 94 } 95 GetNumArgs()96 size_t GetNumArgs() const 97 { 98 return num_args_; 99 } 100 GetAcc()101 const interpreter::VRegister &GetAcc() const 102 { 103 return acc_; 104 } 105 GetAcc()106 interpreter::VRegister &GetAcc() 107 { 108 return acc_; 109 } 110 SetAcc(const interpreter::VRegister & acc)111 void SetAcc(const interpreter::VRegister &acc) 112 { 113 acc_ = acc; 114 } 115 GetArg(size_t i)116 interpreter::VRegister &GetArg(size_t i) 117 { 118 return args_[i]; 119 } 120 SetArg(size_t i,const interpreter::VRegister & reg)121 void SetArg(size_t i, const interpreter::VRegister ®) 122 { 123 args_[i] = reg; 124 } 125 GetMethodInst()126 const uint8_t *GetMethodInst() 127 { 128 return frame_->GetInstrOffset(); 129 } 130 GetSPFlag()131 const bool *GetSPFlag() const 132 { 133 return sp_flag_; 134 } 135 GetCalleeMethod()136 Method *GetCalleeMethod() 137 { 138 return callee_method_; 139 } 140 GetSize(size_t nargs)141 static size_t GetSize(size_t nargs) 142 { 143 return sizeof(ExecState) + sizeof(interpreter::VRegister) * nargs; 144 } 145 GetExecStateAccOffset()146 static constexpr uint32_t GetExecStateAccOffset() 147 { 148 return MEMBER_OFFSET(ExecState, acc_); 149 } 150 GetExecStateArgsOffset()151 static constexpr uint32_t GetExecStateArgsOffset() 152 { 153 return MEMBER_OFFSET(ExecState, args_); 154 } 155 GetExecStatePcOffset()156 static constexpr uint32_t GetExecStatePcOffset() 157 { 158 return MEMBER_OFFSET(ExecState, pc_); 159 } 160 GetExecStateFrameOffset()161 static constexpr uint32_t GetExecStateFrameOffset() 162 { 163 return MEMBER_OFFSET(ExecState, frame_); 164 } 165 GetExecStateSPFlagAddrOffset()166 static constexpr uint32_t GetExecStateSPFlagAddrOffset() 167 { 168 return MEMBER_OFFSET(ExecState, sp_flag_); 169 } 170 GetCalleeMethodOffset()171 static constexpr uint32_t GetCalleeMethodOffset() 172 { 173 return MEMBER_OFFSET(ExecState, callee_method_); 174 } 175 176 private: 177 const uint8_t *pc_; 178 Frame *frame_; 179 Method *callee_method_; 180 size_t num_args_; 181 const bool *sp_flag_; 182 interpreter::VRegister acc_; 183 __extension__ interpreter::VRegister args_[0]; // NOLINT(modernize-avoid-c-arrays) 184 }; 185 186 CompilerInterface() = default; 187 188 using CompiledEntryPoint = ReturnReason (*)(ExecState *); 189 190 virtual bool CompileMethod(Method *method, uintptr_t bytecode_offset, bool osr) = 0; 191 192 virtual void Destroy() = 0; 193 194 virtual void PreZygoteFork() = 0; 195 196 virtual void PostZygoteFork() = 0; 197 198 virtual void *GetOsrCode(const Method *method) = 0; 199 200 virtual void SetOsrCode(const Method *method, void *ptr) = 0; 201 202 virtual void RemoveOsrCode(const Method *method) = 0; 203 204 virtual ~CompilerInterface() = default; 205 206 NO_COPY_SEMANTIC(CompilerInterface); 207 NO_MOVE_SEMANTIC(CompilerInterface); 208 }; 209 210 } // namespace panda 211 212 #endif // PANDA_RUNTIME_COMPILER_INTERFACE_H_ 213