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)28void 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)41void 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 AssemblerStub *stub = static_cast<AssemblerStub*>( 50 cs->GetConstructor()(nullptr)); 51 stub->GenerateX64(&assembler); 52 delete stub; 53 } 54 buffer_ = assembler.GetBegin(); 55 bufferSize_ = assembler.GetCurrentPosition(); 56 } 57 GenerateStubsAarch64(Chunk * chunk)58void AssemblerModule::GenerateStubsAarch64(Chunk* chunk) 59 { 60 aarch64::ExtendedAssembler assembler(chunk, this); 61 LOG_COMPILER(INFO) << "================ compiling asm stubs ================"; 62 for (size_t i = 0; i < asmCallSigns_.size(); i++) { 63 auto cs = asmCallSigns_[i]; 64 ASSERT(cs->HasConstructor()); 65 LOG_COMPILER(INFO) << "Stub Name: " << cs->GetName(); 66 AssemblerStub *stub = static_cast<AssemblerStub*>( 67 cs->GetConstructor()(nullptr)); 68 stub->GenerateAarch64(&assembler); 69 delete stub; 70 } 71 buffer_ = assembler.GetBegin(); 72 bufferSize_ = assembler.GetCurrentPosition(); 73 } 74 SetUpForAsmStubs()75void AssemblerModule::SetUpForAsmStubs() 76 { 77 RuntimeStubCSigns::GetASMCSigns(asmCallSigns_); 78 for (auto cs : asmCallSigns_) { 79 symbolTable_[cs->GetID()] = new panda::ecmascript::Label(); 80 } 81 } 82 GetArgcFromJSCallMode(JSCallMode mode)83int AssemblerModule::GetArgcFromJSCallMode(JSCallMode mode) 84 { 85 switch (mode) { 86 case JSCallMode::CALL_ARG0: 87 case JSCallMode::CALL_THIS_ARG0: 88 case JSCallMode::DEPRECATED_CALL_ARG0: 89 return 0; 90 case JSCallMode::CALL_ARG1: 91 case JSCallMode::CALL_THIS_ARG1: 92 case JSCallMode::DEPRECATED_CALL_ARG1: 93 return 1; 94 case JSCallMode::CALL_ARG2: 95 case JSCallMode::CALL_THIS_ARG2: 96 case JSCallMode::DEPRECATED_CALL_ARG2: 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)125bool 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_ARG3_WITH_RETURN: 149 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN: 150 return false; 151 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 152 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 153 case JSCallMode::SUPER_CALL_WITH_ARGV: 154 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV: 155 return true; 156 default: 157 LOG_ECMA(FATAL) << "this branch is unreachable"; 158 UNREACHABLE(); 159 } 160 return false; 161 } 162 JSModeHaveThisArg(JSCallMode mode)163bool AssemblerModule::JSModeHaveThisArg(JSCallMode mode) 164 { 165 switch (mode) { 166 case JSCallMode::CALL_ARG0: 167 case JSCallMode::CALL_ARG1: 168 case JSCallMode::CALL_ARG2: 169 case JSCallMode::CALL_ARG3: 170 case JSCallMode::DEPRECATED_CALL_ARG0: 171 case JSCallMode::DEPRECATED_CALL_ARG1: 172 case JSCallMode::DEPRECATED_CALL_ARG2: 173 case JSCallMode::DEPRECATED_CALL_ARG3: 174 case JSCallMode::CALL_WITH_ARGV: 175 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 176 return false; 177 case JSCallMode::CALL_THIS_ARG0: 178 case JSCallMode::CALL_THIS_ARG1: 179 case JSCallMode::CALL_THIS_ARG2: 180 case JSCallMode::CALL_THIS_ARG3: 181 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 182 case JSCallMode::CALL_THIS_WITH_ARGV: 183 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 184 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 185 case JSCallMode::SUPER_CALL_WITH_ARGV: 186 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV: 187 case JSCallMode::CALL_ENTRY: 188 case JSCallMode::CALL_FROM_AOT: 189 case JSCallMode::CALL_GETTER: 190 case JSCallMode::CALL_SETTER: 191 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 192 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN: 193 return true; 194 default: 195 LOG_ECMA(FATAL) << "this branch is unreachable"; 196 UNREACHABLE(); 197 } 198 } 199 JSModeHaveNewTargetArg(JSCallMode mode)200bool AssemblerModule::JSModeHaveNewTargetArg(JSCallMode mode) 201 { 202 switch (mode) { 203 case JSCallMode::CALL_ARG0: 204 case JSCallMode::CALL_ARG1: 205 case JSCallMode::CALL_ARG2: 206 case JSCallMode::CALL_ARG3: 207 case JSCallMode::DEPRECATED_CALL_ARG0: 208 case JSCallMode::DEPRECATED_CALL_ARG1: 209 case JSCallMode::DEPRECATED_CALL_ARG2: 210 case JSCallMode::DEPRECATED_CALL_ARG3: 211 case JSCallMode::CALL_WITH_ARGV: 212 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 213 case JSCallMode::CALL_THIS_WITH_ARGV: 214 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 215 case JSCallMode::CALL_GETTER: 216 case JSCallMode::CALL_SETTER: 217 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 218 case JSCallMode::CALL_THIS_ARG0: 219 case JSCallMode::CALL_THIS_ARG1: 220 case JSCallMode::CALL_THIS_ARG2: 221 case JSCallMode::CALL_THIS_ARG3: 222 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN: 223 return false; 224 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 225 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 226 case JSCallMode::SUPER_CALL_WITH_ARGV: 227 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV: 228 case JSCallMode::CALL_ENTRY: 229 case JSCallMode::CALL_FROM_AOT: 230 return true; 231 default: 232 LOG_ECMA(FATAL) << "this branch is unreachable"; 233 UNREACHABLE(); 234 } 235 } 236 IsJumpToCallCommonEntry(JSCallMode mode)237bool AssemblerModule::IsJumpToCallCommonEntry(JSCallMode mode) 238 { 239 switch (mode) { 240 case JSCallMode::CALL_ARG0: 241 case JSCallMode::CALL_ARG1: 242 case JSCallMode::CALL_ARG2: 243 case JSCallMode::CALL_ARG3: 244 case JSCallMode::DEPRECATED_CALL_ARG0: 245 case JSCallMode::DEPRECATED_CALL_ARG1: 246 case JSCallMode::DEPRECATED_CALL_ARG2: 247 case JSCallMode::DEPRECATED_CALL_ARG3: 248 case JSCallMode::CALL_WITH_ARGV: 249 case JSCallMode::DEPRECATED_CALL_WITH_ARGV: 250 case JSCallMode::CALL_THIS_WITH_ARGV: 251 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV: 252 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV: 253 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV: 254 case JSCallMode::SUPER_CALL_WITH_ARGV: 255 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV: 256 case JSCallMode::CALL_THIS_ARG0: 257 case JSCallMode::CALL_THIS_ARG1: 258 case JSCallMode::CALL_THIS_ARG2: 259 case JSCallMode::CALL_THIS_ARG3: 260 return true; 261 case JSCallMode::CALL_GETTER: 262 case JSCallMode::CALL_SETTER: 263 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN: 264 case JSCallMode::CALL_ENTRY: 265 case JSCallMode::CALL_GENERATOR: 266 case JSCallMode::CALL_FROM_AOT: 267 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN: 268 return false; 269 default: 270 LOG_ECMA(FATAL) << "this branch is unreachable"; 271 UNREACHABLE(); 272 } 273 return false; 274 } 275 276 #define DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE(name) \ 277 void name##Stub::GenerateX64(Assembler *assembler) \ 278 { \ 279 x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler); \ 280 x64::OptimizedCall::name(assemblerX64); \ 281 assemblerX64->Align16(); \ 282 } 283 284 #define DECLARE_FAST_CALL_TRAMPOLINE_X64_GENERATE(name) \ 285 void name##Stub::GenerateX64(Assembler *assembler) \ 286 { \ 287 x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler); \ 288 x64::OptimizedFastCall::name(assemblerX64); \ 289 assemblerX64->Align16(); \ 290 } 291 292 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE(name) \ 293 void name##Stub::GenerateX64(Assembler *assembler) \ 294 { \ 295 x64::ExtendedAssembler *assemblerX64 = static_cast<x64::ExtendedAssembler*>(assembler); \ 296 x64::AsmInterpreterCall::name(assemblerX64); \ 297 assemblerX64->Align16(); \ 298 } 299 300 301 #define DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE(name) \ 302 void name##Stub::GenerateAarch64(Assembler *assembler) \ 303 { \ 304 aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \ 305 aarch64::OptimizedCall::name(assemblerAarch64); \ 306 } 307 308 #define DECLARE_FAST_CALL_TRAMPOLINE_AARCH64_GENERATE(name) \ 309 void name##Stub::GenerateAarch64(Assembler *assembler) \ 310 { \ 311 aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \ 312 aarch64::OptimizedFastCall::name(assemblerAarch64); \ 313 } 314 315 #define DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE(name) \ 316 void name##Stub::GenerateAarch64(Assembler *assembler) \ 317 { \ 318 aarch64::ExtendedAssembler *assemblerAarch64 = static_cast<aarch64::ExtendedAssembler*>(assembler); \ 319 aarch64::AsmInterpreterCall::name(assemblerAarch64); \ 320 } 321 322 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE) 323 FAST_CALL_TRAMPOLINE_LIST(DECLARE_FAST_CALL_TRAMPOLINE_X64_GENERATE) 324 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE) 325 JS_CALL_TRAMPOLINE_LIST(DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE) 326 FAST_CALL_TRAMPOLINE_LIST(DECLARE_FAST_CALL_TRAMPOLINE_AARCH64_GENERATE) 327 ASM_INTERPRETER_TRAMPOLINE_LIST(DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE) 328 #undef DECLARE_JSCALL_TRAMPOLINE_X64_GENERATE 329 #undef DECLARE_FAST_CALL_TRAMPOLINE_X64_GENERATE 330 #undef DECLARE_ASM_INTERPRETER_TRAMPOLINE_X64_GENERATE 331 #undef DECLARE_JSCALL_TRAMPOLINE_AARCH64_GENERATE 332 #undef DECLARE_FAST_CALL_TRAMPOLINE_AARCH64_GENERATE 333 #undef DECLARE_ASM_INTERPRETER_TRAMPOLINE_AARCH64_GENERATE 334 } // namespace panda::ecmascript::kunfu 335