1 /*
2 * Copyright (c) 2023 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 <csignal> // NOLINTNEXTLINE(modernize-deprecated-headers)
19 #include <vector>
20
21 #include "ecmascript/compiler/jit_compiler.h"
22
23 #include "ecmascript/log.h"
24 #include "ecmascript/napi/include/jsnapi.h"
25 #include "ecmascript/platform/file.h"
26
27 namespace panda::ecmascript::kungfu {
JitCompilationOptions(JSRuntimeOptions & runtimeOptions,EcmaVM * vm)28 JitCompilationOptions::JitCompilationOptions(JSRuntimeOptions &runtimeOptions, EcmaVM *vm)
29 {
30 triple_ = runtimeOptions.GetTargetTriple();
31 optLevel_ = runtimeOptions.GetOptLevel();
32 relocMode_ = runtimeOptions.GetRelocMode();
33 logOption_ = runtimeOptions.GetCompilerLogOption();
34 logMethodsList_ = runtimeOptions.GetMethodsListForLog();
35 compilerLogTime_ = runtimeOptions.IsEnableCompilerLogTime();
36 hotnessThreshold_ = runtimeOptions.GetPGOHotnessThreshold();
37 profilerIn_ = std::string(runtimeOptions.GetPGOProfilerPath());
38 isEnableArrayBoundsCheckElimination_ = runtimeOptions.IsEnableArrayBoundsCheckElimination();
39 isEnableTypeLowering_ = runtimeOptions.IsEnableTypeLowering();
40 isEnableEarlyElimination_ = runtimeOptions.IsEnableEarlyElimination();
41 isEnableLaterElimination_ = runtimeOptions.IsEnableLaterElimination();
42 isEnableValueNumbering_ = runtimeOptions.IsEnableValueNumbering();
43 isEnableOptInlining_ = runtimeOptions.IsEnableOptInlining();
44 isEnableOptString_ = runtimeOptions.IsEnableOptString();
45 isEnableTypeInfer_ =
46 isEnableTypeLowering_ || vm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->AssertTypes();
47 isEnableOptPGOType_ = runtimeOptions.IsEnableOptPGOType();
48 isEnableOptTrackField_ = runtimeOptions.IsEnableOptTrackField();
49 isEnableOptLoopPeeling_ = runtimeOptions.IsEnableOptLoopPeeling();
50 isEnableOptOnHeapCheck_ = runtimeOptions.IsEnableOptOnHeapCheck();
51 isEnableOptLoopInvariantCodeMotion_ = runtimeOptions.IsEnableOptLoopInvariantCodeMotion();
52 isEnableCollectLiteralInfo_ = false;
53 isEnableOptConstantFolding_ = runtimeOptions.IsEnableOptConstantFolding();
54 isEnableLexenvSpecialization_ = runtimeOptions.IsEnableLexenvSpecialization();
55 isEnableNativeInline_ = runtimeOptions.IsEnableNativeInline();
56 isEnableLoweringBuiltin_ = runtimeOptions.IsEnableLoweringBuiltin();
57 }
58
Init()59 void JitCompiler::Init()
60 {
61 log_.SetEnableCompilerLogTime(jitOptions_.compilerLogTime_);
62 PassOptions::Builder optionsBuilder;
63 passOptions_ =
64 optionsBuilder.EnableArrayBoundsCheckElimination(jitOptions_.isEnableArrayBoundsCheckElimination_)
65 .EnableTypeLowering(jitOptions_.isEnableTypeLowering_)
66 .EnableEarlyElimination(jitOptions_.isEnableEarlyElimination_)
67 .EnableLaterElimination(jitOptions_.isEnableLaterElimination_)
68 .EnableValueNumbering(jitOptions_.isEnableValueNumbering_)
69 .EnableTypeInfer(jitOptions_.isEnableTypeInfer_)
70 .EnableOptInlining(jitOptions_.isEnableOptInlining_)
71 .EnableOptString(jitOptions_.isEnableOptString_)
72 .EnableOptPGOType(jitOptions_.isEnableOptPGOType_)
73 .EnableOptTrackField(jitOptions_.isEnableOptTrackField_)
74 .EnableOptLoopPeeling(jitOptions_.isEnableOptLoopPeeling_)
75 .EnableOptLoopInvariantCodeMotion(jitOptions_.isEnableOptLoopInvariantCodeMotion_)
76 .EnableCollectLiteralInfo(jitOptions_.isEnableCollectLiteralInfo_)
77 .EnableOptConstantFolding(jitOptions_.isEnableOptConstantFolding_)
78 .EnableLexenvSpecialization(jitOptions_.isEnableLexenvSpecialization_)
79 .EnableInlineNative(jitOptions_.isEnableNativeInline_)
80 .EnableLoweringBuiltin(jitOptions_.isEnableLoweringBuiltin_)
81 .Build();
82 passManager_ = new JitPassManager(vm_,
83 jitOptions_.triple_,
84 jitOptions_.optLevel_,
85 jitOptions_.relocMode_,
86 &log_,
87 &logList_,
88 profilerDecoder_,
89 &passOptions_);
90 aotFileGenerator_ = new AOTFileGenerator(&log_, &logList_, vm_, jitOptions_.triple_,
91 vm_->GetJSOptions().IsCompilerEnableLiteCG());
92 }
93
Create(EcmaVM * vm,JitTask * jitTask)94 JitCompiler *JitCompiler::Create(EcmaVM *vm, JitTask *jitTask)
95 {
96 BytecodeStubCSigns::Initialize();
97 CommonStubCSigns::Initialize();
98 RuntimeStubCSigns::Initialize();
99 TSManager *tsm = new TSManager(vm);
100 vm->GetJSThread()->GetCurrentEcmaContext()->SetTSManager(tsm);
101 vm->GetJSThread()->GetCurrentEcmaContext()->GetTSManager()->Initialize();
102
103 auto jitCompiler = new JitCompiler(vm, jitTask->GetJsFunction());
104 return jitCompiler;
105 }
106
~JitCompiler()107 JitCompiler::~JitCompiler()
108 {
109 if (passManager_ != nullptr) {
110 delete passManager_;
111 passManager_ = nullptr;
112 }
113 if (aotFileGenerator_ != nullptr) {
114 delete aotFileGenerator_;
115 aotFileGenerator_ = nullptr;
116 }
117 }
118
Compile()119 bool JitCompiler::Compile()
120 {
121 return passManager_->Compile(jsFunction_, *aotFileGenerator_);
122 }
123
Finalize(JitTask * jitTask)124 bool JitCompiler::Finalize(JitTask *jitTask)
125 {
126 aotFileGenerator_->JitCreateLitecgModule();
127 passManager_->RunCg();
128 aotFileGenerator_->GetMemoryCodeInfos(jitTask->GetMachineCodeDesc());
129 return true;
130 }
131
CreateJitCompiler(EcmaVM * vm,JitTask * jitTask)132 void *CreateJitCompiler(EcmaVM *vm, JitTask *jitTask)
133 {
134 auto jitCompiler = JitCompiler::Create(vm, jitTask);
135 return jitCompiler;
136 }
137
JitCompile(void * compiler,JitTask * jitTask)138 bool JitCompile(void *compiler, JitTask *jitTask [[maybe_unused]])
139 {
140 ASSERT(jitTask != nullptr);
141 ASSERT(compiler != nullptr);
142 auto jitCompiler = reinterpret_cast<JitCompiler *>(compiler);
143 bool ret = jitCompiler->Compile();
144
145 return ret;
146 }
147
JitFinalize(void * compiler,JitTask * jitTask)148 bool JitFinalize(void *compiler, JitTask *jitTask)
149 {
150 ASSERT(jitTask != nullptr);
151 ASSERT(compiler != nullptr);
152 auto jitCompiler = reinterpret_cast<JitCompiler *>(compiler);
153 bool ret = jitCompiler->Finalize(jitTask);
154 return ret;
155 }
156
DeleteJitCompile(void * handle)157 void DeleteJitCompile(void *handle)
158 {
159 ASSERT(handle != nullptr);
160 delete reinterpret_cast<JitCompiler *>(handle);
161 }
162 } // namespace panda::ecmascript::kungfu
163