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