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