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