• 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 #include "ecmascript/compiler/aot_compiler_preprocessor.h"
16 
17 #include "ecmascript/compiler/bytecode_circuit_builder.h"
18 #include "ecmascript/compiler/pgo_type/pgo_type_parser.h"
19 #include "ecmascript/compiler/pass_manager.h"
20 #include "ecmascript/module/module_resolver.h"
21 #include "ecmascript/ohos/ohos_pgo_processor.h"
22 
23 namespace panda::ecmascript::kungfu {
24 
25 using PGOProfilerManager = pgo::PGOProfilerManager;
26 
CompilationOptions(JSRuntimeOptions & runtimeOptions)27 CompilationOptions::CompilationOptions(JSRuntimeOptions &runtimeOptions)
28 {
29     triple_ = runtimeOptions.GetTargetTriple();
30     if (runtimeOptions.GetAOTOutputFile().empty()) {
31         runtimeOptions.SetAOTOutputFile("aot_file");
32     }
33     outputFileName_ = runtimeOptions.GetAOTOutputFile();
34     optLevel_ = runtimeOptions.GetOptLevel();
35     relocMode_ = runtimeOptions.GetRelocMode();
36     logOption_ = runtimeOptions.GetCompilerLogOption();
37     logMethodsList_ = runtimeOptions.GetMethodsListForLog();
38     compilerLogTime_ = runtimeOptions.IsEnableCompilerLogTime();
39     deviceIsScreenOff_ = runtimeOptions.GetDeviceState();
40     deviceThermalLevel_ = runtimeOptions.GetThermalLevel();
41     maxAotMethodSize_ = runtimeOptions.GetMaxAotMethodSize();
42     maxMethodsInModule_ = runtimeOptions.GetCompilerModuleMethods();
43     hotnessThreshold_ = runtimeOptions.GetPGOHotnessThreshold();
44     profilerIn_ = std::string(runtimeOptions.GetPGOProfilerPath());
45     needMerge_ = false;
46     isEnableArrayBoundsCheckElimination_ = runtimeOptions.IsEnableArrayBoundsCheckElimination();
47     isEnableTypeLowering_ = runtimeOptions.IsEnableTypeLowering();
48     isEnableEarlyElimination_ = runtimeOptions.IsEnableEarlyElimination();
49     isEnableLaterElimination_ = runtimeOptions.IsEnableLaterElimination();
50     isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
51     isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
52     isEnableOptString_ = runtimeOptions.IsEnableOptString();
53     isEnableOptPGOType_ = runtimeOptions.IsEnableOptPGOType();
54     isEnableOptTrackField_ = runtimeOptions.IsEnableOptTrackField();
55     isEnableOptLoopPeeling_ = runtimeOptions.IsEnableOptLoopPeeling();
56     isEnableOptLoopInvariantCodeMotion_ = runtimeOptions.IsEnableOptLoopInvariantCodeMotion();
57     isEnableOptConstantFolding_ = runtimeOptions.IsEnableOptConstantFolding();
58     isEnableLazyDeopt_ = runtimeOptions.IsEnableAotLazyDeopt();
59     isEnableLexenvSpecialization_ = runtimeOptions.IsEnableLexenvSpecialization();
60     isEnableNativeInline_ = runtimeOptions.IsEnableNativeInline();
61     isEnableLoweringBuiltin_ = runtimeOptions.IsEnableLoweringBuiltin();
62     isEnableOptBranchProfiling_ = runtimeOptions.IsEnableBranchProfiling();
63     optBCRange_ = runtimeOptions.GetOptCodeRange();
64     isEnableEscapeAnalysis_ = runtimeOptions.IsEnableEscapeAnalysis();
65     isEnableInductionVariableAnalysis_ = runtimeOptions.IsEnableInductionVariableAnalysis();
66     isEnableVerifierPass_ = !runtimeOptions.IsTargetCompilerMode();
67     isEnableBaselinePgo_ = runtimeOptions.IsEnableBaselinePgo();
68     isEnableMergePoly_ = runtimeOptions.IsEnableMergePoly();
69     std::string optionSelectMethods = runtimeOptions.GetCompilerSelectMethods();
70     std::string optionSkipMethods = runtimeOptions.GetCompilerSkipMethods();
71     if (!optionSelectMethods.empty() && !optionSkipMethods.empty()) {
72         LOG_COMPILER(FATAL) <<
73             "--compiler-select-methods and --compiler-skip-methods should not be set at the same time";
74     }
75     if (!optionSelectMethods.empty()) {
76         ParseOption(optionSelectMethods, optionSelectMethods_);
77     }
78     if (!optionSkipMethods.empty()) {
79         ParseOption(optionSkipMethods, optionSkipMethods_);
80     }
81     anFileMaxByteSize_ = runtimeOptions.GetCompilerAnFileMaxByteSize();
82 }
83 
SplitString(const std::string & str,const char ch) const84 std::vector<std::string> CompilationOptions::SplitString(const std::string &str, const char ch) const
85 {
86     std::vector<std::string> vec {};
87     std::istringstream sstr(str.c_str());
88     std::string split;
89     while (getline(sstr, split, ch)) {
90         vec.emplace_back(split);
91     }
92     return vec;
93 }
94 
ParseOption(const std::string & option,std::map<std::string,std::vector<std::string>> & optionMap) const95 void CompilationOptions::ParseOption(const std::string &option,
96     std::map<std::string, std::vector<std::string>> &optionMap) const
97 {
98     const char colon = ':';
99     const char comma = ',';
100     std::string str = option;
101     size_t posColon = 0;
102     size_t posComma = 0;
103     do {
104         posColon = str.find_last_of(colon);
105         std::string methodNameList = str.substr(posColon + 1, str.size());
106         std::vector<std::string> methodNameVec = SplitString(methodNameList, comma);
107         str = str.substr(0, posColon);
108         posComma = str.find_last_of(comma);
109         std::string recordName = str.substr(posComma + 1, str.size());
110         str = str.substr(0, posComma);
111         optionMap[recordName] = methodNameVec;
112     } while (posComma != std::string::npos);
113 }
114 
HandleTargetCompilerMode(CompilationOptions & cOptions)115 bool AotCompilerPreprocessor::HandleTargetCompilerMode(CompilationOptions &cOptions)
116 {
117     if (runtimeOptions_.IsTargetCompilerMode()) {
118         if (!OhosPkgArgs::ParseArgs(*this, cOptions)) {
119             LOG_COMPILER(ERROR) << GetHelper();
120             LOG_COMPILER(ERROR) << "Parse pkg info failed, exit.";
121             return false;
122         }
123         const auto& mainPkgArgs = GetMainPkgArgs();
124         if (!mainPkgArgs) {
125             LOG_COMPILER(ERROR) << "No main pkg args found, exit";
126             return false;
127         }
128         if (!OhosPgoProcessor::MergeAndRemoveRuntimeAp(cOptions, mainPkgArgs)) {
129             LOG_COMPILER(ERROR) << "Fusion runtime ap failed, exit";
130             return false;
131         }
132         HandleTargetModeInfo(cOptions);
133     }
134     return true;
135 }
136 
HandleTargetModeInfo(CompilationOptions & cOptions)137 void AotCompilerPreprocessor::HandleTargetModeInfo(CompilationOptions &cOptions)
138 {
139     JSRuntimeOptions &vmOpt = vm_->GetJSOptions();
140     ASSERT(vmOpt.IsTargetCompilerMode());
141     // target need fast compiler mode
142     vmOpt.SetFastAOTCompileMode(true);
143     vmOpt.SetOptLevel(DEFAULT_OPT_LEVEL);
144     cOptions.optLevel_ = DEFAULT_OPT_LEVEL;
145     cOptions.isEnableOptTrackField_ = false;
146     cOptions.isEnableLoweringBuiltin_ = false;
147 }
148 
MethodHasTryCatch(const JSPandaFile * jsPandaFile,const MethodLiteral * methodLiteral) const149 bool AotCompilerPreprocessor::MethodHasTryCatch(const JSPandaFile *jsPandaFile,
150                                                 const MethodLiteral *methodLiteral) const
151 {
152     if (jsPandaFile == nullptr || methodLiteral == nullptr) {
153         return false;
154     }
155     auto pf = jsPandaFile->GetPandaFile();
156     panda_file::MethodDataAccessor mda(*pf, methodLiteral->GetMethodId());
157     panda_file::CodeDataAccessor cda(*pf, mda.GetCodeId().value());
158     return cda.GetTriesSize() != 0;
159 }
160 
HandlePandaFileNames(const int argc,const char ** argv)161 bool AotCompilerPreprocessor::HandlePandaFileNames(const int argc, const char **argv)
162 {
163     if (runtimeOptions_.GetCompilerPkgJsonInfo().empty() || pkgsArgs_.empty()) {
164         // if no pkgArgs, last param must be abc file
165         std::string files = argv[argc - 1];
166         if (!base::StringHelper::EndsWith(files, ".abc")) {
167             LOG_COMPILER(ERROR) << "The last argument must be abc file" << std::endl;
168             LOG_COMPILER(ERROR) << GetHelper();
169             return false;
170         }
171         std::string delimiter = GetFileDelimiter();
172         pandaFileNames_ = base::StringHelper::SplitString(files, delimiter);
173     }
174     return true;
175 }
176 
AOTInitialize()177 void AotCompilerPreprocessor::AOTInitialize()
178 {
179     BytecodeStubCSigns::Initialize();
180     CommonStubCSigns::Initialize();
181     BuiltinsStubCSigns::Initialize();
182     RuntimeStubCSigns::Initialize();
183 }
184 
Process(CompilationOptions & cOptions)185 void AotCompilerPreprocessor::Process(CompilationOptions &cOptions)
186 {
187     GenerateBytecodeInfoCollectors(cOptions);
188     GeneratePGOTypes();
189     SnapshotInitialize();
190     DoPreAnalysis(cOptions);
191     GenerateMethodMap(cOptions);
192 }
193 
DoPreAnalysis(CompilationOptions & cOptions)194 void AotCompilerPreprocessor::DoPreAnalysis(CompilationOptions &cOptions)
195 {
196     for (uint32_t i = 0 ; i < fileInfos_.size(); ++i) {
197         JSPandaFile *jsPandaFile = fileInfos_[i].jsPandaFile_.get();
198         auto &collector = *bcInfoCollectors_[i];
199         AnalyzeGraphs(jsPandaFile, collector, cOptions);
200     }
201 }
202 
AnalyzeGraphs(JSPandaFile * jsPandaFile,BytecodeInfoCollector & collector,CompilationOptions & cOptions)203 void AotCompilerPreprocessor::AnalyzeGraphs(JSPandaFile *jsPandaFile,
204                                             BytecodeInfoCollector &collector, CompilationOptions &cOptions)
205 {
206     if (jsPandaFile == nullptr) {
207         return;
208     }
209     auto &bytecodeInfo = collector.GetBytecodeInfo();
210     auto &methodPcInfos = bytecodeInfo.GetMethodPcInfos();
211     for (auto &[methodId, methodInfo] : bytecodeInfo.GetMethodList()) {
212         auto methodLiteral = jsPandaFile->FindMethodLiteral(methodId);
213         auto &methodPcInfo = methodPcInfos[methodInfo.GetMethodPcInfoIndex()];
214         if (MethodHasTryCatch(jsPandaFile, methodLiteral)) {
215             AnalyzeGraph(bytecodeInfo, cOptions, collector, methodLiteral, methodPcInfo);
216         }
217     }
218 }
219 
AnalyzeGraph(BCInfo & bytecodeInfo,CompilationOptions & cOptions,BytecodeInfoCollector & collector,MethodLiteral * methodLiteral,MethodPcInfo & methodPCInfo)220 void AotCompilerPreprocessor::AnalyzeGraph(BCInfo &bytecodeInfo, CompilationOptions &cOptions,
221                                            BytecodeInfoCollector &collector, MethodLiteral *methodLiteral,
222                                            MethodPcInfo &methodPCInfo)
223 {
224     if (methodLiteral == nullptr) {
225         return;
226     }
227     AotMethodLogList logList(cOptions.logMethodsList_);
228     AOTCompilationEnv aotCompilationEnv(vm_);
229     CompilerLog log(cOptions.logOption_);
230     AOTFileGenerator generator(&log, &logList, &aotCompilationEnv, cOptions.triple_, false);
231     PGOProfilerDecoder profilerDecoder;
232     LOptions lOptions = LOptions(DEFAULT_OPT_LEVEL, FPFlag::RESERVE_FP, DEFAULT_REL_MODE);
233     Module *m = generator.AddModule("", cOptions.triple_, lOptions, false);
234     PassContext ctx(cOptions.triple_, &log, &collector, m->GetModule(), &profilerDecoder);
235     auto jsPandaFile = ctx.GetJSPandaFile();
236     auto cmpCfg = ctx.GetCompilerConfig();
237     auto module = m->GetModule();
238     std::string fullName = module->GetFuncName(methodLiteral, jsPandaFile);
239 
240     Circuit circuit(vm_->GetNativeAreaAllocator(), ctx.GetAOTModule()->GetDebugInfo(),
241                     fullName.c_str(), cmpCfg->Is64Bit(), FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
242 
243     PGOProfilerDecoder defDecoder;
244     PGOProfilerDecoder *decoder = cOptions.isEnableOptPGOType_ ? &profilerDecoder : &defDecoder;
245 
246     BytecodeCircuitBuilder builder(jsPandaFile, methodLiteral, methodPCInfo, &circuit,
247                                     ctx.GetByteCodes(), false,
248                                     cOptions.isEnableTypeLowering_,
249                                     fullName, bytecodeInfo.GetRecordNameWithIndex(0), decoder, false);
250     {
251         builder.SetPreAnalysis();
252         builder.BytecodeToCircuit();
253         if (builder.HasIrreducibleLoop()) {
254             irreducibleMethods_.push_back(fullName);
255         }
256     }
257     m->DestroyModule();
258 }
259 
GenerateAbcFileInfos(std::unordered_map<CString,uint32_t> & fileNameToChecksumMap)260 void AotCompilerPreprocessor::GenerateAbcFileInfos(std::unordered_map<CString, uint32_t> &fileNameToChecksumMap)
261 {
262     size_t size = pandaFileNames_.size();
263     for (size_t i = 0; i < size; ++i) {
264         const auto &fileName = pandaFileNames_.at(i);
265         std::string extendedFilePath = panda::os::file::File::GetExtendedFilePath(fileName);
266         std::shared_ptr<JSPandaFile> jsPandaFile = CreateAndVerifyJSPandaFile(extendedFilePath);
267         AbcFileInfo fileInfo(extendedFilePath, jsPandaFile);
268         if (jsPandaFile == nullptr) {
269             LOG_COMPILER(ERROR) << "Cannot execute panda file '" << extendedFilePath << "'";
270             continue;
271         }
272         fileNameToChecksumMap.emplace(jsPandaFile->GetNormalizedFileDesc(), jsPandaFile->GetChecksum());
273         ResolveModule(jsPandaFile.get(), extendedFilePath);
274         fileInfos_.emplace_back(fileInfo);
275     }
276 }
277 
GenerateBytecodeInfoCollectors(const CompilationOptions & cOptions)278 void AotCompilerPreprocessor::GenerateBytecodeInfoCollectors(const CompilationOptions &cOptions)
279 {
280     bcInfoCollectors_.reserve(fileInfos_.size());
281     for (const AbcFileInfo &fileInfo : fileInfos_) {
282         JSPandaFile *jsPandaFile = fileInfo.jsPandaFile_.get();
283         auto collectorPtr = std::make_unique<BytecodeInfoCollector>(&aotCompilationEnv_, jsPandaFile,
284                                                                     profilerDecoder_, cOptions.maxAotMethodSize_);
285         bcInfoCollectors_.emplace_back(std::move(collectorPtr));
286     }
287 }
288 
HandleMergedPgoFile(std::unordered_map<CString,uint32_t> & fileNameToChecksumMap)289 bool AotCompilerPreprocessor::HandleMergedPgoFile(std::unordered_map<CString, uint32_t> &fileNameToChecksumMap)
290 {
291     return PGOProfilerManager::MergeApFiles(fileNameToChecksumMap, profilerDecoder_);
292 }
293 
CreateAndVerifyJSPandaFile(const std::string & fileName)294 std::shared_ptr<JSPandaFile> AotCompilerPreprocessor::CreateAndVerifyJSPandaFile(const std::string &fileName)
295 {
296     JSPandaFileManager *jsPandaFileManager = JSPandaFileManager::GetInstance();
297     std::shared_ptr<JSPandaFile> jsPandaFile = nullptr;
298     if (runtimeOptions_.IsTargetCompilerMode()) {
299         auto pkgArgsIter = pkgsArgs_.find(fileName);
300         if (pkgArgsIter == pkgsArgs_.end()) {
301             jsPandaFile = jsPandaFileManager->OpenJSPandaFile(fileName.c_str());
302         } else if (!(pkgArgsIter->second->GetJSPandaFile(runtimeOptions_, jsPandaFile,
303             pkgArgsIter->second->GetPkgFd()))) {
304             return nullptr;
305         }
306     } else {
307         jsPandaFile = jsPandaFileManager->OpenJSPandaFile(fileName.c_str());
308     }
309     if (jsPandaFile == nullptr) {
310         LOG_ECMA(ERROR) << "open file " << fileName << " error";
311         return nullptr;
312     }
313 
314     if (!jsPandaFile->IsNewVersion()) {
315         LOG_COMPILER(ERROR) << "AOT only support panda file with new ISA, while the '" <<
316             fileName << "' file is the old version";
317         return nullptr;
318     }
319 
320     jsPandaFileManager->AddJSPandaFile(jsPandaFile);
321     return jsPandaFile;
322 }
323 
ResolveModule(const JSPandaFile * jsPandaFile,const std::string & fileName)324 void AotCompilerPreprocessor::ResolveModule(const JSPandaFile *jsPandaFile, const std::string &fileName)
325 {
326     const auto &recordInfo = jsPandaFile->GetJSRecordInfo();
327     JSThread *thread = vm_->GetJSThread();
328     [[maybe_unused]] EcmaHandleScope scope(thread);
329     for (auto info: recordInfo) {
330         if (jsPandaFile->IsModule(info.second)) {
331             auto recordName = info.first;
332             ModuleResolver::HostResolveImportedModule(
333                 thread, fileName.c_str(), CString(recordName.data(), recordName.size()));
334             RETURN_IF_ABRUPT_COMPLETION(thread);
335         }
336     }
337 }
338 
GeneratePGOTypes()339 void AotCompilerPreprocessor::GeneratePGOTypes()
340 {
341     PGOTypeManager* ptManager = vm_->GetPTManager();
342     for (uint32_t i = 0; i < fileInfos_.size(); ++i) {
343         auto& collector = *bcInfoCollectors_[i];
344         PGOTypeParser parser(profilerDecoder_, ptManager);
345         parser.CreatePGOType(collector);
346     }
347     if (vm_->GetJSOptions().IsEnableOptTrackField()) {
348         ptManager->MergeRepresentationForProtoTransition();
349     }
350 }
351 
SnapshotInitialize()352 void AotCompilerPreprocessor::SnapshotInitialize()
353 {
354     PGOTypeManager* ptManager = vm_->GetPTManager();
355     ptManager->InitAOTSnapshot(fileInfos_.size());
356 }
357 
SetIsFastCall(CString fileDesc,uint32_t methodOffset,bool isFastCall)358 void CallMethodFlagMap::SetIsFastCall(CString fileDesc, uint32_t methodOffset, bool isFastCall)
359 {
360     abcIdMethodIdToIsFastCall_[std::pair<CString, uint32_t>(fileDesc, methodOffset)] = isFastCall;
361 }
362 
IsFastCall(CString fileDesc,uint32_t methodOffset) const363 bool CallMethodFlagMap::IsFastCall(CString fileDesc, uint32_t methodOffset) const
364 {
365     if (!abcIdMethodIdToIsFastCall_.count(std::pair<CString, uint32_t>(fileDesc, methodOffset))) {
366         return false;
367     }
368     return abcIdMethodIdToIsFastCall_.at(std::pair<CString, uint32_t>(fileDesc, methodOffset));
369 }
370 
SetIsAotCompile(CString fileDesc,uint32_t methodOffset,bool isAotCompile)371 void CallMethodFlagMap::SetIsAotCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile)
372 {
373     abcIdMethodIdToIsAotCompile_[std::pair<CString, uint32_t>(fileDesc, methodOffset)] = isAotCompile;
374 }
375 
IsAotCompile(CString fileDesc,uint32_t methodOffset) const376 bool CallMethodFlagMap::IsAotCompile(CString fileDesc, uint32_t methodOffset) const
377 {
378     if (!abcIdMethodIdToIsAotCompile_.count(std::pair<CString, uint32_t>(fileDesc, methodOffset))) {
379         return false;
380     }
381     return abcIdMethodIdToIsAotCompile_.at(std::pair<CString, uint32_t>(fileDesc, methodOffset));
382 }
383 
SetIsJitCompile(CString fileDesc,uint32_t methodOffset,bool isAotCompile)384 void CallMethodFlagMap::SetIsJitCompile(CString fileDesc, uint32_t methodOffset, bool isAotCompile)
385 {
386     abcIdMethodIdToIsJitCompile_[std::pair<CString, uint32_t>(fileDesc, methodOffset)] = isAotCompile;
387 }
388 
IsJitCompile(CString fileDesc,uint32_t methodOffset) const389 bool CallMethodFlagMap::IsJitCompile(CString fileDesc, uint32_t methodOffset) const
390 {
391     if (!abcIdMethodIdToIsJitCompile_.count(std::pair<CString, uint32_t>(fileDesc, methodOffset))) {
392         return false;
393     }
394     return abcIdMethodIdToIsJitCompile_.at(std::pair<CString, uint32_t>(fileDesc, methodOffset));
395 }
396 
397 
FilterOption(const std::map<std::string,std::vector<std::string>> & optionMap,const std::string & recordName,const std::string & methodName) const398 bool AotCompilerPreprocessor::FilterOption(const std::map<std::string, std::vector<std::string>> &optionMap,
399     const std::string &recordName, const std::string &methodName) const
400 {
401     if (optionMap.empty()) {
402         return false;
403     }
404 
405     auto it = optionMap.find(recordName);
406     if (it == optionMap.end()) {
407         return false;
408     }
409 
410     std::vector<std::string> vec = it->second;
411     return find(vec.begin(), vec.end(), methodName) != vec.end();
412 }
413 
IsSkipMethod(const JSPandaFile * jsPandaFile,const BCInfo & bytecodeInfo,const CString & recordName,const MethodLiteral * methodLiteral,const MethodPcInfo & methodPCInfo,const std::string & methodName,CompilationOptions & cOptions) const414 bool AotCompilerPreprocessor::IsSkipMethod(const JSPandaFile *jsPandaFile, const BCInfo &bytecodeInfo,
415                                            const CString &recordName, const MethodLiteral *methodLiteral,
416                                            const MethodPcInfo &methodPCInfo, const std::string &methodName,
417                                            CompilationOptions &cOptions) const
418 {
419     if (methodPCInfo.methodsSize > bytecodeInfo.GetMaxMethodSize() ||
420         !profilerDecoder_.Match(jsPandaFile, recordName, methodLiteral->GetMethodId())) {
421         return true;
422     }
423 
424     if (OutCompiledMethodsRange()) {
425         return true;
426     }
427 
428     if (!cOptions.optionSelectMethods_.empty()) {
429         return !FilterOption(cOptions.optionSelectMethods_, ConvertToStdString(recordName), methodName);
430     } else if (!cOptions.optionSkipMethods_.empty()) {
431         return FilterOption(cOptions.optionSkipMethods_, ConvertToStdString(recordName), methodName);
432     }
433 
434     std::string fullName = IRModule::GetFuncName(methodLiteral, jsPandaFile);
435     if (HasSkipMethod(irreducibleMethods_, fullName)) {
436         return true;
437     }
438 
439     if (methodLiteral->IsShared()) {
440         return true;
441     }
442 
443     return false;
444 }
445 
GenerateMethodMap(CompilationOptions & cOptions)446 void AotCompilerPreprocessor::GenerateMethodMap(CompilationOptions &cOptions)
447 {
448     for (uint32_t i = 0; i < fileInfos_.size(); ++i) {
449         JSPandaFile *jsPandaFile = fileInfos_[i].jsPandaFile_.get();
450         auto& collector = *bcInfoCollectors_[i];
451         BCInfo &bytecodeInfo = collector.GetBytecodeInfo();
452         const auto &methodPcInfos = bytecodeInfo.GetMethodPcInfos();
453         auto &methodList = bytecodeInfo.GetMethodList();
454         for (auto it = methodList.begin(); it != methodList.end(); it++) {
455             uint32_t index = it->first;
456             auto &methodInfo = it->second;
457             auto &methodPcInfo = methodPcInfos[methodInfo.GetMethodPcInfoIndex()];
458             auto methodLiteral = jsPandaFile->FindMethodLiteral(index);
459             if (methodLiteral == nullptr) {
460                 continue;
461             }
462             auto methodId = methodLiteral->GetMethodId();
463             const std::string methodName(MethodLiteral::GetMethodName(jsPandaFile, methodId));
464             bool isAotCompile = !IsSkipMethod(jsPandaFile,
465                                               bytecodeInfo,
466                                               MethodLiteral::GetRecordName(jsPandaFile, EntityId(index)),
467                                               methodLiteral,
468                                               methodPcInfo,
469                                               methodName,
470                                               cOptions);
471             bool isFastCall = methodLiteral->IsFastCall();
472             CString fileDesc = jsPandaFile->GetNormalizedFileDesc();
473             uint32_t offset = methodId.GetOffset();
474             callMethodFlagMap_.SetIsAotCompile(fileDesc, offset, isAotCompile);
475             callMethodFlagMap_.SetIsFastCall(fileDesc, offset, isFastCall);
476             LOG_COMPILER(INFO) << fileDesc << "->" << methodName << ", offset: " << offset
477                                << ", isAotCompile: " << isAotCompile << ", isFastCall: " << isFastCall;
478         }
479     }
480 }
481 
HasSkipMethod(const CVector<std::string> & methodList,const std::string & methodName) const482 bool AotCompilerPreprocessor::HasSkipMethod(const CVector<std::string> &methodList,
483                                             const std::string &methodName) const
484 {
485     return std::find(methodList.begin(), methodList.end(), methodName) != methodList.end();
486 }
487 
GetMainPkgArgsAppSignature() const488 std::string AotCompilerPreprocessor::GetMainPkgArgsAppSignature() const
489 {
490     return GetMainPkgArgs() == nullptr ? "" : GetMainPkgArgs()->GetAppSignature();
491 }
492 
ForbidenRebuildAOT(std::string & fileName) const493 bool AotCompilerPreprocessor::ForbidenRebuildAOT(std::string &fileName) const
494 {
495     std::string realPath;
496     if (!RealPath(fileName, realPath, false)) {
497         LOG_COMPILER(ERROR) << "Fail to get realPath: " << fileName;
498         return true;
499     }
500     if (FileExist(realPath.c_str())) {
501         LOG_COMPILER(ERROR) << "AOT file: " << realPath << " exist";
502         return true;
503     }
504     return false;
505 }
506 
HasPreloadAotFile() const507 bool AotCompilerPreprocessor::HasPreloadAotFile() const
508 {
509     std::string hapPath;
510     std::string moduleName;
511     if (GetMainPkgArgs()) {
512         hapPath = GetMainPkgArgs()->GetPath();
513         moduleName = GetMainPkgArgs()->GetModuleName();
514     }
515     std::string fileName = OhosPreloadAppInfo::GetPreloadAOTFileName(hapPath, moduleName);
516     std::string aiFileName = fileName + AOTFileManager::FILE_EXTENSION_AI;
517     std::string anFileName = fileName + AOTFileManager::FILE_EXTENSION_AN;
518     bool existsAnFile = ForbidenRebuildAOT(anFileName);
519     bool existsAiFile = ForbidenRebuildAOT(aiFileName);
520     return (existsAnFile || existsAiFile);
521 }
522 
HasExistsAOTFiles(CompilationOptions & cOptions) const523 bool AotCompilerPreprocessor::HasExistsAOTFiles(CompilationOptions &cOptions) const
524 {
525     std::string anFileName = cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN;
526     std::string aiFileName = cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AI;
527     bool existsAnFile = ForbidenRebuildAOT(anFileName);
528     bool existsAiFile = ForbidenRebuildAOT(aiFileName);
529     return (existsAnFile || existsAiFile);
530 }
531 } // namespace panda::ecmascript::kungfu
532