blob: b27442070ff84862191aac94038543c8bb4f69e7 [file] [log] [blame]
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#include "compiler.h"
4
Brian Carlstrom27ec9612011-09-19 20:20:38 -07005#include <sys/mman.h>
6
Brian Carlstrom2cc022b2011-08-25 10:05:39 -07007#include "assembler.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07008#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -07009#include "class_loader.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070010#include "dex_cache.h"
Brian Carlstrom2cc022b2011-08-25 10:05:39 -070011#include "jni_compiler.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070012#include "jni_internal.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070013#include "oat_file.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070014#include "runtime.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070015#include "stl_util.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070016
Ian Rogers0571d352011-11-03 19:51:38 -070017art::CompiledMethod* oatCompileMethod(const art::Compiler& compiler, bool is_direct,
18 uint32_t method_idx, const art::ClassLoader* class_loader,
19 const art::DexFile& dex_file, art::InstructionSet);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070020
21namespace art {
22
Shih-wei Liaoc486c112011-09-13 16:43:52 -070023namespace arm {
Ian Rogersbdb03912011-09-14 00:55:44 -070024 ByteArray* CreateAbstractMethodErrorStub();
Ian Rogers0571d352011-11-03 19:51:38 -070025 CompiledInvokeStub* ArmCreateInvokeStub(bool is_static, const char* shorty);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070026 ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type);
Ian Rogers169c9a72011-11-13 20:13:17 -080027 ByteArray* CreateJniDlysmLookupStub();
Shih-wei Liaoc486c112011-09-13 16:43:52 -070028}
Shih-wei Liaoc486c112011-09-13 16:43:52 -070029namespace x86 {
Ian Rogersbdb03912011-09-14 00:55:44 -070030 ByteArray* CreateAbstractMethodErrorStub();
Ian Rogers0571d352011-11-03 19:51:38 -070031 CompiledInvokeStub* X86CreateInvokeStub(bool is_static, const char* shorty);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070032 ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type);
Ian Rogers169c9a72011-11-13 20:13:17 -080033 ByteArray* CreateJniDlysmLookupStub();
Brian Carlstrome24fa612011-09-29 00:53:55 -070034}
35
Brian Carlstromaded5f72011-10-07 17:15:04 -070036Compiler::Compiler(InstructionSet instruction_set, bool image)
37 : instruction_set_(instruction_set),
38 jni_compiler_(instruction_set),
39 image_(image),
40 verbose_(false) {
Brian Carlstrom25c33252011-09-18 15:58:35 -070041 CHECK(!Runtime::Current()->IsStarted());
Shih-wei Liaoc486c112011-09-13 16:43:52 -070042}
43
Brian Carlstrom3320cf42011-10-04 14:58:28 -070044Compiler::~Compiler() {
45 STLDeleteValues(&compiled_methods_);
46 STLDeleteValues(&compiled_invoke_stubs_);
47}
48
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070049ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set,
50 Runtime::TrampolineType type) {
Ian Rogersad25ac52011-10-04 19:13:33 -070051 if (instruction_set == kX86) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070052 return x86::X86CreateResolutionTrampoline(type);
Ian Rogersad25ac52011-10-04 19:13:33 -070053 } else {
54 CHECK(instruction_set == kArm || instruction_set == kThumb2);
55 // Generates resolution stub using ARM instruction set
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070056 return arm::ArmCreateResolutionTrampoline(type);
Ian Rogersad25ac52011-10-04 19:13:33 -070057 }
58}
59
Ian Rogers169c9a72011-11-13 20:13:17 -080060ByteArray* Compiler::CreateJniDlysmLookupStub(InstructionSet instruction_set) {
61 switch (instruction_set) {
62 case kArm:
63 case kThumb2:
64 return arm::CreateJniDlysmLookupStub();
65 case kX86:
66 return x86::CreateJniDlysmLookupStub();
67 default:
68 LOG(FATAL) << "Unknown InstructionSet " << (int) instruction_set;
69 return NULL;
70 }
71}
72
Ian Rogersad25ac52011-10-04 19:13:33 -070073ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
74 if (instruction_set == kX86) {
75 return x86::CreateAbstractMethodErrorStub();
76 } else {
77 CHECK(instruction_set == kArm || instruction_set == kThumb2);
78 // Generates resolution stub using ARM instruction set
79 return arm::CreateAbstractMethodErrorStub();
80 }
81}
82
Brian Carlstrom8a487412011-08-29 20:08:52 -070083void Compiler::CompileAll(const ClassLoader* class_loader) {
Brian Carlstrom25c33252011-09-18 15:58:35 -070084 DCHECK(!Runtime::Current()->IsStarted());
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070085 Resolve(class_loader);
jeffhao98eacac2011-09-14 16:11:53 -070086 Verify(class_loader);
Brian Carlstroma5a97a22011-09-15 14:08:49 -070087 InitializeClassesWithoutClinit(class_loader);
Brian Carlstrom83db7722011-08-26 17:32:56 -070088 Compile(class_loader);
Brian Carlstrom9cc262e2011-08-28 12:45:30 -070089 SetCodeAndDirectMethods(class_loader);
Brian Carlstrom8a487412011-08-29 20:08:52 -070090}
91
Brian Carlstrom3320cf42011-10-04 14:58:28 -070092void Compiler::CompileOne(const Method* method) {
Brian Carlstrom25c33252011-09-18 15:58:35 -070093 DCHECK(!Runtime::Current()->IsStarted());
Brian Carlstrom8a487412011-08-29 20:08:52 -070094 const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader();
95 Resolve(class_loader);
jeffhao98eacac2011-09-14 16:11:53 -070096 Verify(class_loader);
Brian Carlstroma5a97a22011-09-15 14:08:49 -070097 InitializeClassesWithoutClinit(class_loader);
Ian Rogers0571d352011-11-03 19:51:38 -070098 // Find the dex_file
99 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
100 const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
101 uint32_t method_idx = method->GetDexMethodIndex();
Ian Rogers169c9a72011-11-13 20:13:17 -0800102 CompileMethod(method->GetAccessFlags(), method_idx, class_loader, dex_file);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700103 SetCodeAndDirectMethods(class_loader);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700104}
105
106void Compiler::Resolve(const ClassLoader* class_loader) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700107 const std::vector<const DexFile*>& class_path
108 = ClassLoader::GetCompileTimeClassPath(class_loader);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700109 for (size_t i = 0; i != class_path.size(); ++i) {
110 const DexFile* dex_file = class_path[i];
111 CHECK(dex_file != NULL);
112 ResolveDexFile(class_loader, *dex_file);
113 }
114}
115
116void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
117 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Brian Carlstromaded5f72011-10-07 17:15:04 -0700118 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700119
120 // Strings are easy, they always are simply resolved to literals in the same file
Brian Carlstromaded5f72011-10-07 17:15:04 -0700121 if (IsImage()) { // Only resolve when we'll have an image, so compiler won't choose fast path
122 for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) {
123 class_linker->ResolveString(dex_file, string_idx, dex_cache);
124 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700125 }
126
Brian Carlstrom845490b2011-09-19 15:56:53 -0700127 // Class derived values are more complicated, they require the linker and loader.
Brian Carlstromffca45d2011-09-16 12:10:49 -0700128 for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) {
129 Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700130 if (klass == NULL) {
131 Thread::Current()->ClearException();
132 }
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700133 }
Brian Carlstrom845490b2011-09-19 15:56:53 -0700134
135 // Method and Field are the worst. We can't resolve without either
136 // context from the code use (to disambiguate virtual vs direct
137 // method and instance vs static field) or from class
138 // definitions. While the compiler will resolve what it can as it
139 // needs it, here we try to resolve fields and methods used in class
140 // definitions, since many of them many never be referenced by
141 // generated code.
142 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
143 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
144
145 // Note the class_data pointer advances through the headers,
146 // static fields, instance fields, direct methods, and virtual
147 // methods.
148 const byte* class_data = dex_file.GetClassData(class_def);
Ian Rogers0571d352011-11-03 19:51:38 -0700149 if (class_data == NULL) {
150 // empty class such as a marker interface
151 continue;
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700152 }
Ian Rogers0571d352011-11-03 19:51:38 -0700153 ClassDataItemIterator it(dex_file, class_data);
154 while (it.HasNextStaticField()) {
155 Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
156 class_loader, true);
157 if (field == NULL) {
158 Thread* self = Thread::Current();
159 CHECK(self->IsExceptionPending());
160 self->ClearException();
Brian Carlstrom845490b2011-09-19 15:56:53 -0700161 }
Ian Rogers0571d352011-11-03 19:51:38 -0700162 it.Next();
Brian Carlstrom845490b2011-09-19 15:56:53 -0700163 }
Ian Rogers0571d352011-11-03 19:51:38 -0700164 while (it.HasNextInstanceField()) {
165 Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
166 class_loader, false);
167 if (field == NULL) {
168 Thread* self = Thread::Current();
169 CHECK(self->IsExceptionPending());
170 self->ClearException();
Brian Carlstrom845490b2011-09-19 15:56:53 -0700171 }
Ian Rogers0571d352011-11-03 19:51:38 -0700172 it.Next();
Brian Carlstrom845490b2011-09-19 15:56:53 -0700173 }
Ian Rogers0571d352011-11-03 19:51:38 -0700174 while (it.HasNextDirectMethod()) {
175 Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
176 class_loader, true);
177 if (method == NULL) {
178 Thread* self = Thread::Current();
179 CHECK(self->IsExceptionPending());
180 self->ClearException();
Brian Carlstrom845490b2011-09-19 15:56:53 -0700181 }
Ian Rogers0571d352011-11-03 19:51:38 -0700182 it.Next();
Brian Carlstrom20cfffa2011-08-26 02:31:27 -0700183 }
Ian Rogers0571d352011-11-03 19:51:38 -0700184 while (it.HasNextVirtualMethod()) {
185 Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
186 class_loader, false);
187 if (method == NULL) {
188 Thread* self = Thread::Current();
189 CHECK(self->IsExceptionPending());
190 self->ClearException();
191 }
192 it.Next();
193 }
194 DCHECK(!it.HasNext());
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700195 }
196}
197
jeffhao98eacac2011-09-14 16:11:53 -0700198void Compiler::Verify(const ClassLoader* class_loader) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700199 const std::vector<const DexFile*>& class_path
200 = ClassLoader::GetCompileTimeClassPath(class_loader);
jeffhao98eacac2011-09-14 16:11:53 -0700201 for (size_t i = 0; i != class_path.size(); ++i) {
202 const DexFile* dex_file = class_path[i];
203 CHECK(dex_file != NULL);
204 VerifyDexFile(class_loader, *dex_file);
205 }
206}
207
208void Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
jeffhaob4df5142011-09-19 20:25:32 -0700209 dex_file.ChangePermissions(PROT_READ | PROT_WRITE);
jeffhao98eacac2011-09-14 16:11:53 -0700210 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Brian Carlstromffca45d2011-09-16 12:10:49 -0700211 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
212 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
jeffhao98eacac2011-09-14 16:11:53 -0700213 const char* descriptor = dex_file.GetClassDescriptor(class_def);
214 Class* klass = class_linker->FindClass(descriptor, class_loader);
Brian Carlstrom65ca0772011-09-24 16:03:08 -0700215 if (klass == NULL) {
216 Thread* self = Thread::Current();
217 CHECK(self->IsExceptionPending());
218 self->ClearException();
219 continue;
220 }
221 CHECK(klass->IsResolved()) << PrettyClass(klass);
jeffhao98eacac2011-09-14 16:11:53 -0700222 class_linker->VerifyClass(klass);
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700223
224 if (klass->IsErroneous()) {
225 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
226 CHECK(Thread::Current()->IsExceptionPending());
227 Thread::Current()->ClearException();
228 // We want to try verification again at run-time, so move back into the resolved state.
229 klass->SetStatus(Class::kStatusResolved);
230 }
231
jeffhao5cfd6fb2011-09-27 13:54:29 -0700232 CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass);
233 CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700234 }
jeffhaob4df5142011-09-19 20:25:32 -0700235 dex_file.ChangePermissions(PROT_READ);
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700236}
237
238void Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700239 const std::vector<const DexFile*>& class_path
240 = ClassLoader::GetCompileTimeClassPath(class_loader);
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700241 for (size_t i = 0; i != class_path.size(); ++i) {
242 const DexFile* dex_file = class_path[i];
243 CHECK(dex_file != NULL);
244 InitializeClassesWithoutClinit(class_loader, *dex_file);
245 }
246}
247
248void Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) {
249 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Brian Carlstromffca45d2011-09-16 12:10:49 -0700250 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
251 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700252 const char* descriptor = dex_file.GetClassDescriptor(class_def);
253 Class* klass = class_linker->FindClass(descriptor, class_loader);
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700254 if (klass != NULL) {
255 class_linker->EnsureInitialized(klass, false);
256 }
257 // clear any class not found or verification exceptions
258 Thread::Current()->ClearException();
Brian Carlstromffca45d2011-09-16 12:10:49 -0700259 }
260
261 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
262 for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) {
263 Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700264 if (klass == NULL) {
265 Thread::Current()->ClearException();
266 } else if (klass->IsInitialized()) {
Brian Carlstromffca45d2011-09-16 12:10:49 -0700267 dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass);
268 }
jeffhao98eacac2011-09-14 16:11:53 -0700269 }
270}
271
Brian Carlstrom83db7722011-08-26 17:32:56 -0700272void Compiler::Compile(const ClassLoader* class_loader) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700273 const std::vector<const DexFile*>& class_path
274 = ClassLoader::GetCompileTimeClassPath(class_loader);
Brian Carlstrom83db7722011-08-26 17:32:56 -0700275 for (size_t i = 0; i != class_path.size(); ++i) {
276 const DexFile* dex_file = class_path[i];
277 CHECK(dex_file != NULL);
278 CompileDexFile(class_loader, *dex_file);
279 }
280}
281
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700282void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
Brian Carlstromffca45d2011-09-16 12:10:49 -0700283 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
284 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogers0571d352011-11-03 19:51:38 -0700285 CompileClass(class_def, class_loader, dex_file);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700286 }
287}
288
Ian Rogers0571d352011-11-03 19:51:38 -0700289void Compiler::CompileClass(const DexFile::ClassDef& class_def, const ClassLoader* class_loader,
290 const DexFile& dex_file) {
291 const byte* class_data = dex_file.GetClassData(class_def);
292 if (class_data == NULL) {
293 // empty class, probably a marker interface
294 return;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700295 }
Ian Rogers0571d352011-11-03 19:51:38 -0700296 ClassDataItemIterator it(dex_file, class_data);
297 // Skip fields
298 while (it.HasNextStaticField()) {
299 it.Next();
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700300 }
Ian Rogers0571d352011-11-03 19:51:38 -0700301 while (it.HasNextInstanceField()) {
302 it.Next();
303 }
304 // Compile direct methods
305 while (it.HasNextDirectMethod()) {
Ian Rogers169c9a72011-11-13 20:13:17 -0800306 CompileMethod(it.GetMemberAccessFlags(), it.GetMemberIndex(), class_loader, dex_file);
Ian Rogers0571d352011-11-03 19:51:38 -0700307 it.Next();
308 }
309 // Compile virtual methods
310 while (it.HasNextVirtualMethod()) {
Ian Rogers169c9a72011-11-13 20:13:17 -0800311 CompileMethod(it.GetMemberAccessFlags(), it.GetMemberIndex(), class_loader, dex_file);
Ian Rogers0571d352011-11-03 19:51:38 -0700312 it.Next();
313 }
314 DCHECK(!it.HasNext());
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700315}
316
Ian Rogers169c9a72011-11-13 20:13:17 -0800317void Compiler::CompileMethod(uint32_t access_flags, uint32_t method_idx,
318 const ClassLoader* class_loader, const DexFile& dex_file) {
Elliott Hughesf09afe82011-10-16 14:24:21 -0700319 CompiledMethod* compiled_method = NULL;
Ian Rogers169c9a72011-11-13 20:13:17 -0800320 if ((access_flags & kAccNative) != 0) {
321 compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700322 CHECK(compiled_method != NULL);
Ian Rogers169c9a72011-11-13 20:13:17 -0800323 } else if ((access_flags & kAccAbstract) != 0) {
Brian Carlstrom2cc022b2011-08-25 10:05:39 -0700324 } else {
Ian Rogers169c9a72011-11-13 20:13:17 -0800325 bool is_direct = (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
Ian Rogers0571d352011-11-03 19:51:38 -0700326 compiled_method = oatCompileMethod(*this, is_direct, method_idx, class_loader, dex_file,
327 kThumb2);
328 // TODO: assert compiled_method is not NULL, currently NULL may be returned if the method
329 // wasn't resolved
Elliott Hughesf09afe82011-10-16 14:24:21 -0700330 }
331
332 if (compiled_method != NULL) {
Ian Rogers0571d352011-11-03 19:51:38 -0700333 MethodReference ref(&dex_file, method_idx);
334 CHECK(compiled_methods_.find(ref) == compiled_methods_.end())
335 << PrettyMethod(method_idx, dex_file);
336 compiled_methods_[ref] = compiled_method;
337 DCHECK(compiled_methods_.find(ref) != compiled_methods_.end())
338 << PrettyMethod(method_idx, dex_file);
339 DCHECK(GetCompiledMethod(ref) != NULL)
340 << PrettyMethod(method_idx, dex_file);
Brian Carlstrom2cc022b2011-08-25 10:05:39 -0700341 }
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -0700342
Ian Rogers0571d352011-11-03 19:51:38 -0700343 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
Ian Rogers169c9a72011-11-13 20:13:17 -0800344 bool is_static = (access_flags & kAccStatic) != 0;
Ian Rogers0571d352011-11-03 19:51:38 -0700345 const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(is_static, shorty);
346 if (compiled_invoke_stub == NULL) {
347 if (instruction_set_ == kX86) {
348 compiled_invoke_stub = art::x86::X86CreateInvokeStub(is_static, shorty);
349 } else {
350 CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2);
351 // Generates invocation stub using ARM instruction set
352 compiled_invoke_stub = art::arm::ArmCreateInvokeStub(is_static, shorty);
353 }
354 CHECK(compiled_invoke_stub != NULL);
355 InsertInvokeStub(is_static, shorty, compiled_invoke_stub);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700356 }
Ian Rogers0571d352011-11-03 19:51:38 -0700357 CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700358}
359
Ian Rogers0571d352011-11-03 19:51:38 -0700360static std::string MakeInvokeStubKey(bool is_static, const char* shorty) {
361 std::string key(shorty);
362 if (is_static) {
363 key += "$"; // musn't be a shorty type character
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700364 }
Ian Rogers0571d352011-11-03 19:51:38 -0700365 return key;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700366}
367
Ian Rogers0571d352011-11-03 19:51:38 -0700368const CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const {
369 std::string key = MakeInvokeStubKey(is_static, shorty);
370 InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700371 if (it == compiled_invoke_stubs_.end()) {
372 return NULL;
Ian Rogers0571d352011-11-03 19:51:38 -0700373 } else {
374 DCHECK(it->second != NULL);
375 return it->second;
376 }
377}
378
379void Compiler::InsertInvokeStub(bool is_static, const char* shorty,
380 const CompiledInvokeStub* compiled_invoke_stub) {
381 std::string key = MakeInvokeStubKey(is_static, shorty);
382 compiled_invoke_stubs_[key] = compiled_invoke_stub;
383}
384
385CompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const {
386 MethodTable::const_iterator it = compiled_methods_.find(ref);
387 if (it == compiled_methods_.end()) {
388 return NULL;
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700389 }
390 CHECK(it->second != NULL);
391 return it->second;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700392}
393
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700394void Compiler::SetCodeAndDirectMethods(const ClassLoader* class_loader) {
Brian Carlstromaded5f72011-10-07 17:15:04 -0700395 const std::vector<const DexFile*>& class_path
396 = ClassLoader::GetCompileTimeClassPath(class_loader);
Brian Carlstrom83db7722011-08-26 17:32:56 -0700397 for (size_t i = 0; i != class_path.size(); ++i) {
398 const DexFile* dex_file = class_path[i];
399 CHECK(dex_file != NULL);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700400 SetCodeAndDirectMethodsDexFile(*dex_file);
Brian Carlstrom83db7722011-08-26 17:32:56 -0700401 }
402}
403
Brian Carlstrom8a487412011-08-29 20:08:52 -0700404void Compiler::SetCodeAndDirectMethodsDexFile(const DexFile& dex_file) {
Ian Rogersad25ac52011-10-04 19:13:33 -0700405 Runtime* runtime = Runtime::Current();
406 ClassLinker* class_linker = runtime->GetClassLinker();
Brian Carlstrom83db7722011-08-26 17:32:56 -0700407 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700408 CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
Brian Carlstrom1caa2c22011-08-28 13:02:33 -0700409 for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
Brian Carlstrom83db7722011-08-26 17:32:56 -0700410 Method* method = dex_cache->GetResolvedMethod(i);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700411 if (method == NULL || method->IsDirect()) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700412 Runtime::TrampolineType type = Runtime::GetTrampolineType(method);
413 ByteArray* res_trampoline = runtime->GetResolutionStubArray(type);
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700414 code_and_direct_methods->SetResolvedDirectMethodTrampoline(i, res_trampoline);
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700415 } else {
416 // TODO: we currently leave the entry blank for resolved
417 // non-direct methods. we could put in an error stub.
Brian Carlstrom83db7722011-08-26 17:32:56 -0700418 }
419 }
420}
421
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700422} // namespace art