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