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