blob: e54dd8935bb80aefb45e4254a100fa45e4de1d64 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070016
17#include "compiler.h"
18
Elliott Hughesd9c67be2012-02-02 19:54:06 -080019#include <vector>
20
Brian Carlstrom27ec9612011-09-19 20:20:38 -070021#include <sys/mman.h>
Elliott Hughesd9c67be2012-02-02 19:54:06 -080022#include <unistd.h>
Brian Carlstrom27ec9612011-09-19 20:20:38 -070023
Brian Carlstrom2cc022b2011-08-25 10:05:39 -070024#include "assembler.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070025#include "class_linker.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070026#include "class_loader.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070027#include "dex_cache.h"
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -070028#include "jni_internal.h"
Logan Chien4dd96f52012-02-29 01:26:58 +080029#include "oat_compilation_unit.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070030#include "oat_file.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080031#include "object_utils.h"
Brian Carlstrom1f870082011-08-23 16:02:11 -070032#include "runtime.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070033#include "stl_util.h"
Elliott Hughes601a1232012-02-02 17:47:38 -080034#include "timing_logger.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070035
Logan Chien9787ac42012-03-06 18:24:03 +080036#if !defined(ART_USE_LLVM_COMPILER)
37#include "jni_compiler.h"
38#endif
39
Shih-wei Liaod1fec812012-02-13 09:51:10 -080040#if defined(ART_USE_LLVM_COMPILER)
41#include "compiler_llvm/compiler_llvm.h"
42#endif
43
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070044namespace art {
45
Shih-wei Liaod1fec812012-02-13 09:51:10 -080046#if !defined(ART_USE_LLVM_COMPILER)
Ian Rogers996cc582012-02-14 22:23:29 -080047CompiledMethod* oatCompileMethod(Compiler& compiler, const DexFile::CodeItem* code_item,
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080048 uint32_t access_flags, uint32_t method_idx,
49 const ClassLoader* class_loader,
50 const DexFile& dex_file, InstructionSet);
Shih-wei Liaod1fec812012-02-13 09:51:10 -080051#endif
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080052
Shih-wei Liaoc486c112011-09-13 16:43:52 -070053namespace arm {
Ian Rogersbdb03912011-09-14 00:55:44 -070054 ByteArray* CreateAbstractMethodErrorStub();
Ian Rogers45619fc2012-02-29 11:15:25 -080055 CompiledInvokeStub* ArmCreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070056 ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type);
Elliott Hughes8add92d2012-01-18 18:18:43 -080057 ByteArray* CreateJniDlsymLookupStub();
Shih-wei Liaoc486c112011-09-13 16:43:52 -070058}
Shih-wei Liaoc486c112011-09-13 16:43:52 -070059namespace x86 {
Ian Rogersbdb03912011-09-14 00:55:44 -070060 ByteArray* CreateAbstractMethodErrorStub();
Ian Rogers45619fc2012-02-29 11:15:25 -080061 CompiledInvokeStub* X86CreateInvokeStub(bool is_static, const char* shorty, uint32_t shorty_len);
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070062 ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type);
Elliott Hughes8add92d2012-01-18 18:18:43 -080063 ByteArray* CreateJniDlsymLookupStub();
Brian Carlstrome24fa612011-09-29 00:53:55 -070064}
65
jeffhaod1224c72012-02-29 13:43:08 -080066namespace verifier {
67 class DexVerifier {
68 public:
69 static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref);
70 static bool IsClassRejected(Compiler::ClassReference ref);
71 };
72}
73
Ian Rogers996cc582012-02-14 22:23:29 -080074static double Percentage(size_t x, size_t y) {
75 return 100.0 * ((double)x) / ((double)(x + y));
76}
77
78static void DumpStat(size_t x, size_t y, const char* str) {
79 if (x == 0 && y == 0) {
80 return;
81 }
82 LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases";
83}
84
Ian Rogersc8b306f2012-02-17 21:34:44 -080085class AOTCompilationStats {
86 public:
87 AOTCompilationStats() : stats_lock_("AOT compilation statistics lock"),
88 types_in_dex_cache_(0), types_not_in_dex_cache_(0),
89 strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
90 resolved_types_(0), unresolved_types_(0),
91 resolved_instance_fields_(0), unresolved_instance_fields_(0),
Ian Rogersfb6adba2012-03-04 21:51:51 -080092 resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
93 virtual_made_direct_(0) {
Ian Rogersc8b306f2012-02-17 21:34:44 -080094 for (size_t i = 0; i < kMaxInvokeType; i++) {
95 resolved_methods_[i] = 0;
96 unresolved_methods_[i] = 0;
97 }
98 }
99
100 void Dump() {
101 DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
102 DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
103 DumpStat(resolved_types_, unresolved_types_, "types resolved");
104 DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
105 DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
106 "static fields resolved");
107 DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_,
108 "static fields local to a class");
109
110 for (size_t i = 0; i < kMaxInvokeType; i++) {
111 std::ostringstream oss;
112 oss << "resolved " << static_cast<InvokeType>(i) << " methods";
113 DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
114 }
Ian Rogersfb6adba2012-03-04 21:51:51 -0800115 DumpStat(virtual_made_direct_, resolved_methods_[kVirtual] + unresolved_methods_[kVirtual],
116 "made direct from virtual");
Ian Rogersc8b306f2012-02-17 21:34:44 -0800117 }
Ian Rogers996cc582012-02-14 22:23:29 -0800118
119// Allow lossy statistics in non-debug builds
120#ifndef NDEBUG
121#define STATS_LOCK() MutexLock mu(stats_lock_)
122#else
123#define STATS_LOCK()
124#endif
125
Ian Rogersc8b306f2012-02-17 21:34:44 -0800126 void TypeInDexCache() {
127 STATS_LOCK();
128 types_in_dex_cache_++;
Ian Rogers996cc582012-02-14 22:23:29 -0800129 }
Ian Rogers996cc582012-02-14 22:23:29 -0800130
Ian Rogersc8b306f2012-02-17 21:34:44 -0800131 void TypeNotInDexCache() {
132 STATS_LOCK();
133 types_not_in_dex_cache_++;
Ian Rogers996cc582012-02-14 22:23:29 -0800134 }
Ian Rogersc8b306f2012-02-17 21:34:44 -0800135
136 void StringInDexCache() {
137 STATS_LOCK();
138 strings_in_dex_cache_++;
139 }
140
141 void StringNotInDexCache() {
142 STATS_LOCK();
143 strings_not_in_dex_cache_++;
144 }
145
146 void TypeDoesntNeedAccessCheck() {
147 STATS_LOCK();
148 resolved_types_++;
149 }
150
151 void TypeNeedsAccessCheck() {
152 STATS_LOCK();
153 unresolved_types_++;
154 }
155
156 void ResolvedInstanceField() {
157 STATS_LOCK();
158 resolved_instance_fields_++;
159 }
160
161 void UnresolvedInstanceField(){
162 STATS_LOCK();
163 unresolved_instance_fields_++;
164 }
165
166 void ResolvedLocalStaticField() {
167 STATS_LOCK();
168 resolved_local_static_fields_++;
169 }
170
171 void ResolvedStaticField() {
172 STATS_LOCK();
173 resolved_static_fields_++;
174 }
175
176 void UnresolvedStaticField() {
177 STATS_LOCK();
178 unresolved_static_fields_++;
179 }
180
181 void ResolvedMethod(InvokeType type) {
182 DCHECK_LE(type, kMaxInvokeType);
183 STATS_LOCK();
184 resolved_methods_[type]++;
185 }
186
187 void UnresolvedMethod(InvokeType type) {
188 DCHECK_LE(type, kMaxInvokeType);
189 STATS_LOCK();
190 unresolved_methods_[type]++;
191 }
192
Ian Rogersfb6adba2012-03-04 21:51:51 -0800193 void VirtualMadeDirect() {
194 STATS_LOCK();
195 virtual_made_direct_++;
196 }
Ian Rogersc8b306f2012-02-17 21:34:44 -0800197 private:
198 Mutex stats_lock_;
199
200 size_t types_in_dex_cache_;
201 size_t types_not_in_dex_cache_;
202
203 size_t strings_in_dex_cache_;
204 size_t strings_not_in_dex_cache_;
205
206 size_t resolved_types_;
207 size_t unresolved_types_;
208
209 size_t resolved_instance_fields_;
210 size_t unresolved_instance_fields_;
211
212 size_t resolved_local_static_fields_;
213 size_t resolved_static_fields_;
214 size_t unresolved_static_fields_;
215
216 size_t resolved_methods_[kMaxInvokeType + 1];
217 size_t unresolved_methods_[kMaxInvokeType + 1];
Ian Rogersfb6adba2012-03-04 21:51:51 -0800218 size_t virtual_made_direct_;
Ian Rogersc8b306f2012-02-17 21:34:44 -0800219
220 DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);;
221};
Ian Rogers996cc582012-02-14 22:23:29 -0800222
Elliott Hughes5523ee02012-02-03 18:18:34 -0800223Compiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_count,
Elliott Hughesde6e4cf2012-02-27 14:46:06 -0800224 bool support_debugging, const std::set<std::string>* image_classes)
Brian Carlstromaded5f72011-10-07 17:15:04 -0700225 : instruction_set_(instruction_set),
Logan Chien9787ac42012-03-06 18:24:03 +0800226#if !defined(ART_USE_LLVM_COMPILER)
Brian Carlstromaded5f72011-10-07 17:15:04 -0700227 jni_compiler_(instruction_set),
Logan Chien9787ac42012-03-06 18:24:03 +0800228#endif
Elliott Hughesc225caa2012-02-03 15:43:37 -0800229 compiled_classes_lock_("compiled classes lock"),
230 compiled_methods_lock_("compiled method lock"),
231 compiled_invoke_stubs_lock_("compiled invoke stubs lock"),
Brian Carlstromaded5f72011-10-07 17:15:04 -0700232 image_(image),
Elliott Hughes5523ee02012-02-03 18:18:34 -0800233 thread_count_(thread_count),
Elliott Hughesde6e4cf2012-02-27 14:46:06 -0800234 support_debugging_(support_debugging),
Ian Rogersc8b306f2012-02-17 21:34:44 -0800235 stats_(new AOTCompilationStats),
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800236 image_classes_(image_classes)
237#if defined(ART_USE_LLVM_COMPILER)
238 ,
239 compiler_llvm_(new compiler_llvm::CompilerLLVM(this, instruction_set))
240#endif
241 {
Brian Carlstrom25c33252011-09-18 15:58:35 -0700242 CHECK(!Runtime::Current()->IsStarted());
Brian Carlstromae826982011-11-09 01:33:42 -0800243 if (!image_) {
244 CHECK(image_classes_ == NULL);
245 }
Shih-wei Liaoc486c112011-09-13 16:43:52 -0700246}
247
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700248Compiler::~Compiler() {
Elliott Hughesc225caa2012-02-03 15:43:37 -0800249 {
250 MutexLock mu(compiled_classes_lock_);
251 STLDeleteValues(&compiled_classes_);
252 }
253 {
254 MutexLock mu(compiled_methods_lock_);
255 STLDeleteValues(&compiled_methods_);
256 }
257 {
258 MutexLock mu(compiled_invoke_stubs_lock_);
259 STLDeleteValues(&compiled_invoke_stubs_);
Elliott Hughesbb551fa2012-01-25 16:35:29 -0800260 }
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700261}
262
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700263ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set,
264 Runtime::TrampolineType type) {
Ian Rogersad25ac52011-10-04 19:13:33 -0700265 if (instruction_set == kX86) {
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700266 return x86::X86CreateResolutionTrampoline(type);
Ian Rogersad25ac52011-10-04 19:13:33 -0700267 } else {
268 CHECK(instruction_set == kArm || instruction_set == kThumb2);
269 // Generates resolution stub using ARM instruction set
Ian Rogers1cb0a1d2011-10-06 15:24:35 -0700270 return arm::ArmCreateResolutionTrampoline(type);
Ian Rogersad25ac52011-10-04 19:13:33 -0700271 }
272}
273
Elliott Hughes8add92d2012-01-18 18:18:43 -0800274ByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
Ian Rogers169c9a72011-11-13 20:13:17 -0800275 switch (instruction_set) {
276 case kArm:
277 case kThumb2:
Elliott Hughes8add92d2012-01-18 18:18:43 -0800278 return arm::CreateJniDlsymLookupStub();
Ian Rogers169c9a72011-11-13 20:13:17 -0800279 case kX86:
Elliott Hughes8add92d2012-01-18 18:18:43 -0800280 return x86::CreateJniDlsymLookupStub();
Ian Rogers169c9a72011-11-13 20:13:17 -0800281 default:
Elliott Hughesba8eee12012-01-24 20:25:24 -0800282 LOG(FATAL) << "Unknown InstructionSet: " << static_cast<int>(instruction_set);
Ian Rogers169c9a72011-11-13 20:13:17 -0800283 return NULL;
284 }
285}
286
Ian Rogersad25ac52011-10-04 19:13:33 -0700287ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
288 if (instruction_set == kX86) {
289 return x86::CreateAbstractMethodErrorStub();
290 } else {
291 CHECK(instruction_set == kArm || instruction_set == kThumb2);
292 // Generates resolution stub using ARM instruction set
293 return arm::CreateAbstractMethodErrorStub();
294 }
295}
296
Jesse Wilson254db0f2011-11-16 16:44:11 -0500297void Compiler::CompileAll(const ClassLoader* class_loader,
Brian Carlstromae826982011-11-09 01:33:42 -0800298 const std::vector<const DexFile*>& dex_files) {
Brian Carlstrom25c33252011-09-18 15:58:35 -0700299 DCHECK(!Runtime::Current()->IsStarted());
Brian Carlstromae826982011-11-09 01:33:42 -0800300
Elliott Hughes601a1232012-02-02 17:47:38 -0800301 TimingLogger timings("compiler");
302
303 PreCompile(class_loader, dex_files, timings);
304
Brian Carlstromae826982011-11-09 01:33:42 -0800305 Compile(class_loader, dex_files);
Elliott Hughes601a1232012-02-02 17:47:38 -0800306 timings.AddSplit("Compile");
307
Brian Carlstromae826982011-11-09 01:33:42 -0800308 PostCompile(class_loader, dex_files);
Elliott Hughes601a1232012-02-02 17:47:38 -0800309 timings.AddSplit("PostCompile");
310
311 if (timings.GetTotalNs() > MsToNs(1000)) {
312 timings.Dump();
313 }
Ian Rogers996cc582012-02-14 22:23:29 -0800314
Ian Rogersc8b306f2012-02-17 21:34:44 -0800315 stats_->Dump();
Brian Carlstrom8a487412011-08-29 20:08:52 -0700316}
317
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700318void Compiler::CompileOne(const Method* method) {
Brian Carlstrom25c33252011-09-18 15:58:35 -0700319 DCHECK(!Runtime::Current()->IsStarted());
Brian Carlstromae826982011-11-09 01:33:42 -0800320
Brian Carlstrom8a487412011-08-29 20:08:52 -0700321 const ClassLoader* class_loader = method->GetDeclaringClass()->GetClassLoader();
Brian Carlstromae826982011-11-09 01:33:42 -0800322
Ian Rogers0571d352011-11-03 19:51:38 -0700323 // Find the dex_file
324 const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
325 const DexFile& dex_file = Runtime::Current()->GetClassLinker()->FindDexFile(dex_cache);
Brian Carlstromae826982011-11-09 01:33:42 -0800326 std::vector<const DexFile*> dex_files;
327 dex_files.push_back(&dex_file);
328
Elliott Hughes601a1232012-02-02 17:47:38 -0800329 TimingLogger timings("CompileOne");
330 PreCompile(class_loader, dex_files, timings);
Brian Carlstromae826982011-11-09 01:33:42 -0800331
Ian Rogers0571d352011-11-03 19:51:38 -0700332 uint32_t method_idx = method->GetDexMethodIndex();
Ian Rogersa3760aa2011-11-14 14:32:37 -0800333 const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset());
334 CompileMethod(code_item, method->GetAccessFlags(), method_idx, class_loader, dex_file);
Brian Carlstromae826982011-11-09 01:33:42 -0800335
336 PostCompile(class_loader, dex_files);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700337}
338
Brian Carlstromae826982011-11-09 01:33:42 -0800339void Compiler::Resolve(const ClassLoader* class_loader,
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800340 const std::vector<const DexFile*>& dex_files, TimingLogger& timings) {
Brian Carlstromae826982011-11-09 01:33:42 -0800341 for (size_t i = 0; i != dex_files.size(); ++i) {
342 const DexFile* dex_file = dex_files[i];
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700343 CHECK(dex_file != NULL);
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800344 ResolveDexFile(class_loader, *dex_file, timings);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700345 }
346}
347
Brian Carlstromae826982011-11-09 01:33:42 -0800348void Compiler::PreCompile(const ClassLoader* class_loader,
Elliott Hughes601a1232012-02-02 17:47:38 -0800349 const std::vector<const DexFile*>& dex_files, TimingLogger& timings) {
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800350 Resolve(class_loader, dex_files, timings);
Elliott Hughes601a1232012-02-02 17:47:38 -0800351
Brian Carlstromae826982011-11-09 01:33:42 -0800352 Verify(class_loader, dex_files);
Elliott Hughes601a1232012-02-02 17:47:38 -0800353 timings.AddSplit("PreCompile.Verify");
354
Brian Carlstromae826982011-11-09 01:33:42 -0800355 InitializeClassesWithoutClinit(class_loader, dex_files);
Elliott Hughes601a1232012-02-02 17:47:38 -0800356 timings.AddSplit("PreCompile.InitializeClassesWithoutClinit");
Brian Carlstromae826982011-11-09 01:33:42 -0800357}
358
359void Compiler::PostCompile(const ClassLoader* class_loader,
360 const std::vector<const DexFile*>& dex_files) {
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800361 SetGcMaps(class_loader, dex_files);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800362#if defined(ART_USE_LLVM_COMPILER)
Logan Chien7f767612012-03-01 18:54:49 +0800363 compiler_llvm_->MaterializeRemainder();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800364#endif
Brian Carlstromae826982011-11-09 01:33:42 -0800365}
366
367bool Compiler::IsImageClass(const std::string& descriptor) const {
368 if (image_classes_ == NULL) {
369 return true;
370 }
371 return image_classes_->find(descriptor) != image_classes_->end();
372}
373
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800374bool Compiler::CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache,
Ian Rogers996cc582012-02-14 22:23:29 -0800375 uint32_t type_idx) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800376 if (!IsImage()) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800377 stats_->TypeNotInDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800378 return false;
379 }
Ian Rogers1bddec32012-02-04 12:27:34 -0800380 Class* resolved_class = dex_cache->GetResolvedType(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800381 if (resolved_class == NULL) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800382 stats_->TypeNotInDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800383 return false;
384 }
Ian Rogers996cc582012-02-14 22:23:29 -0800385 bool result = IsImageClass(ClassHelper(resolved_class).GetDescriptor());
386 if (result) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800387 stats_->TypeInDexCache();
Ian Rogers996cc582012-02-14 22:23:29 -0800388 } else {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800389 stats_->TypeNotInDexCache();
Ian Rogers996cc582012-02-14 22:23:29 -0800390 }
391 return result;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800392}
393
Ian Rogers1bddec32012-02-04 12:27:34 -0800394bool Compiler::CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache,
Ian Rogers996cc582012-02-14 22:23:29 -0800395 uint32_t string_idx) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800396 // TODO: Add support for loading strings referenced by image_classes_
397 // See also Compiler::ResolveDexFile
398
399 // The following is a test saying that if we're building the image without a restricted set of
400 // image classes then we can assume the string is present in the dex cache if it is there now
Ian Rogers996cc582012-02-14 22:23:29 -0800401 bool result = IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL;
402 if (result) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800403 stats_->StringInDexCache();
Ian Rogers996cc582012-02-14 22:23:29 -0800404 } else {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800405 stats_->StringNotInDexCache();
Ian Rogers996cc582012-02-14 22:23:29 -0800406 }
407 return result;
Ian Rogers1bddec32012-02-04 12:27:34 -0800408}
409
410bool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache,
Ian Rogers996cc582012-02-14 22:23:29 -0800411 const DexFile& dex_file, uint32_t type_idx) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800412 // Get type from dex cache assuming it was populated by the verifier
413 Class* resolved_class = dex_cache->GetResolvedType(type_idx);
414 if (resolved_class == NULL) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800415 stats_->TypeNeedsAccessCheck();
Ian Rogers1bddec32012-02-04 12:27:34 -0800416 return false; // Unknown class needs access checks.
417 }
418 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
419 Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
420 if (referrer_class == NULL) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800421 stats_->TypeNeedsAccessCheck();
Ian Rogers1bddec32012-02-04 12:27:34 -0800422 return false; // Incomplete referrer knowledge needs access check.
423 }
424 // Perform access check, will return true if access is ok or false if we're going to have to
425 // check this at runtime (for example for class loaders).
Ian Rogers996cc582012-02-14 22:23:29 -0800426 bool result = referrer_class->CanAccess(resolved_class);
427 if (result) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800428 stats_->TypeDoesntNeedAccessCheck();
Ian Rogers996cc582012-02-14 22:23:29 -0800429 } else {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800430 stats_->TypeNeedsAccessCheck();
Ian Rogers996cc582012-02-14 22:23:29 -0800431 }
432 return result;
Ian Rogers1bddec32012-02-04 12:27:34 -0800433}
434
435bool Compiler::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
436 const DexCache* dex_cache,
437 const DexFile& dex_file,
Ian Rogers996cc582012-02-14 22:23:29 -0800438 uint32_t type_idx) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800439 // Get type from dex cache assuming it was populated by the verifier.
440 Class* resolved_class = dex_cache->GetResolvedType(type_idx);
441 if (resolved_class == NULL) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800442 stats_->TypeNeedsAccessCheck();
Ian Rogers1bddec32012-02-04 12:27:34 -0800443 return false; // Unknown class needs access checks.
444 }
445 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
446 Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
447 if (referrer_class == NULL) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800448 stats_->TypeNeedsAccessCheck();
Ian Rogers1bddec32012-02-04 12:27:34 -0800449 return false; // Incomplete referrer knowledge needs access check.
450 }
451 // Perform access and instantiable checks, will return true if access is ok or false if we're
452 // going to have to check this at runtime (for example for class loaders).
Ian Rogers996cc582012-02-14 22:23:29 -0800453 bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
454 if (result) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800455 stats_->TypeDoesntNeedAccessCheck();
Ian Rogers996cc582012-02-14 22:23:29 -0800456 } else {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800457 stats_->TypeNeedsAccessCheck();
Ian Rogers996cc582012-02-14 22:23:29 -0800458 }
459 return result;
Ian Rogers1bddec32012-02-04 12:27:34 -0800460}
461
Logan Chien4dd96f52012-02-29 01:26:58 +0800462static Class* ComputeReferrerClass(OatCompilationUnit* mUnit) {
463 const DexFile::MethodId& referrer_method_id =
464 mUnit->dex_file_->GetMethodId(mUnit->method_idx_);
465
466 return mUnit->class_linker_->ResolveType(
467 *mUnit->dex_file_, referrer_method_id.class_idx_,
468 mUnit->dex_cache_, mUnit->class_loader_);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800469}
470
Logan Chien4dd96f52012-02-29 01:26:58 +0800471static Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) {
472 return mUnit->class_linker_->ResolveField(
473 *mUnit->dex_file_, field_idx, mUnit->dex_cache_,
474 mUnit->class_loader_, false);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800475}
476
Logan Chien4dd96f52012-02-29 01:26:58 +0800477static Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) {
478 return mUnit->class_linker_->ResolveMethod(
479 *mUnit->dex_file_, method_idx, mUnit->dex_cache_,
480 mUnit->class_loader_, true);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800481}
482
Logan Chien4dd96f52012-02-29 01:26:58 +0800483bool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
jeffhao8cd6dda2012-02-22 10:15:34 -0800484 int& field_offset, bool& is_volatile, bool is_put) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800485 // Conservative defaults
486 field_offset = -1;
487 is_volatile = true;
488 // Try to resolve field
Logan Chien4dd96f52012-02-29 01:26:58 +0800489 Field* resolved_field = ComputeReferrerField(mUnit, field_idx);
Ian Rogers1bddec32012-02-04 12:27:34 -0800490 if (resolved_field != NULL) {
Logan Chien4dd96f52012-02-29 01:26:58 +0800491 Class* referrer_class = ComputeReferrerClass(mUnit);
Ian Rogers1bddec32012-02-04 12:27:34 -0800492 // Try to resolve referring class then access check, failure to pass the
493 Class* fields_class = resolved_field->GetDeclaringClass();
jeffhao8cd6dda2012-02-22 10:15:34 -0800494 bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() &&
495 fields_class != referrer_class;
496 if (referrer_class != NULL && referrer_class->CanAccess(fields_class) &&
497 referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) &&
498 !is_write_to_final_from_wrong_class) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800499 field_offset = resolved_field->GetOffset().Int32Value();
500 is_volatile = resolved_field->IsVolatile();
Ian Rogersc8b306f2012-02-17 21:34:44 -0800501 stats_->ResolvedInstanceField();
Ian Rogers1bddec32012-02-04 12:27:34 -0800502 return true; // Fast path.
503 }
504 }
505 // Clean up any exception left by field/type resolution
506 Thread* thread = Thread::Current();
507 if (thread->IsExceptionPending()) {
508 thread->ClearException();
509 }
Ian Rogersc8b306f2012-02-17 21:34:44 -0800510 stats_->UnresolvedInstanceField();
Ian Rogers1bddec32012-02-04 12:27:34 -0800511 return false; // Incomplete knowledge needs slow path.
512}
513
Logan Chien4dd96f52012-02-29 01:26:58 +0800514bool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
Ian Rogers1bddec32012-02-04 12:27:34 -0800515 int& field_offset, int& ssb_index,
jeffhao8cd6dda2012-02-22 10:15:34 -0800516 bool& is_referrers_class, bool& is_volatile, bool is_put) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800517 // Conservative defaults
518 field_offset = -1;
519 ssb_index = -1;
520 is_referrers_class = false;
521 is_volatile = true;
522 // Try to resolve field
Logan Chien4dd96f52012-02-29 01:26:58 +0800523 Field* resolved_field = ComputeReferrerField(mUnit, field_idx);
Ian Rogers1bddec32012-02-04 12:27:34 -0800524 if (resolved_field != NULL) {
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800525 DCHECK(resolved_field->IsStatic());
Logan Chien4dd96f52012-02-29 01:26:58 +0800526 Class* referrer_class = ComputeReferrerClass(mUnit);
Ian Rogers1bddec32012-02-04 12:27:34 -0800527 if (referrer_class != NULL) {
jeffhao8cd6dda2012-02-22 10:15:34 -0800528 Class* fields_class = resolved_field->GetDeclaringClass();
529 if (fields_class == referrer_class) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800530 is_referrers_class = true; // implies no worrying about class initialization
531 field_offset = resolved_field->GetOffset().Int32Value();
532 is_volatile = resolved_field->IsVolatile();
Ian Rogersc8b306f2012-02-17 21:34:44 -0800533 stats_->ResolvedLocalStaticField();
Ian Rogers1bddec32012-02-04 12:27:34 -0800534 return true; // fast path
535 } else {
jeffhao8cd6dda2012-02-22 10:15:34 -0800536 bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal();
Ian Rogers1bddec32012-02-04 12:27:34 -0800537 if (referrer_class->CanAccess(fields_class) &&
jeffhao8cd6dda2012-02-22 10:15:34 -0800538 referrer_class->CanAccessMember(fields_class, resolved_field->GetAccessFlags()) &&
539 !is_write_to_final_from_wrong_class) {
Ian Rogers1bddec32012-02-04 12:27:34 -0800540 // We have the resolved field, we must make it into a ssbIndex for the referrer
541 // in its static storage base (which may fail if it doesn't have a slot for it)
Ian Rogers4103ad22012-02-06 09:18:25 -0800542 // TODO: for images we can elide the static storage base null check
543 // if we know there's a non-null entry in the image
Logan Chien4dd96f52012-02-29 01:26:58 +0800544 if (fields_class->GetDexCache() == mUnit->dex_cache_) {
Ian Rogers4103ad22012-02-06 09:18:25 -0800545 // common case where the dex cache of both the referrer and the field are the same,
546 // no need to search the dex file
547 ssb_index = fields_class->GetDexTypeIndex();
548 field_offset = resolved_field->GetOffset().Int32Value();
549 is_volatile = resolved_field->IsVolatile();
Ian Rogersc8b306f2012-02-17 21:34:44 -0800550 stats_->ResolvedStaticField();
Ian Rogers4103ad22012-02-06 09:18:25 -0800551 return true;
552 }
553 // Search dex file for localized ssb index
Ian Rogers1bddec32012-02-04 12:27:34 -0800554 std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor());
555 const DexFile::StringId* string_id =
Logan Chien4dd96f52012-02-29 01:26:58 +0800556 mUnit->dex_file_->FindStringId(descriptor);
Ian Rogers1bddec32012-02-04 12:27:34 -0800557 if (string_id != NULL) {
558 const DexFile::TypeId* type_id =
Logan Chien4dd96f52012-02-29 01:26:58 +0800559 mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id));
Ian Rogers1bddec32012-02-04 12:27:34 -0800560 if(type_id != NULL) {
561 // medium path, needs check of static storage base being initialized
Logan Chien4dd96f52012-02-29 01:26:58 +0800562 ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id);
Ian Rogers1bddec32012-02-04 12:27:34 -0800563 field_offset = resolved_field->GetOffset().Int32Value();
564 is_volatile = resolved_field->IsVolatile();
Ian Rogersc8b306f2012-02-17 21:34:44 -0800565 stats_->ResolvedStaticField();
Ian Rogers1bddec32012-02-04 12:27:34 -0800566 return true;
567 }
568 }
569 }
570 }
571 }
572 }
573 // Clean up any exception left by field/type resolution
574 Thread* thread = Thread::Current();
575 if (thread->IsExceptionPending()) {
576 thread->ClearException();
577 }
Ian Rogersc8b306f2012-02-17 21:34:44 -0800578 stats_->UnresolvedStaticField();
Ian Rogers1bddec32012-02-04 12:27:34 -0800579 return false; // Incomplete knowledge needs slow path.
580}
581
Ian Rogersfb6adba2012-03-04 21:51:51 -0800582bool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType& type,
Ian Rogers996cc582012-02-14 22:23:29 -0800583 int& vtable_idx) {
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800584 vtable_idx = -1;
Logan Chien4dd96f52012-02-29 01:26:58 +0800585 Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800586 if (resolved_method != NULL) {
Logan Chien4dd96f52012-02-29 01:26:58 +0800587 Class* referrer_class = ComputeReferrerClass(mUnit);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800588 if (referrer_class != NULL) {
589 Class* methods_class = resolved_method->GetDeclaringClass();
590 if (!referrer_class->CanAccess(methods_class) ||
591 !referrer_class->CanAccessMember(methods_class,
Ian Rogers996cc582012-02-14 22:23:29 -0800592 resolved_method->GetAccessFlags())) {
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800593 // The referring class can't access the resolved method, this may occur as a result of a
594 // protected method being made public by implementing an interface that re-declares the
595 // method public. Resort to the dex file to determine the correct class for the access check
Logan Chien4dd96f52012-02-29 01:26:58 +0800596 const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache());
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800597 methods_class =
Logan Chien4dd96f52012-02-29 01:26:58 +0800598 mUnit->class_linker_->ResolveType(dex_file,
599 dex_file.GetMethodId(method_idx).class_idx_,
600 referrer_class);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800601
602 }
603 if (referrer_class->CanAccess(methods_class) &&
604 referrer_class->CanAccessMember(methods_class,
605 resolved_method->GetAccessFlags())) {
606 vtable_idx = resolved_method->GetMethodIndex();
Ian Rogersfb6adba2012-03-04 21:51:51 -0800607 if (type == kVirtual && (resolved_method->IsFinal() || methods_class->IsFinal())) {
608 stats_->ResolvedMethod(kVirtual);
609 // Sharpen a virtual call into a direct call. The method_idx is into referrer's
610 // dex cache, check that this resolved method is where we expect it.
611 CHECK(referrer_class->GetDexCache()->GetResolvedMethod(method_idx) == resolved_method)
612 << PrettyMethod(resolved_method);
613 type = kDirect;
614 stats_->VirtualMadeDirect();
615 return true;
616 } else if (type != kSuper) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800617 // nothing left to do for static/direct/virtual/interface dispatch
618 stats_->ResolvedMethod(type);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800619 return true;
620 } else {
621 // ensure the vtable index will be correct to dispatch in the vtable of the super class
Ian Rogers996cc582012-02-14 22:23:29 -0800622 if (referrer_class->IsSubClass(methods_class) &&
623 vtable_idx < methods_class->GetVTable()->GetLength()) {
Ian Rogersc8b306f2012-02-17 21:34:44 -0800624 stats_->ResolvedMethod(type);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800625 return true;
626 }
627 }
628 }
629 }
630 }
631 // Clean up any exception left by method/type resolution
632 Thread* thread = Thread::Current();
633 if (thread->IsExceptionPending()) {
634 thread->ClearException();
635 }
Ian Rogersc8b306f2012-02-17 21:34:44 -0800636 stats_->UnresolvedMethod(type);
Ian Rogersa32a6fd2012-02-06 20:18:44 -0800637 return false; // Incomplete knowledge needs slow path.
638}
639
Brian Carlstrom5ead0952011-11-28 22:55:52 -0800640// Return true if the class should be skipped during compilation. We
641// never skip classes in the boot class loader. However, if we have a
642// non-boot class loader and we can resolve the class in the boot
643// class loader, we do skip the class. This happens if an app bundles
644// classes found in the boot classpath. Since at runtime we will
645// select the class from the boot classpath, do not attempt to resolve
646// or compile it now.
647static bool SkipClass(const ClassLoader* class_loader,
648 const DexFile& dex_file,
649 const DexFile::ClassDef& class_def) {
650 if (class_loader == NULL) {
651 return false;
652 }
653 const char* descriptor = dex_file.GetClassDescriptor(class_def);
654 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
655 Class* klass = class_linker->FindClass(descriptor, NULL);
656 if (klass == NULL) {
657 Thread* self = Thread::Current();
658 CHECK(self->IsExceptionPending());
659 self->ClearException();
660 return false;
661 }
662 return true;
663}
664
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800665struct Context {
666 ClassLinker* class_linker;
667 const ClassLoader* class_loader;
Elliott Hughesc225caa2012-02-03 15:43:37 -0800668 Compiler* compiler;
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800669 DexCache* dex_cache;
670 const DexFile* dex_file;
671};
672
673typedef void Callback(Context* context, size_t index);
674
675class WorkerThread {
676 public:
Elliott Hughes1e409252012-02-06 11:21:27 -0800677 WorkerThread(Context* context, size_t begin, size_t end, Callback callback, size_t stripe, bool spawn)
678 : spawn_(spawn), context_(context), begin_(begin), end_(end), callback_(callback), stripe_(stripe) {
679 if (spawn_) {
680 CHECK_PTHREAD_CALL(pthread_create, (&pthread_, NULL, &Go, this), "compiler worker thread");
681 }
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800682 }
683
684 ~WorkerThread() {
Elliott Hughes1e409252012-02-06 11:21:27 -0800685 if (spawn_) {
686 CHECK_PTHREAD_CALL(pthread_join, (pthread_, NULL), "compiler worker shutdown");
687 }
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800688 }
689
690 private:
Elliott Hughes1e409252012-02-06 11:21:27 -0800691 static void* Go(void* arg) {
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800692 WorkerThread* worker = reinterpret_cast<WorkerThread*>(arg);
693 Runtime* runtime = Runtime::Current();
Elliott Hughes1e409252012-02-06 11:21:27 -0800694 if (worker->spawn_) {
695 runtime->AttachCurrentThread("Compiler Worker", true);
696 }
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800697 Thread::Current()->SetState(Thread::kRunnable);
698 worker->Run();
Elliott Hughes1e409252012-02-06 11:21:27 -0800699 if (worker->spawn_) {
700 Thread::Current()->SetState(Thread::kNative);
701 runtime->DetachCurrentThread();
702 }
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800703 return NULL;
704 }
705
Elliott Hughes1e409252012-02-06 11:21:27 -0800706 void Go() {
707 Go(this);
708 }
709
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800710 void Run() {
711 for (size_t i = begin_; i < end_; i += stripe_) {
712 callback_(context_, i);
713 }
714 }
715
716 pthread_t pthread_;
Elliott Hughes1e409252012-02-06 11:21:27 -0800717 bool spawn_;
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800718
719 Context* context_;
720 size_t begin_;
721 size_t end_;
722 Callback* callback_;
723 size_t stripe_;
Elliott Hughes1e409252012-02-06 11:21:27 -0800724
725 friend void ForAll(Context*, size_t, size_t, Callback, size_t);
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800726};
727
Elliott Hughes5523ee02012-02-03 18:18:34 -0800728void ForAll(Context* context, size_t begin, size_t end, Callback callback, size_t thread_count) {
Elliott Hughes1e409252012-02-06 11:21:27 -0800729 CHECK_GT(thread_count, 0U);
Elliott Hughes81d91512012-02-03 16:38:43 -0800730
Elliott Hughes1e409252012-02-06 11:21:27 -0800731 std::vector<WorkerThread*> threads;
Elliott Hughes81d91512012-02-03 16:38:43 -0800732 for (size_t i = 0; i < thread_count; ++i) {
Elliott Hughes1e409252012-02-06 11:21:27 -0800733 threads.push_back(new WorkerThread(context, begin + i, end, callback, thread_count, (i != 0)));
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800734 }
Elliott Hughes1e409252012-02-06 11:21:27 -0800735 threads[0]->Go();
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800736
Elliott Hughes81d91512012-02-03 16:38:43 -0800737 // Switch to kVmWait while we're blocked waiting for the other threads to finish.
738 ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait);
739 STLDeleteElements(&threads);
740}
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800741
742static void ResolveClassFieldsAndMethods(Context* context, size_t class_def_index) {
743 const DexFile& dex_file = *context->dex_file;
744
745 // Method and Field are the worst. We can't resolve without either
746 // context from the code use (to disambiguate virtual vs direct
747 // method and instance vs static field) or from class
748 // definitions. While the compiler will resolve what it can as it
749 // needs it, here we try to resolve fields and methods used in class
750 // definitions, since many of them many never be referenced by
751 // generated code.
752 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
753 if (SkipClass(context->class_loader, dex_file, class_def)) {
754 return;
755 }
756
757 // Note the class_data pointer advances through the headers,
758 // static fields, instance fields, direct methods, and virtual
759 // methods.
760 const byte* class_data = dex_file.GetClassData(class_def);
761 if (class_data == NULL) {
762 // empty class such as a marker interface
763 return;
764 }
Brian Carlstrom5ead0952011-11-28 22:55:52 -0800765 Thread* self = Thread::Current();
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800766 ClassLinker* class_linker = context->class_linker;
767 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
768 ClassDataItemIterator it(dex_file, class_data);
769 while (it.HasNextStaticField()) {
770 Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
771 context->class_loader, true);
772 if (field == NULL) {
773 CHECK(self->IsExceptionPending());
774 self->ClearException();
775 }
776 it.Next();
777 }
778 while (it.HasNextInstanceField()) {
779 Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
780 context->class_loader, false);
781 if (field == NULL) {
782 CHECK(self->IsExceptionPending());
783 self->ClearException();
784 }
785 it.Next();
786 }
787 while (it.HasNextDirectMethod()) {
788 Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
789 context->class_loader, true);
790 if (method == NULL) {
791 CHECK(self->IsExceptionPending());
792 self->ClearException();
793 }
794 it.Next();
795 }
796 while (it.HasNextVirtualMethod()) {
797 Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
798 context->class_loader, false);
799 if (method == NULL) {
800 CHECK(self->IsExceptionPending());
801 self->ClearException();
802 }
803 it.Next();
804 }
805 DCHECK(!it.HasNext());
806}
807
808static void ResolveType(Context* context, size_t type_idx) {
809 // Class derived values are more complicated, they require the linker and loader.
810 Thread* self = Thread::Current();
811 ClassLinker* class_linker = context->class_linker;
812 const DexFile& dex_file = *context->dex_file;
813 Class* klass = class_linker->ResolveType(dex_file, type_idx, context->dex_cache, context->class_loader);
814 if (klass == NULL) {
815 CHECK(self->IsExceptionPending());
816 Thread::Current()->ClearException();
817 }
818}
819
820void Compiler::ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file, TimingLogger& timings) {
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700821 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Brian Carlstromaded5f72011-10-07 17:15:04 -0700822 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700823
Brian Carlstromae826982011-11-09 01:33:42 -0800824 // Strings are easy in that they always are simply resolved to literals in the same file
825 if (image_ && image_classes_ == NULL) {
826 // TODO: Add support for loading strings referenced by image_classes_
827 // See also Compiler::CanAssumeTypeIsPresentInDexCache.
Brian Carlstromaded5f72011-10-07 17:15:04 -0700828 for (size_t string_idx = 0; string_idx < dex_cache->NumStrings(); string_idx++) {
829 class_linker->ResolveString(dex_file, string_idx, dex_cache);
830 }
Elliott Hughesff738062012-02-03 15:00:42 -0800831 timings.AddSplit("Resolve " + dex_file.GetLocation() + " Strings");
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700832 }
833
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800834 Context context;
835 context.class_linker = class_linker;
836 context.class_loader = class_loader;
837 context.dex_cache = dex_cache;
838 context.dex_file = &dex_file;
839
Elliott Hughes5523ee02012-02-03 18:18:34 -0800840 ForAll(&context, 0, dex_cache->NumResolvedTypes(), ResolveType, thread_count_);
Elliott Hughesff738062012-02-03 15:00:42 -0800841 timings.AddSplit("Resolve " + dex_file.GetLocation() + " Types");
Brian Carlstrom845490b2011-09-19 15:56:53 -0700842
Elliott Hughes5523ee02012-02-03 18:18:34 -0800843 ForAll(&context, 0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
Elliott Hughesff738062012-02-03 15:00:42 -0800844 timings.AddSplit("Resolve " + dex_file.GetLocation() + " MethodsAndFields");
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700845}
846
Brian Carlstromae826982011-11-09 01:33:42 -0800847void Compiler::Verify(const ClassLoader* class_loader,
848 const std::vector<const DexFile*>& dex_files) {
849 for (size_t i = 0; i != dex_files.size(); ++i) {
850 const DexFile* dex_file = dex_files[i];
jeffhao98eacac2011-09-14 16:11:53 -0700851 CHECK(dex_file != NULL);
852 VerifyDexFile(class_loader, *dex_file);
853 }
854}
855
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800856static void VerifyClass(Context* context, size_t class_def_index) {
857 const DexFile::ClassDef& class_def = context->dex_file->GetClassDef(class_def_index);
858 const char* descriptor = context->dex_file->GetClassDescriptor(class_def);
859 Class* klass = context->class_linker->FindClass(descriptor, context->class_loader);
860 if (klass == NULL) {
861 Thread* self = Thread::Current();
862 CHECK(self->IsExceptionPending());
863 self->ClearException();
864 return;
865 }
866 CHECK(klass->IsResolved()) << PrettyClass(klass);
867 context->class_linker->VerifyClass(klass);
868
869 if (klass->IsErroneous()) {
870 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
871 CHECK(Thread::Current()->IsExceptionPending());
872 Thread::Current()->ClearException();
873 // We want to try verification again at run-time, so move back into the resolved state.
874 klass->SetStatus(Class::kStatusResolved);
875 }
876
877 CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass);
878 CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
879}
880
jeffhao98eacac2011-09-14 16:11:53 -0700881void Compiler::VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
jeffhaob4df5142011-09-19 20:25:32 -0700882 dex_file.ChangePermissions(PROT_READ | PROT_WRITE);
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700883
Elliott Hughesd9c67be2012-02-02 19:54:06 -0800884 Context context;
885 context.class_linker = Runtime::Current()->GetClassLinker();
886 context.class_loader = class_loader;
887 context.dex_file = &dex_file;
Elliott Hughes5523ee02012-02-03 18:18:34 -0800888 ForAll(&context, 0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
Elliott Hughesd9cdfe92011-10-06 16:09:04 -0700889
jeffhaob4df5142011-09-19 20:25:32 -0700890 dex_file.ChangePermissions(PROT_READ);
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700891}
892
Brian Carlstromae826982011-11-09 01:33:42 -0800893void Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader,
894 const std::vector<const DexFile*>& dex_files) {
895 for (size_t i = 0; i != dex_files.size(); ++i) {
896 const DexFile* dex_file = dex_files[i];
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700897 CHECK(dex_file != NULL);
898 InitializeClassesWithoutClinit(class_loader, *dex_file);
899 }
900}
901
902void Compiler::InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file) {
903 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Brian Carlstromffca45d2011-09-16 12:10:49 -0700904 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
905 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700906 const char* descriptor = dex_file.GetClassDescriptor(class_def);
907 Class* klass = class_linker->FindClass(descriptor, class_loader);
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700908 if (klass != NULL) {
909 class_linker->EnsureInitialized(klass, false);
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800910 // record the final class status if necessary
911 Class::Status status = klass->GetStatus();
912 ClassReference ref(&dex_file, class_def_index);
Elliott Hughesc225caa2012-02-03 15:43:37 -0800913 MutexLock mu(compiled_classes_lock_);
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800914 CompiledClass* compiled_class = GetCompiledClass(ref);
915 if (compiled_class == NULL) {
916 compiled_class = new CompiledClass(status);
917 compiled_classes_[ref] = compiled_class;
918 } else {
919 DCHECK_EQ(status, compiled_class->GetStatus());
920 }
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700921 }
922 // clear any class not found or verification exceptions
923 Thread::Current()->ClearException();
Brian Carlstromffca45d2011-09-16 12:10:49 -0700924 }
925
926 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
927 for (size_t type_idx = 0; type_idx < dex_cache->NumResolvedTypes(); type_idx++) {
928 Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
Brian Carlstrom27ec9612011-09-19 20:20:38 -0700929 if (klass == NULL) {
930 Thread::Current()->ClearException();
931 } else if (klass->IsInitialized()) {
Brian Carlstromffca45d2011-09-16 12:10:49 -0700932 dex_cache->GetInitializedStaticStorage()->Set(type_idx, klass);
933 }
jeffhao98eacac2011-09-14 16:11:53 -0700934 }
935}
936
Brian Carlstromae826982011-11-09 01:33:42 -0800937void Compiler::Compile(const ClassLoader* class_loader,
938 const std::vector<const DexFile*>& dex_files) {
939 for (size_t i = 0; i != dex_files.size(); ++i) {
940 const DexFile* dex_file = dex_files[i];
Brian Carlstrom83db7722011-08-26 17:32:56 -0700941 CHECK(dex_file != NULL);
942 CompileDexFile(class_loader, *dex_file);
943 }
944}
945
Elliott Hughesc225caa2012-02-03 15:43:37 -0800946void Compiler::CompileClass(Context* context, size_t class_def_index) {
947 const ClassLoader* class_loader = context->class_loader;
948 const DexFile& dex_file = *context->dex_file;
949 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Logan Chien7f767612012-03-01 18:54:49 +0800950
951#if defined(ART_USE_LLVM_COMPILER)
952 compiler_llvm::CompilerLLVM* compiler_llvm = context->compiler->GetCompilerLLVM();
953
954 MutexLock GUARD(compiler_llvm->compiler_lock_);
955 // TODO: Remove this. We should not lock the compiler_lock_ in CompileClass()
956 // However, without this mutex lock, we will get segmentation fault.
957#endif
958
Brian Carlstrom5ead0952011-11-28 22:55:52 -0800959 if (SkipClass(class_loader, dex_file, class_def)) {
960 return;
961 }
jeffhaod1224c72012-02-29 13:43:08 -0800962 ClassReference ref(&dex_file, class_def_index);
963 // Skip compiling classes with generic verifier failures since they will still fail at runtime
964 if (verifier::DexVerifier::IsClassRejected(ref)) {
965 return;
966 }
Ian Rogers0571d352011-11-03 19:51:38 -0700967 const byte* class_data = dex_file.GetClassData(class_def);
968 if (class_data == NULL) {
969 // empty class, probably a marker interface
970 return;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700971 }
Ian Rogers0571d352011-11-03 19:51:38 -0700972 ClassDataItemIterator it(dex_file, class_data);
973 // Skip fields
974 while (it.HasNextStaticField()) {
975 it.Next();
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700976 }
Ian Rogers0571d352011-11-03 19:51:38 -0700977 while (it.HasNextInstanceField()) {
978 it.Next();
979 }
980 // Compile direct methods
981 while (it.HasNextDirectMethod()) {
Elliott Hughesc225caa2012-02-03 15:43:37 -0800982 context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
983 it.GetMemberIndex(), class_loader, dex_file);
Ian Rogers0571d352011-11-03 19:51:38 -0700984 it.Next();
985 }
986 // Compile virtual methods
987 while (it.HasNextVirtualMethod()) {
Elliott Hughesc225caa2012-02-03 15:43:37 -0800988 context->compiler->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
989 it.GetMemberIndex(), class_loader, dex_file);
Ian Rogers0571d352011-11-03 19:51:38 -0700990 it.Next();
991 }
992 DCHECK(!it.HasNext());
Logan Chien7f767612012-03-01 18:54:49 +0800993
994#if defined(ART_USE_LLVM_COMPILER)
995 compiler_llvm->MaterializeIfThresholdReached();
996#endif
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700997}
998
Elliott Hughesc225caa2012-02-03 15:43:37 -0800999void Compiler::CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
1000 Context context;
1001 context.class_loader = class_loader;
1002 context.compiler = this;
1003 context.dex_file = &dex_file;
Elliott Hughes5523ee02012-02-03 18:18:34 -08001004 ForAll(&context, 0, dex_file.NumClassDefs(), Compiler::CompileClass, thread_count_);
Elliott Hughesc225caa2012-02-03 15:43:37 -08001005}
1006
Ian Rogersa3760aa2011-11-14 14:32:37 -08001007void Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
1008 uint32_t method_idx, const ClassLoader* class_loader,
1009 const DexFile& dex_file) {
Elliott Hughesf09afe82011-10-16 14:24:21 -07001010 CompiledMethod* compiled_method = NULL;
Elliott Hughesbb551fa2012-01-25 16:35:29 -08001011 uint64_t start_ns = NanoTime();
Logan Chien4dd96f52012-02-29 01:26:58 +08001012
1013#if defined(ART_USE_LLVM_COMPILER)
1014 ClassLinker *class_linker = Runtime::Current()->GetClassLinker();
1015 DexCache *dex_cache = class_linker->FindDexCache(dex_file);
1016
Logan Chiendbe72bd2012-03-01 18:27:33 +08001017 OatCompilationUnit oat_compilation_unit(
1018 class_loader, class_linker, dex_file, *dex_cache, code_item,
1019 method_idx, access_flags);
Logan Chien4dd96f52012-02-29 01:26:58 +08001020#endif
1021
Ian Rogers169c9a72011-11-13 20:13:17 -08001022 if ((access_flags & kAccNative) != 0) {
Logan Chien88894ee2012-02-13 16:42:22 +08001023#if defined(ART_USE_LLVM_COMPILER)
Logan Chiendbe72bd2012-03-01 18:27:33 +08001024 compiled_method = compiler_llvm_->CompileNativeMethod(&oat_compilation_unit);
Logan Chien88894ee2012-02-13 16:42:22 +08001025#else
Ian Rogers169c9a72011-11-13 20:13:17 -08001026 compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file);
Logan Chien88894ee2012-02-13 16:42:22 +08001027#endif
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001028 CHECK(compiled_method != NULL);
Ian Rogers169c9a72011-11-13 20:13:17 -08001029 } else if ((access_flags & kAccAbstract) != 0) {
Brian Carlstrom2cc022b2011-08-25 10:05:39 -07001030 } else {
Shih-wei Liaod1fec812012-02-13 09:51:10 -08001031#if defined(ART_USE_LLVM_COMPILER)
Logan Chiendbe72bd2012-03-01 18:27:33 +08001032 compiled_method = compiler_llvm_->CompileDexMethod(&oat_compilation_unit);
Shih-wei Liaod1fec812012-02-13 09:51:10 -08001033#else
Ian Rogersa3760aa2011-11-14 14:32:37 -08001034 compiled_method = oatCompileMethod(*this, code_item, access_flags, method_idx, class_loader,
1035 dex_file, kThumb2);
Shih-wei Liaod1fec812012-02-13 09:51:10 -08001036#endif
Elliott Hughesbb551fa2012-01-25 16:35:29 -08001037 CHECK(compiled_method != NULL) << PrettyMethod(method_idx, dex_file);
1038 }
Ian Rogers3bb17a62012-01-27 23:56:44 -08001039 uint64_t duration_ns = NanoTime() - start_ns;
buzbee5abfa3e2012-01-31 17:01:43 -08001040 if (duration_ns > MsToNs(100)) {
Elliott Hughesbb551fa2012-01-25 16:35:29 -08001041 LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
Ian Rogers3bb17a62012-01-27 23:56:44 -08001042 << " took " << PrettyDuration(duration_ns);
Elliott Hughesf09afe82011-10-16 14:24:21 -07001043 }
1044
1045 if (compiled_method != NULL) {
Ian Rogers0571d352011-11-03 19:51:38 -07001046 MethodReference ref(&dex_file, method_idx);
Brian Carlstrom0755ec52012-01-11 15:19:46 -08001047 CHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file);
Elliott Hughesc225caa2012-02-03 15:43:37 -08001048 MutexLock mu(compiled_methods_lock_);
Ian Rogers0571d352011-11-03 19:51:38 -07001049 compiled_methods_[ref] = compiled_method;
Brian Carlstrom0755ec52012-01-11 15:19:46 -08001050 DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom2cc022b2011-08-25 10:05:39 -07001051 }
Brian Carlstrom9baa4ae2011-09-01 21:14:14 -07001052
Ian Rogers45619fc2012-02-29 11:15:25 -08001053 uint32_t shorty_len;
1054 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx), &shorty_len);
Ian Rogers169c9a72011-11-13 20:13:17 -08001055 bool is_static = (access_flags & kAccStatic) != 0;
Ian Rogers0571d352011-11-03 19:51:38 -07001056 const CompiledInvokeStub* compiled_invoke_stub = FindInvokeStub(is_static, shorty);
1057 if (compiled_invoke_stub == NULL) {
Logan Chienf04364f2012-02-10 12:01:39 +08001058#if defined(ART_USE_LLVM_COMPILER)
1059 compiled_invoke_stub = compiler_llvm_->CreateInvokeStub(is_static, shorty);
1060#else
Ian Rogers0571d352011-11-03 19:51:38 -07001061 if (instruction_set_ == kX86) {
Ian Rogers45619fc2012-02-29 11:15:25 -08001062 compiled_invoke_stub = ::art::x86::X86CreateInvokeStub(is_static, shorty, shorty_len);
Ian Rogers0571d352011-11-03 19:51:38 -07001063 } else {
1064 CHECK(instruction_set_ == kArm || instruction_set_ == kThumb2);
1065 // Generates invocation stub using ARM instruction set
Ian Rogers45619fc2012-02-29 11:15:25 -08001066 compiled_invoke_stub = ::art::arm::ArmCreateInvokeStub(is_static, shorty, shorty_len);
Ian Rogers0571d352011-11-03 19:51:38 -07001067 }
Logan Chienf04364f2012-02-10 12:01:39 +08001068#endif
1069
Ian Rogers0571d352011-11-03 19:51:38 -07001070 CHECK(compiled_invoke_stub != NULL);
1071 InsertInvokeStub(is_static, shorty, compiled_invoke_stub);
Ian Rogers2c8f6532011-09-02 17:16:34 -07001072 }
Ian Rogers0571d352011-11-03 19:51:38 -07001073 CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001074}
1075
Ian Rogers0571d352011-11-03 19:51:38 -07001076static std::string MakeInvokeStubKey(bool is_static, const char* shorty) {
1077 std::string key(shorty);
1078 if (is_static) {
Elliott Hughesbb551fa2012-01-25 16:35:29 -08001079 key += "$"; // Must not be a shorty type character.
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001080 }
Ian Rogers0571d352011-11-03 19:51:38 -07001081 return key;
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001082}
1083
Ian Rogers0571d352011-11-03 19:51:38 -07001084const CompiledInvokeStub* Compiler::FindInvokeStub(bool is_static, const char* shorty) const {
Elliott Hughesc225caa2012-02-03 15:43:37 -08001085 MutexLock mu(compiled_invoke_stubs_lock_);
Elliott Hughes95572412011-12-13 18:14:20 -08001086 const std::string key(MakeInvokeStubKey(is_static, shorty));
Ian Rogers0571d352011-11-03 19:51:38 -07001087 InvokeStubTable::const_iterator it = compiled_invoke_stubs_.find(key);
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001088 if (it == compiled_invoke_stubs_.end()) {
1089 return NULL;
Ian Rogers0571d352011-11-03 19:51:38 -07001090 } else {
1091 DCHECK(it->second != NULL);
1092 return it->second;
1093 }
1094}
1095
1096void Compiler::InsertInvokeStub(bool is_static, const char* shorty,
1097 const CompiledInvokeStub* compiled_invoke_stub) {
Elliott Hughesc225caa2012-02-03 15:43:37 -08001098 MutexLock mu(compiled_invoke_stubs_lock_);
Elliott Hughes95572412011-12-13 18:14:20 -08001099 std::string key(MakeInvokeStubKey(is_static, shorty));
Ian Rogers0571d352011-11-03 19:51:38 -07001100 compiled_invoke_stubs_[key] = compiled_invoke_stub;
1101}
1102
Brian Carlstrom0755ec52012-01-11 15:19:46 -08001103CompiledClass* Compiler::GetCompiledClass(ClassReference ref) const {
Elliott Hughesc225caa2012-02-03 15:43:37 -08001104 MutexLock mu(compiled_classes_lock_);
Brian Carlstrom0755ec52012-01-11 15:19:46 -08001105 ClassTable::const_iterator it = compiled_classes_.find(ref);
1106 if (it == compiled_classes_.end()) {
1107 return NULL;
1108 }
1109 CHECK(it->second != NULL);
1110 return it->second;
1111}
1112
Ian Rogers0571d352011-11-03 19:51:38 -07001113CompiledMethod* Compiler::GetCompiledMethod(MethodReference ref) const {
Elliott Hughesc225caa2012-02-03 15:43:37 -08001114 MutexLock mu(compiled_methods_lock_);
Ian Rogers0571d352011-11-03 19:51:38 -07001115 MethodTable::const_iterator it = compiled_methods_.find(ref);
1116 if (it == compiled_methods_.end()) {
1117 return NULL;
Brian Carlstrom3320cf42011-10-04 14:58:28 -07001118 }
1119 CHECK(it->second != NULL);
1120 return it->second;
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001121}
1122
Brian Carlstrome7d856b2012-01-11 18:10:55 -08001123void Compiler::SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files) {
1124 for (size_t i = 0; i != dex_files.size(); ++i) {
1125 const DexFile* dex_file = dex_files[i];
1126 CHECK(dex_file != NULL);
1127 SetGcMapsDexFile(class_loader, *dex_file);
1128 }
1129}
1130
1131void Compiler::SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
1132 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1133 DexCache* dex_cache = class_linker->FindDexCache(dex_file);
1134 for (size_t class_def_index = 0; class_def_index < dex_file.NumClassDefs(); class_def_index++) {
1135 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1136 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1137 Class* klass = class_linker->FindClass(descriptor, class_loader);
1138 if (klass == NULL || !klass->IsVerified()) {
1139 Thread::Current()->ClearException();
1140 continue;
1141 }
1142 const byte* class_data = dex_file.GetClassData(class_def);
1143 if (class_data == NULL) {
1144 // empty class such as a marker interface
1145 continue;
1146 }
1147 ClassDataItemIterator it(dex_file, class_data);
1148 while (it.HasNextStaticField()) {
1149 it.Next();
1150 }
1151 while (it.HasNextInstanceField()) {
1152 it.Next();
1153 }
1154 while (it.HasNextDirectMethod()) {
1155 Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
1156 class_loader, true);
1157 SetGcMapsMethod(dex_file, method);
1158 it.Next();
1159 }
1160 while (it.HasNextVirtualMethod()) {
1161 Method* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
1162 class_loader, false);
1163 SetGcMapsMethod(dex_file, method);
1164 it.Next();
1165 }
1166 }
1167}
1168
1169void Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) {
1170 if (method == NULL) {
1171 Thread::Current()->ClearException();
1172 return;
1173 }
1174 uint16_t method_idx = method->GetDexMethodIndex();
1175 MethodReference ref(&dex_file, method_idx);
1176 CompiledMethod* compiled_method = GetCompiledMethod(ref);
1177 if (compiled_method == NULL) {
1178 return;
1179 }
1180 const std::vector<uint8_t>* gc_map = verifier::DexVerifier::GetGcMap(ref);
1181 if (gc_map == NULL) {
1182 return;
1183 }
1184 compiled_method->SetGcMap(*gc_map);
1185}
1186
Logan Chien8b977d32012-02-21 19:14:55 +08001187#if defined(ART_USE_LLVM_COMPILER)
1188void Compiler::SetElfFileName(std::string const& filename) {
1189 compiler_llvm_->SetElfFileName(filename);
1190}
1191
1192void Compiler::SetBitcodeFileName(std::string const& filename) {
1193 compiler_llvm_->SetBitcodeFileName(filename);
1194}
1195#endif
1196
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001197} // namespace art