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