1 /*
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
19 #define ATRACE_TAG ATRACE_TAG_DALVIK
20 #include <utils/Trace.h>
21
22 #include <unordered_set>
23 #include <vector>
24 #include <unistd.h>
25
26 #ifndef __APPLE__
27 #include <malloc.h> // For mallinfo
28 #endif
29
30 #include "art_field-inl.h"
31 #include "art_method-inl.h"
32 #include "base/stl_util.h"
33 #include "base/time_utils.h"
34 #include "base/timing_logger.h"
35 #include "class_linker-inl.h"
36 #include "compiled_class.h"
37 #include "compiled_method.h"
38 #include "compiler.h"
39 #include "compiler_driver-inl.h"
40 #include "dex_compilation_unit.h"
41 #include "dex_file-inl.h"
42 #include "dex/verification_results.h"
43 #include "dex/verified_method.h"
44 #include "dex/quick/dex_file_method_inliner.h"
45 #include "dex/quick/dex_file_to_method_inliner_map.h"
46 #include "driver/compiler_options.h"
47 #include "elf_writer_quick.h"
48 #include "jni_internal.h"
49 #include "object_lock.h"
50 #include "profiler.h"
51 #include "runtime.h"
52 #include "gc/accounting/card_table-inl.h"
53 #include "gc/accounting/heap_bitmap.h"
54 #include "gc/space/image_space.h"
55 #include "gc/space/space.h"
56 #include "mirror/class_loader.h"
57 #include "mirror/class-inl.h"
58 #include "mirror/dex_cache-inl.h"
59 #include "mirror/object-inl.h"
60 #include "mirror/object_array-inl.h"
61 #include "mirror/throwable.h"
62 #include "scoped_thread_state_change.h"
63 #include "ScopedLocalRef.h"
64 #include "handle_scope-inl.h"
65 #include "thread.h"
66 #include "thread_list.h"
67 #include "thread_pool.h"
68 #include "trampolines/trampoline_compiler.h"
69 #include "transaction.h"
70 #include "utils/dex_cache_arrays_layout-inl.h"
71 #include "utils/swap_space.h"
72 #include "verifier/method_verifier.h"
73 #include "verifier/method_verifier-inl.h"
74
75 namespace art {
76
77 static constexpr bool kTimeCompileMethod = !kIsDebugBuild;
78
79 // Whether to produce 64-bit ELF files for 64-bit targets.
80 static constexpr bool kProduce64BitELFFiles = true;
81
82 // Whether classes-to-compile and methods-to-compile are only applied to the boot image, or, when
83 // given, too all compilations.
84 static constexpr bool kRestrictCompilationFiltersToImage = true;
85
Percentage(size_t x,size_t y)86 static double Percentage(size_t x, size_t y) {
87 return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y));
88 }
89
DumpStat(size_t x,size_t y,const char * str)90 static void DumpStat(size_t x, size_t y, const char* str) {
91 if (x == 0 && y == 0) {
92 return;
93 }
94 LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases";
95 }
96
97 class CompilerDriver::AOTCompilationStats {
98 public:
AOTCompilationStats()99 AOTCompilationStats()
100 : stats_lock_("AOT compilation statistics lock"),
101 types_in_dex_cache_(0), types_not_in_dex_cache_(0),
102 strings_in_dex_cache_(0), strings_not_in_dex_cache_(0),
103 resolved_types_(0), unresolved_types_(0),
104 resolved_instance_fields_(0), unresolved_instance_fields_(0),
105 resolved_local_static_fields_(0), resolved_static_fields_(0), unresolved_static_fields_(0),
106 type_based_devirtualization_(0),
107 safe_casts_(0), not_safe_casts_(0) {
108 for (size_t i = 0; i <= kMaxInvokeType; i++) {
109 resolved_methods_[i] = 0;
110 unresolved_methods_[i] = 0;
111 virtual_made_direct_[i] = 0;
112 direct_calls_to_boot_[i] = 0;
113 direct_methods_to_boot_[i] = 0;
114 }
115 }
116
Dump()117 void Dump() {
118 DumpStat(types_in_dex_cache_, types_not_in_dex_cache_, "types known to be in dex cache");
119 DumpStat(strings_in_dex_cache_, strings_not_in_dex_cache_, "strings known to be in dex cache");
120 DumpStat(resolved_types_, unresolved_types_, "types resolved");
121 DumpStat(resolved_instance_fields_, unresolved_instance_fields_, "instance fields resolved");
122 DumpStat(resolved_local_static_fields_ + resolved_static_fields_, unresolved_static_fields_,
123 "static fields resolved");
124 DumpStat(resolved_local_static_fields_, resolved_static_fields_ + unresolved_static_fields_,
125 "static fields local to a class");
126 DumpStat(safe_casts_, not_safe_casts_, "check-casts removed based on type information");
127 // Note, the code below subtracts the stat value so that when added to the stat value we have
128 // 100% of samples. TODO: clean this up.
129 DumpStat(type_based_devirtualization_,
130 resolved_methods_[kVirtual] + unresolved_methods_[kVirtual] +
131 resolved_methods_[kInterface] + unresolved_methods_[kInterface] -
132 type_based_devirtualization_,
133 "virtual/interface calls made direct based on type information");
134
135 for (size_t i = 0; i <= kMaxInvokeType; i++) {
136 std::ostringstream oss;
137 oss << static_cast<InvokeType>(i) << " methods were AOT resolved";
138 DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
139 if (virtual_made_direct_[i] > 0) {
140 std::ostringstream oss2;
141 oss2 << static_cast<InvokeType>(i) << " methods made direct";
142 DumpStat(virtual_made_direct_[i],
143 resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i],
144 oss2.str().c_str());
145 }
146 if (direct_calls_to_boot_[i] > 0) {
147 std::ostringstream oss2;
148 oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot";
149 DumpStat(direct_calls_to_boot_[i],
150 resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i],
151 oss2.str().c_str());
152 }
153 if (direct_methods_to_boot_[i] > 0) {
154 std::ostringstream oss2;
155 oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot";
156 DumpStat(direct_methods_to_boot_[i],
157 resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i],
158 oss2.str().c_str());
159 }
160 }
161 }
162
163 // Allow lossy statistics in non-debug builds.
164 #ifndef NDEBUG
165 #define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_)
166 #else
167 #define STATS_LOCK()
168 #endif
169
TypeInDexCache()170 void TypeInDexCache() {
171 STATS_LOCK();
172 types_in_dex_cache_++;
173 }
174
TypeNotInDexCache()175 void TypeNotInDexCache() {
176 STATS_LOCK();
177 types_not_in_dex_cache_++;
178 }
179
StringInDexCache()180 void StringInDexCache() {
181 STATS_LOCK();
182 strings_in_dex_cache_++;
183 }
184
StringNotInDexCache()185 void StringNotInDexCache() {
186 STATS_LOCK();
187 strings_not_in_dex_cache_++;
188 }
189
TypeDoesntNeedAccessCheck()190 void TypeDoesntNeedAccessCheck() {
191 STATS_LOCK();
192 resolved_types_++;
193 }
194
TypeNeedsAccessCheck()195 void TypeNeedsAccessCheck() {
196 STATS_LOCK();
197 unresolved_types_++;
198 }
199
ResolvedInstanceField()200 void ResolvedInstanceField() {
201 STATS_LOCK();
202 resolved_instance_fields_++;
203 }
204
UnresolvedInstanceField()205 void UnresolvedInstanceField() {
206 STATS_LOCK();
207 unresolved_instance_fields_++;
208 }
209
ResolvedLocalStaticField()210 void ResolvedLocalStaticField() {
211 STATS_LOCK();
212 resolved_local_static_fields_++;
213 }
214
ResolvedStaticField()215 void ResolvedStaticField() {
216 STATS_LOCK();
217 resolved_static_fields_++;
218 }
219
UnresolvedStaticField()220 void UnresolvedStaticField() {
221 STATS_LOCK();
222 unresolved_static_fields_++;
223 }
224
225 // Indicate that type information from the verifier led to devirtualization.
PreciseTypeDevirtualization()226 void PreciseTypeDevirtualization() {
227 STATS_LOCK();
228 type_based_devirtualization_++;
229 }
230
231 // Indicate that a method of the given type was resolved at compile time.
ResolvedMethod(InvokeType type)232 void ResolvedMethod(InvokeType type) {
233 DCHECK_LE(type, kMaxInvokeType);
234 STATS_LOCK();
235 resolved_methods_[type]++;
236 }
237
238 // Indicate that a method of the given type was unresolved at compile time as it was in an
239 // unknown dex file.
UnresolvedMethod(InvokeType type)240 void UnresolvedMethod(InvokeType type) {
241 DCHECK_LE(type, kMaxInvokeType);
242 STATS_LOCK();
243 unresolved_methods_[type]++;
244 }
245
246 // Indicate that a type of virtual method dispatch has been converted into a direct method
247 // dispatch.
VirtualMadeDirect(InvokeType type)248 void VirtualMadeDirect(InvokeType type) {
249 DCHECK(type == kVirtual || type == kInterface || type == kSuper);
250 STATS_LOCK();
251 virtual_made_direct_[type]++;
252 }
253
254 // Indicate that a method of the given type was able to call directly into boot.
DirectCallsToBoot(InvokeType type)255 void DirectCallsToBoot(InvokeType type) {
256 DCHECK_LE(type, kMaxInvokeType);
257 STATS_LOCK();
258 direct_calls_to_boot_[type]++;
259 }
260
261 // Indicate that a method of the given type was able to be resolved directly from boot.
DirectMethodsToBoot(InvokeType type)262 void DirectMethodsToBoot(InvokeType type) {
263 DCHECK_LE(type, kMaxInvokeType);
264 STATS_LOCK();
265 direct_methods_to_boot_[type]++;
266 }
267
ProcessedInvoke(InvokeType type,int flags)268 void ProcessedInvoke(InvokeType type, int flags) {
269 STATS_LOCK();
270 if (flags == 0) {
271 unresolved_methods_[type]++;
272 } else {
273 DCHECK_NE((flags & kFlagMethodResolved), 0);
274 resolved_methods_[type]++;
275 if ((flags & kFlagVirtualMadeDirect) != 0) {
276 virtual_made_direct_[type]++;
277 if ((flags & kFlagPreciseTypeDevirtualization) != 0) {
278 type_based_devirtualization_++;
279 }
280 } else {
281 DCHECK_EQ((flags & kFlagPreciseTypeDevirtualization), 0);
282 }
283 if ((flags & kFlagDirectCallToBoot) != 0) {
284 direct_calls_to_boot_[type]++;
285 }
286 if ((flags & kFlagDirectMethodToBoot) != 0) {
287 direct_methods_to_boot_[type]++;
288 }
289 }
290 }
291
292 // A check-cast could be eliminated due to verifier type analysis.
SafeCast()293 void SafeCast() {
294 STATS_LOCK();
295 safe_casts_++;
296 }
297
298 // A check-cast couldn't be eliminated due to verifier type analysis.
NotASafeCast()299 void NotASafeCast() {
300 STATS_LOCK();
301 not_safe_casts_++;
302 }
303
304 private:
305 Mutex stats_lock_;
306
307 size_t types_in_dex_cache_;
308 size_t types_not_in_dex_cache_;
309
310 size_t strings_in_dex_cache_;
311 size_t strings_not_in_dex_cache_;
312
313 size_t resolved_types_;
314 size_t unresolved_types_;
315
316 size_t resolved_instance_fields_;
317 size_t unresolved_instance_fields_;
318
319 size_t resolved_local_static_fields_;
320 size_t resolved_static_fields_;
321 size_t unresolved_static_fields_;
322 // Type based devirtualization for invoke interface and virtual.
323 size_t type_based_devirtualization_;
324
325 size_t resolved_methods_[kMaxInvokeType + 1];
326 size_t unresolved_methods_[kMaxInvokeType + 1];
327 size_t virtual_made_direct_[kMaxInvokeType + 1];
328 size_t direct_calls_to_boot_[kMaxInvokeType + 1];
329 size_t direct_methods_to_boot_[kMaxInvokeType + 1];
330
331 size_t safe_casts_;
332 size_t not_safe_casts_;
333
334 DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
335 };
336
337
338 extern "C" art::CompiledMethod* ArtCompileDEX(art::CompilerDriver& compiler,
339 const art::DexFile::CodeItem* code_item,
340 uint32_t access_flags,
341 art::InvokeType invoke_type,
342 uint16_t class_def_idx,
343 uint32_t method_idx,
344 jobject class_loader,
345 const art::DexFile& dex_file);
346
CompilerDriver(const CompilerOptions * compiler_options,VerificationResults * verification_results,DexFileToMethodInlinerMap * method_inliner_map,Compiler::Kind compiler_kind,InstructionSet instruction_set,const InstructionSetFeatures * instruction_set_features,bool image,std::unordered_set<std::string> * image_classes,std::unordered_set<std::string> * compiled_classes,std::unordered_set<std::string> * compiled_methods,size_t thread_count,bool dump_stats,bool dump_passes,const std::string & dump_cfg_file_name,CumulativeLogger * timer,int swap_fd,const std::string & profile_file)347 CompilerDriver::CompilerDriver(const CompilerOptions* compiler_options,
348 VerificationResults* verification_results,
349 DexFileToMethodInlinerMap* method_inliner_map,
350 Compiler::Kind compiler_kind,
351 InstructionSet instruction_set,
352 const InstructionSetFeatures* instruction_set_features,
353 bool image, std::unordered_set<std::string>* image_classes,
354 std::unordered_set<std::string>* compiled_classes,
355 std::unordered_set<std::string>* compiled_methods,
356 size_t thread_count, bool dump_stats, bool dump_passes,
357 const std::string& dump_cfg_file_name, CumulativeLogger* timer,
358 int swap_fd, const std::string& profile_file)
359 : swap_space_(swap_fd == -1 ? nullptr : new SwapSpace(swap_fd, 10 * MB)),
360 swap_space_allocator_(new SwapAllocator<void>(swap_space_.get())),
361 profile_present_(false), compiler_options_(compiler_options),
362 verification_results_(verification_results),
363 method_inliner_map_(method_inliner_map),
364 compiler_(Compiler::Create(this, compiler_kind)),
365 compiler_kind_(compiler_kind),
366 instruction_set_(instruction_set),
367 instruction_set_features_(instruction_set_features),
368 freezing_constructor_lock_("freezing constructor lock"),
369 compiled_classes_lock_("compiled classes lock"),
370 compiled_methods_lock_("compiled method lock"),
371 compiled_methods_(MethodTable::key_compare()),
372 non_relative_linker_patch_count_(0u),
373 image_(image),
374 image_classes_(image_classes),
375 classes_to_compile_(compiled_classes),
376 methods_to_compile_(compiled_methods),
377 had_hard_verifier_failure_(false),
378 thread_count_(thread_count),
379 stats_(new AOTCompilationStats),
380 dedupe_enabled_(true),
381 dump_stats_(dump_stats),
382 dump_passes_(dump_passes),
383 dump_cfg_file_name_(dump_cfg_file_name),
384 timings_logger_(timer),
385 compiler_context_(nullptr),
386 support_boot_image_fixup_(instruction_set != kMips && instruction_set != kMips64),
387 dedupe_code_("dedupe code", *swap_space_allocator_),
388 dedupe_src_mapping_table_("dedupe source mapping table", *swap_space_allocator_),
389 dedupe_mapping_table_("dedupe mapping table", *swap_space_allocator_),
390 dedupe_vmap_table_("dedupe vmap table", *swap_space_allocator_),
391 dedupe_gc_map_("dedupe gc map", *swap_space_allocator_),
392 dedupe_cfi_info_("dedupe cfi info", *swap_space_allocator_) {
393 DCHECK(compiler_options_ != nullptr);
394 DCHECK(verification_results_ != nullptr);
395 DCHECK(method_inliner_map_ != nullptr);
396
397 dex_to_dex_compiler_ = reinterpret_cast<DexToDexCompilerFn>(ArtCompileDEX);
398
399 compiler_->Init();
400
401 CHECK_EQ(image_, image_classes_.get() != nullptr);
402
403 // Read the profile file if one is provided.
404 if (!profile_file.empty()) {
405 profile_present_ = profile_file_.LoadFile(profile_file);
406 if (profile_present_) {
407 LOG(INFO) << "Using profile data form file " << profile_file;
408 } else {
409 LOG(INFO) << "Failed to load profile file " << profile_file;
410 }
411 }
412 }
413
DeduplicateCode(const ArrayRef<const uint8_t> & code)414 SwapVector<uint8_t>* CompilerDriver::DeduplicateCode(const ArrayRef<const uint8_t>& code) {
415 DCHECK(dedupe_enabled_);
416 return dedupe_code_.Add(Thread::Current(), code);
417 }
418
DeduplicateSrcMappingTable(const ArrayRef<SrcMapElem> & src_map)419 SwapSrcMap* CompilerDriver::DeduplicateSrcMappingTable(const ArrayRef<SrcMapElem>& src_map) {
420 DCHECK(dedupe_enabled_);
421 return dedupe_src_mapping_table_.Add(Thread::Current(), src_map);
422 }
423
DeduplicateMappingTable(const ArrayRef<const uint8_t> & code)424 SwapVector<uint8_t>* CompilerDriver::DeduplicateMappingTable(const ArrayRef<const uint8_t>& code) {
425 DCHECK(dedupe_enabled_);
426 return dedupe_mapping_table_.Add(Thread::Current(), code);
427 }
428
DeduplicateVMapTable(const ArrayRef<const uint8_t> & code)429 SwapVector<uint8_t>* CompilerDriver::DeduplicateVMapTable(const ArrayRef<const uint8_t>& code) {
430 DCHECK(dedupe_enabled_);
431 return dedupe_vmap_table_.Add(Thread::Current(), code);
432 }
433
DeduplicateGCMap(const ArrayRef<const uint8_t> & code)434 SwapVector<uint8_t>* CompilerDriver::DeduplicateGCMap(const ArrayRef<const uint8_t>& code) {
435 DCHECK(dedupe_enabled_);
436 return dedupe_gc_map_.Add(Thread::Current(), code);
437 }
438
DeduplicateCFIInfo(const ArrayRef<const uint8_t> & cfi_info)439 SwapVector<uint8_t>* CompilerDriver::DeduplicateCFIInfo(const ArrayRef<const uint8_t>& cfi_info) {
440 DCHECK(dedupe_enabled_);
441 return dedupe_cfi_info_.Add(Thread::Current(), cfi_info);
442 }
443
~CompilerDriver()444 CompilerDriver::~CompilerDriver() {
445 Thread* self = Thread::Current();
446 {
447 MutexLock mu(self, compiled_classes_lock_);
448 STLDeleteValues(&compiled_classes_);
449 }
450 {
451 MutexLock mu(self, compiled_methods_lock_);
452 for (auto& pair : compiled_methods_) {
453 CompiledMethod::ReleaseSwapAllocatedCompiledMethod(this, pair.second);
454 }
455 }
456 compiler_->UnInit();
457 }
458
459 #define CREATE_TRAMPOLINE(type, abi, offset) \
460 if (Is64BitInstructionSet(instruction_set_)) { \
461 return CreateTrampoline64(instruction_set_, abi, \
462 type ## _ENTRYPOINT_OFFSET(8, offset)); \
463 } else { \
464 return CreateTrampoline32(instruction_set_, abi, \
465 type ## _ENTRYPOINT_OFFSET(4, offset)); \
466 }
467
CreateInterpreterToInterpreterBridge() const468 const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToInterpreterBridge() const {
469 CREATE_TRAMPOLINE(INTERPRETER, kInterpreterAbi, pInterpreterToInterpreterBridge)
470 }
471
CreateInterpreterToCompiledCodeBridge() const472 const std::vector<uint8_t>* CompilerDriver::CreateInterpreterToCompiledCodeBridge() const {
473 CREATE_TRAMPOLINE(INTERPRETER, kInterpreterAbi, pInterpreterToCompiledCodeBridge)
474 }
475
CreateJniDlsymLookup() const476 const std::vector<uint8_t>* CompilerDriver::CreateJniDlsymLookup() const {
477 CREATE_TRAMPOLINE(JNI, kJniAbi, pDlsymLookup)
478 }
479
CreateQuickGenericJniTrampoline() const480 const std::vector<uint8_t>* CompilerDriver::CreateQuickGenericJniTrampoline() const {
481 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickGenericJniTrampoline)
482 }
483
CreateQuickImtConflictTrampoline() const484 const std::vector<uint8_t>* CompilerDriver::CreateQuickImtConflictTrampoline() const {
485 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickImtConflictTrampoline)
486 }
487
CreateQuickResolutionTrampoline() const488 const std::vector<uint8_t>* CompilerDriver::CreateQuickResolutionTrampoline() const {
489 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickResolutionTrampoline)
490 }
491
CreateQuickToInterpreterBridge() const492 const std::vector<uint8_t>* CompilerDriver::CreateQuickToInterpreterBridge() const {
493 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickToInterpreterBridge)
494 }
495 #undef CREATE_TRAMPOLINE
496
CompileAll(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)497 void CompilerDriver::CompileAll(jobject class_loader,
498 const std::vector<const DexFile*>& dex_files,
499 TimingLogger* timings) {
500 DCHECK(!Runtime::Current()->IsStarted());
501 std::unique_ptr<ThreadPool> thread_pool(
502 new ThreadPool("Compiler driver thread pool", thread_count_ - 1));
503 VLOG(compiler) << "Before precompile " << GetMemoryUsageString(false);
504 PreCompile(class_loader, dex_files, thread_pool.get(), timings);
505 Compile(class_loader, dex_files, thread_pool.get(), timings);
506 if (dump_stats_) {
507 stats_->Dump();
508 }
509 }
510
GetDexToDexCompilationlevel(Thread * self,Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,const DexFile::ClassDef & class_def)511 DexToDexCompilationLevel CompilerDriver::GetDexToDexCompilationlevel(
512 Thread* self, Handle<mirror::ClassLoader> class_loader, const DexFile& dex_file,
513 const DexFile::ClassDef& class_def) {
514 auto* const runtime = Runtime::Current();
515 if (runtime->UseJit() || GetCompilerOptions().VerifyAtRuntime()) {
516 // Verify at runtime shouldn't dex to dex since we didn't resolve of verify.
517 return kDontDexToDexCompile;
518 }
519 const char* descriptor = dex_file.GetClassDescriptor(class_def);
520 ClassLinker* class_linker = runtime->GetClassLinker();
521 mirror::Class* klass = class_linker->FindClass(self, descriptor, class_loader);
522 if (klass == nullptr) {
523 CHECK(self->IsExceptionPending());
524 self->ClearException();
525 return kDontDexToDexCompile;
526 }
527 // DexToDex at the kOptimize level may introduce quickened opcodes, which replace symbolic
528 // references with actual offsets. We cannot re-verify such instructions.
529 //
530 // We store the verification information in the class status in the oat file, which the linker
531 // can validate (checksums) and use to skip load-time verification. It is thus safe to
532 // optimize when a class has been fully verified before.
533 if (klass->IsVerified()) {
534 // Class is verified so we can enable DEX-to-DEX compilation for performance.
535 return kOptimize;
536 } else if (klass->IsCompileTimeVerified()) {
537 // Class verification has soft-failed. Anyway, ensure at least correctness.
538 DCHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime);
539 return kRequired;
540 } else {
541 // Class verification has failed: do not run DEX-to-DEX compilation.
542 return kDontDexToDexCompile;
543 }
544 }
545
CompileOne(Thread * self,ArtMethod * method,TimingLogger * timings)546 void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings) {
547 DCHECK(!Runtime::Current()->IsStarted());
548 jobject jclass_loader;
549 const DexFile* dex_file;
550 uint16_t class_def_idx;
551 uint32_t method_idx = method->GetDexMethodIndex();
552 uint32_t access_flags = method->GetAccessFlags();
553 InvokeType invoke_type = method->GetInvokeType();
554 {
555 ScopedObjectAccessUnchecked soa(self);
556 ScopedLocalRef<jobject> local_class_loader(
557 soa.Env(), soa.AddLocalReference<jobject>(method->GetDeclaringClass()->GetClassLoader()));
558 jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
559 // Find the dex_file
560 dex_file = method->GetDexFile();
561 class_def_idx = method->GetClassDefIndex();
562 }
563 const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
564 self->TransitionFromRunnableToSuspended(kNative);
565
566 std::vector<const DexFile*> dex_files;
567 dex_files.push_back(dex_file);
568
569 std::unique_ptr<ThreadPool> thread_pool(new ThreadPool("Compiler driver thread pool", 0U));
570 PreCompile(jclass_loader, dex_files, thread_pool.get(), timings);
571
572 // Can we run DEX-to-DEX compiler on this class ?
573 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
574 {
575 ScopedObjectAccess soa(self);
576 const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
577 StackHandleScope<1> hs(soa.Self());
578 Handle<mirror::ClassLoader> class_loader(
579 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
580 dex_to_dex_compilation_level = GetDexToDexCompilationlevel(self, class_loader, *dex_file,
581 class_def);
582 }
583 CompileMethod(self, code_item, access_flags, invoke_type, class_def_idx, method_idx,
584 jclass_loader, *dex_file, dex_to_dex_compilation_level, true);
585
586 self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
587 self->TransitionFromSuspendedToRunnable();
588 }
589
CompileMethod(Thread * self,ArtMethod * method)590 CompiledMethod* CompilerDriver::CompileMethod(Thread* self, ArtMethod* method) {
591 const uint32_t method_idx = method->GetDexMethodIndex();
592 const uint32_t access_flags = method->GetAccessFlags();
593 const InvokeType invoke_type = method->GetInvokeType();
594 StackHandleScope<1> hs(self);
595 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
596 method->GetDeclaringClass()->GetClassLoader()));
597 jobject jclass_loader = class_loader.ToJObject();
598 const DexFile* dex_file = method->GetDexFile();
599 const uint16_t class_def_idx = method->GetClassDefIndex();
600 const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
601 DexToDexCompilationLevel dex_to_dex_compilation_level =
602 GetDexToDexCompilationlevel(self, class_loader, *dex_file, class_def);
603 const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
604 self->TransitionFromRunnableToSuspended(kNative);
605 CompileMethod(self, code_item, access_flags, invoke_type, class_def_idx, method_idx,
606 jclass_loader, *dex_file, dex_to_dex_compilation_level, true);
607 auto* compiled_method = GetCompiledMethod(MethodReference(dex_file, method_idx));
608 self->TransitionFromSuspendedToRunnable();
609 return compiled_method;
610 }
611
Resolve(jobject class_loader,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)612 void CompilerDriver::Resolve(jobject class_loader, const std::vector<const DexFile*>& dex_files,
613 ThreadPool* thread_pool, TimingLogger* timings) {
614 for (size_t i = 0; i != dex_files.size(); ++i) {
615 const DexFile* dex_file = dex_files[i];
616 CHECK(dex_file != nullptr);
617 ResolveDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
618 }
619 }
620
PreCompile(jobject class_loader,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)621 void CompilerDriver::PreCompile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
622 ThreadPool* thread_pool, TimingLogger* timings) {
623 LoadImageClasses(timings);
624 VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString(false);
625
626 const bool verification_enabled = compiler_options_->IsVerificationEnabled();
627 const bool never_verify = compiler_options_->NeverVerify();
628
629 // We need to resolve for never_verify since it needs to run dex to dex to add the
630 // RETURN_VOID_NO_BARRIER.
631 if (never_verify || verification_enabled) {
632 Resolve(class_loader, dex_files, thread_pool, timings);
633 VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
634 }
635
636 if (never_verify) {
637 VLOG(compiler) << "Verify none mode specified, skipping verification.";
638 SetVerified(class_loader, dex_files, thread_pool, timings);
639 }
640
641 if (!verification_enabled) {
642 return;
643 }
644
645 Verify(class_loader, dex_files, thread_pool, timings);
646 VLOG(compiler) << "Verify: " << GetMemoryUsageString(false);
647
648 if (had_hard_verifier_failure_ && GetCompilerOptions().AbortOnHardVerifierFailure()) {
649 LOG(FATAL) << "Had a hard failure verifying all classes, and was asked to abort in such "
650 << "situations. Please check the log.";
651 }
652
653 InitializeClasses(class_loader, dex_files, thread_pool, timings);
654 VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false);
655
656 UpdateImageClasses(timings);
657 VLOG(compiler) << "UpdateImageClasses: " << GetMemoryUsageString(false);
658 }
659
IsImageClass(const char * descriptor) const660 bool CompilerDriver::IsImageClass(const char* descriptor) const {
661 if (!IsImage()) {
662 // NOTE: Currently unreachable, all callers check IsImage().
663 return false;
664 } else {
665 return image_classes_->find(descriptor) != image_classes_->end();
666 }
667 }
668
IsClassToCompile(const char * descriptor) const669 bool CompilerDriver::IsClassToCompile(const char* descriptor) const {
670 if (kRestrictCompilationFiltersToImage && !IsImage()) {
671 return true;
672 }
673
674 if (classes_to_compile_ == nullptr) {
675 return true;
676 }
677 return classes_to_compile_->find(descriptor) != classes_to_compile_->end();
678 }
679
IsMethodToCompile(const MethodReference & method_ref) const680 bool CompilerDriver::IsMethodToCompile(const MethodReference& method_ref) const {
681 if (kRestrictCompilationFiltersToImage && !IsImage()) {
682 return true;
683 }
684
685 if (methods_to_compile_ == nullptr) {
686 return true;
687 }
688
689 std::string tmp = PrettyMethod(method_ref.dex_method_index, *method_ref.dex_file, true);
690 return methods_to_compile_->find(tmp.c_str()) != methods_to_compile_->end();
691 }
692
ResolveExceptionsForMethod(ArtMethod * method_handle,std::set<std::pair<uint16_t,const DexFile * >> & exceptions_to_resolve)693 static void ResolveExceptionsForMethod(
694 ArtMethod* method_handle, std::set<std::pair<uint16_t, const DexFile*>>& exceptions_to_resolve)
695 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
696 const DexFile::CodeItem* code_item = method_handle->GetCodeItem();
697 if (code_item == nullptr) {
698 return; // native or abstract method
699 }
700 if (code_item->tries_size_ == 0) {
701 return; // nothing to process
702 }
703 const uint8_t* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0);
704 size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list);
705 for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
706 int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list);
707 bool has_catch_all = false;
708 if (encoded_catch_handler_size <= 0) {
709 encoded_catch_handler_size = -encoded_catch_handler_size;
710 has_catch_all = true;
711 }
712 for (int32_t j = 0; j < encoded_catch_handler_size; j++) {
713 uint16_t encoded_catch_handler_handlers_type_idx =
714 DecodeUnsignedLeb128(&encoded_catch_handler_list);
715 // Add to set of types to resolve if not already in the dex cache resolved types
716 if (!method_handle->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
717 exceptions_to_resolve.insert(
718 std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx,
719 method_handle->GetDexFile()));
720 }
721 // ignore address associated with catch handler
722 DecodeUnsignedLeb128(&encoded_catch_handler_list);
723 }
724 if (has_catch_all) {
725 // ignore catch all address
726 DecodeUnsignedLeb128(&encoded_catch_handler_list);
727 }
728 }
729 }
730
ResolveCatchBlockExceptionsClassVisitor(mirror::Class * c,void * arg)731 static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
732 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
733 auto* exceptions_to_resolve =
734 reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*>>*>(arg);
735 const auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
736 for (auto& m : c->GetVirtualMethods(pointer_size)) {
737 ResolveExceptionsForMethod(&m, *exceptions_to_resolve);
738 }
739 for (auto& m : c->GetDirectMethods(pointer_size)) {
740 ResolveExceptionsForMethod(&m, *exceptions_to_resolve);
741 }
742 return true;
743 }
744
RecordImageClassesVisitor(mirror::Class * klass,void * arg)745 static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
746 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
747 std::unordered_set<std::string>* image_classes =
748 reinterpret_cast<std::unordered_set<std::string>*>(arg);
749 std::string temp;
750 image_classes->insert(klass->GetDescriptor(&temp));
751 return true;
752 }
753
754 // Make a list of descriptors for classes to include in the image
LoadImageClasses(TimingLogger * timings)755 void CompilerDriver::LoadImageClasses(TimingLogger* timings)
756 LOCKS_EXCLUDED(Locks::mutator_lock_) {
757 CHECK(timings != nullptr);
758 if (!IsImage()) {
759 return;
760 }
761
762 TimingLogger::ScopedTiming t("LoadImageClasses", timings);
763 // Make a first class to load all classes explicitly listed in the file
764 Thread* self = Thread::Current();
765 ScopedObjectAccess soa(self);
766 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
767 CHECK(image_classes_.get() != nullptr);
768 for (auto it = image_classes_->begin(), end = image_classes_->end(); it != end;) {
769 const std::string& descriptor(*it);
770 StackHandleScope<1> hs(self);
771 Handle<mirror::Class> klass(
772 hs.NewHandle(class_linker->FindSystemClass(self, descriptor.c_str())));
773 if (klass.Get() == nullptr) {
774 VLOG(compiler) << "Failed to find class " << descriptor;
775 image_classes_->erase(it++);
776 self->ClearException();
777 } else {
778 ++it;
779 }
780 }
781
782 // Resolve exception classes referenced by the loaded classes. The catch logic assumes
783 // exceptions are resolved by the verifier when there is a catch block in an interested method.
784 // Do this here so that exception classes appear to have been specified image classes.
785 std::set<std::pair<uint16_t, const DexFile*>> unresolved_exception_types;
786 StackHandleScope<1> hs(self);
787 Handle<mirror::Class> java_lang_Throwable(
788 hs.NewHandle(class_linker->FindSystemClass(self, "Ljava/lang/Throwable;")));
789 do {
790 unresolved_exception_types.clear();
791 class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor,
792 &unresolved_exception_types);
793 for (const std::pair<uint16_t, const DexFile*>& exception_type : unresolved_exception_types) {
794 uint16_t exception_type_idx = exception_type.first;
795 const DexFile* dex_file = exception_type.second;
796 StackHandleScope<2> hs2(self);
797 Handle<mirror::DexCache> dex_cache(hs2.NewHandle(class_linker->FindDexCache(*dex_file)));
798 Handle<mirror::Class> klass(hs2.NewHandle(
799 class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache,
800 NullHandle<mirror::ClassLoader>())));
801 if (klass.Get() == nullptr) {
802 const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
803 const char* descriptor = dex_file->GetTypeDescriptor(type_id);
804 LOG(FATAL) << "Failed to resolve class " << descriptor;
805 }
806 DCHECK(java_lang_Throwable->IsAssignableFrom(klass.Get()));
807 }
808 // Resolving exceptions may load classes that reference more exceptions, iterate until no
809 // more are found
810 } while (!unresolved_exception_types.empty());
811
812 // We walk the roots looking for classes so that we'll pick up the
813 // above classes plus any classes them depend on such super
814 // classes, interfaces, and the required ClassLinker roots.
815 class_linker->VisitClasses(RecordImageClassesVisitor, image_classes_.get());
816
817 CHECK_NE(image_classes_->size(), 0U);
818 }
819
MaybeAddToImageClasses(Handle<mirror::Class> c,std::unordered_set<std::string> * image_classes)820 static void MaybeAddToImageClasses(Handle<mirror::Class> c,
821 std::unordered_set<std::string>* image_classes)
822 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
823 Thread* self = Thread::Current();
824 StackHandleScope<1> hs(self);
825 // Make a copy of the handle so that we don't clobber it doing Assign.
826 MutableHandle<mirror::Class> klass(hs.NewHandle(c.Get()));
827 std::string temp;
828 const size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
829 while (!klass->IsObjectClass()) {
830 const char* descriptor = klass->GetDescriptor(&temp);
831 std::pair<std::unordered_set<std::string>::iterator, bool> result =
832 image_classes->insert(descriptor);
833 if (!result.second) { // Previously inserted.
834 break;
835 }
836 VLOG(compiler) << "Adding " << descriptor << " to image classes";
837 for (size_t i = 0; i < klass->NumDirectInterfaces(); ++i) {
838 StackHandleScope<1> hs2(self);
839 MaybeAddToImageClasses(hs2.NewHandle(mirror::Class::GetDirectInterface(self, klass, i)),
840 image_classes);
841 }
842 for (auto& m : c->GetVirtualMethods(pointer_size)) {
843 if (m.IsMiranda() || (true)) {
844 StackHandleScope<1> hs2(self);
845 MaybeAddToImageClasses(hs2.NewHandle(m.GetDeclaringClass()), image_classes);
846 }
847 }
848 if (klass->IsArrayClass()) {
849 StackHandleScope<1> hs2(self);
850 MaybeAddToImageClasses(hs2.NewHandle(klass->GetComponentType()), image_classes);
851 }
852 klass.Assign(klass->GetSuperClass());
853 }
854 }
855
856 // Keeps all the data for the update together. Also doubles as the reference visitor.
857 // Note: we can use object pointers because we suspend all threads.
858 class ClinitImageUpdate {
859 public:
Create(std::unordered_set<std::string> * image_class_descriptors,Thread * self,ClassLinker * linker,std::string * error_msg)860 static ClinitImageUpdate* Create(std::unordered_set<std::string>* image_class_descriptors,
861 Thread* self, ClassLinker* linker, std::string* error_msg) {
862 std::unique_ptr<ClinitImageUpdate> res(new ClinitImageUpdate(image_class_descriptors, self,
863 linker));
864 if (res->dex_cache_class_ == nullptr) {
865 *error_msg = "Could not find DexCache class.";
866 return nullptr;
867 }
868
869 return res.release();
870 }
871
~ClinitImageUpdate()872 ~ClinitImageUpdate() {
873 // Allow others to suspend again.
874 self_->EndAssertNoThreadSuspension(old_cause_);
875 }
876
877 // Visitor for VisitReferences.
operator ()(mirror::Object * object,MemberOffset field_offset,bool) const878 void operator()(mirror::Object* object, MemberOffset field_offset, bool /* is_static */) const
879 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
880 mirror::Object* ref = object->GetFieldObject<mirror::Object>(field_offset);
881 if (ref != nullptr) {
882 VisitClinitClassesObject(ref);
883 }
884 }
885
886 // java.lang.Reference visitor for VisitReferences.
operator ()(mirror::Class *,mirror::Reference *) const887 void operator()(mirror::Class* /* klass */, mirror::Reference* /* ref */) const {
888 }
889
Walk()890 void Walk() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
891 // Use the initial classes as roots for a search.
892 for (mirror::Class* klass_root : image_classes_) {
893 VisitClinitClassesObject(klass_root);
894 }
895 }
896
897 private:
ClinitImageUpdate(std::unordered_set<std::string> * image_class_descriptors,Thread * self,ClassLinker * linker)898 ClinitImageUpdate(std::unordered_set<std::string>* image_class_descriptors, Thread* self,
899 ClassLinker* linker)
900 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) :
901 image_class_descriptors_(image_class_descriptors), self_(self) {
902 CHECK(linker != nullptr);
903 CHECK(image_class_descriptors != nullptr);
904
905 // Make sure nobody interferes with us.
906 old_cause_ = self->StartAssertNoThreadSuspension("Boot image closure");
907
908 // Find the interesting classes.
909 dex_cache_class_ = linker->LookupClass(self, "Ljava/lang/DexCache;",
910 ComputeModifiedUtf8Hash("Ljava/lang/DexCache;"), nullptr);
911
912 // Find all the already-marked classes.
913 WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
914 linker->VisitClasses(FindImageClasses, this);
915 }
916
FindImageClasses(mirror::Class * klass,void * arg)917 static bool FindImageClasses(mirror::Class* klass, void* arg)
918 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
919 ClinitImageUpdate* data = reinterpret_cast<ClinitImageUpdate*>(arg);
920 std::string temp;
921 const char* name = klass->GetDescriptor(&temp);
922 if (data->image_class_descriptors_->find(name) != data->image_class_descriptors_->end()) {
923 data->image_classes_.push_back(klass);
924 } else {
925 // Check whether it is initialized and has a clinit. They must be kept, too.
926 if (klass->IsInitialized() && klass->FindClassInitializer(
927 Runtime::Current()->GetClassLinker()->GetImagePointerSize()) != nullptr) {
928 data->image_classes_.push_back(klass);
929 }
930 }
931
932 return true;
933 }
934
VisitClinitClassesObject(mirror::Object * object) const935 void VisitClinitClassesObject(mirror::Object* object) const
936 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
937 DCHECK(object != nullptr);
938 if (marked_objects_.find(object) != marked_objects_.end()) {
939 // Already processed.
940 return;
941 }
942
943 // Mark it.
944 marked_objects_.insert(object);
945
946 if (object->IsClass()) {
947 // If it is a class, add it.
948 StackHandleScope<1> hs(self_);
949 MaybeAddToImageClasses(hs.NewHandle(object->AsClass()), image_class_descriptors_);
950 } else {
951 // Else visit the object's class.
952 VisitClinitClassesObject(object->GetClass());
953 }
954
955 // If it is not a DexCache, visit all references.
956 mirror::Class* klass = object->GetClass();
957 if (klass != dex_cache_class_) {
958 object->VisitReferences<false /* visit class */>(*this, *this);
959 }
960 }
961
962 mutable std::unordered_set<mirror::Object*> marked_objects_;
963 std::unordered_set<std::string>* const image_class_descriptors_;
964 std::vector<mirror::Class*> image_classes_;
965 const mirror::Class* dex_cache_class_;
966 Thread* const self_;
967 const char* old_cause_;
968
969 DISALLOW_COPY_AND_ASSIGN(ClinitImageUpdate);
970 };
971
UpdateImageClasses(TimingLogger * timings)972 void CompilerDriver::UpdateImageClasses(TimingLogger* timings) {
973 if (IsImage()) {
974 TimingLogger::ScopedTiming t("UpdateImageClasses", timings);
975
976 Runtime* current = Runtime::Current();
977
978 // Suspend all threads.
979 current->GetThreadList()->SuspendAll(__FUNCTION__);
980
981 std::string error_msg;
982 std::unique_ptr<ClinitImageUpdate> update(ClinitImageUpdate::Create(image_classes_.get(),
983 Thread::Current(),
984 current->GetClassLinker(),
985 &error_msg));
986 CHECK(update.get() != nullptr) << error_msg; // TODO: Soft failure?
987
988 // Do the marking.
989 update->Walk();
990
991 // Resume threads.
992 current->GetThreadList()->ResumeAll();
993 }
994 }
995
CanAssumeClassIsLoaded(mirror::Class * klass)996 bool CompilerDriver::CanAssumeClassIsLoaded(mirror::Class* klass) {
997 Runtime* runtime = Runtime::Current();
998 if (!runtime->IsAotCompiler()) {
999 DCHECK(runtime->UseJit());
1000 // Having the klass reference here implies that the klass is already loaded.
1001 return true;
1002 }
1003 if (!IsImage()) {
1004 // Assume loaded only if klass is in the boot image. App classes cannot be assumed
1005 // loaded because we don't even know what class loader will be used to load them.
1006 bool class_in_image = runtime->GetHeap()->FindSpaceFromObject(klass, false)->IsImageSpace();
1007 return class_in_image;
1008 }
1009 std::string temp;
1010 const char* descriptor = klass->GetDescriptor(&temp);
1011 return IsImageClass(descriptor);
1012 }
1013
CanAssumeTypeIsPresentInDexCache(const DexFile & dex_file,uint32_t type_idx)1014 bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx) {
1015 if (IsImage() &&
1016 IsImageClass(dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_))) {
1017 {
1018 ScopedObjectAccess soa(Thread::Current());
1019 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
1020 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
1021 if (resolved_class == nullptr) {
1022 // Erroneous class.
1023 stats_->TypeNotInDexCache();
1024 return false;
1025 }
1026 }
1027 stats_->TypeInDexCache();
1028 return true;
1029 } else {
1030 stats_->TypeNotInDexCache();
1031 return false;
1032 }
1033 }
1034
CanAssumeStringIsPresentInDexCache(const DexFile & dex_file,uint32_t string_idx)1035 bool CompilerDriver::CanAssumeStringIsPresentInDexCache(const DexFile& dex_file,
1036 uint32_t string_idx) {
1037 // See also Compiler::ResolveDexFile
1038
1039 bool result = false;
1040 if (IsImage()) {
1041 // We resolve all const-string strings when building for the image.
1042 ScopedObjectAccess soa(Thread::Current());
1043 StackHandleScope<1> hs(soa.Self());
1044 Handle<mirror::DexCache> dex_cache(
1045 hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(dex_file)));
1046 Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache);
1047 result = true;
1048 }
1049 if (result) {
1050 stats_->StringInDexCache();
1051 } else {
1052 stats_->StringNotInDexCache();
1053 }
1054 return result;
1055 }
1056
CanAccessTypeWithoutChecks(uint32_t referrer_idx,const DexFile & dex_file,uint32_t type_idx,bool * type_known_final,bool * type_known_abstract,bool * equals_referrers_class)1057 bool CompilerDriver::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
1058 uint32_t type_idx,
1059 bool* type_known_final, bool* type_known_abstract,
1060 bool* equals_referrers_class) {
1061 if (type_known_final != nullptr) {
1062 *type_known_final = false;
1063 }
1064 if (type_known_abstract != nullptr) {
1065 *type_known_abstract = false;
1066 }
1067 if (equals_referrers_class != nullptr) {
1068 *equals_referrers_class = false;
1069 }
1070 ScopedObjectAccess soa(Thread::Current());
1071 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
1072 // Get type from dex cache assuming it was populated by the verifier
1073 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
1074 if (resolved_class == nullptr) {
1075 stats_->TypeNeedsAccessCheck();
1076 return false; // Unknown class needs access checks.
1077 }
1078 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
1079 if (equals_referrers_class != nullptr) {
1080 *equals_referrers_class = (method_id.class_idx_ == type_idx);
1081 }
1082 mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
1083 if (referrer_class == nullptr) {
1084 stats_->TypeNeedsAccessCheck();
1085 return false; // Incomplete referrer knowledge needs access check.
1086 }
1087 // Perform access check, will return true if access is ok or false if we're going to have to
1088 // check this at runtime (for example for class loaders).
1089 bool result = referrer_class->CanAccess(resolved_class);
1090 if (result) {
1091 stats_->TypeDoesntNeedAccessCheck();
1092 if (type_known_final != nullptr) {
1093 *type_known_final = resolved_class->IsFinal() && !resolved_class->IsArrayClass();
1094 }
1095 if (type_known_abstract != nullptr) {
1096 *type_known_abstract = resolved_class->IsAbstract() && !resolved_class->IsArrayClass();
1097 }
1098 } else {
1099 stats_->TypeNeedsAccessCheck();
1100 }
1101 return result;
1102 }
1103
CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,const DexFile & dex_file,uint32_t type_idx)1104 bool CompilerDriver::CanAccessInstantiableTypeWithoutChecks(uint32_t referrer_idx,
1105 const DexFile& dex_file,
1106 uint32_t type_idx) {
1107 ScopedObjectAccess soa(Thread::Current());
1108 mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
1109 // Get type from dex cache assuming it was populated by the verifier.
1110 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
1111 if (resolved_class == nullptr) {
1112 stats_->TypeNeedsAccessCheck();
1113 return false; // Unknown class needs access checks.
1114 }
1115 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
1116 mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
1117 if (referrer_class == nullptr) {
1118 stats_->TypeNeedsAccessCheck();
1119 return false; // Incomplete referrer knowledge needs access check.
1120 }
1121 // Perform access and instantiable checks, will return true if access is ok or false if we're
1122 // going to have to check this at runtime (for example for class loaders).
1123 bool result = referrer_class->CanAccess(resolved_class) && resolved_class->IsInstantiable();
1124 if (result) {
1125 stats_->TypeDoesntNeedAccessCheck();
1126 } else {
1127 stats_->TypeNeedsAccessCheck();
1128 }
1129 return result;
1130 }
1131
CanEmbedTypeInCode(const DexFile & dex_file,uint32_t type_idx,bool * is_type_initialized,bool * use_direct_type_ptr,uintptr_t * direct_type_ptr,bool * out_is_finalizable)1132 bool CompilerDriver::CanEmbedTypeInCode(const DexFile& dex_file, uint32_t type_idx,
1133 bool* is_type_initialized, bool* use_direct_type_ptr,
1134 uintptr_t* direct_type_ptr, bool* out_is_finalizable) {
1135 ScopedObjectAccess soa(Thread::Current());
1136 Runtime* runtime = Runtime::Current();
1137 mirror::DexCache* dex_cache = runtime->GetClassLinker()->FindDexCache(dex_file);
1138 mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
1139 if (resolved_class == nullptr) {
1140 return false;
1141 }
1142 if (GetCompilerOptions().GetCompilePic()) {
1143 // Do not allow a direct class pointer to be used when compiling for position-independent
1144 return false;
1145 }
1146 *out_is_finalizable = resolved_class->IsFinalizable();
1147 gc::Heap* heap = runtime->GetHeap();
1148 const bool compiling_boot = heap->IsCompilingBoot();
1149 const bool support_boot_image_fixup = GetSupportBootImageFixup();
1150 if (compiling_boot) {
1151 // boot -> boot class pointers.
1152 // True if the class is in the image at boot compiling time.
1153 const bool is_image_class = IsImage() && IsImageClass(
1154 dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_));
1155 // True if pc relative load works.
1156 if (is_image_class && support_boot_image_fixup) {
1157 *is_type_initialized = resolved_class->IsInitialized();
1158 *use_direct_type_ptr = false;
1159 *direct_type_ptr = 0;
1160 return true;
1161 } else {
1162 return false;
1163 }
1164 } else if (runtime->UseJit() && !heap->IsMovableObject(resolved_class)) {
1165 *is_type_initialized = resolved_class->IsInitialized();
1166 // If the class may move around, then don't embed it as a direct pointer.
1167 *use_direct_type_ptr = true;
1168 *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
1169 return true;
1170 } else {
1171 // True if the class is in the image at app compiling time.
1172 const bool class_in_image = heap->FindSpaceFromObject(resolved_class, false)->IsImageSpace();
1173 if (class_in_image && support_boot_image_fixup) {
1174 // boot -> app class pointers.
1175 *is_type_initialized = resolved_class->IsInitialized();
1176 // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
1177 *use_direct_type_ptr = !GetCompilerOptions().GetIncludePatchInformation();
1178 *direct_type_ptr = reinterpret_cast<uintptr_t>(resolved_class);
1179 return true;
1180 } else {
1181 // app -> app class pointers.
1182 // Give up because app does not have an image and class
1183 // isn't created at compile time. TODO: implement this
1184 // if/when each app gets an image.
1185 return false;
1186 }
1187 }
1188 }
1189
CanEmbedReferenceTypeInCode(ClassReference * ref,bool * use_direct_ptr,uintptr_t * direct_type_ptr)1190 bool CompilerDriver::CanEmbedReferenceTypeInCode(ClassReference* ref,
1191 bool* use_direct_ptr,
1192 uintptr_t* direct_type_ptr) {
1193 CHECK(ref != nullptr);
1194 CHECK(use_direct_ptr != nullptr);
1195 CHECK(direct_type_ptr != nullptr);
1196
1197 ScopedObjectAccess soa(Thread::Current());
1198 mirror::Class* reference_class = mirror::Reference::GetJavaLangRefReference();
1199 bool is_initialized = false;
1200 bool unused_finalizable;
1201 // Make sure we have a finished Reference class object before attempting to use it.
1202 if (!CanEmbedTypeInCode(*reference_class->GetDexCache()->GetDexFile(),
1203 reference_class->GetDexTypeIndex(), &is_initialized,
1204 use_direct_ptr, direct_type_ptr, &unused_finalizable) ||
1205 !is_initialized) {
1206 return false;
1207 }
1208 ref->first = &reference_class->GetDexFile();
1209 ref->second = reference_class->GetDexClassDefIndex();
1210 return true;
1211 }
1212
GetReferenceSlowFlagOffset() const1213 uint32_t CompilerDriver::GetReferenceSlowFlagOffset() const {
1214 ScopedObjectAccess soa(Thread::Current());
1215 mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
1216 DCHECK(klass->IsInitialized());
1217 return klass->GetSlowPathFlagOffset().Uint32Value();
1218 }
1219
GetReferenceDisableFlagOffset() const1220 uint32_t CompilerDriver::GetReferenceDisableFlagOffset() const {
1221 ScopedObjectAccess soa(Thread::Current());
1222 mirror::Class* klass = mirror::Reference::GetJavaLangRefReference();
1223 DCHECK(klass->IsInitialized());
1224 return klass->GetDisableIntrinsicFlagOffset().Uint32Value();
1225 }
1226
GetDexCacheArraysLayout(const DexFile * dex_file)1227 DexCacheArraysLayout CompilerDriver::GetDexCacheArraysLayout(const DexFile* dex_file) {
1228 // Currently only image dex caches have fixed array layout.
1229 return IsImage() && GetSupportBootImageFixup()
1230 ? DexCacheArraysLayout(GetInstructionSetPointerSize(instruction_set_), dex_file)
1231 : DexCacheArraysLayout();
1232 }
1233
ProcessedInstanceField(bool resolved)1234 void CompilerDriver::ProcessedInstanceField(bool resolved) {
1235 if (!resolved) {
1236 stats_->UnresolvedInstanceField();
1237 } else {
1238 stats_->ResolvedInstanceField();
1239 }
1240 }
1241
ProcessedStaticField(bool resolved,bool local)1242 void CompilerDriver::ProcessedStaticField(bool resolved, bool local) {
1243 if (!resolved) {
1244 stats_->UnresolvedStaticField();
1245 } else if (local) {
1246 stats_->ResolvedLocalStaticField();
1247 } else {
1248 stats_->ResolvedStaticField();
1249 }
1250 }
1251
ProcessedInvoke(InvokeType invoke_type,int flags)1252 void CompilerDriver::ProcessedInvoke(InvokeType invoke_type, int flags) {
1253 stats_->ProcessedInvoke(invoke_type, flags);
1254 }
1255
ComputeInstanceFieldInfo(uint32_t field_idx,const DexCompilationUnit * mUnit,bool is_put,const ScopedObjectAccess & soa)1256 ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
1257 const DexCompilationUnit* mUnit, bool is_put,
1258 const ScopedObjectAccess& soa) {
1259 // Try to resolve the field and compiling method's class.
1260 ArtField* resolved_field;
1261 mirror::Class* referrer_class;
1262 mirror::DexCache* dex_cache;
1263 {
1264 StackHandleScope<3> hs(soa.Self());
1265 Handle<mirror::DexCache> dex_cache_handle(
1266 hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
1267 Handle<mirror::ClassLoader> class_loader_handle(
1268 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
1269 resolved_field =
1270 ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false);
1271 referrer_class = resolved_field != nullptr
1272 ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
1273 dex_cache = dex_cache_handle.Get();
1274 }
1275 bool can_link = false;
1276 if (resolved_field != nullptr && referrer_class != nullptr) {
1277 std::pair<bool, bool> fast_path = IsFastInstanceField(
1278 dex_cache, referrer_class, resolved_field, field_idx);
1279 can_link = is_put ? fast_path.second : fast_path.first;
1280 }
1281 ProcessedInstanceField(can_link);
1282 return can_link ? resolved_field : nullptr;
1283 }
1284
ComputeInstanceFieldInfo(uint32_t field_idx,const DexCompilationUnit * mUnit,bool is_put,MemberOffset * field_offset,bool * is_volatile)1285 bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
1286 bool is_put, MemberOffset* field_offset,
1287 bool* is_volatile) {
1288 ScopedObjectAccess soa(Thread::Current());
1289 ArtField* resolved_field = ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa);
1290
1291 if (resolved_field == nullptr) {
1292 // Conservative defaults.
1293 *is_volatile = true;
1294 *field_offset = MemberOffset(static_cast<size_t>(-1));
1295 return false;
1296 } else {
1297 *is_volatile = resolved_field->IsVolatile();
1298 *field_offset = resolved_field->GetOffset();
1299 return true;
1300 }
1301 }
1302
ComputeStaticFieldInfo(uint32_t field_idx,const DexCompilationUnit * mUnit,bool is_put,MemberOffset * field_offset,uint32_t * storage_index,bool * is_referrers_class,bool * is_volatile,bool * is_initialized,Primitive::Type * type)1303 bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
1304 bool is_put, MemberOffset* field_offset,
1305 uint32_t* storage_index, bool* is_referrers_class,
1306 bool* is_volatile, bool* is_initialized,
1307 Primitive::Type* type) {
1308 ScopedObjectAccess soa(Thread::Current());
1309 // Try to resolve the field and compiling method's class.
1310 ArtField* resolved_field;
1311 mirror::Class* referrer_class;
1312 mirror::DexCache* dex_cache;
1313 {
1314 StackHandleScope<2> hs(soa.Self());
1315 Handle<mirror::DexCache> dex_cache_handle(
1316 hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
1317 Handle<mirror::ClassLoader> class_loader_handle(
1318 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
1319 resolved_field =
1320 ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true);
1321 referrer_class = resolved_field != nullptr
1322 ? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
1323 dex_cache = dex_cache_handle.Get();
1324 }
1325 bool result = false;
1326 if (resolved_field != nullptr && referrer_class != nullptr) {
1327 *is_volatile = IsFieldVolatile(resolved_field);
1328 std::pair<bool, bool> fast_path = IsFastStaticField(
1329 dex_cache, referrer_class, resolved_field, field_idx, storage_index);
1330 result = is_put ? fast_path.second : fast_path.first;
1331 }
1332 if (result) {
1333 *field_offset = GetFieldOffset(resolved_field);
1334 *is_referrers_class = IsStaticFieldInReferrerClass(referrer_class, resolved_field);
1335 // *is_referrers_class == true implies no worrying about class initialization.
1336 *is_initialized = (*is_referrers_class) ||
1337 (IsStaticFieldsClassInitialized(referrer_class, resolved_field) &&
1338 CanAssumeTypeIsPresentInDexCache(*mUnit->GetDexFile(), *storage_index));
1339 *type = resolved_field->GetTypeAsPrimitiveType();
1340 } else {
1341 // Conservative defaults.
1342 *is_volatile = true;
1343 *field_offset = MemberOffset(static_cast<size_t>(-1));
1344 *storage_index = -1;
1345 *is_referrers_class = false;
1346 *is_initialized = false;
1347 *type = Primitive::kPrimVoid;
1348 }
1349 ProcessedStaticField(result, *is_referrers_class);
1350 return result;
1351 }
1352
GetCodeAndMethodForDirectCall(InvokeType * type,InvokeType sharp_type,bool no_guarantee_of_dex_cache_entry,const mirror::Class * referrer_class,ArtMethod * method,int * stats_flags,MethodReference * target_method,uintptr_t * direct_code,uintptr_t * direct_method)1353 void CompilerDriver::GetCodeAndMethodForDirectCall(InvokeType* type, InvokeType sharp_type,
1354 bool no_guarantee_of_dex_cache_entry,
1355 const mirror::Class* referrer_class,
1356 ArtMethod* method,
1357 int* stats_flags,
1358 MethodReference* target_method,
1359 uintptr_t* direct_code,
1360 uintptr_t* direct_method) {
1361 // For direct and static methods compute possible direct_code and direct_method values, ie
1362 // an address for the Method* being invoked and an address of the code for that Method*.
1363 // For interface calls compute a value for direct_method that is the interface method being
1364 // invoked, so this can be passed to the out-of-line runtime support code.
1365 *direct_code = 0;
1366 *direct_method = 0;
1367 Runtime* const runtime = Runtime::Current();
1368 gc::Heap* const heap = runtime->GetHeap();
1369 auto* cl = runtime->GetClassLinker();
1370 const auto pointer_size = cl->GetImagePointerSize();
1371 bool use_dex_cache = GetCompilerOptions().GetCompilePic(); // Off by default
1372 const bool compiling_boot = heap->IsCompilingBoot();
1373 // TODO This is somewhat hacky. We should refactor all of this invoke codepath.
1374 const bool force_relocations = (compiling_boot ||
1375 GetCompilerOptions().GetIncludePatchInformation());
1376 if (sharp_type != kStatic && sharp_type != kDirect) {
1377 return;
1378 }
1379 // TODO: support patching on all architectures.
1380 use_dex_cache = use_dex_cache || (force_relocations && !support_boot_image_fixup_);
1381 mirror::Class* declaring_class = method->GetDeclaringClass();
1382 bool method_code_in_boot = declaring_class->GetClassLoader() == nullptr;
1383 if (!use_dex_cache) {
1384 if (!method_code_in_boot) {
1385 use_dex_cache = true;
1386 } else {
1387 bool has_clinit_trampoline =
1388 method->IsStatic() && !declaring_class->IsInitialized();
1389 if (has_clinit_trampoline && declaring_class != referrer_class) {
1390 // Ensure we run the clinit trampoline unless we are invoking a static method in the same
1391 // class.
1392 use_dex_cache = true;
1393 }
1394 }
1395 }
1396 if (runtime->UseJit()) {
1397 // If we are the JIT, then don't allow a direct call to the interpreter bridge since this will
1398 // never be updated even after we compile the method.
1399 if (cl->IsQuickToInterpreterBridge(
1400 reinterpret_cast<const void*>(compiler_->GetEntryPointOf(method)))) {
1401 use_dex_cache = true;
1402 }
1403 }
1404 if (method_code_in_boot) {
1405 *stats_flags |= kFlagDirectCallToBoot | kFlagDirectMethodToBoot;
1406 }
1407 if (!use_dex_cache && force_relocations) {
1408 bool is_in_image;
1409 if (IsImage()) {
1410 is_in_image = IsImageClass(method->GetDeclaringClassDescriptor());
1411 } else {
1412 is_in_image = instruction_set_ != kX86 && instruction_set_ != kX86_64 &&
1413 heap->FindSpaceFromObject(method->GetDeclaringClass(), false)->IsImageSpace() &&
1414 !cl->IsQuickToInterpreterBridge(
1415 reinterpret_cast<const void*>(compiler_->GetEntryPointOf(method)));
1416 }
1417 if (!is_in_image) {
1418 // We can only branch directly to Methods that are resolved in the DexCache.
1419 // Otherwise we won't invoke the resolution trampoline.
1420 use_dex_cache = true;
1421 }
1422 }
1423 // The method is defined not within this dex file. We need a dex cache slot within the current
1424 // dex file or direct pointers.
1425 bool must_use_direct_pointers = false;
1426 mirror::DexCache* dex_cache = declaring_class->GetDexCache();
1427 if (target_method->dex_file == dex_cache->GetDexFile() &&
1428 !(runtime->UseJit() && dex_cache->GetResolvedMethod(
1429 method->GetDexMethodIndex(), pointer_size) == nullptr)) {
1430 target_method->dex_method_index = method->GetDexMethodIndex();
1431 } else {
1432 if (no_guarantee_of_dex_cache_entry) {
1433 // See if the method is also declared in this dex cache.
1434 uint32_t dex_method_idx = method->FindDexMethodIndexInOtherDexFile(
1435 *target_method->dex_file, target_method->dex_method_index);
1436 if (dex_method_idx != DexFile::kDexNoIndex) {
1437 target_method->dex_method_index = dex_method_idx;
1438 } else {
1439 if (force_relocations && !use_dex_cache) {
1440 target_method->dex_method_index = method->GetDexMethodIndex();
1441 target_method->dex_file = dex_cache->GetDexFile();
1442 }
1443 must_use_direct_pointers = true;
1444 }
1445 }
1446 }
1447 if (use_dex_cache) {
1448 if (must_use_direct_pointers) {
1449 // Fail. Test above showed the only safe dispatch was via the dex cache, however, the direct
1450 // pointers are required as the dex cache lacks an appropriate entry.
1451 VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
1452 } else {
1453 *type = sharp_type;
1454 }
1455 } else {
1456 auto* image_space = heap->GetImageSpace();
1457 bool method_in_image = false;
1458 if (image_space != nullptr) {
1459 const auto& method_section = image_space->GetImageHeader().GetMethodsSection();
1460 method_in_image = method_section.Contains(
1461 reinterpret_cast<uint8_t*>(method) - image_space->Begin());
1462 }
1463 if (method_in_image || compiling_boot || runtime->UseJit()) {
1464 // We know we must be able to get to the method in the image, so use that pointer.
1465 // In the case where we are the JIT, we can always use direct pointers since we know where
1466 // the method and its code are / will be. We don't sharpen to interpreter bridge since we
1467 // check IsQuickToInterpreterBridge above.
1468 CHECK(!method->IsAbstract());
1469 *type = sharp_type;
1470 *direct_method = force_relocations ? -1 : reinterpret_cast<uintptr_t>(method);
1471 *direct_code = force_relocations ? -1 : compiler_->GetEntryPointOf(method);
1472 target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
1473 target_method->dex_method_index = method->GetDexMethodIndex();
1474 } else if (!must_use_direct_pointers) {
1475 // Set the code and rely on the dex cache for the method.
1476 *type = sharp_type;
1477 if (force_relocations) {
1478 *direct_code = -1;
1479 target_method->dex_file = method->GetDeclaringClass()->GetDexCache()->GetDexFile();
1480 target_method->dex_method_index = method->GetDexMethodIndex();
1481 } else {
1482 *direct_code = compiler_->GetEntryPointOf(method);
1483 }
1484 } else {
1485 // Direct pointers were required but none were available.
1486 VLOG(compiler) << "Dex cache devirtualization failed for: " << PrettyMethod(method);
1487 }
1488 }
1489 }
1490
ComputeInvokeInfo(const DexCompilationUnit * mUnit,const uint32_t dex_pc,bool update_stats,bool enable_devirtualization,InvokeType * invoke_type,MethodReference * target_method,int * vtable_idx,uintptr_t * direct_code,uintptr_t * direct_method)1491 bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const uint32_t dex_pc,
1492 bool update_stats, bool enable_devirtualization,
1493 InvokeType* invoke_type, MethodReference* target_method,
1494 int* vtable_idx, uintptr_t* direct_code,
1495 uintptr_t* direct_method) {
1496 InvokeType orig_invoke_type = *invoke_type;
1497 int stats_flags = 0;
1498 ScopedObjectAccess soa(Thread::Current());
1499 // Try to resolve the method and compiling method's class.
1500 StackHandleScope<3> hs(soa.Self());
1501 Handle<mirror::DexCache> dex_cache(
1502 hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
1503 Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
1504 soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
1505 uint32_t method_idx = target_method->dex_method_index;
1506 ArtMethod* resolved_method = ResolveMethod(
1507 soa, dex_cache, class_loader, mUnit, method_idx, orig_invoke_type);
1508 auto h_referrer_class = hs.NewHandle(resolved_method != nullptr ?
1509 ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit) : nullptr);
1510 bool result = false;
1511 if (resolved_method != nullptr) {
1512 *vtable_idx = GetResolvedMethodVTableIndex(resolved_method, orig_invoke_type);
1513
1514 if (enable_devirtualization && mUnit->GetVerifiedMethod() != nullptr) {
1515 const MethodReference* devirt_target = mUnit->GetVerifiedMethod()->GetDevirtTarget(dex_pc);
1516
1517 stats_flags = IsFastInvoke(
1518 soa, dex_cache, class_loader, mUnit, h_referrer_class.Get(), resolved_method,
1519 invoke_type, target_method, devirt_target, direct_code, direct_method);
1520 result = stats_flags != 0;
1521 } else {
1522 // Devirtualization not enabled. Inline IsFastInvoke(), dropping the devirtualization parts.
1523 if (UNLIKELY(h_referrer_class.Get() == nullptr) ||
1524 UNLIKELY(!h_referrer_class->CanAccessResolvedMethod(resolved_method->GetDeclaringClass(),
1525 resolved_method, dex_cache.Get(),
1526 target_method->dex_method_index)) ||
1527 *invoke_type == kSuper) {
1528 // Slow path. (Without devirtualization, all super calls go slow path as well.)
1529 } else {
1530 // Sharpening failed so generate a regular resolved method dispatch.
1531 stats_flags = kFlagMethodResolved;
1532 GetCodeAndMethodForDirectCall(
1533 invoke_type, *invoke_type, false, h_referrer_class.Get(), resolved_method, &stats_flags,
1534 target_method, direct_code, direct_method);
1535 result = true;
1536 }
1537 }
1538 }
1539 if (!result) {
1540 // Conservative defaults.
1541 *vtable_idx = -1;
1542 *direct_code = 0u;
1543 *direct_method = 0u;
1544 }
1545 if (update_stats) {
1546 ProcessedInvoke(orig_invoke_type, stats_flags);
1547 }
1548 return result;
1549 }
1550
GetVerifiedMethod(const DexFile * dex_file,uint32_t method_idx) const1551 const VerifiedMethod* CompilerDriver::GetVerifiedMethod(const DexFile* dex_file,
1552 uint32_t method_idx) const {
1553 MethodReference ref(dex_file, method_idx);
1554 return verification_results_->GetVerifiedMethod(ref);
1555 }
1556
IsSafeCast(const DexCompilationUnit * mUnit,uint32_t dex_pc)1557 bool CompilerDriver::IsSafeCast(const DexCompilationUnit* mUnit, uint32_t dex_pc) {
1558 if (!compiler_options_->IsVerificationEnabled()) {
1559 // If we didn't verify, every cast has to be treated as non-safe.
1560 return false;
1561 }
1562 DCHECK(mUnit->GetVerifiedMethod() != nullptr);
1563 bool result = mUnit->GetVerifiedMethod()->IsSafeCast(dex_pc);
1564 if (result) {
1565 stats_->SafeCast();
1566 } else {
1567 stats_->NotASafeCast();
1568 }
1569 return result;
1570 }
1571
1572 class ParallelCompilationManager {
1573 public:
1574 typedef void Callback(const ParallelCompilationManager* manager, size_t index);
1575
ParallelCompilationManager(ClassLinker * class_linker,jobject class_loader,CompilerDriver * compiler,const DexFile * dex_file,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool)1576 ParallelCompilationManager(ClassLinker* class_linker,
1577 jobject class_loader,
1578 CompilerDriver* compiler,
1579 const DexFile* dex_file,
1580 const std::vector<const DexFile*>& dex_files,
1581 ThreadPool* thread_pool)
1582 : index_(0),
1583 class_linker_(class_linker),
1584 class_loader_(class_loader),
1585 compiler_(compiler),
1586 dex_file_(dex_file),
1587 dex_files_(dex_files),
1588 thread_pool_(thread_pool) {}
1589
GetClassLinker() const1590 ClassLinker* GetClassLinker() const {
1591 CHECK(class_linker_ != nullptr);
1592 return class_linker_;
1593 }
1594
GetClassLoader() const1595 jobject GetClassLoader() const {
1596 return class_loader_;
1597 }
1598
GetCompiler() const1599 CompilerDriver* GetCompiler() const {
1600 CHECK(compiler_ != nullptr);
1601 return compiler_;
1602 }
1603
GetDexFile() const1604 const DexFile* GetDexFile() const {
1605 CHECK(dex_file_ != nullptr);
1606 return dex_file_;
1607 }
1608
GetDexFiles() const1609 const std::vector<const DexFile*>& GetDexFiles() const {
1610 return dex_files_;
1611 }
1612
ForAll(size_t begin,size_t end,Callback callback,size_t work_units)1613 void ForAll(size_t begin, size_t end, Callback callback, size_t work_units) {
1614 Thread* self = Thread::Current();
1615 self->AssertNoPendingException();
1616 CHECK_GT(work_units, 0U);
1617
1618 index_.StoreRelaxed(begin);
1619 for (size_t i = 0; i < work_units; ++i) {
1620 thread_pool_->AddTask(self, new ForAllClosure(this, end, callback));
1621 }
1622 thread_pool_->StartWorkers(self);
1623
1624 // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
1625 // thread destructor's called below perform join).
1626 CHECK_NE(self->GetState(), kRunnable);
1627
1628 // Wait for all the worker threads to finish.
1629 thread_pool_->Wait(self, true, false);
1630 }
1631
NextIndex()1632 size_t NextIndex() {
1633 return index_.FetchAndAddSequentiallyConsistent(1);
1634 }
1635
1636 private:
1637 class ForAllClosure : public Task {
1638 public:
ForAllClosure(ParallelCompilationManager * manager,size_t end,Callback * callback)1639 ForAllClosure(ParallelCompilationManager* manager, size_t end, Callback* callback)
1640 : manager_(manager),
1641 end_(end),
1642 callback_(callback) {}
1643
Run(Thread * self)1644 virtual void Run(Thread* self) {
1645 while (true) {
1646 const size_t index = manager_->NextIndex();
1647 if (UNLIKELY(index >= end_)) {
1648 break;
1649 }
1650 callback_(manager_, index);
1651 self->AssertNoPendingException();
1652 }
1653 }
1654
Finalize()1655 virtual void Finalize() {
1656 delete this;
1657 }
1658
1659 private:
1660 ParallelCompilationManager* const manager_;
1661 const size_t end_;
1662 Callback* const callback_;
1663 };
1664
1665 AtomicInteger index_;
1666 ClassLinker* const class_linker_;
1667 const jobject class_loader_;
1668 CompilerDriver* const compiler_;
1669 const DexFile* const dex_file_;
1670 const std::vector<const DexFile*>& dex_files_;
1671 ThreadPool* const thread_pool_;
1672
1673 DISALLOW_COPY_AND_ASSIGN(ParallelCompilationManager);
1674 };
1675
1676 // A fast version of SkipClass above if the class pointer is available
1677 // that avoids the expensive FindInClassPath search.
SkipClass(jobject class_loader,const DexFile & dex_file,mirror::Class * klass)1678 static bool SkipClass(jobject class_loader, const DexFile& dex_file, mirror::Class* klass)
1679 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1680 DCHECK(klass != nullptr);
1681 const DexFile& original_dex_file = *klass->GetDexCache()->GetDexFile();
1682 if (&dex_file != &original_dex_file) {
1683 if (class_loader == nullptr) {
1684 LOG(WARNING) << "Skipping class " << PrettyDescriptor(klass) << " from "
1685 << dex_file.GetLocation() << " previously found in "
1686 << original_dex_file.GetLocation();
1687 }
1688 return true;
1689 }
1690 return false;
1691 }
1692
CheckAndClearResolveException(Thread * self)1693 static void CheckAndClearResolveException(Thread* self)
1694 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1695 CHECK(self->IsExceptionPending());
1696 mirror::Throwable* exception = self->GetException();
1697 std::string temp;
1698 const char* descriptor = exception->GetClass()->GetDescriptor(&temp);
1699 const char* expected_exceptions[] = {
1700 "Ljava/lang/IllegalAccessError;",
1701 "Ljava/lang/IncompatibleClassChangeError;",
1702 "Ljava/lang/InstantiationError;",
1703 "Ljava/lang/LinkageError;",
1704 "Ljava/lang/NoClassDefFoundError;",
1705 "Ljava/lang/NoSuchFieldError;",
1706 "Ljava/lang/NoSuchMethodError;"
1707 };
1708 bool found = false;
1709 for (size_t i = 0; (found == false) && (i < arraysize(expected_exceptions)); ++i) {
1710 if (strcmp(descriptor, expected_exceptions[i]) == 0) {
1711 found = true;
1712 }
1713 }
1714 if (!found) {
1715 LOG(FATAL) << "Unexpected exception " << exception->Dump();
1716 }
1717 self->ClearException();
1718 }
1719
ResolveClassFieldsAndMethods(const ParallelCompilationManager * manager,size_t class_def_index)1720 static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manager,
1721 size_t class_def_index)
1722 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1723 ATRACE_CALL();
1724 Thread* self = Thread::Current();
1725 jobject jclass_loader = manager->GetClassLoader();
1726 const DexFile& dex_file = *manager->GetDexFile();
1727 ClassLinker* class_linker = manager->GetClassLinker();
1728
1729 // If an instance field is final then we need to have a barrier on the return, static final
1730 // fields are assigned within the lock held for class initialization. Conservatively assume
1731 // constructor barriers are always required.
1732 bool requires_constructor_barrier = true;
1733
1734 // Method and Field are the worst. We can't resolve without either
1735 // context from the code use (to disambiguate virtual vs direct
1736 // method and instance vs static field) or from class
1737 // definitions. While the compiler will resolve what it can as it
1738 // needs it, here we try to resolve fields and methods used in class
1739 // definitions, since many of them many never be referenced by
1740 // generated code.
1741 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1742 ScopedObjectAccess soa(self);
1743 StackHandleScope<2> hs(soa.Self());
1744 Handle<mirror::ClassLoader> class_loader(
1745 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1746 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1747 // Resolve the class.
1748 mirror::Class* klass = class_linker->ResolveType(dex_file, class_def.class_idx_, dex_cache,
1749 class_loader);
1750 bool resolve_fields_and_methods;
1751 if (klass == nullptr) {
1752 // Class couldn't be resolved, for example, super-class is in a different dex file. Don't
1753 // attempt to resolve methods and fields when there is no declaring class.
1754 CheckAndClearResolveException(soa.Self());
1755 resolve_fields_and_methods = false;
1756 } else {
1757 // We successfully resolved a class, should we skip it?
1758 if (SkipClass(jclass_loader, dex_file, klass)) {
1759 return;
1760 }
1761 // We want to resolve the methods and fields eagerly.
1762 resolve_fields_and_methods = true;
1763 }
1764 // Note the class_data pointer advances through the headers,
1765 // static fields, instance fields, direct methods, and virtual
1766 // methods.
1767 const uint8_t* class_data = dex_file.GetClassData(class_def);
1768 if (class_data == nullptr) {
1769 // Empty class such as a marker interface.
1770 requires_constructor_barrier = false;
1771 } else {
1772 ClassDataItemIterator it(dex_file, class_data);
1773 while (it.HasNextStaticField()) {
1774 if (resolve_fields_and_methods) {
1775 ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1776 dex_cache, class_loader, true);
1777 if (field == nullptr) {
1778 CheckAndClearResolveException(soa.Self());
1779 }
1780 }
1781 it.Next();
1782 }
1783 // We require a constructor barrier if there are final instance fields.
1784 requires_constructor_barrier = false;
1785 while (it.HasNextInstanceField()) {
1786 if (it.MemberIsFinal()) {
1787 requires_constructor_barrier = true;
1788 }
1789 if (resolve_fields_and_methods) {
1790 ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
1791 dex_cache, class_loader, false);
1792 if (field == nullptr) {
1793 CheckAndClearResolveException(soa.Self());
1794 }
1795 }
1796 it.Next();
1797 }
1798 if (resolve_fields_and_methods) {
1799 while (it.HasNextDirectMethod()) {
1800 ArtMethod* method = class_linker->ResolveMethod(
1801 dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
1802 it.GetMethodInvokeType(class_def));
1803 if (method == nullptr) {
1804 CheckAndClearResolveException(soa.Self());
1805 }
1806 it.Next();
1807 }
1808 while (it.HasNextVirtualMethod()) {
1809 ArtMethod* method = class_linker->ResolveMethod(
1810 dex_file, it.GetMemberIndex(), dex_cache, class_loader, nullptr,
1811 it.GetMethodInvokeType(class_def));
1812 if (method == nullptr) {
1813 CheckAndClearResolveException(soa.Self());
1814 }
1815 it.Next();
1816 }
1817 DCHECK(!it.HasNext());
1818 }
1819 }
1820 if (requires_constructor_barrier) {
1821 manager->GetCompiler()->AddRequiresConstructorBarrier(self, &dex_file, class_def_index);
1822 }
1823 }
1824
ResolveType(const ParallelCompilationManager * manager,size_t type_idx)1825 static void ResolveType(const ParallelCompilationManager* manager, size_t type_idx)
1826 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1827 // Class derived values are more complicated, they require the linker and loader.
1828 ScopedObjectAccess soa(Thread::Current());
1829 ClassLinker* class_linker = manager->GetClassLinker();
1830 const DexFile& dex_file = *manager->GetDexFile();
1831 StackHandleScope<2> hs(soa.Self());
1832 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1833 Handle<mirror::ClassLoader> class_loader(
1834 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(manager->GetClassLoader())));
1835 mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
1836
1837 if (klass == nullptr) {
1838 CHECK(soa.Self()->IsExceptionPending());
1839 mirror::Throwable* exception = soa.Self()->GetException();
1840 VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
1841 if (exception->GetClass()->DescriptorEquals("Ljava/lang/OutOfMemoryError;")) {
1842 // There's little point continuing compilation if the heap is exhausted.
1843 LOG(FATAL) << "Out of memory during type resolution for compilation";
1844 }
1845 soa.Self()->ClearException();
1846 }
1847 }
1848
ResolveDexFile(jobject class_loader,const DexFile & dex_file,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)1849 void CompilerDriver::ResolveDexFile(jobject class_loader, const DexFile& dex_file,
1850 const std::vector<const DexFile*>& dex_files,
1851 ThreadPool* thread_pool, TimingLogger* timings) {
1852 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1853
1854 // TODO: we could resolve strings here, although the string table is largely filled with class
1855 // and method names.
1856
1857 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1858 thread_pool);
1859 if (IsImage()) {
1860 // For images we resolve all types, such as array, whereas for applications just those with
1861 // classdefs are resolved by ResolveClassFieldsAndMethods.
1862 TimingLogger::ScopedTiming t("Resolve Types", timings);
1863 context.ForAll(0, dex_file.NumTypeIds(), ResolveType, thread_count_);
1864 }
1865
1866 TimingLogger::ScopedTiming t("Resolve MethodsAndFields", timings);
1867 context.ForAll(0, dex_file.NumClassDefs(), ResolveClassFieldsAndMethods, thread_count_);
1868 }
1869
SetVerified(jobject class_loader,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)1870 void CompilerDriver::SetVerified(jobject class_loader, const std::vector<const DexFile*>& dex_files,
1871 ThreadPool* thread_pool, TimingLogger* timings) {
1872 for (size_t i = 0; i != dex_files.size(); ++i) {
1873 const DexFile* dex_file = dex_files[i];
1874 CHECK(dex_file != nullptr);
1875 SetVerifiedDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
1876 }
1877 }
1878
Verify(jobject class_loader,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)1879 void CompilerDriver::Verify(jobject class_loader, const std::vector<const DexFile*>& dex_files,
1880 ThreadPool* thread_pool, TimingLogger* timings) {
1881 for (size_t i = 0; i != dex_files.size(); ++i) {
1882 const DexFile* dex_file = dex_files[i];
1883 CHECK(dex_file != nullptr);
1884 VerifyDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
1885 }
1886 }
1887
VerifyClass(const ParallelCompilationManager * manager,size_t class_def_index)1888 static void VerifyClass(const ParallelCompilationManager* manager, size_t class_def_index)
1889 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1890 ATRACE_CALL();
1891 ScopedObjectAccess soa(Thread::Current());
1892 const DexFile& dex_file = *manager->GetDexFile();
1893 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1894 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1895 ClassLinker* class_linker = manager->GetClassLinker();
1896 jobject jclass_loader = manager->GetClassLoader();
1897 StackHandleScope<3> hs(soa.Self());
1898 Handle<mirror::ClassLoader> class_loader(
1899 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1900 Handle<mirror::Class> klass(
1901 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1902 if (klass.Get() == nullptr) {
1903 CHECK(soa.Self()->IsExceptionPending());
1904 soa.Self()->ClearException();
1905
1906 /*
1907 * At compile time, we can still structurally verify the class even if FindClass fails.
1908 * This is to ensure the class is structurally sound for compilation. An unsound class
1909 * will be rejected by the verifier and later skipped during compilation in the compiler.
1910 */
1911 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(dex_file)));
1912 std::string error_msg;
1913 if (verifier::MethodVerifier::VerifyClass(soa.Self(), &dex_file, dex_cache, class_loader,
1914 &class_def, true, &error_msg) ==
1915 verifier::MethodVerifier::kHardFailure) {
1916 LOG(ERROR) << "Verification failed on class " << PrettyDescriptor(descriptor)
1917 << " because: " << error_msg;
1918 manager->GetCompiler()->SetHadHardVerifierFailure();
1919 }
1920 } else if (!SkipClass(jclass_loader, dex_file, klass.Get())) {
1921 CHECK(klass->IsResolved()) << PrettyClass(klass.Get());
1922 class_linker->VerifyClass(soa.Self(), klass);
1923
1924 if (klass->IsErroneous()) {
1925 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
1926 CHECK(soa.Self()->IsExceptionPending());
1927 soa.Self()->ClearException();
1928 manager->GetCompiler()->SetHadHardVerifierFailure();
1929 }
1930
1931 CHECK(klass->IsCompileTimeVerified() || klass->IsErroneous())
1932 << PrettyDescriptor(klass.Get()) << ": state=" << klass->GetStatus();
1933
1934 // It is *very* problematic if there are verification errors in the boot classpath. For example,
1935 // we rely on things working OK without verification when the decryption dialog is brought up.
1936 // So abort in a debug build if we find this violated.
1937 DCHECK(!manager->GetCompiler()->IsImage() || klass->IsVerified()) << "Boot classpath class " <<
1938 PrettyClass(klass.Get()) << " failed to fully verify.";
1939 }
1940 soa.Self()->AssertNoPendingException();
1941 }
1942
VerifyDexFile(jobject class_loader,const DexFile & dex_file,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)1943 void CompilerDriver::VerifyDexFile(jobject class_loader, const DexFile& dex_file,
1944 const std::vector<const DexFile*>& dex_files,
1945 ThreadPool* thread_pool, TimingLogger* timings) {
1946 TimingLogger::ScopedTiming t("Verify Dex File", timings);
1947 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1948 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1949 thread_pool);
1950 context.ForAll(0, dex_file.NumClassDefs(), VerifyClass, thread_count_);
1951 }
1952
SetVerifiedClass(const ParallelCompilationManager * manager,size_t class_def_index)1953 static void SetVerifiedClass(const ParallelCompilationManager* manager, size_t class_def_index)
1954 LOCKS_EXCLUDED(Locks::mutator_lock_) {
1955 ATRACE_CALL();
1956 ScopedObjectAccess soa(Thread::Current());
1957 const DexFile& dex_file = *manager->GetDexFile();
1958 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1959 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1960 ClassLinker* class_linker = manager->GetClassLinker();
1961 jobject jclass_loader = manager->GetClassLoader();
1962 StackHandleScope<3> hs(soa.Self());
1963 Handle<mirror::ClassLoader> class_loader(
1964 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
1965 Handle<mirror::Class> klass(
1966 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1967 // Class might have failed resolution. Then don't set it to verified.
1968 if (klass.Get() != nullptr) {
1969 // Only do this if the class is resolved. If even resolution fails, quickening will go very,
1970 // very wrong.
1971 if (klass->IsResolved()) {
1972 if (klass->GetStatus() < mirror::Class::kStatusVerified) {
1973 ObjectLock<mirror::Class> lock(soa.Self(), klass);
1974 // Set class status to verified.
1975 mirror::Class::SetStatus(klass, mirror::Class::kStatusVerified, soa.Self());
1976 // Mark methods as pre-verified. If we don't do this, the interpreter will run with
1977 // access checks.
1978 klass->SetPreverifiedFlagOnAllMethods(
1979 GetInstructionSetPointerSize(manager->GetCompiler()->GetInstructionSet()));
1980 klass->SetPreverified();
1981 }
1982 // Record the final class status if necessary.
1983 ClassReference ref(manager->GetDexFile(), class_def_index);
1984 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
1985 }
1986 } else {
1987 Thread* self = soa.Self();
1988 DCHECK(self->IsExceptionPending());
1989 self->ClearException();
1990 }
1991 }
1992
SetVerifiedDexFile(jobject class_loader,const DexFile & dex_file,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)1993 void CompilerDriver::SetVerifiedDexFile(jobject class_loader, const DexFile& dex_file,
1994 const std::vector<const DexFile*>& dex_files,
1995 ThreadPool* thread_pool, TimingLogger* timings) {
1996 TimingLogger::ScopedTiming t("Verify Dex File", timings);
1997 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1998 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, dex_files,
1999 thread_pool);
2000 context.ForAll(0, dex_file.NumClassDefs(), SetVerifiedClass, thread_count_);
2001 }
2002
InitializeClass(const ParallelCompilationManager * manager,size_t class_def_index)2003 static void InitializeClass(const ParallelCompilationManager* manager, size_t class_def_index)
2004 LOCKS_EXCLUDED(Locks::mutator_lock_) {
2005 ATRACE_CALL();
2006 jobject jclass_loader = manager->GetClassLoader();
2007 const DexFile& dex_file = *manager->GetDexFile();
2008 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
2009 const DexFile::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
2010 const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_);
2011
2012 ScopedObjectAccess soa(Thread::Current());
2013 StackHandleScope<3> hs(soa.Self());
2014 Handle<mirror::ClassLoader> class_loader(
2015 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
2016 Handle<mirror::Class> klass(
2017 hs.NewHandle(manager->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
2018
2019 if (klass.Get() != nullptr && !SkipClass(jclass_loader, dex_file, klass.Get())) {
2020 // Only try to initialize classes that were successfully verified.
2021 if (klass->IsVerified()) {
2022 // Attempt to initialize the class but bail if we either need to initialize the super-class
2023 // or static fields.
2024 manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, false);
2025 if (!klass->IsInitialized()) {
2026 // We don't want non-trivial class initialization occurring on multiple threads due to
2027 // deadlock problems. For example, a parent class is initialized (holding its lock) that
2028 // refers to a sub-class in its static/class initializer causing it to try to acquire the
2029 // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
2030 // after first initializing its parents, whose locks are acquired. This leads to a
2031 // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
2032 // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
2033 // than use a special Object for the purpose we use the Class of java.lang.Class.
2034 Handle<mirror::Class> h_klass(hs.NewHandle(klass->GetClass()));
2035 ObjectLock<mirror::Class> lock(soa.Self(), h_klass);
2036 // Attempt to initialize allowing initialization of parent classes but still not static
2037 // fields.
2038 manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true);
2039 if (!klass->IsInitialized()) {
2040 // We need to initialize static fields, we only do this for image classes that aren't
2041 // marked with the $NoPreloadHolder (which implies this should not be initialized early).
2042 bool can_init_static_fields = manager->GetCompiler()->IsImage() &&
2043 manager->GetCompiler()->IsImageClass(descriptor) &&
2044 !StringPiece(descriptor).ends_with("$NoPreloadHolder;");
2045 if (can_init_static_fields) {
2046 VLOG(compiler) << "Initializing: " << descriptor;
2047 // TODO multithreading support. We should ensure the current compilation thread has
2048 // exclusive access to the runtime and the transaction. To achieve this, we could use
2049 // a ReaderWriterMutex but we're holding the mutator lock so we fail mutex sanity
2050 // checks in Thread::AssertThreadSuspensionIsAllowable.
2051 Runtime* const runtime = Runtime::Current();
2052 Transaction transaction;
2053
2054 // Run the class initializer in transaction mode.
2055 runtime->EnterTransactionMode(&transaction);
2056 const mirror::Class::Status old_status = klass->GetStatus();
2057 bool success = manager->GetClassLinker()->EnsureInitialized(soa.Self(), klass, true,
2058 true);
2059 // TODO we detach transaction from runtime to indicate we quit the transactional
2060 // mode which prevents the GC from visiting objects modified during the transaction.
2061 // Ensure GC is not run so don't access freed objects when aborting transaction.
2062
2063 ScopedAssertNoThreadSuspension ants(soa.Self(), "Transaction end");
2064 runtime->ExitTransactionMode();
2065
2066 if (!success) {
2067 CHECK(soa.Self()->IsExceptionPending());
2068 mirror::Throwable* exception = soa.Self()->GetException();
2069 VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
2070 << exception->Dump();
2071 std::ostream* file_log = manager->GetCompiler()->
2072 GetCompilerOptions().GetInitFailureOutput();
2073 if (file_log != nullptr) {
2074 *file_log << descriptor << "\n";
2075 *file_log << exception->Dump() << "\n";
2076 }
2077 soa.Self()->ClearException();
2078 transaction.Rollback();
2079 CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
2080 }
2081 }
2082 }
2083 soa.Self()->AssertNoPendingException();
2084 }
2085 }
2086 // Record the final class status if necessary.
2087 ClassReference ref(manager->GetDexFile(), class_def_index);
2088 manager->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
2089 }
2090 // Clear any class not found or verification exceptions.
2091 soa.Self()->ClearException();
2092 }
2093
InitializeClasses(jobject jni_class_loader,const DexFile & dex_file,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)2094 void CompilerDriver::InitializeClasses(jobject jni_class_loader, const DexFile& dex_file,
2095 const std::vector<const DexFile*>& dex_files,
2096 ThreadPool* thread_pool, TimingLogger* timings) {
2097 TimingLogger::ScopedTiming t("InitializeNoClinit", timings);
2098 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2099 ParallelCompilationManager context(class_linker, jni_class_loader, this, &dex_file, dex_files,
2100 thread_pool);
2101 size_t thread_count;
2102 if (IsImage()) {
2103 // TODO: remove this when transactional mode supports multithreading.
2104 thread_count = 1U;
2105 } else {
2106 thread_count = thread_count_;
2107 }
2108 context.ForAll(0, dex_file.NumClassDefs(), InitializeClass, thread_count);
2109 }
2110
InitializeClasses(jobject class_loader,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)2111 void CompilerDriver::InitializeClasses(jobject class_loader,
2112 const std::vector<const DexFile*>& dex_files,
2113 ThreadPool* thread_pool, TimingLogger* timings) {
2114 for (size_t i = 0; i != dex_files.size(); ++i) {
2115 const DexFile* dex_file = dex_files[i];
2116 CHECK(dex_file != nullptr);
2117 InitializeClasses(class_loader, *dex_file, dex_files, thread_pool, timings);
2118 }
2119 if (IsImage()) {
2120 // Prune garbage objects created during aborted transactions.
2121 Runtime::Current()->GetHeap()->CollectGarbage(true);
2122 }
2123 }
2124
Compile(jobject class_loader,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)2125 void CompilerDriver::Compile(jobject class_loader, const std::vector<const DexFile*>& dex_files,
2126 ThreadPool* thread_pool, TimingLogger* timings) {
2127 for (size_t i = 0; i != dex_files.size(); ++i) {
2128 const DexFile* dex_file = dex_files[i];
2129 CHECK(dex_file != nullptr);
2130 CompileDexFile(class_loader, *dex_file, dex_files, thread_pool, timings);
2131 }
2132 VLOG(compiler) << "Compile: " << GetMemoryUsageString(false);
2133 }
2134
CompileClass(const ParallelCompilationManager * manager,size_t class_def_index)2135 void CompilerDriver::CompileClass(const ParallelCompilationManager* manager,
2136 size_t class_def_index) {
2137 ATRACE_CALL();
2138 const DexFile& dex_file = *manager->GetDexFile();
2139 const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
2140 ClassLinker* class_linker = manager->GetClassLinker();
2141 jobject jclass_loader = manager->GetClassLoader();
2142 Thread* self = Thread::Current();
2143 {
2144 // Use a scoped object access to perform to the quick SkipClass check.
2145 const char* descriptor = dex_file.GetClassDescriptor(class_def);
2146 ScopedObjectAccess soa(self);
2147 StackHandleScope<3> hs(soa.Self());
2148 Handle<mirror::ClassLoader> class_loader(
2149 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
2150 Handle<mirror::Class> klass(
2151 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
2152 if (klass.Get() == nullptr) {
2153 CHECK(soa.Self()->IsExceptionPending());
2154 soa.Self()->ClearException();
2155 } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
2156 return;
2157 }
2158 }
2159 ClassReference ref(&dex_file, class_def_index);
2160 // Skip compiling classes with generic verifier failures since they will still fail at runtime
2161 if (manager->GetCompiler()->verification_results_->IsClassRejected(ref)) {
2162 return;
2163 }
2164 const uint8_t* class_data = dex_file.GetClassData(class_def);
2165 if (class_data == nullptr) {
2166 // empty class, probably a marker interface
2167 return;
2168 }
2169
2170 CompilerDriver* const driver = manager->GetCompiler();
2171
2172 // Can we run DEX-to-DEX compiler on this class ?
2173 DexToDexCompilationLevel dex_to_dex_compilation_level = kDontDexToDexCompile;
2174 {
2175 ScopedObjectAccess soa(self);
2176 StackHandleScope<1> hs(soa.Self());
2177 Handle<mirror::ClassLoader> class_loader(
2178 hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader)));
2179 dex_to_dex_compilation_level = driver->GetDexToDexCompilationlevel(
2180 soa.Self(), class_loader, dex_file, class_def);
2181 }
2182 ClassDataItemIterator it(dex_file, class_data);
2183 // Skip fields
2184 while (it.HasNextStaticField()) {
2185 it.Next();
2186 }
2187 while (it.HasNextInstanceField()) {
2188 it.Next();
2189 }
2190
2191 bool compilation_enabled = driver->IsClassToCompile(
2192 dex_file.StringByTypeIdx(class_def.class_idx_));
2193
2194 // Compile direct methods
2195 int64_t previous_direct_method_idx = -1;
2196 while (it.HasNextDirectMethod()) {
2197 uint32_t method_idx = it.GetMemberIndex();
2198 if (method_idx == previous_direct_method_idx) {
2199 // smali can create dex files with two encoded_methods sharing the same method_idx
2200 // http://code.google.com/p/smali/issues/detail?id=119
2201 it.Next();
2202 continue;
2203 }
2204 previous_direct_method_idx = method_idx;
2205 driver->CompileMethod(self, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
2206 it.GetMethodInvokeType(class_def), class_def_index,
2207 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
2208 compilation_enabled);
2209 it.Next();
2210 }
2211 // Compile virtual methods
2212 int64_t previous_virtual_method_idx = -1;
2213 while (it.HasNextVirtualMethod()) {
2214 uint32_t method_idx = it.GetMemberIndex();
2215 if (method_idx == previous_virtual_method_idx) {
2216 // smali can create dex files with two encoded_methods sharing the same method_idx
2217 // http://code.google.com/p/smali/issues/detail?id=119
2218 it.Next();
2219 continue;
2220 }
2221 previous_virtual_method_idx = method_idx;
2222 driver->CompileMethod(self, it.GetMethodCodeItem(), it.GetMethodAccessFlags(),
2223 it.GetMethodInvokeType(class_def), class_def_index,
2224 method_idx, jclass_loader, dex_file, dex_to_dex_compilation_level,
2225 compilation_enabled);
2226 it.Next();
2227 }
2228 DCHECK(!it.HasNext());
2229 }
2230
CompileDexFile(jobject class_loader,const DexFile & dex_file,const std::vector<const DexFile * > & dex_files,ThreadPool * thread_pool,TimingLogger * timings)2231 void CompilerDriver::CompileDexFile(jobject class_loader, const DexFile& dex_file,
2232 const std::vector<const DexFile*>& dex_files,
2233 ThreadPool* thread_pool, TimingLogger* timings) {
2234 TimingLogger::ScopedTiming t("Compile Dex File", timings);
2235 ParallelCompilationManager context(Runtime::Current()->GetClassLinker(), class_loader, this,
2236 &dex_file, dex_files, thread_pool);
2237 context.ForAll(0, dex_file.NumClassDefs(), CompilerDriver::CompileClass, thread_count_);
2238 }
2239
2240 // Does the runtime for the InstructionSet provide an implementation returned by
2241 // GetQuickGenericJniStub allowing down calls that aren't compiled using a JNI compiler?
InstructionSetHasGenericJniStub(InstructionSet isa)2242 static bool InstructionSetHasGenericJniStub(InstructionSet isa) {
2243 switch (isa) {
2244 case kArm:
2245 case kArm64:
2246 case kThumb2:
2247 case kMips:
2248 case kMips64:
2249 case kX86:
2250 case kX86_64: return true;
2251 default: return false;
2252 }
2253 }
2254
CompileMethod(Thread * self,const DexFile::CodeItem * code_item,uint32_t access_flags,InvokeType invoke_type,uint16_t class_def_idx,uint32_t method_idx,jobject class_loader,const DexFile & dex_file,DexToDexCompilationLevel dex_to_dex_compilation_level,bool compilation_enabled)2255 void CompilerDriver::CompileMethod(Thread* self, const DexFile::CodeItem* code_item,
2256 uint32_t access_flags, InvokeType invoke_type,
2257 uint16_t class_def_idx, uint32_t method_idx,
2258 jobject class_loader, const DexFile& dex_file,
2259 DexToDexCompilationLevel dex_to_dex_compilation_level,
2260 bool compilation_enabled) {
2261 CompiledMethod* compiled_method = nullptr;
2262 uint64_t start_ns = kTimeCompileMethod ? NanoTime() : 0;
2263 MethodReference method_ref(&dex_file, method_idx);
2264
2265 if ((access_flags & kAccNative) != 0) {
2266 // Are we interpreting only and have support for generic JNI down calls?
2267 if (!compiler_options_->IsCompilationEnabled() &&
2268 InstructionSetHasGenericJniStub(instruction_set_)) {
2269 // Leaving this empty will trigger the generic JNI version
2270 } else {
2271 compiled_method = compiler_->JniCompile(access_flags, method_idx, dex_file);
2272 CHECK(compiled_method != nullptr);
2273 }
2274 } else if ((access_flags & kAccAbstract) != 0) {
2275 // Abstract methods don't have code.
2276 } else {
2277 bool has_verified_method = verification_results_->GetVerifiedMethod(method_ref) != nullptr;
2278 bool compile = compilation_enabled &&
2279 // Basic checks, e.g., not <clinit>.
2280 verification_results_->IsCandidateForCompilation(method_ref, access_flags) &&
2281 // Did not fail to create VerifiedMethod metadata.
2282 has_verified_method &&
2283 // Is eligable for compilation by methods-to-compile filter.
2284 IsMethodToCompile(method_ref);
2285 if (compile) {
2286 // NOTE: if compiler declines to compile this method, it will return null.
2287 compiled_method = compiler_->Compile(code_item, access_flags, invoke_type, class_def_idx,
2288 method_idx, class_loader, dex_file);
2289 }
2290 if (compiled_method == nullptr && dex_to_dex_compilation_level != kDontDexToDexCompile) {
2291 // TODO: add a command-line option to disable DEX-to-DEX compilation ?
2292 // Do not optimize if a VerifiedMethod is missing. SafeCast elision, for example, relies on
2293 // it.
2294 (*dex_to_dex_compiler_)(*this, code_item, access_flags,
2295 invoke_type, class_def_idx,
2296 method_idx, class_loader, dex_file,
2297 has_verified_method ? dex_to_dex_compilation_level : kRequired);
2298 }
2299 }
2300 if (kTimeCompileMethod) {
2301 uint64_t duration_ns = NanoTime() - start_ns;
2302 if (duration_ns > MsToNs(compiler_->GetMaximumCompilationTimeBeforeWarning())) {
2303 LOG(WARNING) << "Compilation of " << PrettyMethod(method_idx, dex_file)
2304 << " took " << PrettyDuration(duration_ns);
2305 }
2306 }
2307
2308 if (compiled_method != nullptr) {
2309 // Count non-relative linker patches.
2310 size_t non_relative_linker_patch_count = 0u;
2311 for (const LinkerPatch& patch : compiled_method->GetPatches()) {
2312 if (!patch.IsPcRelative()) {
2313 ++non_relative_linker_patch_count;
2314 }
2315 }
2316 bool compile_pic = GetCompilerOptions().GetCompilePic(); // Off by default
2317 // When compiling with PIC, there should be zero non-relative linker patches
2318 CHECK(!compile_pic || non_relative_linker_patch_count == 0u);
2319
2320 DCHECK(GetCompiledMethod(method_ref) == nullptr) << PrettyMethod(method_idx, dex_file);
2321 {
2322 MutexLock mu(self, compiled_methods_lock_);
2323 compiled_methods_.Put(method_ref, compiled_method);
2324 non_relative_linker_patch_count_ += non_relative_linker_patch_count;
2325 }
2326 DCHECK(GetCompiledMethod(method_ref) != nullptr) << PrettyMethod(method_idx, dex_file);
2327 }
2328
2329 // Done compiling, delete the verified method to reduce native memory usage. Do not delete in
2330 // optimizing compiler, which may need the verified method again for inlining.
2331 if (compiler_kind_ != Compiler::kOptimizing) {
2332 verification_results_->RemoveVerifiedMethod(method_ref);
2333 }
2334
2335 if (self->IsExceptionPending()) {
2336 ScopedObjectAccess soa(self);
2337 LOG(FATAL) << "Unexpected exception compiling: " << PrettyMethod(method_idx, dex_file) << "\n"
2338 << self->GetException()->Dump();
2339 }
2340 }
2341
RemoveCompiledMethod(const MethodReference & method_ref)2342 void CompilerDriver::RemoveCompiledMethod(const MethodReference& method_ref) {
2343 CompiledMethod* compiled_method = nullptr;
2344 {
2345 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2346 auto it = compiled_methods_.find(method_ref);
2347 if (it != compiled_methods_.end()) {
2348 compiled_method = it->second;
2349 compiled_methods_.erase(it);
2350 }
2351 }
2352 if (compiled_method != nullptr) {
2353 CompiledMethod::ReleaseSwapAllocatedCompiledMethod(this, compiled_method);
2354 }
2355 }
2356
GetCompiledClass(ClassReference ref) const2357 CompiledClass* CompilerDriver::GetCompiledClass(ClassReference ref) const {
2358 MutexLock mu(Thread::Current(), compiled_classes_lock_);
2359 ClassTable::const_iterator it = compiled_classes_.find(ref);
2360 if (it == compiled_classes_.end()) {
2361 return nullptr;
2362 }
2363 CHECK(it->second != nullptr);
2364 return it->second;
2365 }
2366
RecordClassStatus(ClassReference ref,mirror::Class::Status status)2367 void CompilerDriver::RecordClassStatus(ClassReference ref, mirror::Class::Status status) {
2368 MutexLock mu(Thread::Current(), compiled_classes_lock_);
2369 auto it = compiled_classes_.find(ref);
2370 if (it == compiled_classes_.end() || it->second->GetStatus() != status) {
2371 // An entry doesn't exist or the status is lower than the new status.
2372 if (it != compiled_classes_.end()) {
2373 CHECK_GT(status, it->second->GetStatus());
2374 delete it->second;
2375 }
2376 switch (status) {
2377 case mirror::Class::kStatusNotReady:
2378 case mirror::Class::kStatusError:
2379 case mirror::Class::kStatusRetryVerificationAtRuntime:
2380 case mirror::Class::kStatusVerified:
2381 case mirror::Class::kStatusInitialized:
2382 break; // Expected states.
2383 default:
2384 LOG(FATAL) << "Unexpected class status for class "
2385 << PrettyDescriptor(ref.first->GetClassDescriptor(ref.first->GetClassDef(ref.second)))
2386 << " of " << status;
2387 }
2388 CompiledClass* compiled_class = new CompiledClass(status);
2389 compiled_classes_.Overwrite(ref, compiled_class);
2390 }
2391 }
2392
GetCompiledMethod(MethodReference ref) const2393 CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const {
2394 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2395 MethodTable::const_iterator it = compiled_methods_.find(ref);
2396 if (it == compiled_methods_.end()) {
2397 return nullptr;
2398 }
2399 CHECK(it->second != nullptr);
2400 return it->second;
2401 }
2402
IsMethodVerifiedWithoutFailures(uint32_t method_idx,uint16_t class_def_idx,const DexFile & dex_file) const2403 bool CompilerDriver::IsMethodVerifiedWithoutFailures(uint32_t method_idx,
2404 uint16_t class_def_idx,
2405 const DexFile& dex_file) const {
2406 const VerifiedMethod* verified_method = GetVerifiedMethod(&dex_file, method_idx);
2407 if (verified_method != nullptr) {
2408 return !verified_method->HasVerificationFailures();
2409 }
2410
2411 // If we can't find verification metadata, check if this is a system class (we trust that system
2412 // classes have their methods verified). If it's not, be conservative and assume the method
2413 // has not been verified successfully.
2414
2415 // TODO: When compiling the boot image it should be safe to assume that everything is verified,
2416 // even if methods are not found in the verification cache.
2417 const char* descriptor = dex_file.GetClassDescriptor(dex_file.GetClassDef(class_def_idx));
2418 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2419 Thread* self = Thread::Current();
2420 ScopedObjectAccess soa(self);
2421 bool is_system_class = class_linker->FindSystemClass(self, descriptor) != nullptr;
2422 if (!is_system_class) {
2423 self->ClearException();
2424 }
2425 return is_system_class;
2426 }
2427
GetNonRelativeLinkerPatchCount() const2428 size_t CompilerDriver::GetNonRelativeLinkerPatchCount() const {
2429 MutexLock mu(Thread::Current(), compiled_methods_lock_);
2430 return non_relative_linker_patch_count_;
2431 }
2432
AddRequiresConstructorBarrier(Thread * self,const DexFile * dex_file,uint16_t class_def_index)2433 void CompilerDriver::AddRequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
2434 uint16_t class_def_index) {
2435 WriterMutexLock mu(self, freezing_constructor_lock_);
2436 freezing_constructor_classes_.insert(ClassReference(dex_file, class_def_index));
2437 }
2438
RequiresConstructorBarrier(Thread * self,const DexFile * dex_file,uint16_t class_def_index) const2439 bool CompilerDriver::RequiresConstructorBarrier(Thread* self, const DexFile* dex_file,
2440 uint16_t class_def_index) const {
2441 ReaderMutexLock mu(self, freezing_constructor_lock_);
2442 return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
2443 }
2444
WriteElf(const std::string & android_root,bool is_host,const std::vector<const art::DexFile * > & dex_files,OatWriter * oat_writer,art::File * file)2445 bool CompilerDriver::WriteElf(const std::string& android_root,
2446 bool is_host,
2447 const std::vector<const art::DexFile*>& dex_files,
2448 OatWriter* oat_writer,
2449 art::File* file)
2450 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2451 if (kProduce64BitELFFiles && Is64BitInstructionSet(GetInstructionSet())) {
2452 return art::ElfWriterQuick64::Create(file, oat_writer, dex_files, android_root, is_host, *this);
2453 } else {
2454 return art::ElfWriterQuick32::Create(file, oat_writer, dex_files, android_root, is_host, *this);
2455 }
2456 }
2457
SkipCompilation(const std::string & method_name)2458 bool CompilerDriver::SkipCompilation(const std::string& method_name) {
2459 if (!profile_present_) {
2460 return false;
2461 }
2462 // First find the method in the profile file.
2463 ProfileFile::ProfileData data;
2464 if (!profile_file_.GetProfileData(&data, method_name)) {
2465 // Not in profile, no information can be determined.
2466 if (kIsDebugBuild) {
2467 VLOG(compiler) << "not compiling " << method_name << " because it's not in the profile";
2468 }
2469 return true;
2470 }
2471
2472 // Methods that comprise top_k_threshold % of the total samples will be compiled.
2473 // Compare against the start of the topK percentage bucket just in case the threshold
2474 // falls inside a bucket.
2475 bool compile = data.GetTopKUsedPercentage() - data.GetUsedPercent()
2476 <= compiler_options_->GetTopKProfileThreshold();
2477 if (kIsDebugBuild) {
2478 if (compile) {
2479 LOG(INFO) << "compiling method " << method_name << " because its usage is part of top "
2480 << data.GetTopKUsedPercentage() << "% with a percent of " << data.GetUsedPercent() << "%"
2481 << " (topKThreshold=" << compiler_options_->GetTopKProfileThreshold() << ")";
2482 } else {
2483 VLOG(compiler) << "not compiling method " << method_name
2484 << " because it's not part of leading " << compiler_options_->GetTopKProfileThreshold()
2485 << "% samples)";
2486 }
2487 }
2488 return !compile;
2489 }
2490
GetMemoryUsageString(bool extended) const2491 std::string CompilerDriver::GetMemoryUsageString(bool extended) const {
2492 std::ostringstream oss;
2493 Runtime* const runtime = Runtime::Current();
2494 const ArenaPool* arena_pool = runtime->GetArenaPool();
2495 gc::Heap* const heap = runtime->GetHeap();
2496 oss << "arena alloc=" << PrettySize(arena_pool->GetBytesAllocated());
2497 oss << " java alloc=" << PrettySize(heap->GetBytesAllocated());
2498 #if defined(__BIONIC__) || defined(__GLIBC__)
2499 struct mallinfo info = mallinfo();
2500 const size_t allocated_space = static_cast<size_t>(info.uordblks);
2501 const size_t free_space = static_cast<size_t>(info.fordblks);
2502 oss << " native alloc=" << PrettySize(allocated_space) << " free="
2503 << PrettySize(free_space);
2504 #endif
2505 if (swap_space_.get() != nullptr) {
2506 oss << " swap=" << PrettySize(swap_space_->GetSize());
2507 }
2508 if (extended) {
2509 oss << "\nCode dedupe: " << dedupe_code_.DumpStats();
2510 oss << "\nMapping table dedupe: " << dedupe_mapping_table_.DumpStats();
2511 oss << "\nVmap table dedupe: " << dedupe_vmap_table_.DumpStats();
2512 oss << "\nGC map dedupe: " << dedupe_gc_map_.DumpStats();
2513 oss << "\nCFI info dedupe: " << dedupe_cfi_info_.DumpStats();
2514 }
2515 return oss.str();
2516 }
2517
IsStringTypeIndex(uint16_t type_index,const DexFile * dex_file)2518 bool CompilerDriver::IsStringTypeIndex(uint16_t type_index, const DexFile* dex_file) {
2519 const char* type = dex_file->GetTypeDescriptor(dex_file->GetTypeId(type_index));
2520 return strcmp(type, "Ljava/lang/String;") == 0;
2521 }
2522
IsStringInit(uint32_t method_index,const DexFile * dex_file,int32_t * offset)2523 bool CompilerDriver::IsStringInit(uint32_t method_index, const DexFile* dex_file, int32_t* offset) {
2524 DexFileMethodInliner* inliner = GetMethodInlinerMap()->GetMethodInliner(dex_file);
2525 size_t pointer_size = InstructionSetPointerSize(GetInstructionSet());
2526 *offset = inliner->GetOffsetForStringInit(method_index, pointer_size);
2527 return inliner->IsStringInitMethodIndex(method_index);
2528 }
2529
2530 } // namespace art
2531