compiler_driver.cc revision 845490bda68f7d025ea7f45775c847d2932e00dc
1// Copyright 2011 Google Inc. All Rights Reserved. 2 3#include "compiler.h" 4 5#include "assembler.h" 6#include "class_linker.h" 7#include "class_loader.h" 8#include "dex_cache.h" 9#include "jni_compiler.h" 10#include "jni_internal.h" 11#include "runtime.h" 12 13extern bool oatCompileMethod(const art::Compiler& compiler, art::Method*, art::InstructionSet); 14 15namespace art { 16 17namespace arm { 18 ByteArray* CreateAbstractMethodErrorStub(); 19} 20 21namespace x86 { 22 ByteArray* CreateAbstractMethodErrorStub(); 23} 24 25Compiler::Compiler(InstructionSet insns) : instruction_set_(insns), jni_compiler_(insns), 26 verbose_(false) { 27 CHECK(!Runtime::Current()->IsStarted()); 28 if (insns == kArm || insns == kThumb2) { 29 abstract_method_error_stub_ = arm::CreateAbstractMethodErrorStub(); 30 } else if (insns == kX86) { 31 abstract_method_error_stub_ = x86::CreateAbstractMethodErrorStub(); 32 } 33} 34 35void Compiler::CompileAll(const ClassLoader* class_loader) { 36 DCHECK(!Runtime::Current()->IsStarted()); 37 Resolve(class_loader); 38 Verify(class_loader); 39 InitializeClassesWithoutClinit(class_loader); 40 Compile(class_loader); 41 SetCodeAndDirectMethods(class_loader); 42} 43 44void Compiler::CompileOne(Method* method) { 45 DCHECK(!Runtime::Current()->IsStarted()); 46 const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 47 Resolve(class_loader); 48 Verify(class_loader); 49 InitializeClassesWithoutClinit(class_loader); 50 CompileMethod(method); 51 SetCodeAndDirectMethods(class_loader); 52} 53 54void Compiler::Resolve(const ClassLoader* class_loader) { 55 const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 56 for (size_t i = 0; i != class_path.size(); ++i) { 57 const DexFile* dex_file = class_path[i]; 58 CHECK(dex_file != NULL); 59 ResolveDexFile(class_loader, *dex_file); 60 } 61} 62 63void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 64 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 65 66 // Strings are easy, they always are simply resolved to literals in the same file 67 DexCache* dex_cache = class_linker->FindDexCache(dex_file); 68 for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 69 class_linker->ResolveString(dex_file, string_idx, dex_cache); 70 } 71 72 // Class derived values are more complicated, they require the linker and loader. 73 for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 74 Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 75 CHECK(klass->IsResolved()); 76 } 77 78 // Method and Field are the worst. We can't resolve without either 79 // context from the code use (to disambiguate virtual vs direct 80 // method and instance vs static field) or from class 81 // definitions. While the compiler will resolve what it can as it 82 // needs it, here we try to resolve fields and methods used in class 83 // definitions, since many of them many never be referenced by 84 // generated code. 85 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 86 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 87 88 // Note the class_data pointer advances through the headers, 89 // static fields, instance fields, direct methods, and virtual 90 // methods. 91 const byte* class_data = dex_file.GetClassData(class_def); 92 93 DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data); 94 size_t num_static_fields = header.static_fields_size_; 95 size_t num_instance_fields = header.instance_fields_size_; 96 size_t num_direct_methods = header.direct_methods_size_; 97 size_t num_virtual_methods = header.virtual_methods_size_; 98 99 if (num_static_fields != 0) { 100 uint32_t last_idx = 0; 101 for (size_t i = 0; i < num_static_fields; ++i) { 102 DexFile::Field dex_field; 103 dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx); 104 class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, class_loader, true); 105 } 106 } 107 if (num_instance_fields != 0) { 108 uint32_t last_idx = 0; 109 for (size_t i = 0; i < num_instance_fields; ++i) { 110 DexFile::Field dex_field; 111 dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx); 112 class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, class_loader, false); 113 } 114 } 115 if (num_direct_methods != 0) { 116 uint32_t last_idx = 0; 117 for (size_t i = 0; i < num_direct_methods; ++i) { 118 DexFile::Method dex_method; 119 dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); 120 class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, class_loader, 121 true); 122 } 123 } 124 if (num_virtual_methods != 0) { 125 uint32_t last_idx = 0; 126 for (size_t i = 0; i < num_virtual_methods; ++i) { 127 DexFile::Method dex_method; 128 dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); 129 class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, class_loader, 130 false); 131 } 132 } 133 } 134} 135 136void Compiler::Verify(const ClassLoader* class_loader) { 137 const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 138 for (size_t i = 0; i != class_path.size(); ++i) { 139 const DexFile* dex_file = class_path[i]; 140 CHECK(dex_file != NULL); 141 VerifyDexFile(class_loader, *dex_file); 142 } 143} 144 145void Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 146 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 147 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 148 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 149 const char* descriptor = dex_file.GetClassDescriptor(class_def); 150 Class* klass = class_linker->FindClass(descriptor, class_loader); 151 CHECK(klass->IsResolved()); 152 CHECK(klass != NULL); 153 class_linker->VerifyClass(klass); 154 CHECK(klass->IsVerified() || klass->IsErroneous()); 155 } 156} 157 158void Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader) { 159 const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 160 for (size_t i = 0; i != class_path.size(); ++i) { 161 const DexFile* dex_file = class_path[i]; 162 CHECK(dex_file != NULL); 163 InitializeClassesWithoutClinit(class_loader, *dex_file); 164 } 165} 166 167void Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 168 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 169 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 170 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 171 const char* descriptor = dex_file.GetClassDescriptor(class_def); 172 Class* klass = class_linker->FindClass(descriptor, class_loader); 173 class_linker->EnsureInitialized(klass, false); 174 } 175 176 DexCache* dex_cache = class_linker->FindDexCache(dex_file); 177 for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 178 Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 179 if (klass->IsInitialized()) { 180 dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 181 } 182 } 183} 184 185void Compiler::Compile(const ClassLoader* class_loader) { 186 const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 187 for (size_t i = 0; i != class_path.size(); ++i) { 188 const DexFile* dex_file = class_path[i]; 189 CHECK(dex_file != NULL); 190 CompileDexFile(class_loader, *dex_file); 191 } 192} 193 194void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 195 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 196 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 197 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 198 const char* descriptor = dex_file.GetClassDescriptor(class_def); 199 Class* klass = class_linker->FindClass(descriptor, class_loader); 200 CHECK(klass != NULL); 201 CompileClass(klass); 202 } 203} 204 205void Compiler::CompileClass(Class* klass) { 206 for (size_t i = 0; i < klass->NumDirectMethods(); i++) { 207 CompileMethod(klass->GetDirectMethod(i)); 208 } 209 for (size_t i = 0; i < klass->NumVirtualMethods(); i++) { 210 CompileMethod(klass->GetVirtualMethod(i)); 211 } 212} 213 214namespace arm { 215 void ArmCreateInvokeStub(Method* method); 216} 217namespace x86 { 218 void X86CreateInvokeStub(Method* method); 219} 220 221void Compiler::CompileMethod(Method* method) { 222 if (method->IsNative()) { 223 jni_compiler_.Compile(method); 224 // unregister will install the stub to lookup via dlsym 225 // TODO: this is only necessary for tests 226 if (!method->IsRegistered()) { 227 method->UnregisterNative(); 228 } 229 } else if (method->IsAbstract()) { 230 DCHECK(abstract_method_error_stub_ != NULL); 231 if (instruction_set_ == kX86) { 232 method->SetCode(abstract_method_error_stub_, kX86); 233 } else { 234 CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 235 method->SetCode(abstract_method_error_stub_, kArm); 236 } 237 } else { 238 oatCompileMethod(*this, method, kThumb2); 239 } 240 CHECK(method->GetCode() != NULL); 241 242 if (instruction_set_ == kX86) { 243 art::x86::X86CreateInvokeStub(method); 244 } else { 245 CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 246 // Generates invocation stub using ARM instruction set 247 art::arm::ArmCreateInvokeStub(method); 248 } 249 CHECK(method->GetInvokeStub() != NULL); 250} 251 252void Compiler::SetCodeAndDirectMethods(const ClassLoader* class_loader) { 253 const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 254 for (size_t i = 0; i != class_path.size(); ++i) { 255 const DexFile* dex_file = class_path[i]; 256 CHECK(dex_file != NULL); 257 SetCodeAndDirectMethodsDexFile(*dex_file); 258 } 259} 260 261void Compiler::SetCodeAndDirectMethodsDexFile(const DexFile& dex_file) { 262 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 263 DexCache* dex_cache = class_linker->FindDexCache(dex_file); 264 CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods(); 265 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { 266 Method* method = dex_cache->GetResolvedMethod(i); 267 if (method == NULL) { 268 code_and_direct_methods->SetResolvedDirectMethodTrampoline(i); 269 } else if (method->IsDirect()) { 270 code_and_direct_methods->SetResolvedDirectMethod(i, method); 271 } else { 272 // TODO: we currently leave the entry blank for resolved 273 // non-direct methods. we could put in an error stub. 274 } 275 } 276} 277 278} // namespace art 279