• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/assembler_module.h"
17 
18 #include "ecmascript/compiler/assembler/aarch64/assembler_aarch64.h"
19 #include "ecmascript/compiler/assembler/x64/assembler_x64.h"
20 #include "ecmascript/compiler/call_signature.h"
21 #include "ecmascript/compiler/circuit_builder.h"
22 #include "ecmascript/compiler/circuit_builder_helper.h"
23 #include "ecmascript/compiler/trampoline/aarch64/common_call.h"
24 #include "ecmascript/compiler/trampoline/x64/common_call.h"
25 #include "ecmascript/compiler/rt_call_signature.h"
26 
27 namespace panda::ecmascript::kungfu {
Run(const CompilationConfig * cfg,Chunk * chunk)28 void AssemblerModule::Run(const CompilationConfig *cfg, Chunk* chunk)
29 {
30     SetUpForAsmStubs();
31     if (cfg->IsAmd64()) {
32         GenerateStubsX64(chunk);
33     } else if (cfg->IsAArch64()) {
34         GenerateStubsAarch64(chunk);
35     } else {
36         LOG_ECMA(FATAL) << "this branch is unreachable";
37         UNREACHABLE();
38     }
39 }
40 
GenerateStubsX64(Chunk * chunk)41 void AssemblerModule::GenerateStubsX64(Chunk* chunk)
42 {
43     x64::ExtendedAssembler assembler(chunk, this);
44     LOG_COMPILER(INFO) << "================ compiling asm stubs ================";
45     for (size_t i = 0; i < asmCallSigns_.size(); i++) {
46         auto cs = asmCallSigns_[i];
47         ASSERT(cs->HasConstructor());
48         LOG_COMPILER(INFO) << "Stub Name: " << cs->GetName();
49         stubsOffset_.emplace_back(assembler.GetCurrentPosition());
50         AssemblerStub *stub = static_cast<AssemblerStub*>(
51             cs->GetConstructor()(nullptr));
52         stub->GenerateX64(&assembler);
53         delete stub;
54     }
55     buffer_ = assembler.GetBegin();
56     bufferSize_ = assembler.GetCurrentPosition();
57     stubsOffset_.emplace_back(static_cast<uint32_t>(bufferSize_));
58 }
59 
GenerateStubsAarch64(Chunk * chunk)60 void AssemblerModule::GenerateStubsAarch64(Chunk* chunk)
61 {
62     aarch64::ExtendedAssembler assembler(chunk, this);
63     LOG_COMPILER(INFO) << "================ compiling asm stubs ================";
64     for (size_t i = 0; i < asmCallSigns_.size(); i++) {
65         auto cs = asmCallSigns_[i];
66         ASSERT(cs->HasConstructor());
67         LOG_COMPILER(INFO) << "Stub Name: " << cs->GetName();
68         stubsOffset_.emplace_back(assembler.GetCurrentPosition());
69         AssemblerStub *stub = static_cast<AssemblerStub*>(
70             cs->GetConstructor()(nullptr));
71         stub->GenerateAarch64(&assembler);
72         delete stub;
73     }
74     buffer_ = assembler.GetBegin();
75     bufferSize_ = assembler.GetCurrentPosition();
76     stubsOffset_.emplace_back(static_cast<uint32_t>(bufferSize_));
77 }
78 
SetUpForAsmStubs()79 void AssemblerModule::SetUpForAsmStubs()
80 {
81     RuntimeStubCSigns::GetASMCSigns(asmCallSigns_);
82     for (auto cs : asmCallSigns_) {
83         symbolTable_[cs->GetID()] = new panda::ecmascript::Label();
84     }
85 }
86 
GetArgcFromJSCallMode(JSCallMode mode)87 int AssemblerModule::GetArgcFromJSCallMode(JSCallMode mode)
88 {
89     switch (mode) {
90         case JSCallMode::CALL_ARG0:
91         case JSCallMode::CALL_THIS_ARG0:
92         case JSCallMode::DEPRECATED_CALL_ARG0:
93             return 0;
94         case JSCallMode::CALL_ARG1:
95         case JSCallMode::CALL_THIS_ARG1:
96         case JSCallMode::DEPRECATED_CALL_ARG1:
97             return 1;
98         case JSCallMode::CALL_ARG2:
99         case JSCallMode::CALL_THIS_ARG2:
100         case JSCallMode::DEPRECATED_CALL_ARG2:
101         case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
102             return 2; // 2: arg2
103         case JSCallMode::CALL_ARG3:
104         case JSCallMode::CALL_THIS_ARG3:
105         case JSCallMode::DEPRECATED_CALL_ARG3:
106         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
107             return 3; // 3: arg3
108         case JSCallMode::CALL_THIS_WITH_ARGV:
109         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
110         case JSCallMode::CALL_WITH_ARGV:
111         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
112         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
113         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
114         case JSCallMode::SUPER_CALL_WITH_ARGV:
115         case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
116         case JSCallMode::CALL_ENTRY:
117         case JSCallMode::CALL_FROM_AOT:
118         case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
119             return -1;
120         case JSCallMode::CALL_GETTER:
121             return 0;
122         case JSCallMode::CALL_SETTER:
123             return 1;
124         default:
125             LOG_ECMA(FATAL) << "this branch is unreachable";
126             UNREACHABLE();
127     }
128 }
129 
IsCallNew(JSCallMode mode)130 bool AssemblerModule::IsCallNew(JSCallMode mode)
131 {
132     switch (mode) {
133         case JSCallMode::CALL_ARG0:
134         case JSCallMode::CALL_THIS_ARG0:
135         case JSCallMode::DEPRECATED_CALL_ARG0:
136         case JSCallMode::CALL_ARG1:
137         case JSCallMode::CALL_THIS_ARG1:
138         case JSCallMode::DEPRECATED_CALL_ARG1:
139         case JSCallMode::CALL_ARG2:
140         case JSCallMode::CALL_THIS_ARG2:
141         case JSCallMode::DEPRECATED_CALL_ARG2:
142         case JSCallMode::CALL_ARG3:
143         case JSCallMode::CALL_THIS_ARG3:
144         case JSCallMode::DEPRECATED_CALL_ARG3:
145         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
146         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
147         case JSCallMode::CALL_THIS_WITH_ARGV:
148         case JSCallMode::CALL_WITH_ARGV:
149         case JSCallMode::CALL_GETTER:
150         case JSCallMode::CALL_SETTER:
151         case JSCallMode::CALL_ENTRY:
152         case JSCallMode::CALL_FROM_AOT:
153         case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
154         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
155         case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
156             return false;
157         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
158         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
159         case JSCallMode::SUPER_CALL_WITH_ARGV:
160         case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
161             return true;
162         default:
163             LOG_ECMA(FATAL) << "this branch is unreachable";
164             UNREACHABLE();
165     }
166     return false;
167 }
168 
JSModeHaveThisArg(JSCallMode mode)169 bool AssemblerModule::JSModeHaveThisArg(JSCallMode mode)
170 {
171     switch (mode) {
172         case JSCallMode::CALL_ARG0:
173         case JSCallMode::CALL_ARG1:
174         case JSCallMode::CALL_ARG2:
175         case JSCallMode::CALL_ARG3:
176         case JSCallMode::DEPRECATED_CALL_ARG0:
177         case JSCallMode::DEPRECATED_CALL_ARG1:
178         case JSCallMode::DEPRECATED_CALL_ARG2:
179         case JSCallMode::DEPRECATED_CALL_ARG3:
180         case JSCallMode::CALL_WITH_ARGV:
181         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
182             return false;
183         case JSCallMode::CALL_THIS_ARG0:
184         case JSCallMode::CALL_THIS_ARG1:
185         case JSCallMode::CALL_THIS_ARG2:
186         case JSCallMode::CALL_THIS_ARG3:
187         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
188         case JSCallMode::CALL_THIS_WITH_ARGV:
189         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
190         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
191         case JSCallMode::SUPER_CALL_WITH_ARGV:
192         case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
193         case JSCallMode::CALL_ENTRY:
194         case JSCallMode::CALL_FROM_AOT:
195         case JSCallMode::CALL_GETTER:
196         case JSCallMode::CALL_SETTER:
197         case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
198         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
199         case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
200             return true;
201         default:
202             LOG_ECMA(FATAL) << "this branch is unreachable";
203             UNREACHABLE();
204     }
205 }
206 
JSModeHaveNewTargetArg(JSCallMode mode)207 bool AssemblerModule::JSModeHaveNewTargetArg(JSCallMode mode)
208 {
209     switch (mode) {
210         case JSCallMode::CALL_ARG0:
211         case JSCallMode::CALL_ARG1:
212         case JSCallMode::CALL_ARG2:
213         case JSCallMode::CALL_ARG3:
214         case JSCallMode::DEPRECATED_CALL_ARG0:
215         case JSCallMode::DEPRECATED_CALL_ARG1:
216         case JSCallMode::DEPRECATED_CALL_ARG2:
217         case JSCallMode::DEPRECATED_CALL_ARG3:
218         case JSCallMode::CALL_WITH_ARGV:
219         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
220         case JSCallMode::CALL_THIS_WITH_ARGV:
221         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
222         case JSCallMode::CALL_GETTER:
223         case JSCallMode::CALL_SETTER:
224         case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
225         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
226         case JSCallMode::CALL_THIS_ARG0:
227         case JSCallMode::CALL_THIS_ARG1:
228         case JSCallMode::CALL_THIS_ARG2:
229         case JSCallMode::CALL_THIS_ARG3:
230         case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
231             return false;
232         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
233         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
234         case JSCallMode::SUPER_CALL_WITH_ARGV:
235         case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
236         case JSCallMode::CALL_ENTRY:
237         case JSCallMode::CALL_FROM_AOT:
238             return true;
239         default:
240             LOG_ECMA(FATAL) << "this branch is unreachable";
241             UNREACHABLE();
242     }
243 }
244 
IsJumpToCallCommonEntry(JSCallMode mode)245 bool AssemblerModule::IsJumpToCallCommonEntry(JSCallMode mode)
246 {
247     switch (mode) {
248         case JSCallMode::CALL_ARG0:
249         case JSCallMode::CALL_ARG1:
250         case JSCallMode::CALL_ARG2:
251         case JSCallMode::CALL_ARG3:
252         case JSCallMode::DEPRECATED_CALL_ARG0:
253         case JSCallMode::DEPRECATED_CALL_ARG1:
254         case JSCallMode::DEPRECATED_CALL_ARG2:
255         case JSCallMode::DEPRECATED_CALL_ARG3:
256         case JSCallMode::CALL_WITH_ARGV:
257         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
258         case JSCallMode::CALL_THIS_WITH_ARGV:
259         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
260         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
261         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
262         case JSCallMode::SUPER_CALL_WITH_ARGV:
263         case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
264         case JSCallMode::CALL_THIS_ARG0:
265         case JSCallMode::CALL_THIS_ARG1:
266         case JSCallMode::CALL_THIS_ARG2:
267         case JSCallMode::CALL_THIS_ARG3:
268             return true;
269         case JSCallMode::CALL_GETTER:
270         case JSCallMode::CALL_SETTER:
271         case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
272         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
273         case JSCallMode::CALL_ENTRY:
274         case JSCallMode::CALL_GENERATOR:
275         case JSCallMode::CALL_FROM_AOT:
276         case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
277             return false;
278         default:
279             LOG_ECMA(FATAL) << "this branch is unreachable";
280             UNREACHABLE();
281     }
282     return false;
283 }
284 
285 #define DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE(name)                                              \
286 void name##Stub::GenerateX64(Assembler *assembler)                                                \
287 {                                                                                                 \
288     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
289     x64::OptimizedCall::name(assemblerX64);                                                       \
290     assemblerX64->Align16();                                                                      \
291 }
292 
293 #define DECLARE_FAST_CALL_TRAMPOLINE_X64_GENERATE(name)                                           \
294 void name##Stub::GenerateX64(Assembler *assembler)                                                \
295 {                                                                                                 \
296     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
297     x64::OptimizedFastCall::name(assemblerX64);                                                   \
298     assemblerX64->Align16();                                                                      \
299 }
300 
301 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE(name)                                     \
302 void name##Stub::GenerateX64(Assembler *assembler)                                                \
303 {                                                                                                 \
304     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
305     x64::AsmInterpreterCall::name(assemblerX64);                                                  \
306     assemblerX64->Align16();                                                                      \
307 }
308 
309 #define DECLARE_BASELINE_TRAMPOLINE_X64_GENERATE(name)                                            \
310 void name##Stub::GenerateX64(Assembler *assembler)                                                \
311 {                                                                                                 \
312     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
313     x64::BaselineCall::name(assemblerX64);                                                        \
314     assemblerX64->Align16();                                                                      \
315 }
316 
317 
318 #define DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE(name)                                                \
319 void name##Stub::GenerateAarch64(Assembler *assembler)                                                  \
320 {                                                                                                       \
321     aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \
322     aarch64::OptimizedCall::name(assemblerAarch64);                                                     \
323 }
324 
325 #define DECLARE_FAST_CALL_TRAMPOLINE_AARCH64_GENERATE(name)                                             \
326 void name##Stub::GenerateAarch64(Assembler *assembler)                                                  \
327 {                                                                                                       \
328     aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \
329     aarch64::OptimizedFastCall::name(assemblerAarch64);                                                 \
330 }
331 
332 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE(name)                                       \
333 void name##Stub::GenerateAarch64(Assembler *assembler)                                                  \
334 {                                                                                                       \
335     aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \
336     aarch64::AsmInterpreterCall::name(assemblerAarch64);                                                \
337 }
338 
339 #define DECLARE_BASELINE_TRAMPOLINE_AARCH64_GENERATE(name)                                              \
340 void name##Stub::GenerateAarch64(Assembler *assembler)                                                  \
341 {                                                                                                       \
342     aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \
343     aarch64::BaselineCall::name(assemblerAarch64);                                                      \
344 }
345 
346 
347 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE)
348 FAST_CALL_TRAMPOLINE_LIST(DECLARE_FAST_CALL_TRAMPOLINE_X64_GENERATE)
349 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE)
350 BASELINE_TRAMPOLINE_LIST(DECLARE_BASELINE_TRAMPOLINE_X64_GENERATE)
351 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE)
352 FAST_CALL_TRAMPOLINE_LIST(DECLARE_FAST_CALL_TRAMPOLINE_AARCH64_GENERATE)
353 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE)
354 BASELINE_TRAMPOLINE_LIST(DECLARE_BASELINE_TRAMPOLINE_AARCH64_GENERATE)
355 #undef DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE
356 #undef DECLARE_FAST_CALL_TRAMPOLINE_X64_GENERATE
357 #undef DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE
358 #undef DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE
359 #undef DECLARE_FAST_CALL_TRAMPOLINE_AARCH64_GENERATE
360 #undef DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE
361 }  // namespace panda::ecmascript::kunfu
362