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