• 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 "ecmascript/compiler/stub_compiler.h"
17 
18 #include "ecmascript/base/config.h"
19 #include "ecmascript/base/string_helper.h"
20 #include "ecmascript/compiler/common_stubs.h"
21 #include "ecmascript/compiler/file_generators.h"
22 #include "ecmascript/compiler/interpreter_stub-inl.h"
23 #include "ecmascript/compiler/llvm_codegen.h"
24 #include "ecmascript/compiler/pass.h"
25 #include "ecmascript/compiler/scheduler.h"
26 #include "ecmascript/compiler/stub.h"
27 #include "ecmascript/compiler/stub_builder-inl.h"
28 #include "ecmascript/compiler/verifier.h"
29 #include "ecmascript/js_runtime_options.h"
30 #include "ecmascript/log.h"
31 #include "ecmascript/napi/include/jsnapi.h"
32 
33 namespace panda::ecmascript::kungfu {
34 class StubPassData : public PassData {
35 public:
StubPassData(Stub * stub,LLVMModule * module,CompilerLog * log)36     explicit StubPassData(Stub *stub, LLVMModule *module, CompilerLog *log)
37         : PassData(nullptr, nullptr, nullptr, log, "stubs"), module_(module), stub_(stub) {}
38     ~StubPassData() = default;
39 
GetCompilationConfig() const40     const CompilationConfig *GetCompilationConfig() const
41     {
42         return module_->GetCompilationConfig();
43     }
44 
GetCircuit() const45     Circuit *GetCircuit() const
46     {
47         return stub_->GetEnvironment()->GetCircuit();
48     }
49 
GetStubModule() const50     LLVMModule *GetStubModule() const
51     {
52         return module_;
53     }
54 
GetStub() const55     Stub *GetStub() const
56     {
57         return stub_;
58     }
59 
60 private:
61     LLVMModule *module_;
62     Stub *stub_;
63 };
64 
65 class StubBuildCircuitPass {
66 public:
Run(StubPassData * data)67     bool Run(StubPassData *data)
68     {
69         auto stub = data->GetStub();
70         LOG_COMPILER(INFO) << "Stub Name: " << stub->GetMethodName();
71         stub->GenerateCircuit(data->GetCompilationConfig());
72         return true;
73     }
74 };
75 
76 class StubLLVMIRGenPass {
77 public:
CreateCodeGen(LLVMModule * module,bool enableLog)78     void CreateCodeGen(LLVMModule *module, bool enableLog)
79     {
80         llvmImpl_ = std::make_unique<LLVMIRGeneratorImpl>(module, enableLog);
81     }
82 
Run(StubPassData * data,size_t index)83     bool Run(StubPassData *data, size_t index)
84     {
85         bool enableLog =  data->GetLog()->GetEnableMethodLog() && data->GetLog()->OutputCIR();
86         auto stubModule = data->GetStubModule();
87         CreateCodeGen(stubModule, enableLog);
88         CodeGenerator codegen(llvmImpl_, "stubs");
89         codegen.RunForStub(data->GetCircuit(), data->GetConstScheduleResult(), index, data->GetCompilationConfig());
90         return true;
91     }
92 private:
93     std::unique_ptr<CodeGeneratorImpl> llvmImpl_ {nullptr};
94 };
95 
RunPipeline(LLVMModule * module) const96 void StubCompiler::RunPipeline(LLVMModule *module) const
97 {
98     auto callSigns = module->GetCSigns();
99     CompilerLog *log = GetLog();
100     auto logList = GetLogList();
101     auto cconfig = module->GetCompilationConfig();
102     NativeAreaAllocator allocator;
103 
104     bool enableMethodLog = !log->NoneMethod();
105     for (size_t i = 0; i < callSigns.size(); i++) {
106         Circuit circuit(&allocator, cconfig->Is64Bit());
107         Stub stub(callSigns[i], &circuit);
108         ASSERT(callSigns[i]->HasConstructor());
109         void* env = reinterpret_cast<void*>(stub.GetEnvironment());
110         StubBuilder* stubBuilder = static_cast<StubBuilder*>(callSigns[i]->GetConstructor()(env));
111         stub.SetStubBuilder(stubBuilder);
112 
113         if (log->CertainMethod()) {
114             enableMethodLog = logList->IncludesMethod(stub.GetMethodName());
115         }
116         log->SetEnableMethodLog(enableMethodLog);
117 
118         StubPassData data(&stub, module, log);
119         PassRunner<StubPassData> pipeline(&data);
120         pipeline.RunPass<StubBuildCircuitPass>();
121         pipeline.RunPass<VerifierPass>();
122         pipeline.RunPass<SchedulingPass>();
123         pipeline.RunPass<StubLLVMIRGenPass>(i);
124         delete stubBuilder;
125     }
126 }
127 
InitializeCS() const128 void StubCompiler::InitializeCS() const
129 {
130     BytecodeStubCSigns::Initialize();
131     CommonStubCSigns::Initialize();
132     BuiltinsStubCSigns::Initialize();
133     RuntimeStubCSigns::Initialize();
134 }
135 
BuildStubModuleAndSave() const136 bool StubCompiler::BuildStubModuleAndSave() const
137 {
138     InitializeCS();
139     size_t res = 0;
140     CompilerLog *log = GetLog();
141     const MethodLogList *logList = GetLogList();
142     StubFileGenerator generator(log, logList, triple_, enablePGOProfiler_);
143     if (!filePath_.empty()) {
144         LOG_COMPILER(INFO) << "compiling bytecode handler stubs";
145         LLVMModule bcStubModule("bc_stub", triple_, enablePGOProfiler_);
146         LLVMAssembler bcStubAssembler(bcStubModule.GetModule(), LOptions(optLevel_, false, relocMode_));
147         bcStubModule.SetUpForBytecodeHandlerStubs();
148         RunPipeline(&bcStubModule);
149         generator.AddModule(&bcStubModule, &bcStubAssembler);
150         res++;
151 
152         LOG_COMPILER(INFO) << "compiling common stubs";
153         LLVMModule comStubModule("com_stub", triple_, enablePGOProfiler_);
154         LLVMAssembler comStubAssembler(comStubModule.GetModule(), LOptions(optLevel_, true, relocMode_));
155         comStubModule.SetUpForCommonStubs();
156         RunPipeline(&comStubModule);
157         generator.AddModule(&comStubModule, &comStubAssembler);
158         res++;
159 
160         LOG_COMPILER(INFO) << "compiling builtins stubs";
161         LLVMModule builtinsStubModule("builtins_stub", triple_, enablePGOProfiler_);
162         LLVMAssembler builtinsStubAssembler(builtinsStubModule.GetModule(), LOptions(optLevel_, true, relocMode_));
163         builtinsStubModule.SetUpForBuiltinsStubs();
164         RunPipeline(&builtinsStubModule);
165         generator.AddModule(&builtinsStubModule, &builtinsStubAssembler);
166         res++;
167         generator.SaveStubFile(filePath_);
168     }
169     return (res > 0);
170 }
GetHelper()171 std::string GetHelper()
172 {
173     std::string str;
174     str.append(STUB_HELP_HEAD_MSG);
175     str.append(HELP_OPTION_MSG);
176     return str;
177 }
178 }  // namespace panda::ecmascript::kungfu
179 
main(const int argc,const char ** argv)180 int main(const int argc, const char **argv)
181 {
182     panda::ecmascript::JSRuntimeOptions runtimeOptions;
183     bool ret = runtimeOptions.ParseCommand(argc, argv);
184     if (!ret) {
185         std::cerr << panda::ecmascript::kungfu::GetHelper();
186         return 1;
187     }
188 
189     panda::ecmascript::Log::Initialize(runtimeOptions);
190     std::string triple = runtimeOptions.GetTargetTriple();
191     std::string stubFile = runtimeOptions.GetStubFile();
192     size_t optLevel = runtimeOptions.GetOptLevel();
193     size_t relocMode = runtimeOptions.GetRelocMode();
194     std::string logOption = runtimeOptions.GetCompilerLogOption();
195     std::string methodsList = runtimeOptions.GetMethodsListForLog();
196     bool enablePGOProfiler = runtimeOptions.IsEnablePGOProfiler();
197     panda::ecmascript::kungfu::CompilerLog logOpt(logOption);
198     panda::ecmascript::kungfu::MethodLogList logList(methodsList);
199     panda::ecmascript::kungfu::StubCompiler compiler(
200         triple, stubFile, optLevel, relocMode, &logOpt, &logList, enablePGOProfiler);
201 
202     bool res = compiler.BuildStubModuleAndSave();
203     LOG_COMPILER(INFO) << "stub compiler run finish, result condition(T/F):" << std::boolalpha << res;
204     return res ? 0 : -1;
205 }
206