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