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