14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include <chrono> 174514f5e3Sopenharmony_ci#include <iostream> 184514f5e3Sopenharmony_ci#include <memory> 194514f5e3Sopenharmony_ci 204514f5e3Sopenharmony_ci#include "ecmascript/base/string_helper.h" 214514f5e3Sopenharmony_ci#include "ecmascript/checkpoint/thread_state_transition.h" 224514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_compilation_env.h" 234514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_compiler_preprocessor.h" 244514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/aot_file_manager.h" 254514f5e3Sopenharmony_ci#include "ecmascript/compiler/pass_manager.h" 264514f5e3Sopenharmony_ci#include "ecmascript/ecma_string.h" 274514f5e3Sopenharmony_ci#include "ecmascript/js_runtime_options.h" 284514f5e3Sopenharmony_ci#include "ecmascript/log.h" 294514f5e3Sopenharmony_ci#include "ecmascript/log_wrapper.h" 304514f5e3Sopenharmony_ci#include "ecmascript/napi/include/jsnapi.h" 314514f5e3Sopenharmony_ci#include "ecmascript/ohos/enable_aot_list_helper.h" 324514f5e3Sopenharmony_ci#include "ecmascript/ohos/ohos_pkg_args.h" 334514f5e3Sopenharmony_ci#include "ecmascript/platform/aot_crash_info.h" 344514f5e3Sopenharmony_ci#include "ecmascript/platform/file.h" 354514f5e3Sopenharmony_ci#include "ecmascript/platform/filesystem.h" 364514f5e3Sopenharmony_ci 374514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_compiler_stats.h" 384514f5e3Sopenharmony_ci 394514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 404514f5e3Sopenharmony_cinamespace { 414514f5e3Sopenharmony_ci/** 424514f5e3Sopenharmony_ci * @param ErrCode return code of ark_aot_compiler 434514f5e3Sopenharmony_ci * @attention it must sync with RetStatusOfCompiler of 444514f5e3Sopenharmony_ci * "ets_runtime/compiler_service/include/aot_compiler_constants.h" 454514f5e3Sopenharmony_ci */ 464514f5e3Sopenharmony_cienum ErrCode { 474514f5e3Sopenharmony_ci ERR_OK = (0), // IMPORTANT: Only if aot compiler SUCCESS and save an/ai SUCCESS, return ERR_OK. 484514f5e3Sopenharmony_ci ERR_FAIL = (-1), 494514f5e3Sopenharmony_ci ERR_HELP = (1), 504514f5e3Sopenharmony_ci ERR_NO_AP = (2), 514514f5e3Sopenharmony_ci ERR_MERGE_AP = (3), 524514f5e3Sopenharmony_ci ERR_CHECK_VERSION = (4), 534514f5e3Sopenharmony_ci ERR_AN_EMPTY = (5), 544514f5e3Sopenharmony_ci ERR_AN_FAIL = (6), 554514f5e3Sopenharmony_ci ERR_AI_FAIL = (7), 564514f5e3Sopenharmony_ci}; 574514f5e3Sopenharmony_ci 584514f5e3Sopenharmony_cibool CheckVersion(JSRuntimeOptions& runtimeOptions, AotCompilerStats& compilerStats, bool isPgoMerged) 594514f5e3Sopenharmony_ci{ 604514f5e3Sopenharmony_ci if (runtimeOptions.IsCheckPgoVersion()) { 614514f5e3Sopenharmony_ci if (!isPgoMerged) { 624514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "CheckVersion ap and abc may not match"; 634514f5e3Sopenharmony_ci compilerStats.SetPgoFileLegal(false); 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci if (runtimeOptions.IsTargetCompilerMode()) { 664514f5e3Sopenharmony_ci compilerStats.PrintCompilerStatsLog(); 674514f5e3Sopenharmony_ci } 684514f5e3Sopenharmony_ci return true; 694514f5e3Sopenharmony_ci } 704514f5e3Sopenharmony_ci return false; 714514f5e3Sopenharmony_ci} 724514f5e3Sopenharmony_ci 734514f5e3Sopenharmony_cibool IsExistsPkgInfo(AotCompilerPreprocessor &cPreprocessor) 744514f5e3Sopenharmony_ci{ 754514f5e3Sopenharmony_ci if (cPreprocessor.GetMainPkgArgs()) { 764514f5e3Sopenharmony_ci return true; 774514f5e3Sopenharmony_ci } 784514f5e3Sopenharmony_ci return false; 794514f5e3Sopenharmony_ci} 804514f5e3Sopenharmony_ci} // namespace 814514f5e3Sopenharmony_ci 824514f5e3Sopenharmony_ciint Main(const int argc, const char **argv) 834514f5e3Sopenharmony_ci{ 844514f5e3Sopenharmony_ci if (argc < 2) { // 2: at least have two arguments 854514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << AotCompilerPreprocessor::GetHelper(); 864514f5e3Sopenharmony_ci return ERR_FAIL; 874514f5e3Sopenharmony_ci } 884514f5e3Sopenharmony_ci 894514f5e3Sopenharmony_ci JSRuntimeOptions runtimeOptions; 904514f5e3Sopenharmony_ci bool retOpt = runtimeOptions.ParseCommand(argc, argv); 914514f5e3Sopenharmony_ci if (!retOpt) { 924514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << AotCompilerPreprocessor::GetHelper(); 934514f5e3Sopenharmony_ci return ERR_HELP; 944514f5e3Sopenharmony_ci } 954514f5e3Sopenharmony_ci 964514f5e3Sopenharmony_ci bool ret = true; 974514f5e3Sopenharmony_ci // ark_aot_compiler running need disable asm interpreter to disable the loading of AOT files. 984514f5e3Sopenharmony_ci runtimeOptions.SetEnableAsmInterpreter(false); 994514f5e3Sopenharmony_ci runtimeOptions.SetOptionsForTargetCompilation(); 1004514f5e3Sopenharmony_ci EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions); 1014514f5e3Sopenharmony_ci if (vm == nullptr) { 1024514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Cannot Create vm"; 1034514f5e3Sopenharmony_ci return ERR_FAIL; 1044514f5e3Sopenharmony_ci } 1054514f5e3Sopenharmony_ci 1064514f5e3Sopenharmony_ci { 1074514f5e3Sopenharmony_ci AOTCompilationEnv aotCompilationEnv(vm); 1084514f5e3Sopenharmony_ci ecmascript::ThreadManagedScope managedScope(vm->GetJSThread()); 1094514f5e3Sopenharmony_ci LocalScope scope(vm); 1104514f5e3Sopenharmony_ci arg_list_t pandaFileNames {}; 1114514f5e3Sopenharmony_ci std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap; 1124514f5e3Sopenharmony_ci CompilationOptions cOptions(runtimeOptions); 1134514f5e3Sopenharmony_ci 1144514f5e3Sopenharmony_ci CompilerLog log(cOptions.logOption_); 1154514f5e3Sopenharmony_ci log.SetEnableCompilerLogTime(cOptions.compilerLogTime_); 1164514f5e3Sopenharmony_ci AotMethodLogList logList(cOptions.logMethodsList_); 1174514f5e3Sopenharmony_ci PGOProfilerDecoder profilerDecoder; 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ci AotCompilerPreprocessor cPreprocessor(vm, runtimeOptions, pkgArgsMap, profilerDecoder, pandaFileNames); 1204514f5e3Sopenharmony_ci if (!cPreprocessor.HandleTargetCompilerMode(cOptions) || !cPreprocessor.HandlePandaFileNames(argc, argv)) { 1214514f5e3Sopenharmony_ci return ERR_HELP; 1224514f5e3Sopenharmony_ci } 1234514f5e3Sopenharmony_ci 1244514f5e3Sopenharmony_ci if (IsExistsPkgInfo(cPreprocessor)) { 1254514f5e3Sopenharmony_ci if (AotCrashInfo::IsAotEscaped(cPreprocessor.GetMainPkgArgs()->GetPgoDir())) { 1264514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Stop compile AOT because there are multiple crashes"; 1274514f5e3Sopenharmony_ci return ERR_FAIL; 1284514f5e3Sopenharmony_ci } 1294514f5e3Sopenharmony_ci } 1304514f5e3Sopenharmony_ci if (runtimeOptions.IsPartialCompilerMode() && cOptions.profilerIn_.empty()) { 1314514f5e3Sopenharmony_ci // no need to compile in partial mode without any ap files. 1324514f5e3Sopenharmony_ci return ERR_NO_AP; 1334514f5e3Sopenharmony_ci } 1344514f5e3Sopenharmony_ci 1354514f5e3Sopenharmony_ci AotCompilerStats compilerStats; 1364514f5e3Sopenharmony_ci std::string bundleName = ""; 1374514f5e3Sopenharmony_ci if (cPreprocessor.GetMainPkgArgs()) { 1384514f5e3Sopenharmony_ci bundleName = cPreprocessor.GetMainPkgArgs()->GetBundleName(); 1394514f5e3Sopenharmony_ci } 1404514f5e3Sopenharmony_ci compilerStats.SetBundleName(bundleName); 1414514f5e3Sopenharmony_ci compilerStats.SetAotFilePath(cOptions.outputFileName_); 1424514f5e3Sopenharmony_ci compilerStats.SetPgoPath(cOptions.profilerIn_); 1434514f5e3Sopenharmony_ci compilerStats.StartCompiler(); 1444514f5e3Sopenharmony_ci profilerDecoder.SetHotnessThreshold(cOptions.hotnessThreshold_); 1454514f5e3Sopenharmony_ci profilerDecoder.SetInPath(cOptions.profilerIn_); 1464514f5e3Sopenharmony_ci cPreprocessor.AOTInitialize(); 1474514f5e3Sopenharmony_ci uint32_t checksum = cPreprocessor.GenerateAbcFileInfos(); 1484514f5e3Sopenharmony_ci 1494514f5e3Sopenharmony_ci if (runtimeOptions.IsTargetCompilerMode() && (cPreprocessor.HasExistsAOTFiles(cOptions) || 1504514f5e3Sopenharmony_ci cPreprocessor.HasPreloadAotFile())) { 1514514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "The AOT file already exists and will not be compiled anymore"; 1524514f5e3Sopenharmony_ci return ERR_OK; 1534514f5e3Sopenharmony_ci } 1544514f5e3Sopenharmony_ci 1554514f5e3Sopenharmony_ci ret = cPreprocessor.GetCompilerResult(); 1564514f5e3Sopenharmony_ci // Notice: lx move load pandaFileHead and verify before GeneralAbcFileInfos. 1574514f5e3Sopenharmony_ci // need support multiple abc 1584514f5e3Sopenharmony_ci auto isPgoMerged = cPreprocessor.HandleMergedPgoFile(checksum); 1594514f5e3Sopenharmony_ci if (CheckVersion(runtimeOptions, compilerStats, isPgoMerged)) { 1604514f5e3Sopenharmony_ci return ERR_CHECK_VERSION; 1614514f5e3Sopenharmony_ci } 1624514f5e3Sopenharmony_ci std::string appSignature = cPreprocessor.GetMainPkgArgsAppSignature(); 1634514f5e3Sopenharmony_ci if (!isPgoMerged) { 1644514f5e3Sopenharmony_ci AOTFileGenerator::SaveEmptyAOTFile( 1654514f5e3Sopenharmony_ci cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN, appSignature, true); 1664514f5e3Sopenharmony_ci AOTFileGenerator::SaveEmptyAOTFile( 1674514f5e3Sopenharmony_ci cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AI, appSignature, false); 1684514f5e3Sopenharmony_ci return ERR_MERGE_AP; 1694514f5e3Sopenharmony_ci } 1704514f5e3Sopenharmony_ci cPreprocessor.Process(cOptions); 1714514f5e3Sopenharmony_ci 1724514f5e3Sopenharmony_ci PassOptions::Builder optionsBuilder; 1734514f5e3Sopenharmony_ci PassOptions passOptions = 1744514f5e3Sopenharmony_ci optionsBuilder.EnableArrayBoundsCheckElimination(cOptions.isEnableArrayBoundsCheckElimination_) 1754514f5e3Sopenharmony_ci .EnableTypeLowering(cOptions.isEnableTypeLowering_) 1764514f5e3Sopenharmony_ci .EnableEarlyElimination(cOptions.isEnableEarlyElimination_) 1774514f5e3Sopenharmony_ci .EnableLaterElimination(cOptions.isEnableLaterElimination_) 1784514f5e3Sopenharmony_ci .EnableValueNumbering(cOptions.isEnableValueNumbering_) 1794514f5e3Sopenharmony_ci .EnableOptInlining(cOptions.isEnableOptInlining_) 1804514f5e3Sopenharmony_ci .EnableOptString(cOptions.isEnableOptString_) 1814514f5e3Sopenharmony_ci .EnableOptPGOType(cOptions.isEnableOptPGOType_) 1824514f5e3Sopenharmony_ci .EnableOptTrackField(cOptions.isEnableOptTrackField_) 1834514f5e3Sopenharmony_ci .EnableOptLoopPeeling(cOptions.isEnableOptLoopPeeling_) 1844514f5e3Sopenharmony_ci .EnableOptLoopInvariantCodeMotion(cOptions.isEnableOptLoopInvariantCodeMotion_) 1854514f5e3Sopenharmony_ci .EnableOptConstantFolding(cOptions.isEnableOptConstantFolding_) 1864514f5e3Sopenharmony_ci .EnableLexenvSpecialization(cOptions.isEnableLexenvSpecialization_) 1874514f5e3Sopenharmony_ci .EnableInlineNative(cOptions.isEnableNativeInline_) 1884514f5e3Sopenharmony_ci .EnableLoweringBuiltin(cOptions.isEnableLoweringBuiltin_) 1894514f5e3Sopenharmony_ci .EnableOptBranchProfiling(cOptions.isEnableOptBranchProfiling_) 1904514f5e3Sopenharmony_ci .EnableEscapeAnalysis(cOptions.isEnableEscapeAnalysis_) 1914514f5e3Sopenharmony_ci .EnableInductionVariableAnalysis(cOptions.isEnableInductionVariableAnalysis_) 1924514f5e3Sopenharmony_ci .EnableVerifierPass(cOptions.isEnableVerifierPass_) 1934514f5e3Sopenharmony_ci .Build(); 1944514f5e3Sopenharmony_ci 1954514f5e3Sopenharmony_ci PassManager passManager(&aotCompilationEnv, 1964514f5e3Sopenharmony_ci cOptions.triple_, 1974514f5e3Sopenharmony_ci cOptions.optLevel_, 1984514f5e3Sopenharmony_ci cOptions.relocMode_, 1994514f5e3Sopenharmony_ci &log, 2004514f5e3Sopenharmony_ci &logList, 2014514f5e3Sopenharmony_ci cOptions.maxAotMethodSize_, 2024514f5e3Sopenharmony_ci cOptions.maxMethodsInModule_, 2034514f5e3Sopenharmony_ci profilerDecoder, 2044514f5e3Sopenharmony_ci &passOptions, 2054514f5e3Sopenharmony_ci cPreprocessor.GetCallMethodFlagMap(), 2064514f5e3Sopenharmony_ci cPreprocessor.GetAbcFileInfo(), 2074514f5e3Sopenharmony_ci cPreprocessor.GetBcInfoCollectors(), 2084514f5e3Sopenharmony_ci cOptions.optBCRange_); 2094514f5e3Sopenharmony_ci 2104514f5e3Sopenharmony_ci bool isEnableLiteCG = runtimeOptions.IsCompilerEnableLiteCG(); 2114514f5e3Sopenharmony_ci if (ohos::EnableAotJitListHelper::GetInstance()->IsEnableAot(bundleName)) { 2124514f5e3Sopenharmony_ci isEnableLiteCG = true; 2134514f5e3Sopenharmony_ci } 2144514f5e3Sopenharmony_ci vm->GetJSOptions().SetCompilerEnableLiteCG(isEnableLiteCG); 2154514f5e3Sopenharmony_ci compilerStats.SetIsLiteCg(isEnableLiteCG); 2164514f5e3Sopenharmony_ci 2174514f5e3Sopenharmony_ci AOTFileGenerator generator(&log, &logList, &aotCompilationEnv, cOptions.triple_, isEnableLiteCG); 2184514f5e3Sopenharmony_ci 2194514f5e3Sopenharmony_ci passManager.CompileValidFiles(generator, ret, compilerStats); 2204514f5e3Sopenharmony_ci if (compilerStats.GetCompilerMethodCount() == 0) { 2214514f5e3Sopenharmony_ci return runtimeOptions.IsPartialCompilerMode() ? ERR_AN_EMPTY : ERR_OK; 2224514f5e3Sopenharmony_ci } 2234514f5e3Sopenharmony_ci if (!generator.SaveAOTFile(cOptions.outputFileName_ + AOTFileManager::FILE_EXTENSION_AN, appSignature)) { 2244514f5e3Sopenharmony_ci return ERR_AN_FAIL; 2254514f5e3Sopenharmony_ci } 2264514f5e3Sopenharmony_ci if (!generator.SaveSnapshotFile()) { 2274514f5e3Sopenharmony_ci return ERR_AI_FAIL; 2284514f5e3Sopenharmony_ci } 2294514f5e3Sopenharmony_ci log.Print(); 2304514f5e3Sopenharmony_ci if (runtimeOptions.IsTargetCompilerMode()) { 2314514f5e3Sopenharmony_ci compilerStats.PrintCompilerStatsLog(); 2324514f5e3Sopenharmony_ci } 2334514f5e3Sopenharmony_ci if (IsExistsPkgInfo(cPreprocessor)) { 2344514f5e3Sopenharmony_ci ohos::EnableAotJitListHelper::GetInstance()->AddEnableListCount( 2354514f5e3Sopenharmony_ci ret, cPreprocessor.GetMainPkgArgs()->GetPgoDir()); 2364514f5e3Sopenharmony_ci } 2374514f5e3Sopenharmony_ci } 2384514f5e3Sopenharmony_ci 2394514f5e3Sopenharmony_ci if (vm->GetJSOptions().IsEnableCompilerLogSnapshot()) { 2404514f5e3Sopenharmony_ci vm->PrintAOTSnapShotStats(); 2414514f5e3Sopenharmony_ci } 2424514f5e3Sopenharmony_ci LOG_COMPILER(INFO) << (ret ? "ts aot compile success" : "ts aot compile failed"); 2434514f5e3Sopenharmony_ci JSNApi::DestroyJSVM(vm); 2444514f5e3Sopenharmony_ci return ret ? ERR_OK : ERR_FAIL; 2454514f5e3Sopenharmony_ci} 2464514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 2474514f5e3Sopenharmony_ci 2484514f5e3Sopenharmony_ciint main(const int argc, const char **argv) 2494514f5e3Sopenharmony_ci{ 2504514f5e3Sopenharmony_ci auto result = panda::ecmascript::kungfu::Main(argc, argv); 2514514f5e3Sopenharmony_ci return result; 2524514f5e3Sopenharmony_ci} 253