Home | History | Annotate | Download | only in compiler
      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 "compilers.h"
     18 
     19 #include "dex/mir_graph.h"
     20 #include "dex/quick/mir_to_lir.h"
     21 #include "elf_writer_quick.h"
     22 #include "mirror/art_method-inl.h"
     23 
     24 namespace art {
     25 
     26 extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver* driver);
     27 extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver* driver);
     28 extern "C" art::CompiledMethod* ArtQuickCompileMethod(art::CompilerDriver* driver,
     29                                                       const art::DexFile::CodeItem* code_item,
     30                                                       uint32_t access_flags,
     31                                                       art::InvokeType invoke_type,
     32                                                       uint16_t class_def_idx,
     33                                                       uint32_t method_idx,
     34                                                       jobject class_loader,
     35                                                       const art::DexFile& dex_file);
     36 
     37 extern "C" art::CompiledMethod* ArtQuickJniCompileMethod(art::CompilerDriver* driver,
     38                                                          uint32_t access_flags, uint32_t method_idx,
     39                                                          const art::DexFile& dex_file);
     40 
     41 // Hack for CFI CIE initialization
     42 extern std::vector<uint8_t>* X86CFIInitialization(bool is_x86_64);
     43 
     44 void QuickCompiler::Init() const {
     45   ArtInitQuickCompilerContext(GetCompilerDriver());
     46 }
     47 
     48 void QuickCompiler::UnInit() const {
     49   ArtUnInitQuickCompilerContext(GetCompilerDriver());
     50 }
     51 
     52 CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item,
     53                                        uint32_t access_flags,
     54                                        InvokeType invoke_type,
     55                                        uint16_t class_def_idx,
     56                                        uint32_t method_idx,
     57                                        jobject class_loader,
     58                                        const DexFile& dex_file) const {
     59   CompiledMethod* method = TryCompileWithSeaIR(code_item,
     60                                                access_flags,
     61                                                invoke_type,
     62                                                class_def_idx,
     63                                                method_idx,
     64                                                class_loader,
     65                                                dex_file);
     66   if (method != nullptr) {
     67     return method;
     68   }
     69 
     70   return ArtQuickCompileMethod(GetCompilerDriver(),
     71                                code_item,
     72                                access_flags,
     73                                invoke_type,
     74                                class_def_idx,
     75                                method_idx,
     76                                class_loader,
     77                                dex_file);
     78 }
     79 
     80 CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags,
     81                                           uint32_t method_idx,
     82                                           const DexFile& dex_file) const {
     83   return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
     84 }
     85 
     86 uintptr_t QuickCompiler::GetEntryPointOf(mirror::ArtMethod* method) const {
     87   size_t pointer_size = InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet());
     88   return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
     89       pointer_size));
     90 }
     91 
     92 bool QuickCompiler::WriteElf(art::File* file,
     93                              OatWriter* oat_writer,
     94                              const std::vector<const art::DexFile*>& dex_files,
     95                              const std::string& android_root,
     96                              bool is_host) const {
     97   return art::ElfWriterQuick::Create(file, oat_writer, dex_files, android_root, is_host,
     98                                      *GetCompilerDriver());
     99 }
    100 
    101 Backend* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
    102   Mir2Lir* mir_to_lir = nullptr;
    103   switch (cu->instruction_set) {
    104     case kThumb2:
    105       mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    106       break;
    107     case kArm64:
    108       mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    109       break;
    110     case kMips:
    111       mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    112       break;
    113     case kX86:
    114       // Fall-through.
    115     case kX86_64:
    116       mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    117       break;
    118     default:
    119       LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set;
    120   }
    121 
    122   /* The number of compiler temporaries depends on backend so set it up now if possible */
    123   if (mir_to_lir) {
    124     size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps();
    125     bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps);
    126     CHECK(set_max);
    127   }
    128   return mir_to_lir;
    129 }
    130 
    131 std::vector<uint8_t>* QuickCompiler::GetCallFrameInformationInitialization(
    132     const CompilerDriver& driver) const {
    133   if (driver.GetInstructionSet() == kX86) {
    134     return X86CFIInitialization(false);
    135   }
    136   if (driver.GetInstructionSet() == kX86_64) {
    137     return X86CFIInitialization(true);
    138   }
    139   return nullptr;
    140 }
    141 
    142 CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item,
    143                                             uint32_t access_flags,
    144                                             InvokeType invoke_type,
    145                                             uint16_t class_def_idx,
    146                                             uint32_t method_idx,
    147                                             jobject class_loader,
    148                                             const DexFile& dex_file) const {
    149   CompiledMethod* method = TryCompile(code_item, access_flags, invoke_type, class_def_idx,
    150                                       method_idx, class_loader, dex_file);
    151   if (method != nullptr) {
    152     return method;
    153   }
    154 
    155   return QuickCompiler::Compile(code_item, access_flags, invoke_type, class_def_idx, method_idx,
    156                                 class_loader, dex_file);
    157 }
    158 
    159 }  // namespace art
    160