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   return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCode());
     88 }
     89 
     90 bool QuickCompiler::WriteElf(art::File* file,
     91                              OatWriter* oat_writer,
     92                              const std::vector<const art::DexFile*>& dex_files,
     93                              const std::string& android_root,
     94                              bool is_host) const {
     95   return art::ElfWriterQuick::Create(file, oat_writer, dex_files, android_root, is_host,
     96                                      *GetCompilerDriver());
     97 }
     98 
     99 Backend* QuickCompiler::GetCodeGenerator(CompilationUnit* cu, void* compilation_unit) const {
    100   Mir2Lir* mir_to_lir = nullptr;
    101   switch (cu->instruction_set) {
    102     case kThumb2:
    103       mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    104       break;
    105     case kArm64:
    106       mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    107       break;
    108     case kMips:
    109       mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    110       break;
    111     case kX86:
    112       // Fall-through.
    113     case kX86_64:
    114       mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
    115       break;
    116     default:
    117       LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set;
    118   }
    119 
    120   /* The number of compiler temporaries depends on backend so set it up now if possible */
    121   if (mir_to_lir) {
    122     size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps();
    123     bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps);
    124     CHECK(set_max);
    125   }
    126   return mir_to_lir;
    127 }
    128 
    129 std::vector<uint8_t>* QuickCompiler::GetCallFrameInformationInitialization(
    130     const CompilerDriver& driver) const {
    131   if (driver.GetInstructionSet() == kX86) {
    132     return X86CFIInitialization(false);
    133   }
    134   if (driver.GetInstructionSet() == kX86_64) {
    135     return X86CFIInitialization(true);
    136   }
    137   return nullptr;
    138 }
    139 
    140 CompiledMethod* OptimizingCompiler::Compile(const DexFile::CodeItem* code_item,
    141                                             uint32_t access_flags,
    142                                             InvokeType invoke_type,
    143                                             uint16_t class_def_idx,
    144                                             uint32_t method_idx,
    145                                             jobject class_loader,
    146                                             const DexFile& dex_file) const {
    147   CompiledMethod* method = TryCompile(code_item, access_flags, invoke_type, class_def_idx,
    148                                       method_idx, class_loader, dex_file);
    149   if (method != nullptr) {
    150     return method;
    151   }
    152 
    153   return QuickCompiler::Compile(code_item, access_flags, invoke_type, class_def_idx, method_idx,
    154                                 class_loader, dex_file);
    155 }
    156 
    157 }  // namespace art
    158