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