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