• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H
16 #define ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H
17 
18 #include "ecmascript/compiler/bytecode_info_collector.h"
19 #include "ecmascript/compiler/compiler_log.h"
20 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
21 #include "ecmascript/ecma_vm.h"
22 #include "macros.h"
23 #include "ecmascript/compiler/aot_compilation_env.h"
24 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
25 #include "ecmascript/ohos/ohos_preload_app_info.h"
26 
27 namespace panda::ecmascript::kungfu {
28 class OhosPkgArgs;
29 using PGOProfilerDecoder = pgo::PGOProfilerDecoder;
30 
31 struct AbcFileInfo {
AbcFileInfoAbcFileInfo32     explicit AbcFileInfo(std::string extendedFilePath, std::shared_ptr<JSPandaFile> jsPandaFile)
33         : extendedFilePath_(extendedFilePath), jsPandaFile_(jsPandaFile) {}
34     ~AbcFileInfo() = default;
35 
36     std::string extendedFilePath_;
37     std::shared_ptr<JSPandaFile> jsPandaFile_;
38 };
39 
40 class CallMethodFlagMap {
41 public:
CallMethodFlagMap()42     CallMethodFlagMap() {}
43     void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall);
44     bool IsFastCall(CString fileDesc, uint32_t methodOffset) const;
45     void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile);
46     bool IsAotCompile(CString fileDesc, uint32_t methodOffset) const;
47     void SetIsJitCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile);
48     bool IsJitCompile(CString fileDesc, uint32_t methodOffset) const;
49 private:
50     std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsFastCall_ {};
51     std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsAotCompile_ {};
52     std::map<std::pair<CString, uint32_t>, bool> abcIdMethodIdToIsJitCompile_ {};
53 };
54 
55 struct CompilationOptions {
56     explicit CompilationOptions(JSRuntimeOptions &runtimeOptions);
57     void ParseOption(const std::string &option, std::map<std::string, std::vector<std::string>> &optionMap) const;
58     std::vector<std::string> SplitString(const std::string &str, const char ch) const;
59     std::string triple_;
60     std::string outputFileName_;
61     size_t optLevel_;
62     size_t relocMode_;
63     std::string logOption_;
64     std::string logMethodsList_;
65     bool compilerLogTime_;
66     bool deviceIsScreenOff_;
67     size_t maxAotMethodSize_;
68     size_t maxMethodsInModule_;
69     uint32_t hotnessThreshold_;
70     int32_t deviceThermalLevel_ {0};
71     std::string profilerIn_;
72     std::string optBCRange_;
73     bool needMerge_ {false};
74     bool isEnableArrayBoundsCheckElimination_ {true};
75     bool isEnableTypeLowering_ {true};
76     bool isEnableEarlyElimination_ {true};
77     bool isEnableLaterElimination_ {true};
78     bool isEnableValueNumbering_ {true};
79     bool isEnableOptInlining_ {true};
80     bool isEnableEmptyCatchFunction_ {false};
81     bool isEnableOptString_ {true};
82     bool isEnableOptPGOType_ {true};
83     bool isEnableOptTrackField_ {true};
84     bool isEnableOptLoopPeeling_ {true};
85     bool isEnableOptLoopInvariantCodeMotion_ {false};
86     bool isEnableOptConstantFolding_ {true};
87     bool isEnableLexenvSpecialization_ {false};
88     bool isEnableNativeInline_ {true};
89     bool isEnablePGOHCRLowering_ {false};
90     bool isEnableLoweringBuiltin_ {true};
91     bool isEnableOptBranchProfiling_ {true};
92     bool isEnableEscapeAnalysis_ {false};
93     bool isEnableInductionVariableAnalysis_ {false};
94     bool isEnableVerifierPass_ {true};
95     bool isEnableBaselinePgo_ {false};
96     std::map<std::string, std::vector<std::string>> optionSelectMethods_;
97     std::map<std::string, std::vector<std::string>> optionSkipMethods_;
98 };
99 
100 class AotCompilerPreprocessor {
101 public:
AotCompilerPreprocessor(EcmaVM * vm,JSRuntimeOptions & runtimeOptions,std::map<std::string,std::shared_ptr<OhosPkgArgs>> & pkgsArgs,PGOProfilerDecoder & profilerDecoder,arg_list_t & pandaFileNames)102     AotCompilerPreprocessor(EcmaVM *vm, JSRuntimeOptions &runtimeOptions,
103                             std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs,
104                             PGOProfilerDecoder &profilerDecoder, arg_list_t &pandaFileNames)
105         : vm_(vm),
106           runtimeOptions_(runtimeOptions),
107           pkgsArgs_(pkgsArgs),
108           profilerDecoder_(profilerDecoder),
109           pandaFileNames_(pandaFileNames),
110           aotCompilationEnv_(vm) {};
111 
112     ~AotCompilerPreprocessor() = default;
113 
114     bool HandleTargetCompilerMode(CompilationOptions &cOptions);
115 
116     bool HandlePandaFileNames(const int argc, const char **argv);
117 
118     void AOTInitialize();
119 
120     void DoPreAnalysis(CompilationOptions &cOptions);
121 
122     void AnalyzeGraphs(JSPandaFile *jsPandaFile, BytecodeInfoCollector &collector, CompilationOptions &cOptions);
123 
124     void AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions, BytecodeInfoCollector &collector,
125                       MethodLiteral *methodLiteral, MethodPcInfo &methodPCInfo);
126 
127     void Process(CompilationOptions &cOptions);
128 
129     uint32_t GenerateAbcFileInfos();
130 
131     void GenerateBytecodeInfoCollectors(const CompilationOptions &cOptions);
132 
133     bool HandleMergedPgoFile(uint32_t checksum);
134 
135     void GeneratePGOTypes();
136 
137     void SnapshotInitialize();
138 
139     bool FilterOption(const std::map<std::string, std::vector<std::string>> &optionMap,
140                       const std::string &recordName, const std::string &methodName) const;
141 
142     bool IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo,
143                       const CString &recordName, const MethodLiteral *methodLiteral,
144                       const MethodPcInfo &methodPCInfo, const std::string &methodName,
145                       CompilationOptions &cOptions) const;
146 
147     void GenerateMethodMap(CompilationOptions &cOptions);
148 
149     bool MethodHasTryCatch(const JSPandaFile *jsPandaFile, const MethodLiteral *methodLiteral) const;
150 
151     bool HasSkipMethod(const CVector<std::string> &methodList, const std::string &methodName) const;
152 
153     bool ForbidenRebuildAOT(std::string &fileName) const;
154 
155     bool HasPreloadAotFile() const;
156 
157     bool HasExistsAOTFiles(CompilationOptions &cOptions) const;
158 
SetIsFastCall(CString fileDesc,uint32_t methodOffset,bool isFastCall)159     void SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall)
160     {
161         callMethodFlagMap_.SetIsFastCall(fileDesc, methodOffset, isFastCall);
162     }
163 
IsFastCall(CString fileDesc,uint32_t methodOffset)164     bool IsFastCall(CString fileDesc, uint32_t methodOffset)
165     {
166         return callMethodFlagMap_.IsFastCall(fileDesc, methodOffset);
167     }
168 
SetIsAotCompile(CString fileDesc,uint32_t methodOffset,bool isAotCompile)169     void SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile)
170     {
171         callMethodFlagMap_.SetIsAotCompile(fileDesc, methodOffset, isAotCompile);
172     }
173 
GetIsAotCompile(CString fileDesc,uint32_t methodOffset)174     bool GetIsAotCompile(CString fileDesc, uint32_t methodOffset)
175     {
176         return callMethodFlagMap_.IsAotCompile(fileDesc, methodOffset);
177     }
178 
179     std::string GetMainPkgArgsAppSignature() const;
180 
GetCompilerResult()181     bool GetCompilerResult()
182     {
183         // The size of fileInfos is not equal to pandaFiles size, set compiler result to false
184         return fileInfos_.size() == pandaFileNames_.size();
185     }
186 
GetAbcFileInfo()187     const CVector<AbcFileInfo>& GetAbcFileInfo() const
188     {
189         return fileInfos_;
190     }
191 
GetBcInfoCollectors()192     const CVector<std::unique_ptr<BytecodeInfoCollector>>& GetBcInfoCollectors() const
193     {
194         return bcInfoCollectors_;
195     }
196 
GetMainPkgArgs()197     std::shared_ptr<OhosPkgArgs> GetMainPkgArgs() const
198     {
199         if (pkgsArgs_.empty()) {
200             return nullptr;
201         }
202         return pkgsArgs_.at(mainPkgName_);
203     }
204 
GetMainPkgName()205     std::string GetMainPkgName() const
206     {
207         return mainPkgName_;
208     }
209 
GetPkgsArgs()210     const std::map<std::string, std::shared_ptr<OhosPkgArgs>> &GetPkgsArgs() const
211     {
212         return pkgsArgs_;
213     }
GetCallMethodFlagMap()214     CallMethodFlagMap *GetCallMethodFlagMap()
215     {
216         return &callMethodFlagMap_;
217     }
218 
GetHelper()219     static std::string GetHelper()
220     {
221         std::string str;
222         str.append(COMPILER_HELP_HEAD_MSG);
223         str.append(HELP_OPTION_MSG);
224         return str;
225     }
226 
227 private:
228     NO_COPY_SEMANTIC(AotCompilerPreprocessor);
229     NO_MOVE_SEMANTIC(AotCompilerPreprocessor);
230     void HandleTargetModeInfo(CompilationOptions &cOptions);
231 
232     std::shared_ptr<JSPandaFile> CreateAndVerifyJSPandaFile(const std::string &fileName);
233 
234     void ResolveModule(const JSPandaFile *jsPandaFile, const std::string &fileName);
235 
OutCompiledMethodsRange()236     bool OutCompiledMethodsRange() const
237     {
238         static uint32_t compiledMethodsCount = 0;
239         ++compiledMethodsCount;
240         return compiledMethodsCount < runtimeOptions_.GetCompilerMethodsRange().first ||
241             runtimeOptions_.GetCompilerMethodsRange().second <= compiledMethodsCount;
242     }
243 
244     EcmaVM *vm_;
245     JSRuntimeOptions &runtimeOptions_;
246     std::map<std::string, std::shared_ptr<OhosPkgArgs>> &pkgsArgs_;
247     std::string mainPkgName_;
248     PGOProfilerDecoder &profilerDecoder_;
249     arg_list_t &pandaFileNames_;
250     CVector<AbcFileInfo> fileInfos_;
251     CVector<std::unique_ptr<BytecodeInfoCollector>> bcInfoCollectors_;
252     CallMethodFlagMap callMethodFlagMap_;
253     AOTCompilationEnv aotCompilationEnv_;
254     CVector<std::string> emptyCatchBBMethods_;
255     CVector<std::string> irreducibleMethods_;
256     friend class OhosPkgArgs;
257 };
258 }  // namespace panda::ecmascript::kungfu
259 #endif  // ECMASCRIPT_COMPILER_AOT_COMPILER_PREPROCESSOR_H
260