quick_compiler.cc revision 5667fdbb6e441dee7534ade18b628ed396daf593
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "quick_compiler.h" 18 19#include <cstdint> 20 21#include "compiler.h" 22#include "dex/frontend.h" 23#include "dex/mir_graph.h" 24#include "dex/quick/mir_to_lir.h" 25#include "driver/compiler_driver.h" 26#include "elf_writer_quick.h" 27#include "jni/quick/jni_compiler.h" 28#include "mirror/art_method-inl.h" 29#include "base/logging.h" 30 31// Specific compiler backends. 32#include "dex/quick/arm/backend_arm.h" 33#include "dex/quick/arm64/backend_arm64.h" 34#include "dex/quick/mips/backend_mips.h" 35#include "dex/quick/x86/backend_x86.h" 36 37namespace art { 38 39class QuickCompiler : public Compiler { 40 public: 41 explicit QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {} 42 43 void Init() const OVERRIDE; 44 45 void UnInit() const OVERRIDE; 46 47 bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, CompilationUnit* cu) const 48 OVERRIDE; 49 50 CompiledMethod* Compile(const DexFile::CodeItem* code_item, 51 uint32_t access_flags, 52 InvokeType invoke_type, 53 uint16_t class_def_idx, 54 uint32_t method_idx, 55 jobject class_loader, 56 const DexFile& dex_file) const OVERRIDE; 57 58 CompiledMethod* JniCompile(uint32_t access_flags, 59 uint32_t method_idx, 60 const DexFile& dex_file) const OVERRIDE; 61 62 uintptr_t GetEntryPointOf(mirror::ArtMethod* method) const OVERRIDE 63 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 64 65 bool WriteElf(art::File* file, 66 OatWriter* oat_writer, 67 const std::vector<const art::DexFile*>& dex_files, 68 const std::string& android_root, 69 bool is_host) const 70 OVERRIDE 71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 72 73 Backend* GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const OVERRIDE; 74 75 void InitCompilationUnit(CompilationUnit& cu) const OVERRIDE; 76 77 private: 78 DISALLOW_COPY_AND_ASSIGN(QuickCompiler); 79}; 80 81COMPILE_ASSERT(0U == static_cast<size_t>(kNone), kNone_not_0); 82COMPILE_ASSERT(1U == static_cast<size_t>(kArm), kArm_not_1); 83COMPILE_ASSERT(2U == static_cast<size_t>(kArm64), kArm64_not_2); 84COMPILE_ASSERT(3U == static_cast<size_t>(kThumb2), kThumb2_not_3); 85COMPILE_ASSERT(4U == static_cast<size_t>(kX86), kX86_not_4); 86COMPILE_ASSERT(5U == static_cast<size_t>(kX86_64), kX86_64_not_5); 87COMPILE_ASSERT(6U == static_cast<size_t>(kMips), kMips_not_6); 88COMPILE_ASSERT(7U == static_cast<size_t>(kMips64), kMips64_not_7); 89 90// Additional disabled optimizations (over generally disabled) per instruction set. 91static constexpr uint32_t kDisabledOptimizationsPerISA[] = { 92 // 0 = kNone. 93 ~0U, 94 // 1 = kArm, unused (will use kThumb2). 95 ~0U, 96 // 2 = kArm64. 97 0, 98 // 3 = kThumb2. 99 0, 100 // 4 = kX86. 101 (1 << kLoadStoreElimination) | 102 0, 103 // 5 = kX86_64. 104 (1 << kLoadStoreElimination) | 105 0, 106 // 6 = kMips. 107 (1 << kLoadStoreElimination) | 108 (1 << kLoadHoisting) | 109 (1 << kSuppressLoads) | 110 (1 << kNullCheckElimination) | 111 (1 << kPromoteRegs) | 112 (1 << kTrackLiveTemps) | 113 (1 << kSafeOptimizations) | 114 (1 << kBBOpt) | 115 (1 << kMatch) | 116 (1 << kPromoteCompilerTemps) | 117 0, 118 // 7 = kMips64. 119 ~0U 120}; 121COMPILE_ASSERT(sizeof(kDisabledOptimizationsPerISA) == 8 * sizeof(uint32_t), kDisabledOpts_unexp); 122 123// Supported shorty types per instruction set. nullptr means that all are available. 124// Z : boolean 125// B : byte 126// S : short 127// C : char 128// I : int 129// J : long 130// F : float 131// D : double 132// L : reference(object, array) 133// V : void 134static const char* kSupportedTypes[] = { 135 // 0 = kNone. 136 "", 137 // 1 = kArm, unused (will use kThumb2). 138 "", 139 // 2 = kArm64. 140 nullptr, 141 // 3 = kThumb2. 142 nullptr, 143 // 4 = kX86. 144 nullptr, 145 // 5 = kX86_64. 146 nullptr, 147 // 6 = kMips. 148 nullptr, 149 // 7 = kMips64. 150 "" 151}; 152COMPILE_ASSERT(sizeof(kSupportedTypes) == 8 * sizeof(char*), kSupportedTypes_unexp); 153 154static int kAllOpcodes[] = { 155 Instruction::NOP, 156 Instruction::MOVE, 157 Instruction::MOVE_FROM16, 158 Instruction::MOVE_16, 159 Instruction::MOVE_WIDE, 160 Instruction::MOVE_WIDE_FROM16, 161 Instruction::MOVE_WIDE_16, 162 Instruction::MOVE_OBJECT, 163 Instruction::MOVE_OBJECT_FROM16, 164 Instruction::MOVE_OBJECT_16, 165 Instruction::MOVE_RESULT, 166 Instruction::MOVE_RESULT_WIDE, 167 Instruction::MOVE_RESULT_OBJECT, 168 Instruction::MOVE_EXCEPTION, 169 Instruction::RETURN_VOID, 170 Instruction::RETURN, 171 Instruction::RETURN_WIDE, 172 Instruction::RETURN_OBJECT, 173 Instruction::CONST_4, 174 Instruction::CONST_16, 175 Instruction::CONST, 176 Instruction::CONST_HIGH16, 177 Instruction::CONST_WIDE_16, 178 Instruction::CONST_WIDE_32, 179 Instruction::CONST_WIDE, 180 Instruction::CONST_WIDE_HIGH16, 181 Instruction::CONST_STRING, 182 Instruction::CONST_STRING_JUMBO, 183 Instruction::CONST_CLASS, 184 Instruction::MONITOR_ENTER, 185 Instruction::MONITOR_EXIT, 186 Instruction::CHECK_CAST, 187 Instruction::INSTANCE_OF, 188 Instruction::ARRAY_LENGTH, 189 Instruction::NEW_INSTANCE, 190 Instruction::NEW_ARRAY, 191 Instruction::FILLED_NEW_ARRAY, 192 Instruction::FILLED_NEW_ARRAY_RANGE, 193 Instruction::FILL_ARRAY_DATA, 194 Instruction::THROW, 195 Instruction::GOTO, 196 Instruction::GOTO_16, 197 Instruction::GOTO_32, 198 Instruction::PACKED_SWITCH, 199 Instruction::SPARSE_SWITCH, 200 Instruction::CMPL_FLOAT, 201 Instruction::CMPG_FLOAT, 202 Instruction::CMPL_DOUBLE, 203 Instruction::CMPG_DOUBLE, 204 Instruction::CMP_LONG, 205 Instruction::IF_EQ, 206 Instruction::IF_NE, 207 Instruction::IF_LT, 208 Instruction::IF_GE, 209 Instruction::IF_GT, 210 Instruction::IF_LE, 211 Instruction::IF_EQZ, 212 Instruction::IF_NEZ, 213 Instruction::IF_LTZ, 214 Instruction::IF_GEZ, 215 Instruction::IF_GTZ, 216 Instruction::IF_LEZ, 217 Instruction::UNUSED_3E, 218 Instruction::UNUSED_3F, 219 Instruction::UNUSED_40, 220 Instruction::UNUSED_41, 221 Instruction::UNUSED_42, 222 Instruction::UNUSED_43, 223 Instruction::AGET, 224 Instruction::AGET_WIDE, 225 Instruction::AGET_OBJECT, 226 Instruction::AGET_BOOLEAN, 227 Instruction::AGET_BYTE, 228 Instruction::AGET_CHAR, 229 Instruction::AGET_SHORT, 230 Instruction::APUT, 231 Instruction::APUT_WIDE, 232 Instruction::APUT_OBJECT, 233 Instruction::APUT_BOOLEAN, 234 Instruction::APUT_BYTE, 235 Instruction::APUT_CHAR, 236 Instruction::APUT_SHORT, 237 Instruction::IGET, 238 Instruction::IGET_WIDE, 239 Instruction::IGET_OBJECT, 240 Instruction::IGET_BOOLEAN, 241 Instruction::IGET_BYTE, 242 Instruction::IGET_CHAR, 243 Instruction::IGET_SHORT, 244 Instruction::IPUT, 245 Instruction::IPUT_WIDE, 246 Instruction::IPUT_OBJECT, 247 Instruction::IPUT_BOOLEAN, 248 Instruction::IPUT_BYTE, 249 Instruction::IPUT_CHAR, 250 Instruction::IPUT_SHORT, 251 Instruction::SGET, 252 Instruction::SGET_WIDE, 253 Instruction::SGET_OBJECT, 254 Instruction::SGET_BOOLEAN, 255 Instruction::SGET_BYTE, 256 Instruction::SGET_CHAR, 257 Instruction::SGET_SHORT, 258 Instruction::SPUT, 259 Instruction::SPUT_WIDE, 260 Instruction::SPUT_OBJECT, 261 Instruction::SPUT_BOOLEAN, 262 Instruction::SPUT_BYTE, 263 Instruction::SPUT_CHAR, 264 Instruction::SPUT_SHORT, 265 Instruction::INVOKE_VIRTUAL, 266 Instruction::INVOKE_SUPER, 267 Instruction::INVOKE_DIRECT, 268 Instruction::INVOKE_STATIC, 269 Instruction::INVOKE_INTERFACE, 270 Instruction::RETURN_VOID_BARRIER, 271 Instruction::INVOKE_VIRTUAL_RANGE, 272 Instruction::INVOKE_SUPER_RANGE, 273 Instruction::INVOKE_DIRECT_RANGE, 274 Instruction::INVOKE_STATIC_RANGE, 275 Instruction::INVOKE_INTERFACE_RANGE, 276 Instruction::UNUSED_79, 277 Instruction::UNUSED_7A, 278 Instruction::NEG_INT, 279 Instruction::NOT_INT, 280 Instruction::NEG_LONG, 281 Instruction::NOT_LONG, 282 Instruction::NEG_FLOAT, 283 Instruction::NEG_DOUBLE, 284 Instruction::INT_TO_LONG, 285 Instruction::INT_TO_FLOAT, 286 Instruction::INT_TO_DOUBLE, 287 Instruction::LONG_TO_INT, 288 Instruction::LONG_TO_FLOAT, 289 Instruction::LONG_TO_DOUBLE, 290 Instruction::FLOAT_TO_INT, 291 Instruction::FLOAT_TO_LONG, 292 Instruction::FLOAT_TO_DOUBLE, 293 Instruction::DOUBLE_TO_INT, 294 Instruction::DOUBLE_TO_LONG, 295 Instruction::DOUBLE_TO_FLOAT, 296 Instruction::INT_TO_BYTE, 297 Instruction::INT_TO_CHAR, 298 Instruction::INT_TO_SHORT, 299 Instruction::ADD_INT, 300 Instruction::SUB_INT, 301 Instruction::MUL_INT, 302 Instruction::DIV_INT, 303 Instruction::REM_INT, 304 Instruction::AND_INT, 305 Instruction::OR_INT, 306 Instruction::XOR_INT, 307 Instruction::SHL_INT, 308 Instruction::SHR_INT, 309 Instruction::USHR_INT, 310 Instruction::ADD_LONG, 311 Instruction::SUB_LONG, 312 Instruction::MUL_LONG, 313 Instruction::DIV_LONG, 314 Instruction::REM_LONG, 315 Instruction::AND_LONG, 316 Instruction::OR_LONG, 317 Instruction::XOR_LONG, 318 Instruction::SHL_LONG, 319 Instruction::SHR_LONG, 320 Instruction::USHR_LONG, 321 Instruction::ADD_FLOAT, 322 Instruction::SUB_FLOAT, 323 Instruction::MUL_FLOAT, 324 Instruction::DIV_FLOAT, 325 Instruction::REM_FLOAT, 326 Instruction::ADD_DOUBLE, 327 Instruction::SUB_DOUBLE, 328 Instruction::MUL_DOUBLE, 329 Instruction::DIV_DOUBLE, 330 Instruction::REM_DOUBLE, 331 Instruction::ADD_INT_2ADDR, 332 Instruction::SUB_INT_2ADDR, 333 Instruction::MUL_INT_2ADDR, 334 Instruction::DIV_INT_2ADDR, 335 Instruction::REM_INT_2ADDR, 336 Instruction::AND_INT_2ADDR, 337 Instruction::OR_INT_2ADDR, 338 Instruction::XOR_INT_2ADDR, 339 Instruction::SHL_INT_2ADDR, 340 Instruction::SHR_INT_2ADDR, 341 Instruction::USHR_INT_2ADDR, 342 Instruction::ADD_LONG_2ADDR, 343 Instruction::SUB_LONG_2ADDR, 344 Instruction::MUL_LONG_2ADDR, 345 Instruction::DIV_LONG_2ADDR, 346 Instruction::REM_LONG_2ADDR, 347 Instruction::AND_LONG_2ADDR, 348 Instruction::OR_LONG_2ADDR, 349 Instruction::XOR_LONG_2ADDR, 350 Instruction::SHL_LONG_2ADDR, 351 Instruction::SHR_LONG_2ADDR, 352 Instruction::USHR_LONG_2ADDR, 353 Instruction::ADD_FLOAT_2ADDR, 354 Instruction::SUB_FLOAT_2ADDR, 355 Instruction::MUL_FLOAT_2ADDR, 356 Instruction::DIV_FLOAT_2ADDR, 357 Instruction::REM_FLOAT_2ADDR, 358 Instruction::ADD_DOUBLE_2ADDR, 359 Instruction::SUB_DOUBLE_2ADDR, 360 Instruction::MUL_DOUBLE_2ADDR, 361 Instruction::DIV_DOUBLE_2ADDR, 362 Instruction::REM_DOUBLE_2ADDR, 363 Instruction::ADD_INT_LIT16, 364 Instruction::RSUB_INT, 365 Instruction::MUL_INT_LIT16, 366 Instruction::DIV_INT_LIT16, 367 Instruction::REM_INT_LIT16, 368 Instruction::AND_INT_LIT16, 369 Instruction::OR_INT_LIT16, 370 Instruction::XOR_INT_LIT16, 371 Instruction::ADD_INT_LIT8, 372 Instruction::RSUB_INT_LIT8, 373 Instruction::MUL_INT_LIT8, 374 Instruction::DIV_INT_LIT8, 375 Instruction::REM_INT_LIT8, 376 Instruction::AND_INT_LIT8, 377 Instruction::OR_INT_LIT8, 378 Instruction::XOR_INT_LIT8, 379 Instruction::SHL_INT_LIT8, 380 Instruction::SHR_INT_LIT8, 381 Instruction::USHR_INT_LIT8, 382 Instruction::IGET_QUICK, 383 Instruction::IGET_WIDE_QUICK, 384 Instruction::IGET_OBJECT_QUICK, 385 Instruction::IPUT_QUICK, 386 Instruction::IPUT_WIDE_QUICK, 387 Instruction::IPUT_OBJECT_QUICK, 388 Instruction::INVOKE_VIRTUAL_QUICK, 389 Instruction::INVOKE_VIRTUAL_RANGE_QUICK, 390 Instruction::IPUT_BOOLEAN_QUICK, 391 Instruction::IPUT_BYTE_QUICK, 392 Instruction::IPUT_CHAR_QUICK, 393 Instruction::IPUT_SHORT_QUICK, 394 Instruction::UNUSED_EF, 395 Instruction::UNUSED_F0, 396 Instruction::UNUSED_F1, 397 Instruction::UNUSED_F2, 398 Instruction::UNUSED_F3, 399 Instruction::UNUSED_F4, 400 Instruction::UNUSED_F5, 401 Instruction::UNUSED_F6, 402 Instruction::UNUSED_F7, 403 Instruction::UNUSED_F8, 404 Instruction::UNUSED_F9, 405 Instruction::UNUSED_FA, 406 Instruction::UNUSED_FB, 407 Instruction::UNUSED_FC, 408 Instruction::UNUSED_FD, 409 Instruction::UNUSED_FE, 410 Instruction::UNUSED_FF, 411 // ----- ExtendedMIROpcode ----- 412 kMirOpPhi, 413 kMirOpCopy, 414 kMirOpFusedCmplFloat, 415 kMirOpFusedCmpgFloat, 416 kMirOpFusedCmplDouble, 417 kMirOpFusedCmpgDouble, 418 kMirOpFusedCmpLong, 419 kMirOpNop, 420 kMirOpNullCheck, 421 kMirOpRangeCheck, 422 kMirOpDivZeroCheck, 423 kMirOpCheck, 424 kMirOpCheckPart2, 425 kMirOpSelect, 426}; 427 428static int kInvokeOpcodes[] = { 429 Instruction::INVOKE_VIRTUAL, 430 Instruction::INVOKE_SUPER, 431 Instruction::INVOKE_DIRECT, 432 Instruction::INVOKE_STATIC, 433 Instruction::INVOKE_INTERFACE, 434 Instruction::INVOKE_VIRTUAL_RANGE, 435 Instruction::INVOKE_SUPER_RANGE, 436 Instruction::INVOKE_DIRECT_RANGE, 437 Instruction::INVOKE_STATIC_RANGE, 438 Instruction::INVOKE_INTERFACE_RANGE, 439 Instruction::INVOKE_VIRTUAL_QUICK, 440 Instruction::INVOKE_VIRTUAL_RANGE_QUICK, 441}; 442 443// Unsupported opcodes. nullptr can be used when everything is supported. Size of the lists is 444// recorded below. 445static const int* kUnsupportedOpcodes[] = { 446 // 0 = kNone. 447 kAllOpcodes, 448 // 1 = kArm, unused (will use kThumb2). 449 kAllOpcodes, 450 // 2 = kArm64. 451 nullptr, 452 // 3 = kThumb2. 453 nullptr, 454 // 4 = kX86. 455 nullptr, 456 // 5 = kX86_64. 457 nullptr, 458 // 6 = kMips. 459 nullptr, 460 // 7 = kMips64. 461 kAllOpcodes 462}; 463COMPILE_ASSERT(sizeof(kUnsupportedOpcodes) == 8 * sizeof(int*), kUnsupportedOpcodes_unexp); 464 465// Size of the arrays stored above. 466static const size_t kUnsupportedOpcodesSize[] = { 467 // 0 = kNone. 468 arraysize(kAllOpcodes), 469 // 1 = kArm, unused (will use kThumb2). 470 arraysize(kAllOpcodes), 471 // 2 = kArm64. 472 0, 473 // 3 = kThumb2. 474 0, 475 // 4 = kX86. 476 0, 477 // 5 = kX86_64. 478 0, 479 // 6 = kMips. 480 0, 481 // 7 = kMips64. 482 arraysize(kAllOpcodes), 483}; 484COMPILE_ASSERT(sizeof(kUnsupportedOpcodesSize) == 8 * sizeof(size_t), 485 kUnsupportedOpcodesSize_unexp); 486 487// The maximum amount of Dalvik register in a method for which we will start compiling. Tries to 488// avoid an abort when we need to manage more SSA registers than we can. 489static constexpr size_t kMaxAllowedDalvikRegisters = INT16_MAX / 2; 490 491static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) { 492 const char* supported_types = kSupportedTypes[instruction_set]; 493 if (supported_types == nullptr) { 494 // Everything available. 495 return true; 496 } 497 498 uint32_t shorty_size = strlen(shorty); 499 CHECK_GE(shorty_size, 1u); 500 501 for (uint32_t i = 0; i < shorty_size; i++) { 502 if (strchr(supported_types, shorty[i]) == nullptr) { 503 return false; 504 } 505 } 506 return true; 507} 508 509// Skip the method that we do not support currently. 510bool QuickCompiler::CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, 511 CompilationUnit* cu) const { 512 // This is a limitation in mir_graph. See MirGraph::SetNumSSARegs. 513 if (cu->mir_graph->GetNumOfCodeAndTempVRs() > kMaxAllowedDalvikRegisters) { 514 VLOG(compiler) << "Too many dalvik registers : " << cu->mir_graph->GetNumOfCodeAndTempVRs(); 515 return false; 516 } 517 518 // Check whether we do have limitations at all. 519 if (kSupportedTypes[cu->instruction_set] == nullptr && 520 kUnsupportedOpcodesSize[cu->instruction_set] == 0U) { 521 return true; 522 } 523 524 // Check if we can compile the prototype. 525 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 526 if (!CanCompileShorty(shorty, cu->instruction_set)) { 527 VLOG(compiler) << "Unsupported shorty : " << shorty; 528 return false; 529 } 530 531 const int *unsupport_list = kUnsupportedOpcodes[cu->instruction_set]; 532 int unsupport_list_size = kUnsupportedOpcodesSize[cu->instruction_set]; 533 534 for (unsigned int idx = 0; idx < cu->mir_graph->GetNumBlocks(); idx++) { 535 BasicBlock* bb = cu->mir_graph->GetBasicBlock(idx); 536 if (bb == NULL) continue; 537 if (bb->block_type == kDead) continue; 538 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) { 539 int opcode = mir->dalvikInsn.opcode; 540 // Check if we support the byte code. 541 if (std::find(unsupport_list, unsupport_list + unsupport_list_size, opcode) 542 != unsupport_list + unsupport_list_size) { 543 if (!MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 544 VLOG(compiler) << "Unsupported dalvik byte code : " 545 << mir->dalvikInsn.opcode; 546 } else { 547 VLOG(compiler) << "Unsupported extended MIR opcode : " 548 << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst]; 549 } 550 return false; 551 } 552 // Check if it invokes a prototype that we cannot support. 553 if (std::find(kInvokeOpcodes, kInvokeOpcodes + arraysize(kInvokeOpcodes), opcode) 554 != kInvokeOpcodes + arraysize(kInvokeOpcodes)) { 555 uint32_t invoke_method_idx = mir->dalvikInsn.vB; 556 const char* invoke_method_shorty = dex_file.GetMethodShorty( 557 dex_file.GetMethodId(invoke_method_idx)); 558 if (!CanCompileShorty(invoke_method_shorty, cu->instruction_set)) { 559 VLOG(compiler) << "Unsupported to invoke '" 560 << PrettyMethod(invoke_method_idx, dex_file) 561 << "' with shorty : " << invoke_method_shorty; 562 return false; 563 } 564 } 565 } 566 } 567 return true; 568} 569 570void QuickCompiler::InitCompilationUnit(CompilationUnit& cu) const { 571 // Disable optimizations according to instruction set. 572 cu.disable_opt |= kDisabledOptimizationsPerISA[cu.instruction_set]; 573} 574 575void QuickCompiler::Init() const { 576 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr); 577} 578 579void QuickCompiler::UnInit() const { 580 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr); 581} 582 583CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item, 584 uint32_t access_flags, 585 InvokeType invoke_type, 586 uint16_t class_def_idx, 587 uint32_t method_idx, 588 jobject class_loader, 589 const DexFile& dex_file) const { 590 CompiledMethod* method = TryCompileWithSeaIR(code_item, 591 access_flags, 592 invoke_type, 593 class_def_idx, 594 method_idx, 595 class_loader, 596 dex_file); 597 if (method != nullptr) { 598 return method; 599 } 600 601 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use 602 // build default. 603 CompilerDriver* driver = GetCompilerDriver(); 604 return CompileOneMethod(driver, this, code_item, access_flags, invoke_type, class_def_idx, 605 method_idx, class_loader, dex_file, nullptr /* use thread llvm_info */); 606} 607 608CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags, 609 uint32_t method_idx, 610 const DexFile& dex_file) const { 611 return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file); 612} 613 614uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const { 615 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCode()); 616} 617 618bool QuickCompiler::WriteElf(art::File* file, 619 OatWriter* oat_writer, 620 const std::vector<const art::DexFile*>& dex_files, 621 const std::string& android_root, 622 bool is_host) const { 623 return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host, 624 *GetCompilerDriver()); 625} 626 627Backend* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const { 628 Mir2Lir* mir_to_lir = nullptr; 629 switch (cu->instruction_set) { 630 case kThumb2: 631 mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 632 break; 633 case kArm64: 634 mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 635 break; 636 case kMips: 637 mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 638 break; 639 case kX86: 640 // Fall-through. 641 case kX86_64: 642 mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 643 break; 644 default: 645 LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set; 646 } 647 648 /* The number of compiler temporaries depends on backend so set it up now if possible */ 649 if (mir_to_lir) { 650 size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps(); 651 bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps); 652 CHECK(set_max); 653 } 654 return mir_to_lir; 655} 656 657 658Compiler* CreateQuickCompiler(CompilerDriver* driver) { 659 return new QuickCompiler(driver); 660} 661 662} // namespace art 663