• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 || methodLiteral->IsShared()) {
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