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 <signal.h> // NOLINTNEXTLINE(modernize-deprecated-headers)
19 #include <vector>
20
21 #include "ecmascript/aot_file_manager.h"
22 #include "ecmascript/base/string_helper.h"
23 #include "ecmascript/compiler/pass_manager.h"
24 #include "ecmascript/compiler/compiler_log.h"
25 #include "ecmascript/ecma_string.h"
26 #include "ecmascript/ecma_vm.h"
27 #include "ecmascript/js_runtime_options.h"
28 #include "ecmascript/log.h"
29 #include "ecmascript/napi/include/jsnapi.h"
30 #include "ecmascript/platform/file.h"
31
32 namespace panda::ecmascript::kungfu {
GetHelper()33 std::string GetHelper()
34 {
35 std::string str;
36 str.append(COMMON_HELP_HEAD_MSG);
37 str.append(HELP_OPTION_MSG);
38 str.append(HELP_TAIL_MSG);
39 return str;
40 }
41
AOTInitialize(EcmaVM * vm)42 void AOTInitialize(EcmaVM *vm)
43 {
44 BytecodeStubCSigns::Initialize();
45 CommonStubCSigns::Initialize();
46 RuntimeStubCSigns::Initialize();
47 vm->GetTSManager()->Initialize();
48 }
49
Main(const int argc,const char ** argv)50 int Main(const int argc, const char **argv)
51 {
52 auto startTime =
53 std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch())
54 .count();
55 std::string entrypoint = "init::func_main_0";
56
57 int newArgc = argc;
58 if (argc < 2) { // 2: at least have two arguments
59 std::cerr << GetHelper();
60 return -1;
61 }
62
63 std::string files = argv[argc - 1];
64 if (!base::StringHelper::EndsWith(files, ".abc")) {
65 std::cerr << "The last argument must be abc file" << std::endl;
66 std::cerr << GetHelper();
67 return 1;
68 }
69
70 newArgc--;
71 JSRuntimeOptions runtimeOptions;
72 bool retOpt = runtimeOptions.ParseCommand(newArgc, argv);
73 if (!retOpt) {
74 std::cerr << GetHelper();
75 return 1;
76 }
77
78 if (runtimeOptions.IsStartupTime()) {
79 LOG_COMPILER(DEBUG) << "Startup start time: " << startTime;
80 }
81
82 bool ret = true;
83 // ark_aot_compiler running need disable asm interpreter to disable the loading of AOT files.
84 runtimeOptions.SetEnableAsmInterpreter(false);
85 EcmaVM *vm = JSNApi::CreateEcmaVM(runtimeOptions);
86 if (vm == nullptr) {
87 LOG_COMPILER(ERROR) << "Cannot Create vm";
88 return -1;
89 }
90
91 {
92 LocalScope scope(vm);
93 std::string delimiter = GetFileDelimiter();
94 arg_list_t pandaFileNames = base::StringHelper::SplitString(files, delimiter);
95 std::string triple = runtimeOptions.GetTargetTriple();
96 if (runtimeOptions.GetAOTOutputFile().empty()) {
97 runtimeOptions.SetAOTOutputFile("aot_file");
98 }
99 std::string outputFileName = runtimeOptions.GetAOTOutputFile();
100 size_t optLevel = runtimeOptions.GetOptLevel();
101 size_t relocMode = runtimeOptions.GetRelocMode();
102 std::string logOption = runtimeOptions.GetCompilerLogOption();
103 std::string logMethodsList = runtimeOptions.GetMethodsListForLog();
104 bool compilerLogTime = runtimeOptions.IsEnableCompilerLogTime();
105 bool isTraceBC = runtimeOptions.IsTraceBC();
106 size_t maxAotMethodSize = runtimeOptions.GetMaxAotMethodSize();
107 bool isEnableTypeLowering = runtimeOptions.IsEnableTypeLowering();
108 uint32_t hotnessThreshold = runtimeOptions.GetPGOHotnessThreshold();
109 AOTInitialize(vm);
110
111 CompilerLog log(logOption, isTraceBC);
112 log.SetEnableCompilerLogTime(compilerLogTime);
113 AotMethodLogList logList(logMethodsList);
114 AOTFileGenerator generator(&log, &logList, vm, triple);
115 std::string profilerIn(runtimeOptions.GetPGOProfilerPath());
116 if (runtimeOptions.WasSetEntryPoint()) {
117 entrypoint = runtimeOptions.GetEntryPoint();
118 }
119 PassManager passManager(vm, entrypoint, triple, optLevel, relocMode, &log, &logList, maxAotMethodSize,
120 isEnableTypeLowering, profilerIn, hotnessThreshold);
121 for (const auto &fileName : pandaFileNames) {
122 auto extendedFilePath = panda::os::file::File::GetExtendedFilePath(fileName);
123 LOG_COMPILER(INFO) << "AOT compile: " << extendedFilePath;
124 if (passManager.Compile(extendedFilePath, generator) == false) {
125 ret = false;
126 continue;
127 }
128 }
129 generator.SaveAOTFile(outputFileName + AOTFileManager::FILE_EXTENSION_AN);
130 generator.SaveSnapshotFile();
131 log.Print();
132 }
133
134 LOG_COMPILER(INFO) << (ret ? "ts aot compile success" : "ts aot compile failed");
135 JSNApi::DestroyJSVM(vm);
136 return ret ? 0 : -1;
137 }
138 } // namespace panda::ecmascript::kungfu
139
main(const int argc,const char ** argv)140 int main(const int argc, const char **argv)
141 {
142 auto result = panda::ecmascript::kungfu::Main(argc, argv);
143 return result;
144 }
145