1 /* 2 * Copyright (c) 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 16 #ifndef ECMASCRIPT_COMPILER_COMPILATION_DRIVER_H 17 #define ECMASCRIPT_COMPILER_COMPILATION_DRIVER_H 18 19 #include "ecmascript/compiler/aot_compiler_preprocessor.h" 20 #include "ecmascript/compiler/bytecode_info_collector.h" 21 #include "ecmascript/js_function.h" 22 23 namespace panda::ecmascript::kungfu { 24 class AOTFileGenerator; 25 class CompilerLog; 26 struct LOptions; 27 class Module; 28 class CompilationDriver { 29 public: 30 CompilationDriver(PGOProfilerDecoder &profilerDecoder, 31 BytecodeInfoCollector* collector, 32 AOTFileGenerator *fileGenerator, 33 const std::string &fileName, 34 const std::string &triple, 35 LOptions *lOptions, 36 CompilerLog *log, 37 bool outputAsm, 38 size_t maxMethodsInModule); 39 ~CompilationDriver() = default; 40 41 NO_COPY_SEMANTIC(CompilationDriver); 42 NO_MOVE_SEMANTIC(CompilationDriver); 43 IsPGOLoaded()44 bool IsPGOLoaded() const 45 { 46 return pfDecoder_.IsLoaded(); 47 } 48 49 template <class Callback> CompileMethod(const Callback & cb,const CString & recordName,const std::string & methodName,MethodLiteral * methodLiteral,uint32_t methodOffset,const MethodPcInfo & methodPcInfo,MethodInfo & methodInfo)50 void CompileMethod(const Callback &cb, 51 const CString &recordName, 52 const std::string &methodName, 53 MethodLiteral *methodLiteral, 54 uint32_t methodOffset, 55 const MethodPcInfo &methodPcInfo, 56 MethodInfo &methodInfo) 57 { 58 Module *module = GetModule(); 59 cb(recordName, methodName, methodLiteral, methodOffset, 60 methodPcInfo, methodInfo, module); 61 IncCompiledMethod(); 62 CompileModuleThenDestroyIfNeeded(false); 63 } 64 65 template <class Callback> Run(const CallMethodFlagMap & callMethonFlagMap,const Callback & cb)66 void Run(const CallMethodFlagMap &callMethonFlagMap, const Callback &cb) 67 { 68 SetCurrentCompilationFile(); 69 const auto &methodPcInfos = bytecodeInfo_.GetMethodPcInfos(); 70 for (auto &[methodId, methodInfo] : bytecodeInfo_.GetMethodList()) { 71 bytecodeInfo_.AddMethodOffsetToRecordName(methodId, methodInfo.GetRecordName()); 72 auto &methodPcInfo = methodPcInfos[methodInfo.GetMethodPcInfoIndex()]; 73 auto methodLiteral = jsPandaFile_->FindMethodLiteral(methodId); 74 if (methodLiteral == nullptr) { 75 continue; 76 } 77 const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile_, methodLiteral->GetMethodId())); 78 if (!callMethonFlagMap.IsAotCompile(jsPandaFile_->GetNormalizedFileDesc(), 79 methodLiteral->GetMethodId().GetOffset())) { 80 bytecodeInfo_.AddSkippedMethod(methodId); 81 } else { 82 if (!methodInfo.IsCompiled()) { 83 methodInfo.SetIsCompiled(true); 84 CompileMethod(cb, methodInfo.GetRecordName(), methodName, methodLiteral, 85 methodId, methodPcInfo, methodInfo); 86 } 87 } 88 } 89 CompileLastModuleThenDestroyIfNeeded(); 90 StoreConstantPoolInfo(); 91 } 92 93 void FetchPGOMismatchResult(); 94 GetCompilerMethodCount()95 uint32_t GetCompilerMethodCount() const 96 { 97 return compiledMethodCnt_; 98 } 99 protected: 100 // add maxMethodsInModule_ functions in a module and when a module is 101 // full(maxMethodsInModule_ functions have been put into) or the module is the last module, 102 // compile it and the destroy it. 103 Module *GetModule(); 104 105 void IncCompiledMethod(); 106 107 bool IsCurModuleFull() const; 108 109 void CompileModuleThenDestroyIfNeeded(bool isJit = false); 110 111 void CompileLastModuleThenDestroyIfNeeded(); 112 113 std::vector<std::string> SplitString(const std::string &str, const char ch) const; 114 115 void SetCurrentCompilationFile() const; 116 117 void StoreConstantPoolInfo() const; 118 119 CompilationEnv *compilationEnv_ {nullptr}; 120 const JSPandaFile *jsPandaFile_ {nullptr}; 121 PGOProfilerDecoder &pfDecoder_; 122 BytecodeInfoCollector* collector_; 123 BCInfo &bytecodeInfo_; 124 uint32_t compiledMethodCnt_ {0}; 125 AOTFileGenerator *fileGenerator_ {nullptr}; 126 std::string fileName_ {}; 127 std::string triple_ {}; 128 LOptions *lOptions_ {nullptr}; 129 CompilerLog *log_ {nullptr}; 130 bool outputAsm_ {false}; 131 size_t maxMethodsInModule_ {0}; 132 }; 133 134 class JitCompilationDriver : public CompilationDriver { 135 public: JitCompilationDriver(PGOProfilerDecoder & profilerDecoder,BytecodeInfoCollector * collector,AOTFileGenerator * fileGenerator,const std::string & fileName,const std::string & triple,LOptions * lOptions,CompilerLog * log,bool outputAsm,size_t maxMethodsInModule)136 JitCompilationDriver(PGOProfilerDecoder &profilerDecoder, 137 BytecodeInfoCollector* collector, 138 AOTFileGenerator *fileGenerator, 139 const std::string &fileName, 140 const std::string &triple, 141 LOptions *lOptions, 142 CompilerLog *log, 143 bool outputAsm, 144 size_t maxMethodsInModule) 145 : CompilationDriver(profilerDecoder, collector, fileGenerator, fileName, triple, lOptions, 146 log, outputAsm, maxMethodsInModule) { }; 147 ~JitCompilationDriver() = default; 148 bool RunCg(); 149 Module *GetModule(); 150 151 template <class Callback> CompileMethod(const JSPandaFile * jsPandaFile,MethodLiteral * methodLiteral,JSHandle<ProfileTypeInfo> & profileTypeInfo,const uint8_t * pcStart,const panda_file::File::Header * header,ApEntityId abcId,const Callback & cb)152 bool CompileMethod(const JSPandaFile *jsPandaFile, MethodLiteral *methodLiteral, 153 JSHandle<ProfileTypeInfo> &profileTypeInfo, const uint8_t *pcStart, 154 const panda_file::File::Header *header, ApEntityId abcId, const Callback &cb) 155 { 156 SetCurrentCompilationFile(); 157 if (methodLiteral == nullptr) { 158 return false; 159 } 160 const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, methodLiteral->GetMethodId())); 161 162 auto &methodList = bytecodeInfo_.GetMethodList(); 163 const auto &methodPcInfos = bytecodeInfo_.GetMethodPcInfos(); 164 auto &methodInfo = methodList.at(methodLiteral->GetMethodId().GetOffset()); 165 166 auto &methodPcInfo = methodPcInfos[methodInfo.GetMethodPcInfoIndex()]; 167 auto methodOffset = methodLiteral->GetMethodId().GetOffset(); 168 bytecodeInfo_.EraseSkippedMethod(methodOffset); 169 170 Module *module = GetModule(); 171 return cb(bytecodeInfo_.GetRecordNameWithIndex(0), methodName, methodLiteral, profileTypeInfo, 172 methodOffset, methodPcInfo, methodInfo, module, pcStart, header, abcId); 173 } 174 }; 175 } // namespace panda::ecmascript::kungfu 176 #endif // ECMASCRIPT_COMPILER_COMPILATION_DRIVER_H 177