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 ECMASCRIPT_COMPILER_FILE_GENERATORS_H 17 #define ECMASCRIPT_COMPILER_FILE_GENERATORS_H 18 19 #include "ecmascript/base/number_helper.h" 20 #include "ecmascript/compiler/aot_file/aot_file_manager.h" 21 #include "ecmascript/compiler/assembler_module.h" 22 #include "ecmascript/compiler/compiler_log.h" 23 #include "ecmascript/compiler/llvm_codegen.h" 24 #include "ecmascript/compiler/llvm_ir_builder.h" 25 26 namespace panda::ecmascript::kungfu { 27 class Module { 28 public: 29 Module() = default; Module(LLVMModule * module,LLVMAssembler * assembler)30 Module(LLVMModule *module, LLVMAssembler *assembler) 31 : llvmModule_(module), assembler_(assembler) 32 { 33 } 34 35 void CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, StubFileInfo &stubInfo, 36 uint32_t moduleIndex, const CompilerLog &log); 37 38 void CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, AnFileInfo &aotInfo, 39 uint32_t moduleIndex, const CompilerLog &log); 40 IsRelaSection(ElfSecName sec)41 bool IsRelaSection(ElfSecName sec) const 42 { 43 return sec == ElfSecName::RELATEXT || sec == ElfSecName::STRTAB || sec == ElfSecName::SYMTAB; 44 } 45 46 void CollectModuleSectionDes(ModuleSectionDes &moduleDes) const; 47 48 void CollectAnModuleSectionDes(ModuleSectionDes &moduleDes, uint64_t textOffset, 49 std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2CallsiteInfoVec, 50 std::vector<LLVMStackMapType::Pc2Deopt> &pc2DeoptVec) const; 51 52 void CollectStackMapDes(ModuleSectionDes &moduleDes) const; 53 54 void CollectAnStackMapDes(ModuleSectionDes& des, uint64_t textOffset, 55 std::vector<LLVMStackMapType::Pc2CallSiteInfo> &pc2CallsiteInfoVec, 56 std::vector<LLVMStackMapType::Pc2Deopt> &pc2DeoptVec) const; 57 58 uint32_t GetSectionSize(ElfSecName sec) const; 59 60 uintptr_t GetSectionAddr(ElfSecName sec) const; 61 GetMergedRODataAddrAndSize()62 std::tuple<uint64_t, uint32_t> GetMergedRODataAddrAndSize() const 63 { 64 uint64_t addr = base::MAX_UINT64_VALUE; 65 uint32_t size = 0; 66 UpdateRODataInfo(addr, size, ElfSecName::RODATA); 67 UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST4); 68 UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST8); 69 UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST16); 70 UpdateRODataInfo(addr, size, ElfSecName::RODATA_CST32); 71 return std::make_tuple(addr, size); 72 } 73 74 void RunAssembler(const CompilerLog &log, bool fastCompileMode); 75 76 void DisassemblerFunc(std::map<uintptr_t, std::string> &addr2name, uint64_t textOffset, const CompilerLog &log, 77 const MethodLogList &logList, std::ostringstream &codeStream); 78 79 void DestroyModule(); 80 GetModule()81 LLVMModule* GetModule() const 82 { 83 return llvmModule_; 84 } 85 86 private: GetTextAddr()87 uintptr_t GetTextAddr() const 88 { 89 return assembler_->GetSectionAddr(ElfSecName::TEXT); 90 } 91 GetTextSize()92 uint32_t GetTextSize() const 93 { 94 return assembler_->GetSectionSize(ElfSecName::TEXT); 95 } 96 UpdateRODataInfo(uint64_t & addr,uint32_t & size,ElfSecName sec)97 void UpdateRODataInfo(uint64_t &addr, uint32_t &size, ElfSecName sec) const 98 { 99 uint64_t curSectionAddr = GetSectionAddr(sec); 100 addr = ((curSectionAddr != 0) && (curSectionAddr < addr)) ? curSectionAddr : addr; 101 size += GetSectionSize(sec); 102 } 103 104 LLVMModule *llvmModule_ {nullptr}; 105 LLVMAssembler *assembler_ {nullptr}; 106 // record current module first function index in StubFileInfo/AnFileInfo 107 uint32_t startIndex_ {static_cast<uint32_t>(-1)}; 108 uint32_t funcCount_ {0}; 109 }; 110 111 class FileGenerator { 112 public: FileGenerator(const CompilerLog * log,const MethodLogList * logList)113 FileGenerator(const CompilerLog *log, const MethodLogList *logList) : log_(log), logList_(logList) {}; ~FileGenerator()114 virtual ~FileGenerator() 115 { 116 codeStream_.clear(); 117 codeStream_.str(""); 118 } 119 GetLog()120 const CompilerLog GetLog() const 121 { 122 return *log_; 123 } 124 PrintMergedCodeComment()125 void PrintMergedCodeComment() 126 { 127 LOG_COMPILER(INFO) << "\n" << codeStream_.str(); 128 } 129 130 protected: 131 std::vector<Module> modulePackage_ {}; 132 const CompilerLog *log_ {nullptr}; 133 const MethodLogList *logList_ {nullptr}; 134 std::ostringstream codeStream_; 135 RunLLVMAssembler()136 void RunLLVMAssembler() 137 { 138 for (auto m : modulePackage_) { 139 m.RunAssembler(*(log_), false); 140 } 141 } 142 DestroyModule()143 void DestroyModule() 144 { 145 for (auto m : modulePackage_) { 146 m.DestroyModule(); 147 } 148 } 149 150 void CollectStackMapDes(ModuleSectionDes& des); 151 }; 152 153 class AOTFileGenerator : public FileGenerator { 154 public: AOTFileGenerator(const CompilerLog * log,const MethodLogList * logList,EcmaVM * vm,const std::string & triple)155 AOTFileGenerator(const CompilerLog *log, const MethodLogList *logList, EcmaVM* vm, const std::string &triple) 156 : FileGenerator(log, logList), vm_(vm), cfg_(triple) {} 157 158 ~AOTFileGenerator() override = default; 159 160 Module* GetLatestModule(); 161 162 uint32_t GetModuleVecSize() const; 163 164 Module* AddModule(const std::string &name, const std::string &triple, LOptions option, bool logDebug); 165 166 void GenerateMethodToEntryIndexMap(); 167 168 void CompileLatestModuleThenDestroy(); 169 170 void DestroyCollectedStackMapInfo(); 171 172 void GenerateMergedStackmapSection(); 173 174 bool CreateDirIfNotExist(const std::string &filename); 175 176 bool SetFileModeAsDefault(const std::string &filename); 177 178 // save function for aot files containing normal func translated from JS/TS 179 void SaveAOTFile(const std::string &filename); 180 void SaveSnapshotFile(); 181 GetPc2StackMapVec()182 std::vector<LLVMStackMapType::Pc2CallSiteInfo> &GetPc2StackMapVec() 183 { 184 return pc2CallSiteInfoVec_; 185 } GetPc2Deopt()186 std::vector<LLVMStackMapType::Pc2Deopt> &GetPc2Deopt() 187 { 188 return pc2DeoptVec_; 189 } 190 191 private: 192 AnFileInfo aotInfo_; 193 std::vector<LLVMStackMapType::Pc2CallSiteInfo> pc2CallSiteInfoVec_; 194 std::vector<LLVMStackMapType::Pc2Deopt> pc2DeoptVec_; 195 EcmaVM* vm_; 196 CompilationConfig cfg_; 197 // MethodID->EntryIndex 198 std::map<uint32_t, uint32_t> methodToEntryIndexMap_ {}; 199 200 // collect aot component info 201 void CollectCodeInfo(Module *module, uint32_t moduleIdx); 202 203 uint64_t RollbackTextSize(Module *module); 204 }; 205 206 enum class StubFileKind { 207 BC, 208 COM, 209 BUILTIN 210 }; 211 212 class StubFileGenerator : public FileGenerator { 213 public: StubFileGenerator(const CompilerLog * log,const MethodLogList * logList,const std::string & triple)214 StubFileGenerator(const CompilerLog *log, const MethodLogList *logList, const std::string &triple) 215 : FileGenerator(log, logList), 216 cfg_(triple) 217 { 218 } 219 ~StubFileGenerator() override = default; 220 221 Module* AddModule(NativeAreaAllocator *allocator, const std::string &name, const std::string &triple, 222 LOptions option, bool logDebug, StubFileKind k); 223 DisassembleEachFunc(std::map<uintptr_t,std::string> & addr2name)224 void DisassembleEachFunc(std::map<uintptr_t, std::string> &addr2name) 225 { 226 for (auto m : modulePackage_) { 227 m.DisassemblerFunc(addr2name, 0, *(log_), *(logList_), codeStream_); 228 } 229 PrintMergedCodeComment(); 230 } 231 232 void DisassembleAsmStubs(std::map<uintptr_t, std::string> &addr2name); 233 // save function funcs for aot files containing stubs 234 void SaveStubFile(const std::string &filename); 235 236 private: 237 void RunAsmAssembler(); 238 void CollectAsmStubCodeInfo(std::map<uintptr_t, std::string> &addr2name, uint32_t bridgeModuleIdx); 239 void CollectCodeInfo(); 240 241 StubFileInfo stubInfo_; 242 AssemblerModule asmModule_; 243 CompilationConfig cfg_; 244 }; 245 } // namespace panda::ecmascript::kungfu 246 #endif // ECMASCRIPT_COMPILER_FILE_GENERATORS_H 247