quick_compiler.cc revision 7eebd95bddc7c6866ba29010d28b4f8251b43242
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 428// Unsupported opcodes. nullptr can be used when everything is supported. Size of the lists is 429// recorded below. 430static const int* kUnsupportedOpcodes[] = { 431 // 0 = kNone. 432 kAllOpcodes, 433 // 1 = kArm, unused (will use kThumb2). 434 kAllOpcodes, 435 // 2 = kArm64. 436 nullptr, 437 // 3 = kThumb2. 438 nullptr, 439 // 4 = kX86. 440 nullptr, 441 // 5 = kX86_64. 442 nullptr, 443 // 6 = kMips. 444 nullptr, 445 // 7 = kMips64. 446 kAllOpcodes 447}; 448COMPILE_ASSERT(sizeof(kUnsupportedOpcodes) == 8 * sizeof(int*), kUnsupportedOpcodes_unexp); 449 450// Size of the arrays stored above. 451static const size_t kUnsupportedOpcodesSize[] = { 452 // 0 = kNone. 453 arraysize(kAllOpcodes), 454 // 1 = kArm, unused (will use kThumb2). 455 arraysize(kAllOpcodes), 456 // 2 = kArm64. 457 0, 458 // 3 = kThumb2. 459 0, 460 // 4 = kX86. 461 0, 462 // 5 = kX86_64. 463 0, 464 // 6 = kMips. 465 0, 466 // 7 = kMips64. 467 arraysize(kAllOpcodes), 468}; 469COMPILE_ASSERT(sizeof(kUnsupportedOpcodesSize) == 8 * sizeof(size_t), 470 kUnsupportedOpcodesSize_unexp); 471 472// The maximum amount of Dalvik register in a method for which we will start compiling. Tries to 473// avoid an abort when we need to manage more SSA registers than we can. 474static constexpr size_t kMaxAllowedDalvikRegisters = INT16_MAX / 2; 475 476static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) { 477 const char* supported_types = kSupportedTypes[instruction_set]; 478 if (supported_types == nullptr) { 479 // Everything available. 480 return true; 481 } 482 483 uint32_t shorty_size = strlen(shorty); 484 CHECK_GE(shorty_size, 1u); 485 486 for (uint32_t i = 0; i < shorty_size; i++) { 487 if (strchr(supported_types, shorty[i]) == nullptr) { 488 return false; 489 } 490 } 491 return true; 492}; 493 494// Skip the method that we do not support currently. 495bool QuickCompiler::CanCompileMethod(uint32_t method_idx, const DexFile& dex_file, 496 CompilationUnit* cu) const { 497 // This is a limitation in mir_graph. See MirGraph::SetNumSSARegs. 498 if (cu->mir_graph->GetNumOfCodeAndTempVRs() > kMaxAllowedDalvikRegisters) { 499 VLOG(compiler) << "Too many dalvik registers : " << cu->mir_graph->GetNumOfCodeAndTempVRs(); 500 return false; 501 } 502 503 // Check whether we do have limitations at all. 504 if (kSupportedTypes[cu->instruction_set] == nullptr && 505 kUnsupportedOpcodesSize[cu->instruction_set] == 0U) { 506 return true; 507 } 508 509 // Check if we can compile the prototype. 510 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx)); 511 if (!CanCompileShorty(shorty, cu->instruction_set)) { 512 VLOG(compiler) << "Unsupported shorty : " << shorty; 513 return false; 514 } 515 516 const int *unsupport_list = kUnsupportedOpcodes[cu->instruction_set]; 517 int unsupport_list_size = kUnsupportedOpcodesSize[cu->instruction_set]; 518 519 for (unsigned int idx = 0; idx < cu->mir_graph->GetNumBlocks(); idx++) { 520 BasicBlock* bb = cu->mir_graph->GetBasicBlock(idx); 521 if (bb == NULL) continue; 522 if (bb->block_type == kDead) continue; 523 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) { 524 int opcode = mir->dalvikInsn.opcode; 525 // Check if we support the byte code. 526 if (std::find(unsupport_list, unsupport_list + unsupport_list_size, 527 opcode) != unsupport_list + unsupport_list_size) { 528 if (!MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { 529 VLOG(compiler) << "Unsupported dalvik byte code : " 530 << mir->dalvikInsn.opcode; 531 } else { 532 VLOG(compiler) << "Unsupported extended MIR opcode : " 533 << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst]; 534 } 535 return false; 536 } 537 // Check if it invokes a prototype that we cannot support. 538 if (Instruction::INVOKE_VIRTUAL == opcode || 539 Instruction::INVOKE_SUPER == opcode || 540 Instruction::INVOKE_DIRECT == opcode || 541 Instruction::INVOKE_STATIC == opcode || 542 Instruction::INVOKE_INTERFACE == opcode) { 543 uint32_t invoke_method_idx = mir->dalvikInsn.vB; 544 const char* invoke_method_shorty = dex_file.GetMethodShorty( 545 dex_file.GetMethodId(invoke_method_idx)); 546 if (!CanCompileShorty(invoke_method_shorty, cu->instruction_set)) { 547 VLOG(compiler) << "Unsupported to invoke '" 548 << PrettyMethod(invoke_method_idx, dex_file) 549 << "' with shorty : " << invoke_method_shorty; 550 return false; 551 } 552 } 553 } 554 } 555 return true; 556} 557 558void QuickCompiler::InitCompilationUnit(CompilationUnit& cu) const { 559 // Disable optimizations according to instruction set. 560 cu.disable_opt |= kDisabledOptimizationsPerISA[cu.instruction_set]; 561} 562 563void QuickCompiler::Init() const { 564 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr); 565} 566 567void QuickCompiler::UnInit() const { 568 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr); 569} 570 571CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item, 572 uint32_t access_flags, 573 InvokeType invoke_type, 574 uint16_t class_def_idx, 575 uint32_t method_idx, 576 jobject class_loader, 577 const DexFile& dex_file) const { 578 CompiledMethod* method = TryCompileWithSeaIR(code_item, 579 access_flags, 580 invoke_type, 581 class_def_idx, 582 method_idx, 583 class_loader, 584 dex_file); 585 if (method != nullptr) { 586 return method; 587 } 588 589 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use 590 // build default. 591 CompilerDriver* driver = GetCompilerDriver(); 592 return CompileOneMethod(driver, this, code_item, access_flags, invoke_type, class_def_idx, 593 method_idx, class_loader, dex_file, nullptr /* use thread llvm_info */); 594} 595 596CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags, 597 uint32_t method_idx, 598 const DexFile& dex_file) const { 599 return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file); 600} 601 602uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const { 603 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCode()); 604} 605 606bool QuickCompiler::WriteElf(art::File* file, 607 OatWriter* oat_writer, 608 const std::vector<const art::DexFile*>& dex_files, 609 const std::string& android_root, 610 bool is_host) const { 611 return art::ElfWriterQuick::Create(file, oat_writer, dex_files, android_root, is_host, 612 *GetCompilerDriver()); 613} 614 615Backend* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const { 616 Mir2Lir* mir_to_lir = nullptr; 617 switch (cu->instruction_set) { 618 case kThumb2: 619 mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 620 break; 621 case kArm64: 622 mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 623 break; 624 case kMips: 625 mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 626 break; 627 case kX86: 628 // Fall-through. 629 case kX86_64: 630 mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena); 631 break; 632 default: 633 LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set; 634 } 635 636 /* The number of compiler temporaries depends on backend so set it up now if possible */ 637 if (mir_to_lir) { 638 size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps(); 639 bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps); 640 CHECK(set_max); 641 } 642 return mir_to_lir; 643} 644 645 646Compiler* CreateQuickCompiler(CompilerDriver* driver) { 647 return new QuickCompiler(driver); 648} 649 650} // namespace art 651