• 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 #include "libpandafile/bytecode_instruction-inl.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         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             return -1;
111         case JSCallMode::CALL_GETTER:
112             return 0;
113         case JSCallMode::CALL_SETTER:
114             return 1;
115         default:
116             UNREACHABLE();
117     }
118 }
119 
IsCallNew(JSCallMode mode)120 bool AssemblerModule::IsCallNew(JSCallMode mode)
121 {
122     switch (mode) {
123         case JSCallMode::CALL_ARG0:
124         case JSCallMode::CALL_THIS_ARG0:
125         case JSCallMode::DEPRECATED_CALL_ARG0:
126         case JSCallMode::CALL_ARG1:
127         case JSCallMode::CALL_THIS_ARG1:
128         case JSCallMode::DEPRECATED_CALL_ARG1:
129         case JSCallMode::CALL_ARG2:
130         case JSCallMode::CALL_THIS_ARG2:
131         case JSCallMode::DEPRECATED_CALL_ARG2:
132         case JSCallMode::CALL_ARG3:
133         case JSCallMode::CALL_THIS_ARG3:
134         case JSCallMode::DEPRECATED_CALL_ARG3:
135         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
136         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
137         case JSCallMode::CALL_THIS_WITH_ARGV:
138         case JSCallMode::CALL_WITH_ARGV:
139         case JSCallMode::CALL_GETTER:
140         case JSCallMode::CALL_SETTER:
141         case JSCallMode::CALL_ENTRY:
142         case JSCallMode::CALL_FROM_AOT:
143         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
144             return false;
145         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
146         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
147             return true;
148         default:
149             UNREACHABLE();
150     }
151     return false;
152 }
153 
JSModeHaveThisArg(JSCallMode mode)154 bool AssemblerModule::JSModeHaveThisArg(JSCallMode mode)
155 {
156     switch (mode) {
157         case JSCallMode::CALL_ARG0:
158         case JSCallMode::CALL_ARG1:
159         case JSCallMode::CALL_ARG2:
160         case JSCallMode::CALL_ARG3:
161         case JSCallMode::DEPRECATED_CALL_ARG0:
162         case JSCallMode::DEPRECATED_CALL_ARG1:
163         case JSCallMode::DEPRECATED_CALL_ARG2:
164         case JSCallMode::DEPRECATED_CALL_ARG3:
165         case JSCallMode::CALL_WITH_ARGV:
166         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
167             return false;
168         case JSCallMode::CALL_THIS_ARG0:
169         case JSCallMode::CALL_THIS_ARG1:
170         case JSCallMode::CALL_THIS_ARG2:
171         case JSCallMode::CALL_THIS_ARG3:
172         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
173         case JSCallMode::CALL_THIS_WITH_ARGV:
174         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
175         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
176         case JSCallMode::CALL_ENTRY:
177         case JSCallMode::CALL_FROM_AOT:
178         case JSCallMode::CALL_GETTER:
179         case JSCallMode::CALL_SETTER:
180         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
181             return true;
182         default:
183             UNREACHABLE();
184     }
185 }
186 
JSModeHaveNewTargetArg(JSCallMode mode)187 bool AssemblerModule::JSModeHaveNewTargetArg(JSCallMode mode)
188 {
189     switch (mode) {
190         case JSCallMode::CALL_ARG0:
191         case JSCallMode::CALL_ARG1:
192         case JSCallMode::CALL_ARG2:
193         case JSCallMode::CALL_ARG3:
194         case JSCallMode::DEPRECATED_CALL_ARG0:
195         case JSCallMode::DEPRECATED_CALL_ARG1:
196         case JSCallMode::DEPRECATED_CALL_ARG2:
197         case JSCallMode::DEPRECATED_CALL_ARG3:
198         case JSCallMode::CALL_WITH_ARGV:
199         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
200         case JSCallMode::CALL_THIS_WITH_ARGV:
201         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
202         case JSCallMode::CALL_GETTER:
203         case JSCallMode::CALL_SETTER:
204         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
205         case JSCallMode::CALL_THIS_ARG0:
206         case JSCallMode::CALL_THIS_ARG1:
207         case JSCallMode::CALL_THIS_ARG2:
208         case JSCallMode::CALL_THIS_ARG3:
209             return false;
210         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
211         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
212         case JSCallMode::CALL_ENTRY:
213         case JSCallMode::CALL_FROM_AOT:
214             return true;
215         default:
216             UNREACHABLE();
217     }
218 }
219 
IsJumpToCallCommonEntry(JSCallMode mode)220 bool AssemblerModule::IsJumpToCallCommonEntry(JSCallMode mode)
221 {
222     switch (mode) {
223         case JSCallMode::CALL_ARG0:
224         case JSCallMode::CALL_ARG1:
225         case JSCallMode::CALL_ARG2:
226         case JSCallMode::CALL_ARG3:
227         case JSCallMode::DEPRECATED_CALL_ARG0:
228         case JSCallMode::DEPRECATED_CALL_ARG1:
229         case JSCallMode::DEPRECATED_CALL_ARG2:
230         case JSCallMode::DEPRECATED_CALL_ARG3:
231         case JSCallMode::CALL_WITH_ARGV:
232         case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
233         case JSCallMode::CALL_THIS_WITH_ARGV:
234         case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
235         case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
236         case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
237         case JSCallMode::CALL_THIS_ARG0:
238         case JSCallMode::CALL_THIS_ARG1:
239         case JSCallMode::CALL_THIS_ARG2:
240         case JSCallMode::CALL_THIS_ARG3:
241             return true;
242         case JSCallMode::CALL_GETTER:
243         case JSCallMode::CALL_SETTER:
244         case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
245         case JSCallMode::CALL_ENTRY:
246         case JSCallMode::CALL_GENERATOR:
247         case JSCallMode::CALL_FROM_AOT:
248             return false;
249         default:
250             UNREACHABLE();
251     }
252     return false;
253 }
254 
255 #define DECLARE_ASM_STUB_X64_GENERATE(name)                                                       \
256 void name##Stub::GenerateX64(Assembler *assembler)                                                \
257 {                                                                                                 \
258     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
259     x64::AssemblerStubsX64::name(assemblerX64);                                                   \
260     assemblerX64->Align16();                                                                      \
261 }
262 
263 #define DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE(name)                                              \
264 void name##Stub::GenerateX64(Assembler *assembler)                                                \
265 {                                                                                                 \
266     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
267     x64::OptimizedCall::name(assemblerX64);                                                       \
268     assemblerX64->Align16();                                                                      \
269 }
270 
271 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE(name)                                     \
272 void name##Stub::GenerateX64(Assembler *assembler)                                                \
273 {                                                                                                 \
274     x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler);       \
275     x64::AsmInterpreterCall::name(assemblerX64);                                                  \
276     assemblerX64->Align16();                                                                      \
277 }
278 
279 
280 #define DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE(name)                                                \
281 void name##Stub::GenerateAarch64(Assembler *assembler)                                                  \
282 {                                                                                                       \
283     aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \
284     aarch64::OptimizedCall::name(assemblerAarch64);                                                     \
285 }
286 
287 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE(name)                                       \
288 void name##Stub::GenerateAarch64(Assembler *assembler)                                                  \
289 {                                                                                                       \
290     aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \
291     aarch64::AsmInterpreterCall::name(assemblerAarch64);                                                \
292 }
293 
294 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE)
295 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE)
296 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE)
297 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE)
298 #undef DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE
299 #undef DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE
300 }  // namespace panda::ecmascript::kunfu
301