blob: d3d58c919f6dd0c9debf205cdf6b176c130fcda9 [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
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 */
16
17#include "compiler_driver.h"
18
Anwar Ghuloum67f99412013-08-12 14:19:48 -070019#define ATRACE_TAG ATRACE_TAG_DALVIK
20#include <utils/Trace.h>
Brian Carlstrom7940e442013-07-12 13:46:57 -070021
Anwar Ghuloum67f99412013-08-12 14:19:48 -070022#include <vector>
Brian Carlstrom7940e442013-07-12 13:46:57 -070023#include <unistd.h>
24
25#include "base/stl_util.h"
26#include "base/timing_logger.h"
27#include "class_linker.h"
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +000028#include "compiler_backend.h"
Vladimir Markobe0e5462014-02-26 11:24:15 +000029#include "compiler_driver-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070030#include "dex_compilation_unit.h"
31#include "dex_file-inl.h"
Vladimir Markoc7f83202014-01-24 17:55:18 +000032#include "dex/verification_results.h"
Vladimir Marko2730db02014-01-27 11:15:17 +000033#include "dex/verified_method.h"
Vladimir Marko2bc47802014-02-10 09:43:07 +000034#include "dex/quick/dex_file_method_inliner.h"
Mark Mendellae9fd932014-02-10 16:14:35 -080035#include "driver/compiler_options.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070036#include "jni_internal.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070037#include "object_utils.h"
38#include "runtime.h"
39#include "gc/accounting/card_table-inl.h"
40#include "gc/accounting/heap_bitmap.h"
41#include "gc/space/space.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070042#include "mirror/art_field-inl.h"
43#include "mirror/art_method-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070044#include "mirror/class_loader.h"
45#include "mirror/class-inl.h"
46#include "mirror/dex_cache-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070047#include "mirror/object-inl.h"
48#include "mirror/object_array-inl.h"
49#include "mirror/throwable.h"
50#include "scoped_thread_state_change.h"
51#include "ScopedLocalRef.h"
Mathieu Chartierc645f1d2014-03-06 18:11:53 -080052#include "sirt_ref-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070053#include "thread.h"
54#include "thread_pool.h"
Ian Rogers848871b2013-08-05 10:56:33 -070055#include "trampolines/trampoline_compiler.h"
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010056#include "transaction.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070057#include "verifier/method_verifier.h"
Vladimir Marko2bc47802014-02-10 09:43:07 +000058#include "verifier/method_verifier-inl.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070059
Brian Carlstrom7940e442013-07-12 13:46:57 -070060namespace art {
61
62static double Percentage(size_t x, size_t y) {
63 return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y));
64}
65
66static void DumpStat(size_t x, size_t y, const char* str) {
67 if (x == 0 && y == 0) {
68 return;
69 }
Ian Rogerse732ef12013-10-09 15:22:24 -070070 LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases";
Brian Carlstrom7940e442013-07-12 13:46:57 -070071}
72
73class AOTCompilationStats {
74 public:
75 AOTCompilationStats()
76 : stats_lock_("AOT compilation statistics lock"),
77 types_in_dex_cache_(0), types_not_in_dex_cache_(0),
78 strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
79 resolved_types_(0), unresolved_types_(0),
80 resolved_instance_fields_(0), unresolved_instance_fields_(0),
81 resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
82 type_based_devirtualization_(0),
83 safe_casts_(0), not_safe_casts_(0) {
84 for (size_t i = 0; i <= kMaxInvokeType; i++) {
85 resolved_methods_[i] = 0;
86 unresolved_methods_[i] = 0;
87 virtual_made_direct_[i] = 0;
88 direct_calls_to_boot_[i] = 0;
89 direct_methods_to_boot_[i] = 0;
90 }
91 }
92
93 void Dump() {
94 DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
95 DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
96 DumpStat(resolved_types_, unresolved_types_, "types resolved");
97 DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
98 DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
99 "static fields resolved");
100 DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_,
101 "static fields local to a class");
102 DumpStat(safe_casts_, not_safe_casts_, "check-casts removed based on type information");
103 // Note, the code below subtracts the stat value so that when added to the stat value we have
104 // 100% of samples. TODO: clean this up.
105 DumpStat(type_based_devirtualization_,
106 resolved_methods_[kVirtual] + unresolved_methods_[kVirtual] +
107 resolved_methods_[kInterface] + unresolved_methods_[kInterface] -
108 type_based_devirtualization_,
109 "virtual/interface calls made direct based on type information");
110
111 for (size_t i = 0; i <= kMaxInvokeType; i++) {
112 std::ostringstream oss;
113 oss << static_cast<InvokeType>(i) << " methods were AOT resolved";
114 DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
115 if (virtual_made_direct_[i] > 0) {
116 std::ostringstream oss2;
117 oss2 << static_cast<InvokeType>(i) << " methods made direct";
118 DumpStat(virtual_made_direct_[i],
119 resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i],
120 oss2.str().c_str());
121 }
122 if (direct_calls_to_boot_[i] > 0) {
123 std::ostringstream oss2;
124 oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot";
125 DumpStat(direct_calls_to_boot_[i],
126 resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i],
127 oss2.str().c_str());
128 }
129 if (direct_methods_to_boot_[i] > 0) {
130 std::ostringstream oss2;
131 oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot";
132 DumpStat(direct_methods_to_boot_[i],
133 resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i],
134 oss2.str().c_str());
135 }
136 }
137 }
138
139// Allow lossy statistics in non-debug builds.
140#ifndef NDEBUG
141#define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_)
142#else
143#define STATS_LOCK()
144#endif
145
146 void TypeInDexCache() {
147 STATS_LOCK();
148 types_in_dex_cache_++;
149 }
150
151 void TypeNotInDexCache() {
152 STATS_LOCK();
153 types_not_in_dex_cache_++;
154 }
155
156 void StringInDexCache() {
157 STATS_LOCK();
158 strings_in_dex_cache_++;
159 }
160
161 void StringNotInDexCache() {
162 STATS_LOCK();
163 strings_not_in_dex_cache_++;
164 }
165
166 void TypeDoesntNeedAccessCheck() {
167 STATS_LOCK();
168 resolved_types_++;
169 }
170
171 void TypeNeedsAccessCheck() {
172 STATS_LOCK();
173 unresolved_types_++;
174 }
175
176 void ResolvedInstanceField() {
177 STATS_LOCK();
178 resolved_instance_fields_++;
179 }
180
181 void UnresolvedInstanceField() {
182 STATS_LOCK();
183 unresolved_instance_fields_++;
184 }
185
186 void ResolvedLocalStaticField() {
187 STATS_LOCK();
188 resolved_local_static_fields_++;
189 }
190
191 void ResolvedStaticField() {
192 STATS_LOCK();
193 resolved_static_fields_++;
194 }
195
196 void UnresolvedStaticField() {
197 STATS_LOCK();
198 unresolved_static_fields_++;
199 }
200
201 // Indicate that type information from the verifier led to devirtualization.
202 void PreciseTypeDevirtualization() {
203 STATS_LOCK();
204 type_based_devirtualization_++;
205 }
206
207 // Indicate that a method of the given type was resolved at compile time.
208 void ResolvedMethod(InvokeType type) {
209 DCHECK_LE(type, kMaxInvokeType);
210 STATS_LOCK();
211 resolved_methods_[type]++;
212 }
213
214 // Indicate that a method of the given type was unresolved at compile time as it was in an
215 // unknown dex file.
216 void UnresolvedMethod(InvokeType type) {
217 DCHECK_LE(type, kMaxInvokeType);
218 STATS_LOCK();
219 unresolved_methods_[type]++;
220 }
221
222 // Indicate that a type of virtual method dispatch has been converted into a direct method
223 // dispatch.
224 void VirtualMadeDirect(InvokeType type) {
225 DCHECK(type == kVirtual || type == kInterface || type == kSuper);
226 STATS_LOCK();
227 virtual_made_direct_[type]++;
228 }
229
230 // Indicate that a method of the given type was able to call directly into boot.
231 void DirectCallsToBoot(InvokeType type) {
232 DCHECK_LE(type, kMaxInvokeType);
233 STATS_LOCK();
234 direct_calls_to_boot_[type]++;
235 }
236
237 // Indicate that a method of the given type was able to be resolved directly from boot.
238 void DirectMethodsToBoot(InvokeType type) {
239 DCHECK_LE(type, kMaxInvokeType);
240 STATS_LOCK();
241 direct_methods_to_boot_[type]++;
242 }
243
244 // A check-cast could be eliminated due to verifier type analysis.
245 void SafeCast() {
246 STATS_LOCK();
247 safe_casts_++;
248 }
249
250 // A check-cast couldn't be eliminated due to verifier type analysis.
251 void NotASafeCast() {
252 STATS_LOCK();
253 not_safe_casts_++;
254 }
255
256 private:
257 Mutex stats_lock_;
258
259 size_t types_in_dex_cache_;
260 size_t types_not_in_dex_cache_;
261
262 size_t strings_in_dex_cache_;
263 size_t strings_not_in_dex_cache_;
264
265 size_t resolved_types_;
266 size_t unresolved_types_;
267
268 size_t resolved_instance_fields_;
269 size_t unresolved_instance_fields_;
270
271 size_t resolved_local_static_fields_;
272 size_t resolved_static_fields_;
273 size_t unresolved_static_fields_;
274 // Type based devirtualization for invoke interface and virtual.
275 size_t type_based_devirtualization_;
276
277 size_t resolved_methods_[kMaxInvokeType + 1];
278 size_t unresolved_methods_[kMaxInvokeType + 1];
279 size_t virtual_made_direct_[kMaxInvokeType + 1];
280 size_t direct_calls_to_boot_[kMaxInvokeType + 1];
281 size_t direct_methods_to_boot_[kMaxInvokeType + 1];
282
283 size_t safe_casts_;
284 size_t not_safe_casts_;
285
286 DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
287};
288
Brian Carlstrom7940e442013-07-12 13:46:57 -0700289
290extern "C" art::CompiledMethod* ArtCompileDEX(art::CompilerDriver& compiler,
291 const art::DexFile::CodeItem* code_item,
292 uint32_t access_flags,
293 art::InvokeType invoke_type,
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700294 uint16_t class_def_idx,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700295 uint32_t method_idx,
296 jobject class_loader,
297 const art::DexFile& dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700298
Brian Carlstrom6449c622014-02-10 23:48:36 -0800299CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options,
300 VerificationResults* verification_results,
Vladimir Marko5816ed42013-11-27 17:04:20 +0000301 DexFileToMethodInlinerMap* method_inliner_map,
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000302 CompilerBackend::Kind compiler_backend_kind,
303 InstructionSet instruction_set,
Dave Allison70202782013-10-22 17:52:19 -0700304 InstructionSetFeatures instruction_set_features,
buzbeea024a062013-07-31 10:47:37 -0700305 bool image, DescriptorSet* image_classes, size_t thread_count,
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000306 bool dump_stats, bool dump_passes, CumulativeLogger* timer)
Brian Carlstrom6449c622014-02-10 23:48:36 -0800307 : compiler_options_(compiler_options),
308 verification_results_(verification_results),
Vladimir Marko5816ed42013-11-27 17:04:20 +0000309 method_inliner_map_(method_inliner_map),
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000310 compiler_backend_(CompilerBackend::Create(compiler_backend_kind)),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700311 instruction_set_(instruction_set),
Dave Allison70202782013-10-22 17:52:19 -0700312 instruction_set_features_(instruction_set_features),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700313 freezing_constructor_lock_("freezing constructor lock"),
314 compiled_classes_lock_("compiled classes lock"),
315 compiled_methods_lock_("compiled method lock"),
316 image_(image),
317 image_classes_(image_classes),
318 thread_count_(thread_count),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700319 start_ns_(0),
320 stats_(new AOTCompilationStats),
321 dump_stats_(dump_stats),
Nicolas Geoffrayea3fa0b2014-02-10 11:59:41 +0000322 dump_passes_(dump_passes),
323 timings_logger_(timer),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700324 compiler_library_(NULL),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700325 compiler_context_(NULL),
Brian Carlstrom7940e442013-07-12 13:46:57 -0700326 compiler_enable_auto_elf_loading_(NULL),
327 compiler_get_method_code_addr_(NULL),
Mark Mendell55d0eac2014-02-06 11:02:52 -0800328 support_boot_image_fixup_(instruction_set != kMips),
Mark Mendellae9fd932014-02-10 16:14:35 -0800329 cfi_info_(nullptr),
Ian Rogersd133b972013-09-05 11:01:30 -0700330 dedupe_code_("dedupe code"),
331 dedupe_mapping_table_("dedupe mapping table"),
332 dedupe_vmap_table_("dedupe vmap table"),
Mark Mendellae9fd932014-02-10 16:14:35 -0800333 dedupe_gc_map_("dedupe gc map"),
334 dedupe_cfi_info_("dedupe cfi info") {
Brian Carlstrom6449c622014-02-10 23:48:36 -0800335 DCHECK(compiler_options_ != nullptr);
336 DCHECK(verification_results_ != nullptr);
337 DCHECK(method_inliner_map_ != nullptr);
Brian Carlstrom2ce745c2013-07-17 17:44:30 -0700338
Brian Carlstrom7940e442013-07-12 13:46:57 -0700339 CHECK_PTHREAD_CALL(pthread_key_create, (&tls_key_, NULL), "compiler tls key");
340
Sebastien Hertz75021222013-07-16 18:34:50 +0200341 dex_to_dex_compiler_ = reinterpret_cast<DexToDexCompilerFn>(ArtCompileDEX);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700342
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000343 compiler_backend_->Init(*this);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700344
345 CHECK(!Runtime::Current()->IsStarted());
346 if (!image_) {
347 CHECK(image_classes_.get() == NULL);
348 }
Mark Mendellae9fd932014-02-10 16:14:35 -0800349
350 // Are we generating CFI information?
351 if (compiler_options->GetGenerateGDBInformation()) {
352 cfi_info_.reset(compiler_backend_->GetCallFrameInformationInitialization(*this));
353 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700354}
355
Mathieu Chartier193bad92013-08-29 18:46:00 -0700356std::vector<uint8_t>* CompilerDriver::DeduplicateCode(const std::vector<uint8_t>& code) {
357 return dedupe_code_.Add(Thread::Current(), code);
358}
359
360std::vector<uint8_t>* CompilerDriver::DeduplicateMappingTable(const std::vector<uint8_t>& code) {
361 return dedupe_mapping_table_.Add(Thread::Current(), code);
362}
363
364std::vector<uint8_t>* CompilerDriver::DeduplicateVMapTable(const std::vector<uint8_t>& code) {
365 return dedupe_vmap_table_.Add(Thread::Current(), code);
366}
367
368std::vector<uint8_t>* CompilerDriver::DeduplicateGCMap(const std::vector<uint8_t>& code) {
369 return dedupe_gc_map_.Add(Thread::Current(), code);
370}
371
Mark Mendellae9fd932014-02-10 16:14:35 -0800372std::vector<uint8_t>* CompilerDriver::DeduplicateCFIInfo(const std::vector<uint8_t>* cfi_info) {
373 if (cfi_info == nullptr) {
374 return nullptr;
375 }
376 return dedupe_cfi_info_.Add(Thread::Current(), *cfi_info);
377}
378
Brian Carlstrom7940e442013-07-12 13:46:57 -0700379CompilerDriver::~CompilerDriver() {
380 Thread* self = Thread::Current();
381 {
382 MutexLock mu(self, compiled_classes_lock_);
383 STLDeleteValues(&compiled_classes_);
384 }
385 {
386 MutexLock mu(self, compiled_methods_lock_);
387 STLDeleteValues(&compiled_methods_);
388 }
389 {
390 MutexLock mu(self, compiled_methods_lock_);
391 STLDeleteElements(&code_to_patch_);
392 }
393 {
394 MutexLock mu(self, compiled_methods_lock_);
395 STLDeleteElements(&methods_to_patch_);
396 }
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -0800397 {
398 MutexLock mu(self, compiled_methods_lock_);
399 STLDeleteElements(&classes_to_patch_);
400 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700401 CHECK_PTHREAD_CALL(pthread_key_delete, (tls_key_), "delete tls key");
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +0000402 compiler_backend_->UnInit(*this);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700403}
404
405CompilerTls* CompilerDriver::GetTls() {
406 // Lazily create thread-local storage
407 CompilerTls* res = static_cast<CompilerTls*>(pthread_getspecific(tls_key_));
408 if (res == NULL) {
409 res = new CompilerTls();
410 CHECK_PTHREAD_CALL(pthread_setspecific, (tls_key_, res), "compiler tls");
411 }
412 return res;
413}
414
Ian Rogers848871b2013-08-05 10:56:33 -0700415const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToInterpreterBridge() const {
416 return CreateTrampoline(instruction_set_, kInterpreterAbi,
417 INTERPRETER_ENTRYPOINT_OFFSET(pInterpreterToInterpreterBridge));
418}
419
420const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToCompiledCodeBridge() const {
421 return CreateTrampoline(instruction_set_, kInterpreterAbi,
422 INTERPRETER_ENTRYPOINT_OFFSET(pInterpreterToCompiledCodeBridge));
423}
424
425const std::vector<uint8_t>* CompilerDriver::CreateJniDlsymLookup() const {
426 return CreateTrampoline(instruction_set_, kJniAbi, JNI_ENTRYPOINT_OFFSET(pDlsymLookup));
427}
428
Jeff Hao88474b42013-10-23 16:24:40 -0700429const std::vector<uint8_t>* CompilerDriver::CreatePortableImtConflictTrampoline() const {
430 return CreateTrampoline(instruction_set_, kPortableAbi,
431 PORTABLE_ENTRYPOINT_OFFSET(pPortableImtConflictTrampoline));
432}
433
Brian Carlstrom7940e442013-07-12 13:46:57 -0700434const std::vector<uint8_t>* CompilerDriver::CreatePortableResolutionTrampoline() const {
Ian Rogers848871b2013-08-05 10:56:33 -0700435 return CreateTrampoline(instruction_set_, kPortableAbi,
436 PORTABLE_ENTRYPOINT_OFFSET(pPortableResolutionTrampoline));
437}
438
439const std::vector<uint8_t>* CompilerDriver::CreatePortableToInterpreterBridge() const {
440 return CreateTrampoline(instruction_set_, kPortableAbi,
441 PORTABLE_ENTRYPOINT_OFFSET(pPortableToInterpreterBridge));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700442}
443
Andreas Gampe2da88232014-02-27 12:26:20 -0800444const std::vector<uint8_t>* CompilerDriver::CreateQuickGenericJniTrampoline() const {
445 return CreateTrampoline(instruction_set_, kQuickAbi,
446 QUICK_ENTRYPOINT_OFFSET(pQuickGenericJniTrampoline));
447}
448
Jeff Hao88474b42013-10-23 16:24:40 -0700449const std::vector<uint8_t>* CompilerDriver::CreateQuickImtConflictTrampoline() const {
450 return CreateTrampoline(instruction_set_, kQuickAbi,
451 QUICK_ENTRYPOINT_OFFSET(pQuickImtConflictTrampoline));
452}
453
Brian Carlstrom7940e442013-07-12 13:46:57 -0700454const std::vector<uint8_t>* CompilerDriver::CreateQuickResolutionTrampoline() const {
Ian Rogers848871b2013-08-05 10:56:33 -0700455 return CreateTrampoline(instruction_set_, kQuickAbi,
456 QUICK_ENTRYPOINT_OFFSET(pQuickResolutionTrampoline));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700457}
458
Ian Rogers848871b2013-08-05 10:56:33 -0700459const std::vector<uint8_t>* CompilerDriver::CreateQuickToInterpreterBridge() const {
460 return CreateTrampoline(instruction_set_, kQuickAbi,
461 QUICK_ENTRYPOINT_OFFSET(pQuickToInterpreterBridge));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700462}
463
464void CompilerDriver::CompileAll(jobject class_loader,
Brian Carlstrom45602482013-07-21 22:07:55 -0700465 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -0800466 TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700467 DCHECK(!Runtime::Current()->IsStarted());
Mathieu Chartierbcd5e9d2013-11-13 14:33:28 -0800468 UniquePtr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", thread_count_ - 1));
Ian Rogers3d504072014-03-01 09:16:49 -0800469 PreCompile(class_loader, dex_files, thread_pool.get(), timings);
470 Compile(class_loader, dex_files, thread_pool.get(), timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700471 if (dump_stats_) {
472 stats_->Dump();
473 }
474}
475
Mathieu Chartier590fee92013-09-13 13:46:47 -0700476static DexToDexCompilationLevel GetDexToDexCompilationlevel(
Ian Rogers98379392014-02-24 16:53:16 -0800477 Thread* self, SirtRef<mirror::ClassLoader>& class_loader, const DexFile& dex_file,
Mathieu Chartier590fee92013-09-13 13:46:47 -0700478 const DexFile::ClassDef& class_def) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700479 const char* descriptor = dex_file.GetClassDescriptor(class_def);
480 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogers98379392014-02-24 16:53:16 -0800481 mirror::Class* klass = class_linker->FindClass(self, descriptor, class_loader);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700482 if (klass == NULL) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700483 CHECK(self->IsExceptionPending());
484 self->ClearException();
Sebastien Hertz75021222013-07-16 18:34:50 +0200485 return kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700486 }
Sebastien Hertz75021222013-07-16 18:34:50 +0200487 // The verifier can only run on "quick" instructions at runtime (see usage of
488 // FindAccessedFieldAtDexPc and FindInvokedMethodAtDexPc in ThrowNullPointerExceptionFromDexPC
489 // function). Since image classes can be verified again while compiling an application,
490 // we must prevent the DEX-to-DEX compiler from introducing them.
491 // TODO: find a way to enable "quick" instructions for image classes and remove this check.
Mathieu Chartier590fee92013-09-13 13:46:47 -0700492 bool compiling_image_classes = class_loader.get() == nullptr;
Sebastien Hertz75021222013-07-16 18:34:50 +0200493 if (compiling_image_classes) {
494 return kRequired;
495 } else if (klass->IsVerified()) {
496 // Class is verified so we can enable DEX-to-DEX compilation for performance.
497 return kOptimize;
498 } else if (klass->IsCompileTimeVerified()) {
499 // Class verification has soft-failed. Anyway, ensure at least correctness.
500 DCHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime);
501 return kRequired;
502 } else {
503 // Class verification has failed: do not run DEX-to-DEX compilation.
504 return kDontDexToDexCompile;
505 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700506}
507
Ian Rogers3d504072014-03-01 09:16:49 -0800508void CompilerDriver::CompileOne(mirror::ArtMethod* method, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700509 DCHECK(!Runtime::Current()->IsStarted());
510 Thread* self = Thread::Current();
511 jobject jclass_loader;
512 const DexFile* dex_file;
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700513 uint16_t class_def_idx;
Ian Rogersef7d42f2014-01-06 12:55:46 -0800514 uint32_t method_idx = method->GetDexMethodIndex();
515 uint32_t access_flags = method->GetAccessFlags();
516 InvokeType invoke_type = method->GetInvokeType();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700517 {
518 ScopedObjectAccessUnchecked soa(self);
519 ScopedLocalRef<jobject>
520 local_class_loader(soa.Env(),
521 soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
522 jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
523 // Find the dex_file
524 MethodHelper mh(method);
525 dex_file = &mh.GetDexFile();
526 class_def_idx = mh.GetClassDefIndex();
527 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800528 const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
Brian Carlstrom7940e442013-07-12 13:46:57 -0700529 self->TransitionFromRunnableToSuspended(kNative);
530
531 std::vector<const DexFile*> dex_files;
532 dex_files.push_back(dex_file);
533
Mathieu Chartierbcd5e9d2013-11-13 14:33:28 -0800534 UniquePtr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", 0U));
Ian Rogers3d504072014-03-01 09:16:49 -0800535 PreCompile(jclass_loader, dex_files, thread_pool.get(), timings);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700536
Brian Carlstrom7940e442013-07-12 13:46:57 -0700537 // Can we run DEX-to-DEX compiler on this class ?
Sebastien Hertz75021222013-07-16 18:34:50 +0200538 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700539 {
540 ScopedObjectAccess soa(Thread::Current());
541 const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700542 SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
543 soa.Decode<mirror::ClassLoader*>(jclass_loader));
Ian Rogers98379392014-02-24 16:53:16 -0800544 dex_to_dex_compilation_level = GetDexToDexCompilationlevel(self, class_loader, *dex_file,
545 class_def);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700546 }
Ian Rogersef7d42f2014-01-06 12:55:46 -0800547 CompileMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx, jclass_loader,
548 *dex_file, dex_to_dex_compilation_level);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700549
550 self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
551
552 self->TransitionFromSuspendedToRunnable();
553}
554
555void CompilerDriver::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -0800556 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700557 for (size_t i = 0; i != dex_files.size(); ++i) {
558 const DexFile* dex_file = dex_files[i];
559 CHECK(dex_file != NULL);
560 ResolveDexFile(class_loader, *dex_file, thread_pool, timings);
561 }
562}
563
564void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -0800565 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700566 LoadImageClasses(timings);
567
568 Resolve(class_loader, dex_files, thread_pool, timings);
569
570 Verify(class_loader, dex_files, thread_pool, timings);
571
572 InitializeClasses(class_loader, dex_files, thread_pool, timings);
573
574 UpdateImageClasses(timings);
575}
576
Ian Rogersdfb325e2013-10-30 01:00:44 -0700577bool CompilerDriver::IsImageClass(const char* descriptor) const {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700578 if (!IsImage()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700579 return true;
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700580 } else {
Ian Rogersdfb325e2013-10-30 01:00:44 -0700581 return image_classes_->find(descriptor) != image_classes_->end();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700582 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700583}
584
585static void ResolveExceptionsForMethod(MethodHelper* mh,
586 std::set<std::pair<uint16_t, const DexFile*> >& exceptions_to_resolve)
587 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
588 const DexFile::CodeItem* code_item = mh->GetCodeItem();
589 if (code_item == NULL) {
590 return; // native or abstract method
591 }
592 if (code_item->tries_size_ == 0) {
593 return; // nothing to process
594 }
595 const byte* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0);
596 size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list);
597 for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
598 int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list);
599 bool has_catch_all = false;
600 if (encoded_catch_handler_size <= 0) {
601 encoded_catch_handler_size = -encoded_catch_handler_size;
602 has_catch_all = true;
603 }
604 for (int32_t j = 0; j < encoded_catch_handler_size; j++) {
605 uint16_t encoded_catch_handler_handlers_type_idx =
606 DecodeUnsignedLeb128(&encoded_catch_handler_list);
607 // Add to set of types to resolve if not already in the dex cache resolved types
608 if (!mh->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
609 exceptions_to_resolve.insert(
610 std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx,
611 &mh->GetDexFile()));
612 }
613 // ignore address associated with catch handler
614 DecodeUnsignedLeb128(&encoded_catch_handler_list);
615 }
616 if (has_catch_all) {
617 // ignore catch all address
618 DecodeUnsignedLeb128(&encoded_catch_handler_list);
619 }
620 }
621}
622
623static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
624 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
625 std::set<std::pair<uint16_t, const DexFile*> >* exceptions_to_resolve =
626 reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*> >*>(arg);
627 MethodHelper mh;
628 for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700629 mirror::ArtMethod* m = c->GetVirtualMethod(i);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700630 mh.ChangeMethod(m);
631 ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
632 }
633 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700634 mirror::ArtMethod* m = c->GetDirectMethod(i);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700635 mh.ChangeMethod(m);
636 ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
637 }
638 return true;
639}
640
641static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
642 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
643 CompilerDriver::DescriptorSet* image_classes =
644 reinterpret_cast<CompilerDriver::DescriptorSet*>(arg);
645 image_classes->insert(ClassHelper(klass).GetDescriptor());
646 return true;
647}
648
649// Make a list of descriptors for classes to include in the image
Ian Rogers3d504072014-03-01 09:16:49 -0800650void CompilerDriver::LoadImageClasses(TimingLogger* timings)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700651 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700652 if (!IsImage()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700653 return;
654 }
655
Ian Rogers3d504072014-03-01 09:16:49 -0800656 timings->NewSplit("LoadImageClasses");
Brian Carlstrom7940e442013-07-12 13:46:57 -0700657 // Make a first class to load all classes explicitly listed in the file
658 Thread* self = Thread::Current();
659 ScopedObjectAccess soa(self);
660 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Mathieu Chartier02e25112013-08-14 16:14:24 -0700661 for (auto it = image_classes_->begin(), end = image_classes_->end(); it != end;) {
Vladimir Markoe9c36b32013-11-21 15:49:16 +0000662 const std::string& descriptor(*it);
Ian Rogers98379392014-02-24 16:53:16 -0800663 SirtRef<mirror::Class> klass(self, class_linker->FindSystemClass(self, descriptor.c_str()));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700664 if (klass.get() == NULL) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700665 VLOG(compiler) << "Failed to find class " << descriptor;
Vladimir Markoe9c36b32013-11-21 15:49:16 +0000666 image_classes_->erase(it++);
Ian Rogersa436fde2013-08-27 23:34:06 -0700667 self->ClearException();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700668 } else {
669 ++it;
670 }
671 }
672
673 // Resolve exception classes referenced by the loaded classes. The catch logic assumes
674 // exceptions are resolved by the verifier when there is a catch block in an interested method.
675 // Do this here so that exception classes appear to have been specified image classes.
676 std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types;
677 SirtRef<mirror::Class> java_lang_Throwable(self,
Ian Rogers98379392014-02-24 16:53:16 -0800678 class_linker->FindSystemClass(self, "Ljava/lang/Throwable;"));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700679 do {
680 unresolved_exception_types.clear();
681 class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor,
682 &unresolved_exception_types);
Mathieu Chartier02e25112013-08-14 16:14:24 -0700683 for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) {
684 uint16_t exception_type_idx = exception_type.first;
685 const DexFile* dex_file = exception_type.second;
Mathieu Chartier590fee92013-09-13 13:46:47 -0700686 SirtRef<mirror::DexCache> dex_cache(self, class_linker->FindDexCache(*dex_file));
687 SirtRef<mirror::ClassLoader> class_loader(self, nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700688 SirtRef<mirror::Class> klass(self, class_linker->ResolveType(*dex_file, exception_type_idx,
689 dex_cache, class_loader));
690 if (klass.get() == NULL) {
691 const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
692 const char* descriptor = dex_file->GetTypeDescriptor(type_id);
693 LOG(FATAL) << "Failed to resolve class " << descriptor;
694 }
695 DCHECK(java_lang_Throwable->IsAssignableFrom(klass.get()));
696 }
697 // Resolving exceptions may load classes that reference more exceptions, iterate until no
698 // more are found
699 } while (!unresolved_exception_types.empty());
700
701 // We walk the roots looking for classes so that we'll pick up the
702 // above classes plus any classes them depend on such super
703 // classes, interfaces, and the required ClassLinker roots.
704 class_linker->VisitClasses(RecordImageClassesVisitor, image_classes_.get());
705
706 CHECK_NE(image_classes_->size(), 0U);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700707}
708
709static void MaybeAddToImageClasses(mirror::Class* klass, CompilerDriver::DescriptorSet* image_classes)
710 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
711 while (!klass->IsObjectClass()) {
712 ClassHelper kh(klass);
713 const char* descriptor = kh.GetDescriptor();
714 std::pair<CompilerDriver::DescriptorSet::iterator, bool> result =
715 image_classes->insert(descriptor);
716 if (result.second) {
Anwar Ghuloum75a43f12013-08-13 17:22:14 -0700717 VLOG(compiler) << "Adding " << descriptor << " to image classes";
Brian Carlstrom7940e442013-07-12 13:46:57 -0700718 } else {
719 return;
720 }
721 for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
722 MaybeAddToImageClasses(kh.GetDirectInterface(i), image_classes);
723 }
724 if (klass->IsArrayClass()) {
725 MaybeAddToImageClasses(klass->GetComponentType(), image_classes);
726 }
727 klass = klass->GetSuperClass();
728 }
729}
730
731void CompilerDriver::FindClinitImageClassesCallback(mirror::Object* object, void* arg) {
732 DCHECK(object != NULL);
733 DCHECK(arg != NULL);
734 CompilerDriver* compiler_driver = reinterpret_cast<CompilerDriver*>(arg);
735 MaybeAddToImageClasses(object->GetClass(), compiler_driver->image_classes_.get());
736}
737
Ian Rogers3d504072014-03-01 09:16:49 -0800738void CompilerDriver::UpdateImageClasses(TimingLogger* timings) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700739 if (IsImage()) {
Ian Rogers3d504072014-03-01 09:16:49 -0800740 timings->NewSplit("UpdateImageClasses");
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700741
742 // Update image_classes_ with classes for objects created by <clinit> methods.
743 Thread* self = Thread::Current();
744 const char* old_cause = self->StartAssertNoThreadSuspension("ImageWriter");
745 gc::Heap* heap = Runtime::Current()->GetHeap();
746 // TODO: Image spaces only?
Mathieu Chartier590fee92013-09-13 13:46:47 -0700747 ScopedObjectAccess soa(Thread::Current());
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700748 WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
Mathieu Chartier590fee92013-09-13 13:46:47 -0700749 heap->VisitObjects(FindClinitImageClassesCallback, this);
Ian Rogerse6bb3b22013-08-19 21:51:45 -0700750 self->EndAssertNoThreadSuspension(old_cause);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700751 }
Brian Carlstrom7940e442013-07-12 13:46:57 -0700752}
753
Mathieu Chartier590fee92013-09-13 13:46:47 -0700754bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx) {
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700755 if (IsImage() &&
Ian Rogersdfb325e2013-10-30 01:00:44 -0700756 IsImageClass(dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_))) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700757 if (kIsDebugBuild) {
758 ScopedObjectAccess soa(Thread::Current());
759 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
760 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
761 CHECK(resolved_class != NULL);
762 }
763 stats_->TypeInDexCache();
764 return true;
765 } else {
766 stats_->TypeNotInDexCache();
767 return false;
768 }
769}
770
771bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
772 uint32_t string_idx) {
773 // See also Compiler::ResolveDexFile
774
775 bool result = false;
776 if (IsImage()) {
777 // We resolve all const-string strings when building for the image.
778 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartier590fee92013-09-13 13:46:47 -0700779 SirtRef<mirror::DexCache> dex_cache(soa.Self(), Runtime::Current()->GetClassLinker()->FindDexCache(dex_file));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700780 Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache);
781 result = true;
782 }
783 if (result) {
784 stats_->StringInDexCache();
785 } else {
786 stats_->StringNotInDexCache();
787 }
788 return result;
789}
790
791bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
792 uint32_t type_idx,
793 bool* type_known_final, bool* type_known_abstract,
794 bool* equals_referrers_class) {
795 if (type_known_final != NULL) {
796 *type_known_final = false;
797 }
798 if (type_known_abstract != NULL) {
799 *type_known_abstract = false;
800 }
801 if (equals_referrers_class != NULL) {
802 *equals_referrers_class = false;
803 }
804 ScopedObjectAccess soa(Thread::Current());
805 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
806 // Get type from dex cache assuming it was populated by the verifier
807 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
808 if (resolved_class == NULL) {
809 stats_->TypeNeedsAccessCheck();
810 return false; // Unknown class needs access checks.
811 }
812 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
813 if (equals_referrers_class != NULL) {
814 *equals_referrers_class = (method_id.class_idx_ == type_idx);
815 }
816 mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
817 if (referrer_class == NULL) {
818 stats_->TypeNeedsAccessCheck();
819 return false; // Incomplete referrer knowledge needs access check.
820 }
821 // Perform access check, will return true if access is ok or false if we're going to have to
822 // check this at runtime (for example for class loaders).
823 bool result = referrer_class->CanAccess(resolved_class);
824 if (result) {
825 stats_->TypeDoesntNeedAccessCheck();
826 if (type_known_final != NULL) {
827 *type_known_final = resolved_class->IsFinal() && !resolved_class->IsArrayClass();
828 }
829 if (type_known_abstract != NULL) {
830 *type_known_abstract = resolved_class->IsAbstract() && !resolved_class->IsArrayClass();
831 }
832 } else {
833 stats_->TypeNeedsAccessCheck();
834 }
835 return result;
836}
837
838bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
839 const DexFile& dex_file,
840 uint32_t type_idx) {
841 ScopedObjectAccess soa(Thread::Current());
842 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
843 // Get type from dex cache assuming it was populated by the verifier.
844 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
845 if (resolved_class == NULL) {
846 stats_->TypeNeedsAccessCheck();
847 return false; // Unknown class needs access checks.
848 }
849 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
850 mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
851 if (referrer_class == NULL) {
852 stats_->TypeNeedsAccessCheck();
853 return false; // Incomplete referrer knowledge needs access check.
854 }
855 // Perform access and instantiable checks, will return true if access is ok or false if we're
856 // going to have to check this at runtime (for example for class loaders).
857 bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
858 if (result) {
859 stats_->TypeDoesntNeedAccessCheck();
860 } else {
861 stats_->TypeNeedsAccessCheck();
862 }
863 return result;
864}
865
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -0800866bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
867 bool* is_type_initialized, bool* use_direct_type_ptr,
868 uintptr_t* direct_type_ptr) {
869 ScopedObjectAccess soa(Thread::Current());
870 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
871 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
872 if (resolved_class == nullptr) {
873 return false;
874 }
875 const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot();
876 if (compiling_boot) {
877 // boot -> boot class pointers.
878 // True if the class is in the image at boot compiling time.
879 const bool is_image_class = IsImage() && IsImageClass(
880 dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_));
881 // True if pc relative load works.
882 const bool support_boot_image_fixup = GetSupportBootImageFixup();
883 if (is_image_class && support_boot_image_fixup) {
884 *is_type_initialized = resolved_class->IsInitialized();
885 *use_direct_type_ptr = false;
886 *direct_type_ptr = 0;
887 return true;
888 } else {
889 return false;
890 }
891 } else {
892 // True if the class is in the image at app compiling time.
893 const bool class_in_image =
894 Runtime::Current()->GetHeap()->FindSpaceFromObject(resolved_class, false)->IsImageSpace();
895 if (class_in_image) {
896 // boot -> app class pointers.
897 *is_type_initialized = resolved_class->IsInitialized();
898 *use_direct_type_ptr = true;
899 *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
900 return true;
901 } else {
902 // app -> app class pointers.
903 // Give up because app does not have an image and class
904 // isn't created at compile time. TODO: implement this
905 // if/when each app gets an image.
906 return false;
907 }
908 }
909}
910
Vladimir Markobe0e5462014-02-26 11:24:15 +0000911void CompilerDriver::ProcessedInstanceField(bool resolved) {
912 if (!resolved) {
913 stats_->UnresolvedInstanceField();
914 } else {
915 stats_->ResolvedInstanceField();
916 }
917}
918
919void CompilerDriver::ProcessedStaticField(bool resolved, bool local) {
920 if (!resolved) {
921 stats_->UnresolvedStaticField();
922 } else if (local) {
923 stats_->ResolvedLocalStaticField();
924 } else {
925 stats_->ResolvedStaticField();
926 }
927}
928
Brian Carlstrom7940e442013-07-12 13:46:57 -0700929static mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
Mathieu Chartier590fee92013-09-13 13:46:47 -0700930 SirtRef<mirror::DexCache>& dex_cache,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700931 const DexCompilationUnit* mUnit)
932 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
933 // The passed dex_cache is a hint, sanity check before asking the class linker that will take a
934 // lock.
935 if (dex_cache->GetDexFile() != mUnit->GetDexFile()) {
Mathieu Chartier590fee92013-09-13 13:46:47 -0700936 dex_cache.reset(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700937 }
Mathieu Chartier590fee92013-09-13 13:46:47 -0700938 SirtRef<mirror::ClassLoader>
939 class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
940 const DexFile::MethodId& referrer_method_id =
941 mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex());
Brian Carlstrom7940e442013-07-12 13:46:57 -0700942 return mUnit->GetClassLinker()->ResolveType(*mUnit->GetDexFile(), referrer_method_id.class_idx_,
943 dex_cache, class_loader);
944}
945
Brian Carlstromea46f952013-07-30 01:26:50 -0700946static mirror::ArtMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa,
Ian Rogers65ec92c2013-09-06 10:49:58 -0700947 const DexCompilationUnit* mUnit,
948 uint32_t method_idx,
949 InvokeType type)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700950 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier590fee92013-09-13 13:46:47 -0700951 SirtRef<mirror::DexCache> dex_cache(soa.Self(), mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()));
952 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
Brian Carlstrom7940e442013-07-12 13:46:57 -0700953 return mUnit->GetClassLinker()->ResolveMethod(*mUnit->GetDexFile(), method_idx, dex_cache,
954 class_loader, NULL, type);
955}
956
Vladimir Marko2bc47802014-02-10 09:43:07 +0000957bool CompilerDriver::ComputeSpecialAccessorInfo(uint32_t field_idx, bool is_put,
958 verifier::MethodVerifier* verifier,
959 InlineIGetIPutData* result) {
960 mirror::DexCache* dex_cache = verifier->GetDexCache();
961 uint32_t method_idx = verifier->GetMethodReference().dex_method_index;
962 mirror::ArtMethod* method = dex_cache->GetResolvedMethod(method_idx);
963 mirror::ArtField* field = dex_cache->GetResolvedField(field_idx);
Vladimir Markoc7ac6492014-02-12 10:17:09 +0000964 if (method == nullptr || field == nullptr || field->IsStatic()) {
Vladimir Marko2bc47802014-02-10 09:43:07 +0000965 return false;
966 }
967 mirror::Class* method_class = method->GetDeclaringClass();
968 mirror::Class* field_class = field->GetDeclaringClass();
969 if (!method_class->CanAccessResolvedField(field_class, field, dex_cache, field_idx) ||
970 (is_put && field->IsFinal() && method_class != field_class)) {
971 return false;
972 }
973 DCHECK_GE(field->GetOffset().Int32Value(), 0);
Vladimir Marko2bc47802014-02-10 09:43:07 +0000974 result->field_idx = field_idx;
975 result->field_offset = field->GetOffset().Int32Value();
976 result->is_volatile = field->IsVolatile();
977 return true;
978}
979
Brian Carlstrom7940e442013-07-12 13:46:57 -0700980bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
Vladimir Markobe0e5462014-02-26 11:24:15 +0000981 bool is_put, MemberOffset* field_offset,
982 bool* is_volatile) {
Brian Carlstrom7940e442013-07-12 13:46:57 -0700983 ScopedObjectAccess soa(Thread::Current());
Vladimir Markobe0e5462014-02-26 11:24:15 +0000984 // Try to resolve the field and compiling method's class.
985 mirror::ArtField* resolved_field;
986 mirror::Class* referrer_class;
987 mirror::DexCache* dex_cache;
988 {
989 SirtRef<mirror::DexCache> dex_cache_sirt(soa.Self(),
990 mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()));
991 SirtRef<mirror::ClassLoader> class_loader_sirt(soa.Self(),
992 soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
993 SirtRef<mirror::ArtField> resolved_field_sirt(soa.Self(),
994 ResolveField(soa, dex_cache_sirt, class_loader_sirt, mUnit, field_idx, false));
995 referrer_class = (resolved_field_sirt.get() != nullptr)
996 ? ResolveCompilingMethodsClass(soa, dex_cache_sirt, class_loader_sirt, mUnit) : nullptr;
997 resolved_field = resolved_field_sirt.get();
998 dex_cache = dex_cache_sirt.get();
Brian Carlstrom7940e442013-07-12 13:46:57 -0700999 }
Vladimir Markobe0e5462014-02-26 11:24:15 +00001000 bool result = false;
1001 if (resolved_field != nullptr && referrer_class != nullptr) {
1002 *is_volatile = IsFieldVolatile(resolved_field);
1003 std::pair<bool, bool> fast_path = IsFastInstanceField(
1004 dex_cache, referrer_class, resolved_field, field_idx, field_offset);
1005 result = is_put ? fast_path.second : fast_path.first;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001006 }
Vladimir Markobe0e5462014-02-26 11:24:15 +00001007 if (!result) {
1008 // Conservative defaults.
1009 *is_volatile = true;
1010 *field_offset = MemberOffset(static_cast<size_t>(-1));
1011 }
1012 ProcessedInstanceField(result);
1013 return result;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001014}
1015
1016bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
Vladimir Markobe0e5462014-02-26 11:24:15 +00001017 bool is_put, MemberOffset* field_offset,
1018 uint32_t* storage_index, bool* is_referrers_class,
1019 bool* is_volatile, bool* is_initialized) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001020 ScopedObjectAccess soa(Thread::Current());
Vladimir Markobe0e5462014-02-26 11:24:15 +00001021 // Try to resolve the field and compiling method's class.
1022 mirror::ArtField* resolved_field;
1023 mirror::Class* referrer_class;
1024 mirror::DexCache* dex_cache;
1025 {
1026 SirtRef<mirror::DexCache> dex_cache_sirt(soa.Self(),
1027 mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()));
1028 SirtRef<mirror::ClassLoader> class_loader_sirt(soa.Self(),
1029 soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
1030 SirtRef<mirror::ArtField> resolved_field_sirt(soa.Self(),
1031 ResolveField(soa, dex_cache_sirt, class_loader_sirt, mUnit, field_idx, true));
1032 referrer_class = (resolved_field_sirt.get() != nullptr)
1033 ? ResolveCompilingMethodsClass(soa, dex_cache_sirt, class_loader_sirt, mUnit) : nullptr;
1034 resolved_field = resolved_field_sirt.get();
1035 dex_cache = dex_cache_sirt.get();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001036 }
Vladimir Markobe0e5462014-02-26 11:24:15 +00001037 bool result = false;
1038 if (resolved_field != nullptr && referrer_class != nullptr) {
1039 *is_volatile = IsFieldVolatile(resolved_field);
1040 std::pair<bool, bool> fast_path = IsFastStaticField(
1041 dex_cache, referrer_class, resolved_field, field_idx, field_offset,
1042 storage_index, is_referrers_class, is_initialized);
1043 result = is_put ? fast_path.second : fast_path.first;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001044 }
Vladimir Markobe0e5462014-02-26 11:24:15 +00001045 if (!result) {
1046 // Conservative defaults.
1047 *is_volatile = true;
1048 *field_offset = MemberOffset(static_cast<size_t>(-1));
1049 *storage_index = -1;
1050 *is_referrers_class = false;
1051 *is_initialized = false;
1052 }
1053 ProcessedStaticField(result, *is_referrers_class);
1054 return result;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001055}
1056
Ian Rogers83883d72013-10-21 21:07:24 -07001057void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type,
1058 bool no_guarantee_of_dex_cache_entry,
Brian Carlstrom7940e442013-07-12 13:46:57 -07001059 mirror::Class* referrer_class,
Brian Carlstromea46f952013-07-30 01:26:50 -07001060 mirror::ArtMethod* method,
Ian Rogers65ec92c2013-09-06 10:49:58 -07001061 bool update_stats,
Ian Rogers83883d72013-10-21 21:07:24 -07001062 MethodReference* target_method,
Ian Rogers65ec92c2013-09-06 10:49:58 -07001063 uintptr_t* direct_code,
1064 uintptr_t* direct_method) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001065 // For direct and static methods compute possible direct_code and direct_method values, ie
1066 // an address for the Method* being invoked and an address of the code for that Method*.
1067 // For interface calls compute a value for direct_method that is the interface method being
1068 // invoked, so this can be passed to the out-of-line runtime support code.
Ian Rogers65ec92c2013-09-06 10:49:58 -07001069 *direct_code = 0;
1070 *direct_method = 0;
Ian Rogers83883d72013-10-21 21:07:24 -07001071 bool use_dex_cache = false;
Mathieu Chartier590fee92013-09-13 13:46:47 -07001072 const bool compiling_boot = Runtime::Current()->GetHeap()->IsCompilingBoot();
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00001073 if (compiler_backend_->IsPortable()) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001074 if (sharp_type != kStatic && sharp_type != kDirect) {
1075 return;
1076 }
Ian Rogers83883d72013-10-21 21:07:24 -07001077 use_dex_cache = true;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001078 } else {
Jeff Hao88474b42013-10-23 16:24:40 -07001079 if (sharp_type != kStatic && sharp_type != kDirect) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001080 return;
1081 }
Ian Rogers83883d72013-10-21 21:07:24 -07001082 // TODO: support patching on all architectures.
1083 use_dex_cache = compiling_boot && !support_boot_image_fixup_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001084 }
Ian Rogers83883d72013-10-21 21:07:24 -07001085 bool method_code_in_boot = (method->GetDeclaringClass()->GetClassLoader() == nullptr);
1086 if (!use_dex_cache) {
1087 if (!method_code_in_boot) {
1088 use_dex_cache = true;
1089 } else {
1090 bool has_clinit_trampoline =
1091 method->IsStatic() && !method->GetDeclaringClass()->IsInitialized();
1092 if (has_clinit_trampoline && (method->GetDeclaringClass() != referrer_class)) {
1093 // Ensure we run the clinit trampoline unless we are invoking a static method in the same
1094 // class.
1095 use_dex_cache = true;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001096 }
1097 }
Ian Rogers83883d72013-10-21 21:07:24 -07001098 }
1099 if (update_stats && method_code_in_boot) {
Jeff Hao88474b42013-10-23 16:24:40 -07001100 stats_->DirectCallsToBoot(*type);
Ian Rogers83883d72013-10-21 21:07:24 -07001101 stats_->DirectMethodsToBoot(*type);
1102 }
1103 if (!use_dex_cache && compiling_boot) {
1104 MethodHelper mh(method);
Ian Rogersdfb325e2013-10-30 01:00:44 -07001105 if (!IsImageClass(mh.GetDeclaringClassDescriptor())) {
Ian Rogers83883d72013-10-21 21:07:24 -07001106 // We can only branch directly to Methods that are resolved in the DexCache.
1107 // Otherwise we won't invoke the resolution trampoline.
1108 use_dex_cache = true;
1109 }
1110 }
1111 // The method is defined not within this dex file. We need a dex cache slot within the current
1112 // dex file or direct pointers.
1113 bool must_use_direct_pointers = false;
1114 if (target_method->dex_file == method->GetDeclaringClass()->GetDexCache()->GetDexFile()) {
1115 target_method->dex_method_index = method->GetDexMethodIndex();
1116 } else {
1117 // TODO: support patching from one dex file to another in the boot image.
1118 use_dex_cache = use_dex_cache || compiling_boot;
1119 if (no_guarantee_of_dex_cache_entry) {
1120 // See if the method is also declared in this dex cache.
1121 uint32_t dex_method_idx = MethodHelper(method).FindDexMethodIndexInOtherDexFile(
Vladimir Markobbcc0c02014-02-03 14:08:42 +00001122 *target_method->dex_file, target_method->dex_method_index);
Ian Rogers83883d72013-10-21 21:07:24 -07001123 if (dex_method_idx != DexFile::kDexNoIndex) {
1124 target_method->dex_method_index = dex_method_idx;
1125 } else {
1126 must_use_direct_pointers = true;
1127 }
1128 }
1129 }
1130 if (use_dex_cache) {
1131 if (must_use_direct_pointers) {
1132 // Fail. Test above showed the only safe dispatch was via the dex cache, however, the direct
1133 // pointers are required as the dex cache lacks an appropriate entry.
1134 VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
1135 } else {
1136 *type = sharp_type;
1137 }
1138 } else {
1139 if (compiling_boot) {
1140 *type = sharp_type;
1141 *direct_method = -1;
Jeff Hao88474b42013-10-23 16:24:40 -07001142 *direct_code = -1;
Ian Rogers83883d72013-10-21 21:07:24 -07001143 } else {
1144 bool method_in_image =
1145 Runtime::Current()->GetHeap()->FindSpaceFromObject(method, false)->IsImageSpace();
1146 if (method_in_image) {
Jeff Hao88474b42013-10-23 16:24:40 -07001147 CHECK(!method->IsAbstract());
Ian Rogers83883d72013-10-21 21:07:24 -07001148 *type = sharp_type;
1149 *direct_method = reinterpret_cast<uintptr_t>(method);
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00001150 *direct_code = compiler_backend_->GetEntryPointOf(method);
Ian Rogers83883d72013-10-21 21:07:24 -07001151 target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
1152 target_method->dex_method_index = method->GetDexMethodIndex();
1153 } else if (!must_use_direct_pointers) {
1154 // Set the code and rely on the dex cache for the method.
1155 *type = sharp_type;
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00001156 *direct_code = compiler_backend_->GetEntryPointOf(method);
Ian Rogers83883d72013-10-21 21:07:24 -07001157 } else {
1158 // Direct pointers were required but none were available.
1159 VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
1160 }
1161 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001162 }
1163}
1164
1165bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc,
Ian Rogers65ec92c2013-09-06 10:49:58 -07001166 bool update_stats, bool enable_devirtualization,
1167 InvokeType* invoke_type, MethodReference* target_method,
1168 int* vtable_idx, uintptr_t* direct_code,
1169 uintptr_t* direct_method) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001170 ScopedObjectAccess soa(Thread::Current());
Ian Rogers65ec92c2013-09-06 10:49:58 -07001171 *vtable_idx = -1;
1172 *direct_code = 0;
1173 *direct_method = 0;
Brian Carlstromea46f952013-07-30 01:26:50 -07001174 mirror::ArtMethod* resolved_method =
Ian Rogers65ec92c2013-09-06 10:49:58 -07001175 ComputeMethodReferencedFromCompilingMethod(soa, mUnit, target_method->dex_method_index,
1176 *invoke_type);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001177 if (resolved_method != NULL) {
Ian Rogers83883d72013-10-21 21:07:24 -07001178 if (*invoke_type == kVirtual || *invoke_type == kSuper) {
1179 *vtable_idx = resolved_method->GetMethodIndex();
Jeff Hao88474b42013-10-23 16:24:40 -07001180 } else if (*invoke_type == kInterface) {
1181 *vtable_idx = resolved_method->GetDexMethodIndex();
Ian Rogers83883d72013-10-21 21:07:24 -07001182 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001183 // Don't try to fast-path if we don't understand the caller's class or this appears to be an
1184 // Incompatible Class Change Error.
Mathieu Chartier590fee92013-09-13 13:46:47 -07001185 SirtRef<mirror::DexCache> dex_cache(soa.Self(), resolved_method->GetDeclaringClass()->GetDexCache());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001186 mirror::Class* referrer_class =
Mathieu Chartier590fee92013-09-13 13:46:47 -07001187 ComputeCompilingMethodsClass(soa, dex_cache, mUnit);
Ian Rogers65ec92c2013-09-06 10:49:58 -07001188 bool icce = resolved_method->CheckIncompatibleClassChange(*invoke_type);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001189 if (referrer_class != NULL && !icce) {
1190 mirror::Class* methods_class = resolved_method->GetDeclaringClass();
Ian Rogersef7d42f2014-01-06 12:55:46 -08001191 if (referrer_class->CanAccessResolvedMethod(methods_class, resolved_method, dex_cache.get(),
1192 target_method->dex_method_index)) {
Sebastien Hertz1e54d682013-09-06 14:52:10 +02001193 const bool enableFinalBasedSharpening = enable_devirtualization;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001194 // Sharpen a virtual call into a direct call when the target is known not to have been
1195 // overridden (ie is final).
1196 bool can_sharpen_virtual_based_on_type =
Ian Rogers65ec92c2013-09-06 10:49:58 -07001197 (*invoke_type == kVirtual) && (resolved_method->IsFinal() || methods_class->IsFinal());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001198 // For invoke-super, ensure the vtable index will be correct to dispatch in the vtable of
1199 // the super class.
Ian Rogers65ec92c2013-09-06 10:49:58 -07001200 bool can_sharpen_super_based_on_type = (*invoke_type == kSuper) &&
Brian Carlstrom7940e442013-07-12 13:46:57 -07001201 (referrer_class != methods_class) && referrer_class->IsSubClass(methods_class) &&
1202 resolved_method->GetMethodIndex() < methods_class->GetVTable()->GetLength() &&
1203 (methods_class->GetVTable()->Get(resolved_method->GetMethodIndex()) == resolved_method);
1204
Sebastien Hertz1e54d682013-09-06 14:52:10 +02001205 if (enableFinalBasedSharpening && (can_sharpen_virtual_based_on_type ||
Brian Carlstrom7940e442013-07-12 13:46:57 -07001206 can_sharpen_super_based_on_type)) {
Vladimir Marko89786432014-01-31 15:03:55 +00001207 // Sharpen a virtual call into a direct call. The method_idx is into the DexCache
1208 // associated with target_method->dex_file.
1209 CHECK(target_method->dex_file == mUnit->GetDexFile());
1210 DCHECK(dex_cache.get() == mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile()));
1211 CHECK(dex_cache->GetResolvedMethod(target_method->dex_method_index) ==
Brian Carlstrom7940e442013-07-12 13:46:57 -07001212 resolved_method) << PrettyMethod(resolved_method);
Ian Rogers83883d72013-10-21 21:07:24 -07001213 InvokeType orig_invoke_type = *invoke_type;
1214 GetCodeAndMethodForDirectCall(invoke_type, kDirect, false, referrer_class, resolved_method,
1215 update_stats, target_method, direct_code, direct_method);
1216 if (update_stats && (*invoke_type == kDirect)) {
1217 stats_->ResolvedMethod(orig_invoke_type);
1218 stats_->VirtualMadeDirect(orig_invoke_type);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001219 }
Ian Rogers83883d72013-10-21 21:07:24 -07001220 DCHECK_NE(*invoke_type, kSuper) << PrettyMethod(resolved_method);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001221 return true;
1222 }
Sebastien Hertz1e54d682013-09-06 14:52:10 +02001223 const bool enableVerifierBasedSharpening = enable_devirtualization;
Ian Rogers65ec92c2013-09-06 10:49:58 -07001224 if (enableVerifierBasedSharpening && (*invoke_type == kVirtual ||
1225 *invoke_type == kInterface)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001226 // Did the verifier record a more precise invoke target based on its type information?
Vladimir Marko2730db02014-01-27 11:15:17 +00001227 DCHECK(mUnit->GetVerifiedMethod() != nullptr);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001228 const MethodReference* devirt_map_target =
Vladimir Marko2730db02014-01-27 11:15:17 +00001229 mUnit->GetVerifiedMethod()->GetDevirtTarget(dex_pc);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001230 if (devirt_map_target != NULL) {
Mathieu Chartier590fee92013-09-13 13:46:47 -07001231 SirtRef<mirror::DexCache> target_dex_cache(soa.Self(), mUnit->GetClassLinker()->FindDexCache(*devirt_map_target->dex_file));
1232 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()));
Brian Carlstromea46f952013-07-30 01:26:50 -07001233 mirror::ArtMethod* called_method =
Brian Carlstrom7940e442013-07-12 13:46:57 -07001234 mUnit->GetClassLinker()->ResolveMethod(*devirt_map_target->dex_file,
1235 devirt_map_target->dex_method_index,
1236 target_dex_cache, class_loader, NULL,
1237 kVirtual);
1238 CHECK(called_method != NULL);
1239 CHECK(!called_method->IsAbstract());
Ian Rogers83883d72013-10-21 21:07:24 -07001240 InvokeType orig_invoke_type = *invoke_type;
1241 GetCodeAndMethodForDirectCall(invoke_type, kDirect, true, referrer_class, called_method,
1242 update_stats, target_method, direct_code, direct_method);
1243 if (update_stats && (*invoke_type == kDirect)) {
1244 stats_->ResolvedMethod(orig_invoke_type);
1245 stats_->VirtualMadeDirect(orig_invoke_type);
1246 stats_->PreciseTypeDevirtualization();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001247 }
Ian Rogers83883d72013-10-21 21:07:24 -07001248 DCHECK_NE(*invoke_type, kSuper);
1249 return true;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001250 }
1251 }
Ian Rogers65ec92c2013-09-06 10:49:58 -07001252 if (*invoke_type == kSuper) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001253 // Unsharpened super calls are suspicious so go slow-path.
1254 } else {
1255 // Sharpening failed so generate a regular resolved method dispatch.
1256 if (update_stats) {
Ian Rogers65ec92c2013-09-06 10:49:58 -07001257 stats_->ResolvedMethod(*invoke_type);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001258 }
Ian Rogers83883d72013-10-21 21:07:24 -07001259 GetCodeAndMethodForDirectCall(invoke_type, *invoke_type, false, referrer_class, resolved_method,
1260 update_stats, target_method, direct_code, direct_method);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001261 return true;
1262 }
1263 }
1264 }
1265 }
1266 // Clean up any exception left by method/invoke_type resolution
1267 if (soa.Self()->IsExceptionPending()) {
1268 soa.Self()->ClearException();
1269 }
1270 if (update_stats) {
Ian Rogers65ec92c2013-09-06 10:49:58 -07001271 stats_->UnresolvedMethod(*invoke_type);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001272 }
1273 return false; // Incomplete knowledge needs slow path.
1274}
1275
Vladimir Marko2730db02014-01-27 11:15:17 +00001276const VerifiedMethod* CompilerDriver::GetVerifiedMethod(const DexFile* dex_file,
1277 uint32_t method_idx) const {
1278 MethodReference ref(dex_file, method_idx);
1279 return verification_results_->GetVerifiedMethod(ref);
1280}
1281
1282bool CompilerDriver::IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc) {
1283 DCHECK(mUnit->GetVerifiedMethod() != nullptr);
1284 bool result = mUnit->GetVerifiedMethod()->IsSafeCast(dex_pc);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001285 if (result) {
1286 stats_->SafeCast();
1287 } else {
1288 stats_->NotASafeCast();
1289 }
1290 return result;
1291}
1292
1293
1294void CompilerDriver::AddCodePatch(const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07001295 uint16_t referrer_class_def_idx,
1296 uint32_t referrer_method_idx,
1297 InvokeType referrer_invoke_type,
1298 uint32_t target_method_idx,
1299 InvokeType target_invoke_type,
1300 size_t literal_offset) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001301 MutexLock mu(Thread::Current(), compiled_methods_lock_);
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001302 code_to_patch_.push_back(new CallPatchInformation(dex_file,
1303 referrer_class_def_idx,
1304 referrer_method_idx,
1305 referrer_invoke_type,
1306 target_method_idx,
1307 target_invoke_type,
1308 literal_offset));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001309}
Mark Mendell55d0eac2014-02-06 11:02:52 -08001310void CompilerDriver::AddRelativeCodePatch(const DexFile* dex_file,
1311 uint16_t referrer_class_def_idx,
1312 uint32_t referrer_method_idx,
1313 InvokeType referrer_invoke_type,
1314 uint32_t target_method_idx,
1315 InvokeType target_invoke_type,
1316 size_t literal_offset,
1317 int32_t pc_relative_offset) {
1318 MutexLock mu(Thread::Current(), compiled_methods_lock_);
1319 code_to_patch_.push_back(new RelativeCallPatchInformation(dex_file,
1320 referrer_class_def_idx,
1321 referrer_method_idx,
1322 referrer_invoke_type,
1323 target_method_idx,
1324 target_invoke_type,
1325 literal_offset,
1326 pc_relative_offset));
1327}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001328void CompilerDriver::AddMethodPatch(const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07001329 uint16_t referrer_class_def_idx,
1330 uint32_t referrer_method_idx,
1331 InvokeType referrer_invoke_type,
1332 uint32_t target_method_idx,
1333 InvokeType target_invoke_type,
1334 size_t literal_offset) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001335 MutexLock mu(Thread::Current(), compiled_methods_lock_);
Hiroshi Yamauchibe1ca552014-01-15 11:46:48 -08001336 methods_to_patch_.push_back(new CallPatchInformation(dex_file,
1337 referrer_class_def_idx,
1338 referrer_method_idx,
1339 referrer_invoke_type,
1340 target_method_idx,
1341 target_invoke_type,
1342 literal_offset));
1343}
1344void CompilerDriver::AddClassPatch(const DexFile* dex_file,
1345 uint16_t referrer_class_def_idx,
1346 uint32_t referrer_method_idx,
1347 uint32_t target_type_idx,
1348 size_t literal_offset) {
1349 MutexLock mu(Thread::Current(), compiled_methods_lock_);
1350 classes_to_patch_.push_back(new TypePatchInformation(dex_file,
1351 referrer_class_def_idx,
1352 referrer_method_idx,
1353 target_type_idx,
1354 literal_offset));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001355}
1356
1357class ParallelCompilationManager {
1358 public:
1359 typedef void Callback(const ParallelCompilationManager* manager, size_t index);
1360
1361 ParallelCompilationManager(ClassLinker* class_linker,
1362 jobject class_loader,
1363 CompilerDriver* compiler,
1364 const DexFile* dex_file,
Ian Rogers3d504072014-03-01 09:16:49 -08001365 ThreadPool* thread_pool)
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001366 : index_(0),
1367 class_linker_(class_linker),
Brian Carlstrom7940e442013-07-12 13:46:57 -07001368 class_loader_(class_loader),
1369 compiler_(compiler),
1370 dex_file_(dex_file),
Ian Rogers3d504072014-03-01 09:16:49 -08001371 thread_pool_(thread_pool) {}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001372
1373 ClassLinker* GetClassLinker() const {
1374 CHECK(class_linker_ != NULL);
1375 return class_linker_;
1376 }
1377
1378 jobject GetClassLoader() const {
1379 return class_loader_;
1380 }
1381
1382 CompilerDriver* GetCompiler() const {
1383 CHECK(compiler_ != NULL);
1384 return compiler_;
1385 }
1386
1387 const DexFile* GetDexFile() const {
1388 CHECK(dex_file_ != NULL);
1389 return dex_file_;
1390 }
1391
1392 void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
1393 Thread* self = Thread::Current();
1394 self->AssertNoPendingException();
1395 CHECK_GT(work_units, 0U);
1396
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001397 index_ = begin;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001398 for (size_t i = 0; i < work_units; ++i) {
Sebastien Hertz501baec2013-12-13 12:02:36 +01001399 thread_pool_->AddTask(self, new ForAllClosure(this, end, callback));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001400 }
1401 thread_pool_->StartWorkers(self);
1402
1403 // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
1404 // thread destructor's called below perform join).
1405 CHECK_NE(self->GetState(), kRunnable);
1406
1407 // Wait for all the worker threads to finish.
1408 thread_pool_->Wait(self, true, false);
1409 }
1410
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001411 size_t NextIndex() {
Ian Rogersb122a4b2013-11-19 18:00:50 -08001412 return index_.FetchAndAdd(1);
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001413 }
1414
Brian Carlstrom7940e442013-07-12 13:46:57 -07001415 private:
Brian Carlstrom7940e442013-07-12 13:46:57 -07001416 class ForAllClosure : public Task {
1417 public:
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001418 ForAllClosure(ParallelCompilationManager* manager, size_t end, Callback* callback)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001419 : manager_(manager),
Brian Carlstrom7940e442013-07-12 13:46:57 -07001420 end_(end),
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001421 callback_(callback) {}
Brian Carlstrom7940e442013-07-12 13:46:57 -07001422
1423 virtual void Run(Thread* self) {
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001424 while (true) {
1425 const size_t index = manager_->NextIndex();
1426 if (UNLIKELY(index >= end_)) {
1427 break;
1428 }
1429 callback_(manager_, index);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001430 self->AssertNoPendingException();
1431 }
1432 }
1433
1434 virtual void Finalize() {
1435 delete this;
1436 }
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -07001437
Brian Carlstrom7940e442013-07-12 13:46:57 -07001438 private:
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001439 ParallelCompilationManager* const manager_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001440 const size_t end_;
Bernhard Rosenkränzer46053622013-12-12 02:15:52 +01001441 Callback* const callback_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001442 };
1443
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001444 AtomicInteger index_;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001445 ClassLinker* const class_linker_;
1446 const jobject class_loader_;
1447 CompilerDriver* const compiler_;
1448 const DexFile* const dex_file_;
1449 ThreadPool* const thread_pool_;
Mathieu Chartier0b3eb392013-08-23 14:56:59 -07001450
1451 DISALLOW_COPY_AND_ASSIGN(ParallelCompilationManager);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001452};
1453
Jeff Hao0e49b422013-11-08 12:16:56 -08001454// Return true if the class should be skipped during compilation.
1455//
1456// The first case where we skip is for redundant class definitions in
1457// the boot classpath. We skip all but the first definition in that case.
1458//
1459// The second case where we skip is when an app bundles classes found
1460// in the boot classpath. Since at runtime we will select the class from
1461// the boot classpath, we ignore the one from the app.
Ian Rogersbe7149f2013-08-20 09:29:39 -07001462static bool SkipClass(ClassLinker* class_linker, jobject class_loader, const DexFile& dex_file,
1463 const DexFile::ClassDef& class_def) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001464 const char* descriptor = dex_file.GetClassDescriptor(class_def);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001465 if (class_loader == NULL) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001466 DexFile::ClassPathEntry pair = DexFile::FindInClassPath(descriptor, class_linker->GetBootClassPath());
1467 CHECK(pair.second != NULL);
1468 if (pair.first != &dex_file) {
1469 LOG(WARNING) << "Skipping class " << descriptor << " from " << dex_file.GetLocation()
1470 << " previously found in " << pair.first->GetLocation();
1471 return true;
1472 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001473 return false;
1474 }
Ian Rogersbe7149f2013-08-20 09:29:39 -07001475 return class_linker->IsInBootClassPath(descriptor);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001476}
1477
Jeff Hao0e49b422013-11-08 12:16:56 -08001478// A fast version of SkipClass above if the class pointer is available
1479// that avoids the expensive FindInClassPath search.
1480static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Class* klass)
1481 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1482 DCHECK(klass != NULL);
1483 const DexFile& original_dex_file = *klass->GetDexCache()->GetDexFile();
1484 if (&dex_file != &original_dex_file) {
1485 if (class_loader == NULL) {
1486 LOG(WARNING) << "Skipping class " << PrettyDescriptor(klass) << " from "
1487 << dex_file.GetLocation() << " previously found in "
1488 << original_dex_file.GetLocation();
1489 }
1490 return true;
1491 }
1492 return false;
1493}
1494
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001495static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager,
1496 size_t class_def_index)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001497 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001498 ATRACE_CALL();
Ian Rogersbe7149f2013-08-20 09:29:39 -07001499 Thread* self = Thread::Current();
1500 jobject jclass_loader = manager->GetClassLoader();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001501 const DexFile& dex_file = *manager->GetDexFile();
Ian Rogersbe7149f2013-08-20 09:29:39 -07001502 ClassLinker* class_linker = manager->GetClassLinker();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001503
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001504 // If an instance field is final then we need to have a barrier on the return, static final
1505 // fields are assigned within the lock held for class initialization. Conservatively assume
1506 // constructor barriers are always required.
1507 bool requires_constructor_barrier = true;
1508
Brian Carlstrom7940e442013-07-12 13:46:57 -07001509 // Method and Field are the worst. We can't resolve without either
1510 // context from the code use (to disambiguate virtual vs direct
1511 // method and instance vs static field) or from class
1512 // definitions. While the compiler will resolve what it can as it
1513 // needs it, here we try to resolve fields and methods used in class
1514 // definitions, since many of them many never be referenced by
1515 // generated code.
1516 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogersbe7149f2013-08-20 09:29:39 -07001517 if (!SkipClass(class_linker, jclass_loader, dex_file, class_def)) {
Brian Carlstromcb5f5e52013-09-23 17:48:16 -07001518 ScopedObjectAccess soa(self);
Mathieu Chartier590fee92013-09-13 13:46:47 -07001519 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
1520 SirtRef<mirror::DexCache> dex_cache(soa.Self(), class_linker->FindDexCache(dex_file));
Brian Carlstromcb5f5e52013-09-23 17:48:16 -07001521 // Resolve the class.
1522 mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
1523 class_loader);
Brian Carlstromcb5f5e52013-09-23 17:48:16 -07001524 bool resolve_fields_and_methods;
1525 if (klass == NULL) {
1526 // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
1527 // attempt to resolve methods and fields when there is no declaring class.
1528 CHECK(soa.Self()->IsExceptionPending());
1529 soa.Self()->ClearException();
1530 resolve_fields_and_methods = false;
1531 } else {
1532 resolve_fields_and_methods = manager->GetCompiler()->IsImage();
1533 }
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001534 // Note the class_data pointer advances through the headers,
1535 // static fields, instance fields, direct methods, and virtual
1536 // methods.
1537 const byte* class_data = dex_file.GetClassData(class_def);
1538 if (class_data == NULL) {
1539 // Empty class such as a marker interface.
1540 requires_constructor_barrier = false;
1541 } else {
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001542 ClassDataItemIterator it(dex_file, class_data);
1543 while (it.HasNextStaticField()) {
1544 if (resolve_fields_and_methods) {
1545 mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1546 dex_cache, class_loader, true);
1547 if (field == NULL) {
1548 CHECK(soa.Self()->IsExceptionPending());
1549 soa.Self()->ClearException();
1550 }
1551 }
1552 it.Next();
1553 }
1554 // We require a constructor barrier if there are final instance fields.
1555 requires_constructor_barrier = false;
1556 while (it.HasNextInstanceField()) {
1557 if ((it.GetMemberAccessFlags() & kAccFinal) != 0) {
1558 requires_constructor_barrier = true;
1559 }
1560 if (resolve_fields_and_methods) {
1561 mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1562 dex_cache, class_loader, false);
1563 if (field == NULL) {
1564 CHECK(soa.Self()->IsExceptionPending());
1565 soa.Self()->ClearException();
1566 }
1567 }
1568 it.Next();
1569 }
1570 if (resolve_fields_and_methods) {
1571 while (it.HasNextDirectMethod()) {
1572 mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
1573 dex_cache, class_loader, NULL,
1574 it.GetMethodInvokeType(class_def));
1575 if (method == NULL) {
1576 CHECK(soa.Self()->IsExceptionPending());
1577 soa.Self()->ClearException();
1578 }
1579 it.Next();
1580 }
1581 while (it.HasNextVirtualMethod()) {
1582 mirror::ArtMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
1583 dex_cache, class_loader, NULL,
1584 it.GetMethodInvokeType(class_def));
1585 if (method == NULL) {
1586 CHECK(soa.Self()->IsExceptionPending());
1587 soa.Self()->ClearException();
1588 }
1589 it.Next();
1590 }
1591 DCHECK(!it.HasNext());
1592 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001593 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001594 }
1595 if (requires_constructor_barrier) {
Ian Rogersbe7149f2013-08-20 09:29:39 -07001596 manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001597 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001598}
1599
1600static void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
1601 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1602 // Class derived values are more complicated, they require the linker and loader.
1603 ScopedObjectAccess soa(Thread::Current());
1604 ClassLinker* class_linker = manager->GetClassLinker();
1605 const DexFile& dex_file = *manager->GetDexFile();
Mathieu Chartier590fee92013-09-13 13:46:47 -07001606 SirtRef<mirror::DexCache> dex_cache(soa.Self(), class_linker->FindDexCache(dex_file));
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001607 SirtRef<mirror::ClassLoader> class_loader(
1608 soa.Self(), soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader()));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001609 mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
1610
1611 if (klass == NULL) {
1612 CHECK(soa.Self()->IsExceptionPending());
Ian Rogersa436fde2013-08-27 23:34:06 -07001613 mirror::Throwable* exception = soa.Self()->GetException(NULL);
1614 VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
Ian Rogersdfb325e2013-10-30 01:00:44 -07001615 if (strcmp("Ljava/lang/OutOfMemoryError;",
1616 ClassHelper(exception->GetClass()).GetDescriptor()) == 0) {
Ian Rogersa436fde2013-08-27 23:34:06 -07001617 // There's little point continuing compilation if the heap is exhausted.
1618 LOG(FATAL) << "Out of memory during type resolution for compilation";
1619 }
1620 soa.Self()->ClearException();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001621 }
1622}
1623
1624void CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
Ian Rogers3d504072014-03-01 09:16:49 -08001625 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001626 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1627
1628 // TODO: we could resolve strings here, although the string table is largely filled with class
1629 // and method names.
1630
1631 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001632 if (IsImage()) {
1633 // For images we resolve all types, such as array, whereas for applications just those with
1634 // classdefs are resolved by ResolveClassFieldsAndMethods.
Ian Rogers3d504072014-03-01 09:16:49 -08001635 timings->NewSplit("Resolve Types");
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001636 context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
1637 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001638
Ian Rogers3d504072014-03-01 09:16:49 -08001639 timings->NewSplit("Resolve MethodsAndFields");
Brian Carlstrom7940e442013-07-12 13:46:57 -07001640 context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001641}
1642
1643void CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001644 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001645 for (size_t i = 0; i != dex_files.size(); ++i) {
1646 const DexFile* dex_file = dex_files[i];
1647 CHECK(dex_file != NULL);
1648 VerifyDexFile(class_loader, *dex_file, thread_pool, timings);
1649 }
1650}
1651
1652static void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index)
1653 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001654 ATRACE_CALL();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001655 ScopedObjectAccess soa(Thread::Current());
Jeff Hao0e49b422013-11-08 12:16:56 -08001656 const DexFile& dex_file = *manager->GetDexFile();
1657 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1658 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1659 ClassLinker* class_linker = manager->GetClassLinker();
1660 jobject jclass_loader = manager->GetClassLoader();
Mathieu Chartier590fee92013-09-13 13:46:47 -07001661 SirtRef<mirror::ClassLoader> class_loader(
1662 soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
Ian Rogers98379392014-02-24 16:53:16 -08001663 SirtRef<mirror::Class> klass(soa.Self(), class_linker->FindClass(soa.Self(), descriptor,
1664 class_loader));
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001665 if (klass.get() == nullptr) {
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001666 CHECK(soa.Self()->IsExceptionPending());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001667 soa.Self()->ClearException();
1668
1669 /*
1670 * At compile time, we can still structurally verify the class even if FindClass fails.
1671 * This is to ensure the class is structurally sound for compilation. An unsound class
1672 * will be rejected by the verifier and later skipped during compilation in the compiler.
1673 */
Mathieu Chartier590fee92013-09-13 13:46:47 -07001674 SirtRef<mirror::DexCache> dex_cache(soa.Self(), class_linker->FindDexCache(dex_file));
Brian Carlstrom7940e442013-07-12 13:46:57 -07001675 std::string error_msg;
Mathieu Chartier590fee92013-09-13 13:46:47 -07001676 if (verifier::MethodVerifier::VerifyClass(&dex_file, dex_cache, class_loader, &class_def, true,
1677 &error_msg) ==
Brian Carlstrom7940e442013-07-12 13:46:57 -07001678 verifier::MethodVerifier::kHardFailure) {
Jeff Hao0e49b422013-11-08 12:16:56 -08001679 LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
Brian Carlstrom7940e442013-07-12 13:46:57 -07001680 << " because: " << error_msg;
1681 }
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001682 } else if (!SkipClass(jclass_loader, dex_file, klass.get())) {
1683 CHECK(klass->IsResolved()) << PrettyClass(klass.get());
Jeff Hao0e49b422013-11-08 12:16:56 -08001684 class_linker->VerifyClass(klass);
Ian Rogerse6bb3b22013-08-19 21:51:45 -07001685
1686 if (klass->IsErroneous()) {
1687 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1688 CHECK(soa.Self()->IsExceptionPending());
1689 soa.Self()->ClearException();
1690 }
1691
1692 CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001693 << PrettyDescriptor(klass.get()) << ": state=" << klass->GetStatus();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001694 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001695 soa.Self()->AssertNoPendingException();
1696}
1697
1698void CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
Ian Rogers3d504072014-03-01 09:16:49 -08001699 ThreadPool* thread_pool, TimingLogger* timings) {
1700 timings->NewSplit("Verify Dex File");
Brian Carlstrom7940e442013-07-12 13:46:57 -07001701 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1702 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
1703 context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001704}
1705
Brian Carlstrom7940e442013-07-12 13:46:57 -07001706static void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
1707 LOCKS_EXCLUDED(Locks::mutator_lock_) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001708 ATRACE_CALL();
Jeff Hao0e49b422013-11-08 12:16:56 -08001709 jobject jclass_loader = manager->GetClassLoader();
1710 const DexFile& dex_file = *manager->GetDexFile();
1711 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Jeff Haobcdbbfe2013-11-08 18:03:22 -08001712 const DexFile::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
1713 const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_);
Ian Rogersfc0e94b2013-09-23 23:51:32 -07001714
Brian Carlstrom7940e442013-07-12 13:46:57 -07001715 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartier590fee92013-09-13 13:46:47 -07001716 SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
1717 soa.Decode<mirror::ClassLoader*>(jclass_loader));
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001718 SirtRef<mirror::Class> klass(soa.Self(),
Ian Rogers98379392014-02-24 16:53:16 -08001719 manager->GetClassLinker()->FindClass(soa.Self(), descriptor,
1720 class_loader));
Jeff Hao0e49b422013-11-08 12:16:56 -08001721
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001722 if (klass.get() != nullptr && !SkipClass(jclass_loader, dex_file, klass.get())) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001723 // Only try to initialize classes that were successfully verified.
1724 if (klass->IsVerified()) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001725 // Attempt to initialize the class but bail if we either need to initialize the super-class
1726 // or static fields.
1727 manager->GetClassLinker()->EnsureInitialized(klass, false, false);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001728 if (!klass->IsInitialized()) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001729 // We don't want non-trivial class initialization occurring on multiple threads due to
1730 // deadlock problems. For example, a parent class is initialized (holding its lock) that
1731 // refers to a sub-class in its static/class initializer causing it to try to acquire the
1732 // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
1733 // after first initializing its parents, whose locks are acquired. This leads to a
1734 // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
1735 // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
1736 // than use a special Object for the purpose we use the Class of java.lang.Class.
Mathieu Chartierc528dba2013-11-26 12:00:11 -08001737 SirtRef<mirror::Class> sirt_klass(soa.Self(), klass->GetClass());
1738 ObjectLock<mirror::Class> lock(soa.Self(), &sirt_klass);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001739 // Attempt to initialize allowing initialization of parent classes but still not static
1740 // fields.
1741 manager->GetClassLinker()->EnsureInitialized(klass, false, true);
1742 if (!klass->IsInitialized()) {
1743 // We need to initialize static fields, we only do this for image classes that aren't
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001744 // marked with the $NoPreloadHolder (which implies this should not be initialized early).
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001745 bool can_init_static_fields = manager->GetCompiler()->IsImage() &&
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001746 manager->GetCompiler()->IsImageClass(descriptor) &&
1747 !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001748 if (can_init_static_fields) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001749 VLOG(compiler) << "Initializing: " << descriptor;
1750 if (strcmp("Ljava/lang/Void;", descriptor) == 0) {
1751 // Hand initialize j.l.Void to avoid Dex file operations in un-started runtime.
1752 ObjectLock<mirror::Class> lock(soa.Self(), &klass);
1753 mirror::ObjectArray<mirror::ArtField>* fields = klass->GetSFields();
1754 CHECK_EQ(fields->GetLength(), 1);
1755 fields->Get(0)->SetObj<false>(klass.get(),
1756 manager->GetClassLinker()->FindPrimitiveClass('V'));
1757 klass->SetStatus(mirror::Class::kStatusInitialized, soa.Self());
1758 } else {
1759 // TODO multithreading support. We should ensure the current compilation thread has
1760 // exclusive access to the runtime and the transaction. To achieve this, we could use
1761 // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity
1762 // checks in Thread::AssertThreadSuspensionIsAllowable.
1763 Runtime* const runtime = Runtime::Current();
1764 Transaction transaction;
1765
1766 // Run the class initializer in transaction mode.
1767 runtime->EnterTransactionMode(&transaction);
1768 const mirror::Class::Status old_status = klass->GetStatus();
1769 bool success = manager->GetClassLinker()->EnsureInitialized(klass, true, true);
1770 // TODO we detach transaction from runtime to indicate we quit the transactional
1771 // mode which prevents the GC from visiting objects modified during the transaction.
1772 // Ensure GC is not run so don't access freed objects when aborting transaction.
1773 const char* old_casue = soa.Self()->StartAssertNoThreadSuspension("Transaction end");
1774 runtime->ExitTransactionMode();
1775
1776 if (!success) {
1777 CHECK(soa.Self()->IsExceptionPending());
1778 ThrowLocation throw_location;
1779 mirror::Throwable* exception = soa.Self()->GetException(&throw_location);
1780 VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
1781 << exception->Dump();
1782 soa.Self()->ClearException();
1783 transaction.Abort();
1784 CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001785 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001786 soa.Self()->EndAssertNoThreadSuspension(old_casue);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001787 }
1788 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001789 }
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001790 soa.Self()->AssertNoPendingException();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001791 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001792 }
1793 // Record the final class status if necessary.
Brian Carlstrom7940e442013-07-12 13:46:57 -07001794 ClassReference ref(manager->GetDexFile(), class_def_index);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001795 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
Brian Carlstrom7940e442013-07-12 13:46:57 -07001796 }
1797 // Clear any class not found or verification exceptions.
1798 soa.Self()->ClearException();
1799}
1800
1801void CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
Ian Rogers3d504072014-03-01 09:16:49 -08001802 ThreadPool* thread_pool, TimingLogger* timings) {
1803 timings->NewSplit("InitializeNoClinit");
Brian Carlstrom7940e442013-07-12 13:46:57 -07001804 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1805 ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, thread_pool);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001806 size_t thread_count;
1807 if (IsImage()) {
1808 // TODO: remove this when transactional mode supports multithreading.
1809 thread_count = 1U;
1810 } else {
1811 thread_count = thread_count_;
1812 }
1813 context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count);
1814 if (IsImage()) {
1815 // Prune garbage objects created during aborted transactions.
1816 Runtime::Current()->GetHeap()->CollectGarbage(true);
1817 }
Brian Carlstrom7940e442013-07-12 13:46:57 -07001818}
1819
1820void CompilerDriver::InitializeClasses(jobject class_loader,
1821 const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001822 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001823 for (size_t i = 0; i != dex_files.size(); ++i) {
1824 const DexFile* dex_file = dex_files[i];
1825 CHECK(dex_file != NULL);
1826 InitializeClasses(class_loader, *dex_file, thread_pool, timings);
1827 }
1828}
1829
1830void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08001831 ThreadPool* thread_pool, TimingLogger* timings) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001832 for (size_t i = 0; i != dex_files.size(); ++i) {
1833 const DexFile* dex_file = dex_files[i];
1834 CHECK(dex_file != NULL);
1835 CompileDexFile(class_loader, *dex_file, thread_pool, timings);
1836 }
1837}
1838
1839void CompilerDriver::CompileClass(const ParallelCompilationManager* manager, size_t class_def_index) {
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001840 ATRACE_CALL();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001841 jobject jclass_loader = manager->GetClassLoader();
1842 const DexFile& dex_file = *manager->GetDexFile();
1843 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
Ian Rogersbe7149f2013-08-20 09:29:39 -07001844 ClassLinker* class_linker = manager->GetClassLinker();
1845 if (SkipClass(class_linker, jclass_loader, dex_file, class_def)) {
1846 return;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001847 }
1848 ClassReference ref(&dex_file, class_def_index);
1849 // Skip compiling classes with generic verifier failures since they will still fail at runtime
Vladimir Markoc7f83202014-01-24 17:55:18 +00001850 if (manager->GetCompiler()->verification_results_->IsClassRejected(ref)) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001851 return;
1852 }
1853 const byte* class_data = dex_file.GetClassData(class_def);
1854 if (class_data == NULL) {
1855 // empty class, probably a marker interface
1856 return;
1857 }
Anwar Ghuloum67f99412013-08-12 14:19:48 -07001858
Brian Carlstrom7940e442013-07-12 13:46:57 -07001859 // Can we run DEX-to-DEX compiler on this class ?
Sebastien Hertz75021222013-07-16 18:34:50 +02001860 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
Brian Carlstrom7940e442013-07-12 13:46:57 -07001861 {
1862 ScopedObjectAccess soa(Thread::Current());
Mathieu Chartier590fee92013-09-13 13:46:47 -07001863 SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
1864 soa.Decode<mirror::ClassLoader*>(jclass_loader));
Ian Rogers98379392014-02-24 16:53:16 -08001865 dex_to_dex_compilation_level = GetDexToDexCompilationlevel(soa.Self(), class_loader, dex_file,
1866 class_def);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001867 }
1868 ClassDataItemIterator it(dex_file, class_data);
1869 // Skip fields
1870 while (it.HasNextStaticField()) {
1871 it.Next();
1872 }
1873 while (it.HasNextInstanceField()) {
1874 it.Next();
1875 }
Ian Rogersbe7149f2013-08-20 09:29:39 -07001876 CompilerDriver* driver = manager->GetCompiler();
Brian Carlstrom7940e442013-07-12 13:46:57 -07001877 // Compile direct methods
1878 int64_t previous_direct_method_idx = -1;
1879 while (it.HasNextDirectMethod()) {
1880 uint32_t method_idx = it.GetMemberIndex();
1881 if (method_idx == previous_direct_method_idx) {
1882 // smali can create dex files with two encoded_methods sharing the same method_idx
1883 // http://code.google.com/p/smali/issues/detail?id=119
1884 it.Next();
1885 continue;
1886 }
1887 previous_direct_method_idx = method_idx;
Ian Rogersbe7149f2013-08-20 09:29:39 -07001888 driver->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1889 it.GetMethodInvokeType(class_def), class_def_index,
1890 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001891 it.Next();
1892 }
1893 // Compile virtual methods
1894 int64_t previous_virtual_method_idx = -1;
1895 while (it.HasNextVirtualMethod()) {
1896 uint32_t method_idx = it.GetMemberIndex();
1897 if (method_idx == previous_virtual_method_idx) {
1898 // smali can create dex files with two encoded_methods sharing the same method_idx
1899 // http://code.google.com/p/smali/issues/detail?id=119
1900 it.Next();
1901 continue;
1902 }
1903 previous_virtual_method_idx = method_idx;
Ian Rogersbe7149f2013-08-20 09:29:39 -07001904 driver->CompileMethod(it.GetMethodCodeItem(), it.GetMemberAccessFlags(),
1905 it.GetMethodInvokeType(class_def), class_def_index,
1906 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001907 it.Next();
1908 }
1909 DCHECK(!it.HasNext());
1910}
1911
1912void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
Ian Rogers3d504072014-03-01 09:16:49 -08001913 ThreadPool* thread_pool, TimingLogger* timings) {
1914 timings->NewSplit("Compile Dex File");
Ian Rogersbe7149f2013-08-20 09:29:39 -07001915 ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,
1916 &dex_file, thread_pool);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001917 context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001918}
1919
1920void CompilerDriver::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07001921 InvokeType invoke_type, uint16_t class_def_idx,
Brian Carlstrom7940e442013-07-12 13:46:57 -07001922 uint32_t method_idx, jobject class_loader,
1923 const DexFile& dex_file,
Sebastien Hertz75021222013-07-16 18:34:50 +02001924 DexToDexCompilationLevel dex_to_dex_compilation_level) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001925 CompiledMethod* compiled_method = NULL;
1926 uint64_t start_ns = NanoTime();
1927
1928 if ((access_flags & kAccNative) != 0) {
Andreas Gampe2da88232014-02-27 12:26:20 -08001929#if defined(__x86_64__)
1930 // leaving this empty will trigger the generic JNI version
1931#else
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00001932 compiled_method = compiler_backend_->JniCompile(*this, access_flags, method_idx, dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001933 CHECK(compiled_method != NULL);
Andreas Gampe2da88232014-02-27 12:26:20 -08001934#endif
Brian Carlstrom7940e442013-07-12 13:46:57 -07001935 } else if ((access_flags & kAccAbstract) != 0) {
1936 } else {
Dragos Sbirlea90af14d2013-08-15 17:50:16 -07001937 MethodReference method_ref(&dex_file, method_idx);
Brian Carlstrom6449c622014-02-10 23:48:36 -08001938 bool compile = verification_results_->IsCandidateForCompilation(method_ref, access_flags);
Dragos Sbirleabd136a22013-08-13 18:07:04 -07001939
Sebastien Hertz4d4adb12013-07-24 16:14:19 +02001940 if (compile) {
buzbeea024a062013-07-31 10:47:37 -07001941 // NOTE: if compiler declines to compile this method, it will return NULL.
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00001942 compiled_method = compiler_backend_->Compile(
1943 *this, code_item, access_flags, invoke_type, class_def_idx,
1944 method_idx, class_loader, dex_file);
Sebastien Hertz75021222013-07-16 18:34:50 +02001945 } else if (dex_to_dex_compilation_level != kDontDexToDexCompile) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001946 // TODO: add a mode to disable DEX-to-DEX compilation ?
Sebastien Hertz75021222013-07-16 18:34:50 +02001947 (*dex_to_dex_compiler_)(*this, code_item, access_flags,
1948 invoke_type, class_def_idx,
1949 method_idx, class_loader, dex_file,
1950 dex_to_dex_compilation_level);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001951 }
1952 }
1953 uint64_t duration_ns = NanoTime() - start_ns;
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00001954 if (duration_ns > MsToNs(compiler_backend_->GetMaximumCompilationTimeBeforeWarning())) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07001955 LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
1956 << " took " << PrettyDuration(duration_ns);
1957 }
1958
1959 Thread* self = Thread::Current();
1960 if (compiled_method != NULL) {
1961 MethodReference ref(&dex_file, method_idx);
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001962 DCHECK(GetCompiledMethod(ref) == NULL) << PrettyMethod(method_idx, dex_file);
Brian Carlstrom7940e442013-07-12 13:46:57 -07001963 {
1964 MutexLock mu(self, compiled_methods_lock_);
1965 compiled_methods_.Put(ref, compiled_method);
1966 }
1967 DCHECK(GetCompiledMethod(ref) != NULL) << PrettyMethod(method_idx, dex_file);
1968 }
1969
1970 if (self->IsExceptionPending()) {
1971 ScopedObjectAccess soa(self);
1972 LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
1973 << self->GetException(NULL)->Dump();
1974 }
1975}
1976
1977CompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const {
1978 MutexLock mu(Thread::Current(), compiled_classes_lock_);
1979 ClassTable::const_iterator it = compiled_classes_.find(ref);
1980 if (it == compiled_classes_.end()) {
1981 return NULL;
1982 }
1983 CHECK(it->second != NULL);
1984 return it->second;
1985}
1986
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07001987void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
1988 MutexLock mu(Thread::Current(), compiled_classes_lock_);
1989 auto it = compiled_classes_.find(ref);
1990 if (it == compiled_classes_.end() || it->second->GetStatus() != status) {
1991 // An entry doesn't exist or the status is lower than the new status.
1992 if (it != compiled_classes_.end()) {
1993 CHECK_GT(status, it->second->GetStatus());
1994 delete it->second;
1995 }
1996 switch (status) {
1997 case mirror::Class::kStatusNotReady:
1998 case mirror::Class::kStatusError:
1999 case mirror::Class::kStatusRetryVerificationAtRuntime:
2000 case mirror::Class::kStatusVerified:
2001 case mirror::Class::kStatusInitialized:
2002 break; // Expected states.
2003 default:
2004 LOG(FATAL) << "Unexpected class status for class "
2005 << PrettyDescriptor(ref.first->GetClassDescriptor(ref.first->GetClassDef(ref.second)))
2006 << " of " << status;
2007 }
2008 CompiledClass* compiled_class = new CompiledClass(status);
2009 compiled_classes_.Overwrite(ref, compiled_class);
2010 }
2011}
2012
Brian Carlstrom7940e442013-07-12 13:46:57 -07002013CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const {
2014 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2015 MethodTable::const_iterator it = compiled_methods_.find(ref);
2016 if (it == compiled_methods_.end()) {
2017 return NULL;
2018 }
2019 CHECK(it->second != NULL);
2020 return it->second;
2021}
2022
Brian Carlstrom7940e442013-07-12 13:46:57 -07002023void CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002024 uint16_t class_def_index) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002025 WriterMutexLock mu(self, freezing_constructor_lock_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002026 freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
2027}
2028
2029bool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
Ian Rogers8b2c0b92013-09-19 02:56:49 -07002030 uint16_t class_def_index) {
Ian Rogers8f3c9ae2013-08-20 17:26:41 -07002031 ReaderMutexLock mu(self, freezing_constructor_lock_);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002032 return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
2033}
2034
2035bool CompilerDriver::WriteElf(const std::string& android_root,
2036 bool is_host,
2037 const std::vector<const art::DexFile*>& dex_files,
Ian Rogers3d504072014-03-01 09:16:49 -08002038 OatWriter* oat_writer,
Brian Carlstrom7940e442013-07-12 13:46:57 -07002039 art::File* file)
2040 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Nicolas Geoffrayf5df8972014-02-14 18:37:08 +00002041 return compiler_backend_->WriteElf(file, oat_writer, dex_files, android_root, is_host, *this);
Brian Carlstrom7940e442013-07-12 13:46:57 -07002042}
2043void CompilerDriver::InstructionSetToLLVMTarget(InstructionSet instruction_set,
Ian Rogers3d504072014-03-01 09:16:49 -08002044 std::string* target_triple,
2045 std::string* target_cpu,
2046 std::string* target_attr) {
Brian Carlstrom7940e442013-07-12 13:46:57 -07002047 switch (instruction_set) {
2048 case kThumb2:
Ian Rogers3d504072014-03-01 09:16:49 -08002049 *target_triple = "thumb-none-linux-gnueabi";
2050 *target_cpu = "cortex-a9";
2051 *target_attr = "+thumb2,+neon,+neonfp,+vfp3,+db";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002052 break;
2053
2054 case kArm:
Ian Rogers3d504072014-03-01 09:16:49 -08002055 *target_triple = "armv7-none-linux-gnueabi";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002056 // TODO: Fix for Nexus S.
Ian Rogers3d504072014-03-01 09:16:49 -08002057 *target_cpu = "cortex-a9";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002058 // TODO: Fix for Xoom.
Ian Rogers3d504072014-03-01 09:16:49 -08002059 *target_attr = "+v7,+neon,+neonfp,+vfp3,+db";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002060 break;
2061
2062 case kX86:
Ian Rogers3d504072014-03-01 09:16:49 -08002063 *target_triple = "i386-pc-linux-gnu";
2064 *target_attr = "";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002065 break;
2066
2067 case kMips:
Ian Rogers3d504072014-03-01 09:16:49 -08002068 *target_triple = "mipsel-unknown-linux";
2069 *target_attr = "mips32r2";
Brian Carlstrom7940e442013-07-12 13:46:57 -07002070 break;
2071
2072 default:
2073 LOG(FATAL) << "Unknown instruction set: " << instruction_set;
2074 }
2075 }
2076} // namespace art