• 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 
17 #include "ecmascript/checkpoint/thread_state_transition.h"
18 #include "ecmascript/compiler/pass_manager.h"
19 #include "ecmascript/log_wrapper.h"
20 #include "ecmascript/ohos/ohos_pkg_verifier.h"
21 #include "ecmascript/platform/aot_crash_info.h"
22 
23 
24 namespace panda::ecmascript::kungfu {
25 namespace {
26 /**
27  * @param ErrCode return code of ark_aot_compiler
28  * @attention it must sync with RetStatusOfCompiler of
29  *            "ets_runtime/compiler_service/include/aot_compiler_constants.h"
30  */
31 enum ErrCode {
32     ERR_OK = (0),   // IMPORTANT: Only if aot compiler SUCCESS and save an/ai SUCCESS, return ERR_OK.
33     ERR_FAIL = (-1),
34     ERR_HELP = (1),
35     ERR_NO_AP = (2),
36     ERR_MERGE_AP = (3),
37     ERR_CHECK_VERSION = (4),
38     ERR_AN_EMPTY = (5),
39     ERR_AN_FAIL = (6),
40     ERR_AI_FAIL = (7),
41 };
42 
CheckVersion(JSRuntimeOptions & runtimeOptions,AotCompilerStats & compilerStats,bool isPgoMerged)43 bool CheckVersion(JSRuntimeOptions& runtimeOptions, AotCompilerStats& compilerStats, bool isPgoMerged)
44 {
45     if (runtimeOptions.IsCheckPgoVersion()) {
46         if (!isPgoMerged) {
47             LOG_COMPILER(ERROR) << "CheckVersion ap and abc may not match";
48             compilerStats.SetPgoFileLegal(false);
49         }
50         if (runtimeOptions.IsTargetCompilerMode()) {
51             compilerStats.PrintCompilerStatsLog();
52         }
53         return true;
54     }
55     return false;
56 }
57 
58 } // namespace
59 
Main(const int argc,const char ** argv)60 int Main(const int argc, const char **argv)
61 {
62     if (argc < 2) { // 2: at least have two arguments
63         LOG_COMPILER(ERROR) << AotCompilerPreprocessor::GetHelper();
64         return ERR_FAIL;
65     }
66 
67     JSRuntimeOptions runtimeOptions;
68     bool retOpt = runtimeOptions.ParseCommand(argc, argv);
69     if (!retOpt) {
70         LOG_COMPILER(ERROR) << AotCompilerPreprocessor::GetHelper();
71         return ERR_HELP;
72     }
73 
74     bool ret = true;
75     // ark_aot_compiler running need disable asm interpreter to disable the loading of AOT files.
76     runtimeOptions.SetEnableAsmInterpreter(false);
77     runtimeOptions.SetOptionsForTargetCompilation();
78     runtimeOptions.DisableGCTimeoutCheck();
79     EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions);
80     if (vm == nullptr) {
81         LOG_COMPILER(ERROR) << "Cannot Create vm";
82         return ERR_FAIL;
83     }
84 
85     {
86         AOTCompilationEnv aotCompilationEnv(vm);
87         ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
88         LocalScope scope(vm);
89         arg_list_t pandaFileNames {};
90         std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
91         CompilationOptions cOptions(runtimeOptions);
92 
93         CompilerLog log(cOptions.logOption_);
94         log.SetEnableCompilerLogTime(cOptions.compilerLogTime_);
95         AotMethodLogList logList(cOptions.logMethodsList_);
96         PGOProfilerDecoder profilerDecoder;
97 
98         AotCompilerPreprocessor cPreprocessor(vm, runtimeOptions, pkgArgsMap, profilerDecoder, pandaFileNames);
99         if (!cPreprocessor.HandleTargetCompilerMode(cOptions) || !cPreprocessor.HandlePandaFileNames(argc, argv)) {
100             return ERR_HELP;
101         }
102 
103         // Need to verify package information to prevent abnormal input of information
104         if (!ohos::OhosPkgVerifier::VerifyPkgInfo(cPreprocessor, cOptions)) {
105             LOG_COMPILER(ERROR) << "hap verify wrong";
106             return ERR_FAIL;
107         }
108 
109         if (runtimeOptions.IsPartialCompilerMode() && cOptions.profilerIn_.empty()) {
110             // no need to compile in partial mode without any ap files.
111             return ERR_NO_AP;
112         }
113 
114         AotCompilerStats compilerStats;
115         std::string bundleName = "";
116         if (cPreprocessor.GetMainPkgArgs()) {
117             bundleName = cPreprocessor.GetMainPkgArgs()->GetBundleName();
118         }
119         compilerStats.SetBundleName(bundleName);
120         compilerStats.SetAotFilePath(cOptions.outputFileName_);
121         compilerStats.SetPgoPath(cOptions.profilerIn_);
122         compilerStats.StartCompiler();
123         profilerDecoder.SetHotnessThreshold(cOptions.hotnessThreshold_);
124         profilerDecoder.SetInPath(cOptions.profilerIn_);
125         cPreprocessor.AOTInitialize();
126         std::unordered_map<CString, uint32_t> fileNameToChecksumMap;
127         cPreprocessor.GenerateAbcFileInfos(fileNameToChecksumMap);
128 
129         if (runtimeOptions.IsTargetCompilerMode() && (cPreprocessor.HasExistsAOTFiles(cOptions) ||
130             cPreprocessor.HasPreloadAotFile())) {
131             LOG_COMPILER(ERROR) << "The AOT file already exists and will not be compiled anymore";
132             return ERR_OK;
133         }
134         ret = cPreprocessor.GetCompilerResult();
135         // Notice: lx move load pandaFileHead and verify before GeneralAbcFileInfos.
136         // need support multiple abc
137         auto isPgoMerged = cPreprocessor.HandleMergedPgoFile(fileNameToChecksumMap);
138         if (CheckVersion(runtimeOptions, compilerStats, isPgoMerged)) {
139             return ERR_CHECK_VERSION;
140         }
141         std::string appSignature = cPreprocessor.GetMainPkgArgsAppSignature();
142         if (!isPgoMerged) {
143             AOTFileGenerator::SaveEmptyAOTFile(
144                 cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN, appSignature, true);
145             AOTFileGenerator::SaveEmptyAOTFile(
146                 cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AI, appSignature, false);
147             return ERR_MERGE_AP;
148         }
149         cPreprocessor.Process(cOptions);
150 
151         PassOptions::Builder optionsBuilder;
152         PassOptions passOptions =
153             optionsBuilder.EnableArrayBoundsCheckElimination(cOptions.isEnableArrayBoundsCheckElimination_)
154                 .EnableTypeLowering(cOptions.isEnableTypeLowering_)
155                 .EnableEarlyElimination(cOptions.isEnableEarlyElimination_)
156                 .EnableLaterElimination(cOptions.isEnableLaterElimination_)
157                 .EnableValueNumbering(cOptions.isEnableValueNumbering_)
158                 .EnableOptInlining(cOptions.isEnableOptInlining_)
159                 .EnableOptString(cOptions.isEnableOptString_)
160                 .EnableOptPGOType(cOptions.isEnableOptPGOType_)
161                 .EnableOptTrackField(cOptions.isEnableOptTrackField_)
162                 .EnableOptLoopPeeling(cOptions.isEnableOptLoopPeeling_)
163                 .EnableOptLoopInvariantCodeMotion(cOptions.isEnableOptLoopInvariantCodeMotion_)
164                 .EnableOptConstantFolding(cOptions.isEnableOptConstantFolding_)
165                 .EnableLazyDeopt(cOptions.isEnableLazyDeopt_)
166                 .EnableLexenvSpecialization(cOptions.isEnableLexenvSpecialization_)
167                 .EnableInlineNative(cOptions.isEnableNativeInline_)
168                 .EnableLoweringBuiltin(cOptions.isEnableLoweringBuiltin_)
169                 .EnableOptBranchProfiling(cOptions.isEnableOptBranchProfiling_)
170                 .EnableEscapeAnalysis(cOptions.isEnableEscapeAnalysis_)
171                 .EnableInductionVariableAnalysis(cOptions.isEnableInductionVariableAnalysis_)
172                 .EnableVerifierPass(cOptions.isEnableVerifierPass_)
173                 .EnableMergePoly(cOptions.isEnableMergePoly_)
174                 .Build();
175 
176         PassManager passManager(&aotCompilationEnv,
177                                 cOptions.triple_,
178                                 cOptions.optLevel_,
179                                 cOptions.relocMode_,
180                                 &log,
181                                 &logList,
182                                 cOptions.maxAotMethodSize_,
183                                 cOptions.maxMethodsInModule_,
184                                 profilerDecoder,
185                                 &passOptions,
186                                 cPreprocessor.GetCallMethodFlagMap(),
187                                 cPreprocessor.GetAbcFileInfo(),
188                                 cPreprocessor.GetBcInfoCollectors(),
189                                 cOptions.optBCRange_);
190 
191         bool isEnableLiteCG = runtimeOptions.IsCompilerEnableLiteCG();
192         compilerStats.SetIsLiteCg(isEnableLiteCG);
193 
194         AOTFileGenerator generator(&log, &logList, &aotCompilationEnv, cOptions.triple_, isEnableLiteCG,
195                                    cOptions.anFileMaxByteSize_);
196         if (runtimeOptions.IsTargetCompilerMode() && runtimeOptions.IsEnableAotCodeComment()) {
197             if (!generator.CreateAOTCodeCommentFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN)) {
198                 LOG_COMPILER(ERROR) << "Generate aot code comment file failed.";
199             }
200         }
201         passManager.CompileValidFiles(generator, ret, compilerStats);
202         if (compilerStats.GetCompilerMethodCount() == 0) {
203             return runtimeOptions.IsPartialCompilerMode() ? ERR_AN_EMPTY : ERR_OK;
204         }
205         if (!generator.SaveAOTFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN, appSignature,
206                                    fileNameToChecksumMap)) {
207             return ERR_AN_FAIL;
208         }
209         if (!generator.SaveSnapshotFile()) {
210             return ERR_AI_FAIL;
211         }
212         log.Print();
213         if (runtimeOptions.IsTargetCompilerMode()) {
214             compilerStats.PrintCompilerStatsLog();
215             compilerStats.SendDataPartitionSysEvent(cPreprocessor.GetMainPkgArgs()->GetPgoDir());
216         }
217     }
218 
219     if (vm->GetJSOptions().IsEnableCompilerLogSnapshot()) {
220         vm->PrintAOTSnapShotStats();
221     }
222     LOG_COMPILER(INFO) << (ret ? "ts aot compile success" : "ts aot compile failed");
223     JSNApi::DestroyJSVM(vm);
224     return ret ? ERR_OK : ERR_FAIL;
225 }
226 } // namespace panda::ecmascript::kungfu
227 
main(const int argc,const char ** argv)228 int main(const int argc, const char **argv)
229 {
230     auto result = panda::ecmascript::kungfu::Main(argc, argv);
231     return result;
232 }
233