compiler_driver.cc revision 845490bda68f7d025ea7f45775c847d2932e00dc
19ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom// Copyright 2011 Google Inc. All Rights Reserved. 29ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 39ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "compiler.h" 49ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 52cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom#include "assembler.h" 69ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "class_linker.h" 71f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "class_loader.h" 89ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom#include "dex_cache.h" 92cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom#include "jni_compiler.h" 109baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom#include "jni_internal.h" 111f87008b165d26541d832ff805250afdc89c253dBrian Carlstrom#include "runtime.h" 129ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 13161928613d3f097108319de60494fab1aab8d48aBrian Carlstromextern bool oatCompileMethod(const art::Compiler& compiler, art::Method*, art::InstructionSet); 149ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 159ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromnamespace art { 169ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 17c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace arm { 18bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 19c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 20c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 21c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liaonamespace x86 { 22bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers ByteArray* CreateAbstractMethodErrorStub(); 23c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 24c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 25161928613d3f097108319de60494fab1aab8d48aBrian CarlstromCompiler::Compiler(InstructionSet insns) : instruction_set_(insns), jni_compiler_(insns), 26161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom verbose_(false) { 2725c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom CHECK(!Runtime::Current()->IsStarted()); 28c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao if (insns == kArm || insns == kThumb2) { 29bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers abstract_method_error_stub_ = arm::CreateAbstractMethodErrorStub(); 30c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao } else if (insns == kX86) { 31bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers abstract_method_error_stub_ = x86::CreateAbstractMethodErrorStub(); 32c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao } 33c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao} 34c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao 358a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstromvoid Compiler::CompileAll(const ClassLoader* class_loader) { 3625c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 379ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Resolve(class_loader); 3898eacac683b78e60799323e8c7d59e7214808639jeffhao Verify(class_loader); 39a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader); 4083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom Compile(class_loader); 419cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom SetCodeAndDirectMethods(class_loader); 428a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom} 438a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom 448a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstromvoid Compiler::CompileOne(Method* method) { 4525c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom DCHECK(!Runtime::Current()->IsStarted()); 468a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader(); 478a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom Resolve(class_loader); 4898eacac683b78e60799323e8c7d59e7214808639jeffhao Verify(class_loader); 49a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader); 508a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom CompileMethod(method); 518a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom SetCodeAndDirectMethods(class_loader); 529ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 539ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 549ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromvoid Compiler::Resolve(const ClassLoader* class_loader) { 558a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 569ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom for (size_t i = 0; i != class_path.size(); ++i) { 579ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const DexFile* dex_file = class_path[i]; 589ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(dex_file != NULL); 599ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom ResolveDexFile(class_loader, *dex_file); 609ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 619ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 629ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 639ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromvoid Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 649ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 659ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 669ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom // Strings are easy, they always are simply resolved to literals in the same file 679ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 68ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) { 69ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom class_linker->ResolveString(dex_file, string_idx, dex_cache); 709ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 719ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 72845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Class derived values are more complicated, they require the linker and loader. 73ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 74ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 75a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(klass->IsResolved()); 769ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 77845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 78845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Method and Field are the worst. We can't resolve without either 79845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // context from the code use (to disambiguate virtual vs direct 80845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // method and instance vs static field) or from class 81845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions. While the compiler will resolve what it can as it 82845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // needs it, here we try to resolve fields and methods used in class 83845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // definitions, since many of them many never be referenced by 84845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // generated code. 85845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 86845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 87845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 88845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // Note the class_data pointer advances through the headers, 89845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // static fields, instance fields, direct methods, and virtual 90845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom // methods. 91845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 92845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 93845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom DexFile::ClassDataHeader header = dex_file.ReadClassDataHeader(&class_data); 94845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom size_t num_static_fields = header.static_fields_size_; 95845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom size_t num_instance_fields = header.instance_fields_size_; 96845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom size_t num_direct_methods = header.direct_methods_size_; 97845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom size_t num_virtual_methods = header.virtual_methods_size_; 98845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom 99845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom if (num_static_fields != 0) { 100845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom uint32_t last_idx = 0; 101845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom for (size_t i = 0; i < num_static_fields; ++i) { 102845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom DexFile::Field dex_field; 103845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx); 104845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, class_loader, true); 105845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 10620cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 107845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom if (num_instance_fields != 0) { 108845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom uint32_t last_idx = 0; 109845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom for (size_t i = 0; i < num_instance_fields; ++i) { 110845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom DexFile::Field dex_field; 111845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom dex_file.dexReadClassDataField(&class_data, &dex_field, &last_idx); 112845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom class_linker->ResolveField(dex_file, dex_field.field_idx_, dex_cache, class_loader, false); 113845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 114845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 115845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom if (num_direct_methods != 0) { 116845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom uint32_t last_idx = 0; 117845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom for (size_t i = 0; i < num_direct_methods; ++i) { 118845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom DexFile::Method dex_method; 119845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); 120845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, class_loader, 121845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom true); 122845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 123845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 124845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom if (num_virtual_methods != 0) { 125845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom uint32_t last_idx = 0; 126845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom for (size_t i = 0; i < num_virtual_methods; ++i) { 127845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom DexFile::Method dex_method; 128845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx); 129845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom class_linker->ResolveMethod(dex_file, dex_method.method_idx_, dex_cache, class_loader, 130845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom false); 131845490bda68f7d025ea7f45775c847d2932e00dcBrian Carlstrom } 13220cfffabdc9e02b2df798bc4e6b6035d14bf4e36Brian Carlstrom } 1339ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 1349ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 1359ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 13698eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::Verify(const ClassLoader* class_loader) { 13798eacac683b78e60799323e8c7d59e7214808639jeffhao const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 13898eacac683b78e60799323e8c7d59e7214808639jeffhao for (size_t i = 0; i != class_path.size(); ++i) { 13998eacac683b78e60799323e8c7d59e7214808639jeffhao const DexFile* dex_file = class_path[i]; 14098eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(dex_file != NULL); 14198eacac683b78e60799323e8c7d59e7214808639jeffhao VerifyDexFile(class_loader, *dex_file); 14298eacac683b78e60799323e8c7d59e7214808639jeffhao } 14398eacac683b78e60799323e8c7d59e7214808639jeffhao} 14498eacac683b78e60799323e8c7d59e7214808639jeffhao 14598eacac683b78e60799323e8c7d59e7214808639jeffhaovoid Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 14698eacac683b78e60799323e8c7d59e7214808639jeffhao ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 147ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 148ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 14998eacac683b78e60799323e8c7d59e7214808639jeffhao const char* descriptor = dex_file.GetClassDescriptor(class_def); 15098eacac683b78e60799323e8c7d59e7214808639jeffhao Class* klass = class_linker->FindClass(descriptor, class_loader); 151a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(klass->IsResolved()); 15298eacac683b78e60799323e8c7d59e7214808639jeffhao CHECK(klass != NULL); 15398eacac683b78e60799323e8c7d59e7214808639jeffhao class_linker->VerifyClass(klass); 154a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(klass->IsVerified() || klass->IsErroneous()); 155a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 156a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 157a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 158a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader) { 159a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 160a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom for (size_t i = 0; i != class_path.size(); ++i) { 161a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const DexFile* dex_file = class_path[i]; 162a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom CHECK(dex_file != NULL); 163a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom InitializeClassesWithoutClinit(class_loader, *dex_file); 164a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom } 165a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom} 166a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom 167a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstromvoid Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) { 168a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 169ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 170ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 171a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 172a5a97a2bc1dfed70869da34650a5a2a3a3a06ac4Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 17325c3325bf95036bf325fc7cb21b4fd6d40282857Brian Carlstrom class_linker->EnsureInitialized(klass, false); 174ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 175ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom 176ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 177ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) { 178ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader); 179ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom if (klass->IsInitialized()) { 180ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass); 181ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom } 18298eacac683b78e60799323e8c7d59e7214808639jeffhao } 18398eacac683b78e60799323e8c7d59e7214808639jeffhao} 18498eacac683b78e60799323e8c7d59e7214808639jeffhao 18583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstromvoid Compiler::Compile(const ClassLoader* class_loader) { 1868a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 18783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom for (size_t i = 0; i != class_path.size(); ++i) { 18883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom const DexFile* dex_file = class_path[i]; 18983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 19083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CompileDexFile(class_loader, *dex_file); 19183db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 19283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 19383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 1949ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromvoid Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) { 1959ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 196ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) { 197ffca45dbd7e152b8c2cda375d2742f798827698eBrian Carlstrom const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index); 1989ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom const char* descriptor = dex_file.GetClassDescriptor(class_def); 1999ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom Class* klass = class_linker->FindClass(descriptor, class_loader); 2009ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CHECK(klass != NULL); 2019ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CompileClass(klass); 2029ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 2039ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 2049ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 2059ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromvoid Compiler::CompileClass(Class* klass) { 2069ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom for (size_t i = 0; i < klass->NumDirectMethods(); i++) { 2079ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CompileMethod(klass->GetDirectMethod(i)); 2089ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 2099ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom for (size_t i = 0; i < klass->NumVirtualMethods(); i++) { 2109ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom CompileMethod(klass->GetVirtualMethod(i)); 2119ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom } 2129ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 2139ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 2142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm { 2152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers void ArmCreateInvokeStub(Method* method); 2162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} 2172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace x86 { 2182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers void X86CreateInvokeStub(Method* method); 2199baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom} 2209baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 2219ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstromvoid Compiler::CompileMethod(Method* method) { 2222cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom if (method->IsNative()) { 2232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers jni_compiler_.Compile(method); 224161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom // unregister will install the stub to lookup via dlsym 225bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // TODO: this is only necessary for tests 226bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers if (!method->IsRegistered()) { 227bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers method->UnregisterNative(); 228bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers } 2292cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else if (method->IsAbstract()) { 230c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao DCHECK(abstract_method_error_stub_ != NULL); 231c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao if (instruction_set_ == kX86) { 232c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao method->SetCode(abstract_method_error_stub_, kX86); 233c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao } else { 234c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 235c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao method->SetCode(abstract_method_error_stub_, kArm); 236c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao } 2372cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } else { 238161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom oatCompileMethod(*this, method, kThumb2); 2392cc022b653e1e84eed2522254ec684bd097572b8Brian Carlstrom } 240c486c11a1c71ca9c118d57152427b741229cda49Shih-wei Liao CHECK(method->GetCode() != NULL); 2419baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom 2422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers if (instruction_set_ == kX86) { 2432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers art::x86::X86CreateInvokeStub(method); 2442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } else { 2452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2); 2462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers // Generates invocation stub using ARM instruction set 2472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers art::arm::ArmCreateInvokeStub(method); 2482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers } 2499baa4aefc370f48774b6104680193d9a7e4fb631Brian Carlstrom CHECK(method->GetInvokeStub() != NULL); 2509ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} 2519ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom 2529cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstromvoid Compiler::SetCodeAndDirectMethods(const ClassLoader* class_loader) { 2538a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom const std::vector<const DexFile*>& class_path = ClassLoader::GetClassPath(class_loader); 25483db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom for (size_t i = 0; i != class_path.size(); ++i) { 25583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom const DexFile* dex_file = class_path[i]; 25683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom CHECK(dex_file != NULL); 2578a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstrom SetCodeAndDirectMethodsDexFile(*dex_file); 25883db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 25983db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 26083db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 2618a48741b96ca9cc5835cac72ac133c4ca480930fBrian Carlstromvoid Compiler::SetCodeAndDirectMethodsDexFile(const DexFile& dex_file) { 26283db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 26383db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom DexCache* dex_cache = class_linker->FindDexCache(dex_file); 2649cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods(); 2651caa2c205e51dda670207828f25451fb7623cea6Brian Carlstrom for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) { 26683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom Method* method = dex_cache->GetResolvedMethod(i); 2679cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom if (method == NULL) { 2689cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom code_and_direct_methods->SetResolvedDirectMethodTrampoline(i); 2699cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom } else if (method->IsDirect()) { 2709cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom code_and_direct_methods->SetResolvedDirectMethod(i, method); 2719cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom } else { 2729cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom // TODO: we currently leave the entry blank for resolved 2739cc262e2ad5cb507c21cc83b8dc954e9354a469cBrian Carlstrom // non-direct methods. we could put in an error stub. 27483db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 27583db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom } 27683db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom} 27783db7721aef15df6919c0ec072e087bef6041e2dBrian Carlstrom 2789ea1cb1a22be5b85dc2622e3836c46a1c48e3f25Brian Carlstrom} // namespace art 279