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 #include <unistd.h>
20
21 #ifndef __APPLE__
22 #include <malloc.h> // For mallinfo
23 #endif
24
25 #include <string_view>
26 #include <vector>
27
28 #include "android-base/logging.h"
29 #include "android-base/strings.h"
30
31 #include "art_field-inl.h"
32 #include "art_method-inl.h"
33 #include "base/arena_allocator.h"
34 #include "base/array_ref.h"
35 #include "base/bit_vector.h"
36 #include "base/hash_set.h"
37 #include "base/logging.h" // For VLOG
38 #include "base/pointer_size.h"
39 #include "base/stl_util.h"
40 #include "base/systrace.h"
41 #include "base/time_utils.h"
42 #include "base/timing_logger.h"
43 #include "class_linker-inl.h"
44 #include "class_root-inl.h"
45 #include "common_throws.h"
46 #include "compiled_method-inl.h"
47 #include "compiler.h"
48 #include "compiler_callbacks.h"
49 #include "compiler_driver-inl.h"
50 #include "dex/class_accessor-inl.h"
51 #include "dex/descriptors_names.h"
52 #include "dex/dex_file-inl.h"
53 #include "dex/dex_file_annotations.h"
54 #include "dex/dex_file_exception_helpers.h"
55 #include "dex/dex_instruction-inl.h"
56 #include "dex/verification_results.h"
57 #include "driver/compiler_options.h"
58 #include "driver/dex_compilation_unit.h"
59 #include "gc/accounting/card_table-inl.h"
60 #include "gc/accounting/heap_bitmap.h"
61 #include "gc/space/image_space.h"
62 #include "gc/space/space.h"
63 #include "handle_scope-inl.h"
64 #include "intrinsics_enum.h"
65 #include "intrinsics_list.h"
66 #include "jni/jni_internal.h"
67 #include "linker/linker_patch.h"
68 #include "mirror/class-inl.h"
69 #include "mirror/class_loader.h"
70 #include "mirror/dex_cache-inl.h"
71 #include "mirror/object-inl.h"
72 #include "mirror/object-refvisitor-inl.h"
73 #include "mirror/object_array-inl.h"
74 #include "mirror/throwable.h"
75 #include "oat/aot_class_linker.h"
76 #include "object_lock.h"
77 #include "profile/profile_compilation_info.h"
78 #include "runtime.h"
79 #include "runtime_intrinsics.h"
80 #include "scoped_thread_state_change-inl.h"
81 #include "thread.h"
82 #include "thread_list.h"
83 #include "thread_pool.h"
84 #include "trampolines/trampoline_compiler.h"
85 #include "utils/atomic_dex_ref_map-inl.h"
86 #include "utils/swap_space.h"
87 #include "vdex_file.h"
88 #include "verifier/class_verifier.h"
89 #include "verifier/verifier_deps.h"
90 #include "verifier/verifier_enums.h"
91 #include "well_known_classes-inl.h"
92
93 namespace art {
94
95 static constexpr bool kTimeCompileMethod = !kIsDebugBuild;
96
97 // Print additional info during profile guided compilation.
98 static constexpr bool kDebugProfileGuidedCompilation = false;
99
100 // Max encoded fields allowed for initializing app image. Hardcode the number for now
101 // because 5000 should be large enough.
102 static constexpr uint32_t kMaxEncodedFields = 5000;
103
Percentage(size_t x,size_t y)104 static double Percentage(size_t x, size_t y) {
105 return 100.0 * (static_cast<double>(x)) / (static_cast<double>(x + y));
106 }
107
DumpStat(size_t x,size_t y,const char * str)108 static void DumpStat(size_t x, size_t y, const char* str) {
109 if (x == 0 && y == 0) {
110 return;
111 }
112 LOG(INFO) << Percentage(x, y) << "% of " << str << " for " << (x + y) << " cases";
113 }
114
115 class CompilerDriver::AOTCompilationStats {
116 public:
AOTCompilationStats()117 AOTCompilationStats()
118 : stats_lock_("AOT compilation statistics lock") {}
119
Dump()120 void Dump() {
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 const size_t total = std::accumulate(
136 class_status_count_,
137 class_status_count_ + static_cast<size_t>(ClassStatus::kLast) + 1,
138 0u);
139 for (size_t i = 0; i <= static_cast<size_t>(ClassStatus::kLast); ++i) {
140 std::ostringstream oss;
141 oss << "classes with status " << static_cast<ClassStatus>(i);
142 DumpStat(class_status_count_[i], total - class_status_count_[i], oss.str().c_str());
143 }
144
145 for (size_t i = 0; i <= kMaxInvokeType; i++) {
146 std::ostringstream oss;
147 oss << static_cast<InvokeType>(i) << " methods were AOT resolved";
148 DumpStat(resolved_methods_[i], unresolved_methods_[i], oss.str().c_str());
149 if (virtual_made_direct_[i] > 0) {
150 std::ostringstream oss2;
151 oss2 << static_cast<InvokeType>(i) << " methods made direct";
152 DumpStat(virtual_made_direct_[i],
153 resolved_methods_[i] + unresolved_methods_[i] - virtual_made_direct_[i],
154 oss2.str().c_str());
155 }
156 if (direct_calls_to_boot_[i] > 0) {
157 std::ostringstream oss2;
158 oss2 << static_cast<InvokeType>(i) << " method calls are direct into boot";
159 DumpStat(direct_calls_to_boot_[i],
160 resolved_methods_[i] + unresolved_methods_[i] - direct_calls_to_boot_[i],
161 oss2.str().c_str());
162 }
163 if (direct_methods_to_boot_[i] > 0) {
164 std::ostringstream oss2;
165 oss2 << static_cast<InvokeType>(i) << " method calls have methods in boot";
166 DumpStat(direct_methods_to_boot_[i],
167 resolved_methods_[i] + unresolved_methods_[i] - direct_methods_to_boot_[i],
168 oss2.str().c_str());
169 }
170 }
171 }
172
173 // Allow lossy statistics in non-debug builds.
174 #ifndef NDEBUG
175 #define STATS_LOCK() MutexLock mu(Thread::Current(), stats_lock_)
176 #else
177 #define STATS_LOCK()
178 #endif
179
ResolvedInstanceField()180 void ResolvedInstanceField() REQUIRES(!stats_lock_) {
181 STATS_LOCK();
182 resolved_instance_fields_++;
183 }
184
UnresolvedInstanceField()185 void UnresolvedInstanceField() REQUIRES(!stats_lock_) {
186 STATS_LOCK();
187 unresolved_instance_fields_++;
188 }
189
ResolvedLocalStaticField()190 void ResolvedLocalStaticField() REQUIRES(!stats_lock_) {
191 STATS_LOCK();
192 resolved_local_static_fields_++;
193 }
194
ResolvedStaticField()195 void ResolvedStaticField() REQUIRES(!stats_lock_) {
196 STATS_LOCK();
197 resolved_static_fields_++;
198 }
199
UnresolvedStaticField()200 void UnresolvedStaticField() REQUIRES(!stats_lock_) {
201 STATS_LOCK();
202 unresolved_static_fields_++;
203 }
204
205 // Indicate that type information from the verifier led to devirtualization.
PreciseTypeDevirtualization()206 void PreciseTypeDevirtualization() REQUIRES(!stats_lock_) {
207 STATS_LOCK();
208 type_based_devirtualization_++;
209 }
210
211 // A check-cast could be eliminated due to verifier type analysis.
SafeCast()212 void SafeCast() REQUIRES(!stats_lock_) {
213 STATS_LOCK();
214 safe_casts_++;
215 }
216
217 // A check-cast couldn't be eliminated due to verifier type analysis.
NotASafeCast()218 void NotASafeCast() REQUIRES(!stats_lock_) {
219 STATS_LOCK();
220 not_safe_casts_++;
221 }
222
223 // Register a class status.
AddClassStatus(ClassStatus status)224 void AddClassStatus(ClassStatus status) REQUIRES(!stats_lock_) {
225 STATS_LOCK();
226 ++class_status_count_[static_cast<size_t>(status)];
227 }
228
229 private:
230 Mutex stats_lock_;
231
232 size_t resolved_instance_fields_ = 0u;
233 size_t unresolved_instance_fields_ = 0u;
234
235 size_t resolved_local_static_fields_ = 0u;
236 size_t resolved_static_fields_ = 0u;
237 size_t unresolved_static_fields_ = 0u;
238 // Type based devirtualization for invoke interface and virtual.
239 size_t type_based_devirtualization_ = 0u;
240
241 size_t resolved_methods_[kMaxInvokeType + 1] = {};
242 size_t unresolved_methods_[kMaxInvokeType + 1] = {};
243 size_t virtual_made_direct_[kMaxInvokeType + 1] = {};
244 size_t direct_calls_to_boot_[kMaxInvokeType + 1] = {};
245 size_t direct_methods_to_boot_[kMaxInvokeType + 1] = {};
246
247 size_t safe_casts_ = 0u;
248 size_t not_safe_casts_ = 0u;
249
250 size_t class_status_count_[static_cast<size_t>(ClassStatus::kLast) + 1] = {};
251
252 DISALLOW_COPY_AND_ASSIGN(AOTCompilationStats);
253 };
254
CompilerDriver(const CompilerOptions * compiler_options,const VerificationResults * verification_results,size_t thread_count,int swap_fd)255 CompilerDriver::CompilerDriver(
256 const CompilerOptions* compiler_options,
257 const VerificationResults* verification_results,
258 size_t thread_count,
259 int swap_fd)
260 : compiler_options_(compiler_options),
261 verification_results_(verification_results),
262 compiler_(),
263 number_of_soft_verifier_failures_(0),
264 had_hard_verifier_failure_(false),
265 parallel_thread_count_(thread_count),
266 stats_(new AOTCompilationStats),
267 compiled_method_storage_(swap_fd),
268 max_arena_alloc_(0) {
269 DCHECK(compiler_options_ != nullptr);
270
271 compiled_method_storage_.SetDedupeEnabled(compiler_options_->DeduplicateCode());
272 compiler_.reset(Compiler::Create(*compiler_options, &compiled_method_storage_));
273 }
274
~CompilerDriver()275 CompilerDriver::~CompilerDriver() {
276 compiled_methods_.Visit(
277 [this]([[maybe_unused]] const DexFileReference& ref, CompiledMethod* method) {
278 if (method != nullptr) {
279 CompiledMethod::ReleaseSwapAllocatedCompiledMethod(GetCompiledMethodStorage(), method);
280 }
281 });
282 }
283
284
285 #define CREATE_TRAMPOLINE(type, abi, offset) \
286 if (Is64BitInstructionSet(GetCompilerOptions().GetInstructionSet())) { \
287 return CreateTrampoline64(GetCompilerOptions().GetInstructionSet(), \
288 abi, \
289 type ## _ENTRYPOINT_OFFSET(PointerSize::k64, offset)); \
290 } else { \
291 return CreateTrampoline32(GetCompilerOptions().GetInstructionSet(), \
292 abi, \
293 type ## _ENTRYPOINT_OFFSET(PointerSize::k32, offset)); \
294 }
295
CreateJniDlsymLookupTrampoline() const296 std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateJniDlsymLookupTrampoline() const {
297 CREATE_TRAMPOLINE(JNI, kJniAbi, pDlsymLookup)
298 }
299
300 std::unique_ptr<const std::vector<uint8_t>>
CreateJniDlsymLookupCriticalTrampoline() const301 CompilerDriver::CreateJniDlsymLookupCriticalTrampoline() const {
302 // @CriticalNative calls do not have the `JNIEnv*` parameter, so this trampoline uses the
303 // architecture-dependent access to `Thread*` using the managed code ABI, i.e. `kQuickAbi`.
304 CREATE_TRAMPOLINE(JNI, kQuickAbi, pDlsymLookupCritical)
305 }
306
CreateQuickGenericJniTrampoline() const307 std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickGenericJniTrampoline()
308 const {
309 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickGenericJniTrampoline)
310 }
311
CreateQuickImtConflictTrampoline() const312 std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickImtConflictTrampoline()
313 const {
314 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickImtConflictTrampoline)
315 }
316
CreateQuickResolutionTrampoline() const317 std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickResolutionTrampoline()
318 const {
319 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickResolutionTrampoline)
320 }
321
CreateQuickToInterpreterBridge() const322 std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickToInterpreterBridge()
323 const {
324 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickToInterpreterBridge)
325 }
326
CreateNterpTrampoline() const327 std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateNterpTrampoline()
328 const {
329 // We use QuickToInterpreterBridge to not waste one word in the Thread object.
330 // The Nterp trampoline gets replaced with the nterp entrypoint when loading
331 // an image.
332 CREATE_TRAMPOLINE(QUICK, kQuickAbi, pQuickToInterpreterBridge)
333 }
334 #undef CREATE_TRAMPOLINE
335
CompileAll(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)336 void CompilerDriver::CompileAll(jobject class_loader,
337 const std::vector<const DexFile*>& dex_files,
338 TimingLogger* timings) {
339 DCHECK(!Runtime::Current()->IsStarted());
340
341 CheckThreadPools();
342
343 // Compile:
344 // 1) Compile all classes and methods enabled for compilation. May fall back to dex-to-dex
345 // compilation.
346 if (GetCompilerOptions().IsAnyCompilationEnabled()) {
347 Compile(class_loader, dex_files, timings);
348 }
349 if (GetCompilerOptions().GetDumpStats()) {
350 stats_->Dump();
351 }
352 }
353
354 // Does the runtime for the InstructionSet provide an implementation returned by
355 // GetQuickGenericJniStub allowing down calls that aren't compiled using a JNI compiler?
InstructionSetHasGenericJniStub(InstructionSet isa)356 static bool InstructionSetHasGenericJniStub(InstructionSet isa) {
357 switch (isa) {
358 case InstructionSet::kArm:
359 case InstructionSet::kArm64:
360 case InstructionSet::kThumb2:
361 case InstructionSet::kX86:
362 case InstructionSet::kX86_64: return true;
363 default: return false;
364 }
365 }
366
367 template <typename CompileFn>
CompileMethodHarness(Thread * self,CompilerDriver * driver,const dex::CodeItem * code_item,uint32_t access_flags,InvokeType invoke_type,uint16_t class_def_idx,uint32_t method_idx,Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,Handle<mirror::DexCache> dex_cache,CompileFn compile_fn)368 static void CompileMethodHarness(
369 Thread* self,
370 CompilerDriver* driver,
371 const dex::CodeItem* code_item,
372 uint32_t access_flags,
373 InvokeType invoke_type,
374 uint16_t class_def_idx,
375 uint32_t method_idx,
376 Handle<mirror::ClassLoader> class_loader,
377 const DexFile& dex_file,
378 Handle<mirror::DexCache> dex_cache,
379 CompileFn compile_fn) {
380 DCHECK(driver != nullptr);
381 CompiledMethod* compiled_method;
382 uint64_t start_ns = kTimeCompileMethod ? NanoTime() : 0;
383 MethodReference method_ref(&dex_file, method_idx);
384
385 compiled_method = compile_fn(self,
386 driver,
387 code_item,
388 access_flags,
389 invoke_type,
390 class_def_idx,
391 method_idx,
392 class_loader,
393 dex_file,
394 dex_cache);
395
396 if (kTimeCompileMethod) {
397 uint64_t duration_ns = NanoTime() - start_ns;
398 if (duration_ns > MsToNs(driver->GetCompiler()->GetMaximumCompilationTimeBeforeWarning())) {
399 LOG(WARNING) << "Compilation of " << dex_file.PrettyMethod(method_idx)
400 << " took " << PrettyDuration(duration_ns);
401 }
402 }
403
404 if (compiled_method != nullptr) {
405 driver->AddCompiledMethod(method_ref, compiled_method);
406 }
407
408 if (self->IsExceptionPending()) {
409 ScopedObjectAccess soa(self);
410 LOG(FATAL) << "Unexpected exception compiling: " << dex_file.PrettyMethod(method_idx) << "\n"
411 << self->GetException()->Dump();
412 }
413 }
414
415 // Checks whether profile guided compilation is enabled and if the method should be compiled
416 // according to the profile file.
ShouldCompileBasedOnProfile(const CompilerOptions & compiler_options,ProfileCompilationInfo::ProfileIndexType profile_index,MethodReference method_ref)417 static bool ShouldCompileBasedOnProfile(const CompilerOptions& compiler_options,
418 ProfileCompilationInfo::ProfileIndexType profile_index,
419 MethodReference method_ref) {
420 if (profile_index == ProfileCompilationInfo::MaxProfileIndex()) {
421 // No profile for this dex file. Check if we're actually compiling based on a profile.
422 if (!CompilerFilter::DependsOnProfile(compiler_options.GetCompilerFilter())) {
423 return true;
424 }
425 // Profile-based compilation without profile for this dex file. Do not compile the method.
426 DCHECK(compiler_options.GetProfileCompilationInfo() == nullptr ||
427 compiler_options.GetProfileCompilationInfo()->FindDexFile(*method_ref.dex_file) ==
428 ProfileCompilationInfo::MaxProfileIndex());
429 return false;
430 } else {
431 DCHECK(CompilerFilter::DependsOnProfile(compiler_options.GetCompilerFilter()));
432 const ProfileCompilationInfo* profile_compilation_info =
433 compiler_options.GetProfileCompilationInfo();
434 DCHECK(profile_compilation_info != nullptr);
435
436 bool result = profile_compilation_info->IsHotMethod(profile_index, method_ref.index);
437
438 // On non-low RAM devices, compile startup methods to potentially speed up
439 // startup.
440 if (!result && Runtime::Current()->GetHeap()->IsLowMemoryMode()) {
441 result = profile_compilation_info->IsStartupMethod(profile_index, method_ref.index);
442 }
443
444 if (kDebugProfileGuidedCompilation) {
445 LOG(INFO) << "[ProfileGuidedCompilation] "
446 << (result ? "Compiled" : "Skipped") << " method:" << method_ref.PrettyMethod(true);
447 }
448
449
450 return result;
451 }
452 }
453
CompileMethodQuick(Thread * self,CompilerDriver * driver,const dex::CodeItem * code_item,uint32_t access_flags,InvokeType invoke_type,uint16_t class_def_idx,uint32_t method_idx,Handle<mirror::ClassLoader> class_loader,const DexFile & dex_file,Handle<mirror::DexCache> dex_cache,ProfileCompilationInfo::ProfileIndexType profile_index)454 static void CompileMethodQuick(
455 Thread* self,
456 CompilerDriver* driver,
457 const dex::CodeItem* code_item,
458 uint32_t access_flags,
459 InvokeType invoke_type,
460 uint16_t class_def_idx,
461 uint32_t method_idx,
462 Handle<mirror::ClassLoader> class_loader,
463 const DexFile& dex_file,
464 Handle<mirror::DexCache> dex_cache,
465 ProfileCompilationInfo::ProfileIndexType profile_index) {
466 auto quick_fn = [profile_index]([[maybe_unused]] Thread* self,
467 CompilerDriver* driver,
468 const dex::CodeItem* code_item,
469 uint32_t access_flags,
470 InvokeType invoke_type,
471 uint16_t class_def_idx,
472 uint32_t method_idx,
473 Handle<mirror::ClassLoader> class_loader,
474 const DexFile& dex_file,
475 Handle<mirror::DexCache> dex_cache) {
476 DCHECK(driver != nullptr);
477 const VerificationResults* results = driver->GetVerificationResults();
478 DCHECK(results != nullptr);
479 MethodReference method_ref(&dex_file, method_idx);
480 CompiledMethod* compiled_method = nullptr;
481 if (results->IsUncompilableMethod(method_ref)) {
482 return compiled_method;
483 }
484
485 if ((access_flags & kAccNative) != 0) {
486 // Are we extracting only and have support for generic JNI down calls?
487 const CompilerOptions& compiler_options = driver->GetCompilerOptions();
488 if (!compiler_options.IsJniCompilationEnabled() &&
489 InstructionSetHasGenericJniStub(compiler_options.GetInstructionSet())) {
490 // Leaving this empty will trigger the generic JNI version
491 } else {
492 // Query any JNI optimization annotations such as @FastNative or @CriticalNative.
493 access_flags |= annotations::GetNativeMethodAnnotationAccessFlags(
494 dex_file, dex_file.GetClassDef(class_def_idx), method_idx);
495 const void* boot_jni_stub = nullptr;
496 if (!Runtime::Current()->GetHeap()->GetBootImageSpaces().empty()) {
497 // Skip the compilation for native method if found an usable boot JNI stub.
498 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
499 std::string_view shorty = dex_file.GetMethodShortyView(dex_file.GetMethodId(method_idx));
500 boot_jni_stub = class_linker->FindBootJniStub(access_flags, shorty);
501 }
502 if (boot_jni_stub == nullptr) {
503 compiled_method =
504 driver->GetCompiler()->JniCompile(access_flags, method_idx, dex_file, dex_cache);
505 CHECK(compiled_method != nullptr);
506 }
507 }
508 } else if ((access_flags & kAccAbstract) != 0) {
509 // Abstract methods don't have code.
510 } else if (annotations::MethodIsNeverCompile(dex_file,
511 dex_file.GetClassDef(class_def_idx),
512 method_idx)) {
513 // Method is annotated with @NeverCompile and should not be compiled.
514 } else {
515 const CompilerOptions& compiler_options = driver->GetCompilerOptions();
516 // Don't compile class initializers unless kEverything.
517 bool compile = (compiler_options.GetCompilerFilter() == CompilerFilter::kEverything) ||
518 ((access_flags & kAccConstructor) == 0) || ((access_flags & kAccStatic) == 0);
519 // Check if we should compile based on the profile.
520 compile = compile && ShouldCompileBasedOnProfile(compiler_options, profile_index, method_ref);
521
522 if (compile) {
523 // NOTE: if compiler declines to compile this method, it will return null.
524 compiled_method = driver->GetCompiler()->Compile(code_item,
525 access_flags,
526 invoke_type,
527 class_def_idx,
528 method_idx,
529 class_loader,
530 dex_file,
531 dex_cache);
532 ProfileMethodsCheck check_type = compiler_options.CheckProfiledMethodsCompiled();
533 if (UNLIKELY(check_type != ProfileMethodsCheck::kNone)) {
534 DCHECK(ShouldCompileBasedOnProfile(compiler_options, profile_index, method_ref));
535 bool violation = (compiled_method == nullptr);
536 if (violation) {
537 std::ostringstream oss;
538 oss << "Failed to compile "
539 << method_ref.dex_file->PrettyMethod(method_ref.index)
540 << "[" << method_ref.dex_file->GetLocation() << "]"
541 << " as expected by profile";
542 switch (check_type) {
543 case ProfileMethodsCheck::kNone:
544 break;
545 case ProfileMethodsCheck::kLog:
546 LOG(ERROR) << oss.str();
547 break;
548 case ProfileMethodsCheck::kAbort:
549 LOG(FATAL_WITHOUT_ABORT) << oss.str();
550 _exit(1);
551 }
552 }
553 }
554 }
555 }
556 return compiled_method;
557 };
558 CompileMethodHarness(self,
559 driver,
560 code_item,
561 access_flags,
562 invoke_type,
563 class_def_idx,
564 method_idx,
565 class_loader,
566 dex_file,
567 dex_cache,
568 quick_fn);
569 }
570
Resolve(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)571 void CompilerDriver::Resolve(jobject class_loader,
572 const std::vector<const DexFile*>& dex_files,
573 TimingLogger* timings) {
574 // Resolution allocates classes and needs to run single-threaded to be deterministic.
575 bool force_determinism = GetCompilerOptions().IsForceDeterminism();
576 ThreadPool* resolve_thread_pool = force_determinism
577 ? single_thread_pool_.get()
578 : parallel_thread_pool_.get();
579 size_t resolve_thread_count = force_determinism ? 1U : parallel_thread_count_;
580
581 for (size_t i = 0; i != dex_files.size(); ++i) {
582 const DexFile* dex_file = dex_files[i];
583 CHECK(dex_file != nullptr);
584 ResolveDexFile(class_loader,
585 *dex_file,
586 resolve_thread_pool,
587 resolve_thread_count,
588 timings);
589 }
590 }
591
ResolveConstStrings(const std::vector<const DexFile * > & dex_files,bool only_startup_strings,TimingLogger * timings)592 void CompilerDriver::ResolveConstStrings(const std::vector<const DexFile*>& dex_files,
593 bool only_startup_strings,
594 TimingLogger* timings) {
595 const ProfileCompilationInfo* profile_compilation_info =
596 GetCompilerOptions().GetProfileCompilationInfo();
597 if (only_startup_strings && profile_compilation_info == nullptr) {
598 // If there is no profile, don't resolve any strings. Resolving all of the strings in the image
599 // will cause a bloated app image and slow down startup.
600 return;
601 }
602 ScopedObjectAccess soa(Thread::Current());
603 StackHandleScope<1> hs(soa.Self());
604 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
605 MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
606 size_t num_instructions = 0u;
607
608 for (const DexFile* dex_file : dex_files) {
609 dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file));
610 TimingLogger::ScopedTiming t("Resolve const-string Strings", timings);
611
612 ProfileCompilationInfo::ProfileIndexType profile_index =
613 ProfileCompilationInfo::MaxProfileIndex();
614 if (profile_compilation_info != nullptr) {
615 profile_index = profile_compilation_info->FindDexFile(*dex_file);
616 if (profile_index == ProfileCompilationInfo::MaxProfileIndex()) {
617 // We have a `ProfileCompilationInfo` but no data for this dex file.
618 // The code below would not find any method to process.
619 continue;
620 }
621 }
622
623 // TODO: Implement a profile-based filter for the boot image. See b/76145463.
624 for (ClassAccessor accessor : dex_file->GetClasses()) {
625 // Skip methods that failed to verify since they may contain invalid Dex code.
626 if (GetClassStatus(ClassReference(dex_file, accessor.GetClassDefIndex())) <
627 ClassStatus::kRetryVerificationAtRuntime) {
628 continue;
629 }
630
631 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
632 if (profile_compilation_info != nullptr) {
633 DCHECK_NE(profile_index, ProfileCompilationInfo::MaxProfileIndex());
634 // There can be at most one class initializer in a class, so we shall not
635 // call `ProfileCompilationInfo::ContainsClass()` more than once per class.
636 constexpr uint32_t kMask = kAccConstructor | kAccStatic;
637 const bool is_startup_clinit =
638 (method.GetAccessFlags() & kMask) == kMask &&
639 profile_compilation_info->ContainsClass(profile_index, accessor.GetClassIdx());
640
641 if (!is_startup_clinit) {
642 uint32_t method_index = method.GetIndex();
643 bool process_method = only_startup_strings
644 ? profile_compilation_info->IsStartupMethod(profile_index, method_index)
645 : profile_compilation_info->IsMethodInProfile(profile_index, method_index);
646 if (!process_method) {
647 continue;
648 }
649 }
650 }
651
652 // Resolve const-strings in the code. Done to have deterministic allocation behavior. Right
653 // now this is single-threaded for simplicity.
654 // TODO: Collect the relevant string indices in parallel, then allocate them sequentially
655 // in a stable order.
656 for (const DexInstructionPcPair& inst : method.GetInstructions()) {
657 switch (inst->Opcode()) {
658 case Instruction::CONST_STRING:
659 case Instruction::CONST_STRING_JUMBO: {
660 dex::StringIndex string_index((inst->Opcode() == Instruction::CONST_STRING)
661 ? inst->VRegB_21c()
662 : inst->VRegB_31c());
663 ObjPtr<mirror::String> string = class_linker->ResolveString(string_index, dex_cache);
664 CHECK(string != nullptr) << "Could not allocate a string when forcing determinism";
665 ++num_instructions;
666 break;
667 }
668
669 default:
670 break;
671 }
672 }
673 }
674 }
675 }
676 VLOG(compiler) << "Resolved " << num_instructions << " const string instructions";
677 }
678
679 // Initialize type check bit strings for check-cast and instance-of in the code. Done to have
680 // deterministic allocation behavior. Right now this is single-threaded for simplicity.
681 // TODO: Collect the relevant type indices in parallel, then process them sequentially in a
682 // stable order.
683
InitializeTypeCheckBitstrings(CompilerDriver * driver,ClassLinker * class_linker,Handle<mirror::DexCache> dex_cache,const DexFile & dex_file,const ClassAccessor::Method & method)684 static void InitializeTypeCheckBitstrings(CompilerDriver* driver,
685 ClassLinker* class_linker,
686 Handle<mirror::DexCache> dex_cache,
687 const DexFile& dex_file,
688 const ClassAccessor::Method& method)
689 REQUIRES_SHARED(Locks::mutator_lock_) {
690 for (const DexInstructionPcPair& inst : method.GetInstructions()) {
691 switch (inst->Opcode()) {
692 case Instruction::CHECK_CAST:
693 case Instruction::INSTANCE_OF: {
694 dex::TypeIndex type_index(
695 (inst->Opcode() == Instruction::CHECK_CAST) ? inst->VRegB_21c() : inst->VRegC_22c());
696 const char* descriptor = dex_file.GetTypeDescriptor(type_index);
697 // We currently do not use the bitstring type check for array or final (including
698 // primitive) classes. We may reconsider this in future if it's deemed to be beneficial.
699 // And we cannot use it for classes outside the boot image as we do not know the runtime
700 // value of their bitstring when compiling (it may not even get assigned at runtime).
701 if (descriptor[0] == 'L' && driver->GetCompilerOptions().IsImageClass(descriptor)) {
702 ObjPtr<mirror::Class> klass =
703 class_linker->LookupResolvedType(type_index,
704 dex_cache.Get(),
705 /* class_loader= */ nullptr);
706 CHECK(klass != nullptr) << descriptor << " should have been previously resolved.";
707 // Now assign the bitstring if the class is not final. Keep this in sync with sharpening.
708 if (!klass->IsFinal()) {
709 MutexLock subtype_check_lock(Thread::Current(), *Locks::subtype_check_lock_);
710 SubtypeCheck<ObjPtr<mirror::Class>>::EnsureAssigned(klass);
711 }
712 }
713 break;
714 }
715
716 default:
717 break;
718 }
719 }
720 }
721
InitializeTypeCheckBitstrings(CompilerDriver * driver,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)722 static void InitializeTypeCheckBitstrings(CompilerDriver* driver,
723 const std::vector<const DexFile*>& dex_files,
724 TimingLogger* timings) {
725 ScopedObjectAccess soa(Thread::Current());
726 StackHandleScope<1> hs(soa.Self());
727 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
728 MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr));
729
730 for (const DexFile* dex_file : dex_files) {
731 dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file));
732 TimingLogger::ScopedTiming t("Initialize type check bitstrings", timings);
733
734 for (ClassAccessor accessor : dex_file->GetClasses()) {
735 // Direct and virtual methods.
736 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
737 InitializeTypeCheckBitstrings(driver, class_linker, dex_cache, *dex_file, method);
738 }
739 }
740 }
741 }
742
CheckThreadPools()743 inline void CompilerDriver::CheckThreadPools() {
744 DCHECK(parallel_thread_pool_ != nullptr);
745 DCHECK(single_thread_pool_ != nullptr);
746 }
747
EnsureVerifiedOrVerifyAtRuntime(jobject jclass_loader,const std::vector<const DexFile * > & dex_files)748 static void EnsureVerifiedOrVerifyAtRuntime(jobject jclass_loader,
749 const std::vector<const DexFile*>& dex_files) {
750 ScopedObjectAccess soa(Thread::Current());
751 StackHandleScope<2> hs(soa.Self());
752 Handle<mirror::ClassLoader> class_loader(
753 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
754 MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
755 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
756
757 for (const DexFile* dex_file : dex_files) {
758 for (ClassAccessor accessor : dex_file->GetClasses()) {
759 cls.Assign(class_linker->FindClass(soa.Self(), accessor.GetDescriptor(), class_loader));
760 if (cls == nullptr) {
761 soa.Self()->ClearException();
762 } else if (&cls->GetDexFile() == dex_file) {
763 DCHECK(cls->IsErroneous() ||
764 cls->IsVerified() ||
765 cls->ShouldVerifyAtRuntime() ||
766 cls->IsVerifiedNeedsAccessChecks())
767 << cls->PrettyClass()
768 << " " << cls->GetStatus();
769 }
770 }
771 }
772 }
773
PrepareDexFilesForOatFile(TimingLogger * timings)774 void CompilerDriver::PrepareDexFilesForOatFile([[maybe_unused]] TimingLogger* timings) {
775 compiled_classes_.AddDexFiles(GetCompilerOptions().GetDexFilesForOatFile());
776 }
777
778 class CreateConflictTablesVisitor : public ClassVisitor {
779 public:
CreateConflictTablesVisitor(VariableSizedHandleScope & hs)780 explicit CreateConflictTablesVisitor(VariableSizedHandleScope& hs)
781 : hs_(hs) {}
782
operator ()(ObjPtr<mirror::Class> klass)783 bool operator()(ObjPtr<mirror::Class> klass) override
784 REQUIRES_SHARED(Locks::mutator_lock_) {
785 if (Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass)) {
786 return true;
787 }
788 // Collect handles since there may be thread suspension in future EnsureInitialized.
789 to_visit_.push_back(hs_.NewHandle(klass));
790 return true;
791 }
792
FillAllIMTAndConflictTables()793 void FillAllIMTAndConflictTables() REQUIRES_SHARED(Locks::mutator_lock_) {
794 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
795 for (Handle<mirror::Class> c : to_visit_) {
796 // Create the conflict tables.
797 FillIMTAndConflictTables(c.Get());
798 }
799 }
800
801 private:
FillIMTAndConflictTables(ObjPtr<mirror::Class> klass)802 void FillIMTAndConflictTables(ObjPtr<mirror::Class> klass)
803 REQUIRES_SHARED(Locks::mutator_lock_) {
804 if (!klass->ShouldHaveImt()) {
805 return;
806 }
807 if (visited_classes_.find(klass.Ptr()) != visited_classes_.end()) {
808 return;
809 }
810 if (klass->HasSuperClass()) {
811 FillIMTAndConflictTables(klass->GetSuperClass());
812 }
813 if (!klass->IsTemp()) {
814 Runtime::Current()->GetClassLinker()->FillIMTAndConflictTables(klass);
815 }
816 visited_classes_.insert(klass.Ptr());
817 }
818
819 VariableSizedHandleScope& hs_;
820 std::vector<Handle<mirror::Class>> to_visit_;
821 HashSet<mirror::Class*> visited_classes_;
822 };
823
PreCompile(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings,HashSet<std::string> * image_classes)824 void CompilerDriver::PreCompile(jobject class_loader,
825 const std::vector<const DexFile*>& dex_files,
826 TimingLogger* timings,
827 /*inout*/ HashSet<std::string>* image_classes) {
828 CheckThreadPools();
829
830 VLOG(compiler) << "Before precompile " << GetMemoryUsageString(false);
831
832 // Precompile:
833 // 1) Load image classes.
834 // 2) Resolve all classes.
835 // 3) For deterministic boot image, resolve strings for const-string instructions.
836 // 4) Attempt to verify all classes.
837 // 5) Attempt to initialize image classes, and trivially initialized classes.
838 // 6) Update the set of image classes.
839 // 7) For deterministic boot image, initialize bitstrings for type checking.
840
841 LoadImageClasses(timings, class_loader, image_classes);
842 VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString(false);
843
844 if (compiler_options_->AssumeClassesAreVerified()) {
845 VLOG(compiler) << "Verify none mode specified, skipping verification.";
846 SetVerified(class_loader, dex_files, timings);
847 } else {
848 DCHECK(compiler_options_->IsVerificationEnabled());
849
850 if (compiler_options_->IsAnyCompilationEnabled()) {
851 // Avoid adding the dex files in the case where we aren't going to add compiled methods.
852 // This reduces RAM usage for this case.
853 for (const DexFile* dex_file : dex_files) {
854 // Can be already inserted. This happens for gtests.
855 if (!compiled_methods_.HaveDexFile(dex_file)) {
856 compiled_methods_.AddDexFile(dex_file);
857 }
858 }
859 }
860
861 // Resolve eagerly for compilations always, and for verifications only if we are running with
862 // multiple threads.
863 const bool should_resolve_eagerly =
864 compiler_options_->IsAnyCompilationEnabled() ||
865 (!GetCompilerOptions().IsForceDeterminism() && parallel_thread_count_ > 1);
866 if (should_resolve_eagerly) {
867 Resolve(class_loader, dex_files, timings);
868 VLOG(compiler) << "Resolve: " << GetMemoryUsageString(false);
869 }
870
871 Verify(class_loader, dex_files, timings);
872 VLOG(compiler) << "Verify: " << GetMemoryUsageString(false);
873
874 if (GetCompilerOptions().IsForceDeterminism() &&
875 (GetCompilerOptions().IsBootImage() || GetCompilerOptions().IsBootImageExtension())) {
876 // Resolve strings from const-string. Do this now to have a deterministic image.
877 ResolveConstStrings(dex_files, /*only_startup_strings=*/ false, timings);
878 VLOG(compiler) << "Resolve const-strings: " << GetMemoryUsageString(false);
879 } else if (GetCompilerOptions().ResolveStartupConstStrings()) {
880 ResolveConstStrings(dex_files, /*only_startup_strings=*/ true, timings);
881 }
882
883 if (had_hard_verifier_failure_ && GetCompilerOptions().AbortOnHardVerifierFailure()) {
884 // Avoid dumping threads. Even if we shut down the thread pools, there will still be three
885 // instances of this thread's stack.
886 LOG(FATAL_WITHOUT_ABORT) << "Had a hard failure verifying all classes, and was asked to abort "
887 << "in such situations. Please check the log.";
888 _exit(1);
889 } else if (number_of_soft_verifier_failures_ > 0 &&
890 GetCompilerOptions().AbortOnSoftVerifierFailure()) {
891 LOG(FATAL_WITHOUT_ABORT) << "Had " << number_of_soft_verifier_failures_ << " soft failure(s) "
892 << "verifying all classes, and was asked to abort in such situations. "
893 << "Please check the log.";
894 _exit(1);
895 }
896
897 if (GetCompilerOptions().IsAppImage() && had_hard_verifier_failure_) {
898 // Prune erroneous classes and classes that depend on them.
899 UpdateImageClasses(timings, image_classes);
900 VLOG(compiler) << "verify/UpdateImageClasses: " << GetMemoryUsageString(false);
901 }
902 }
903
904 if (GetCompilerOptions().IsGeneratingImage()) {
905 // We can only initialize classes when their verification bit is set.
906 if (compiler_options_->AssumeClassesAreVerified() ||
907 compiler_options_->IsVerificationEnabled()) {
908 if (kIsDebugBuild) {
909 EnsureVerifiedOrVerifyAtRuntime(class_loader, dex_files);
910 }
911 InitializeClasses(class_loader, dex_files, timings);
912 VLOG(compiler) << "InitializeClasses: " << GetMemoryUsageString(false);
913 }
914 {
915 // Create conflict tables, as the runtime expects boot image classes to
916 // always have their conflict tables filled.
917 ScopedObjectAccess soa(Thread::Current());
918 VariableSizedHandleScope hs(soa.Self());
919 CreateConflictTablesVisitor visitor(hs);
920 Runtime::Current()->GetClassLinker()->VisitClassesWithoutClassesLock(&visitor);
921 visitor.FillAllIMTAndConflictTables();
922 }
923
924 if (GetCompilerOptions().IsBootImage() || GetCompilerOptions().IsBootImageExtension()) {
925 UpdateImageClasses(timings, image_classes);
926 VLOG(compiler) << "UpdateImageClasses: " << GetMemoryUsageString(false);
927 }
928
929 if (kBitstringSubtypeCheckEnabled &&
930 GetCompilerOptions().IsForceDeterminism() && GetCompilerOptions().IsBootImage()) {
931 // Initialize type check bit string used by check-cast and instanceof.
932 // Do this now to have a deterministic image.
933 // Note: This is done after UpdateImageClasses() at it relies on the image
934 // classes to be final.
935 InitializeTypeCheckBitstrings(this, dex_files, timings);
936 }
937 }
938 }
939
940 class ResolveCatchBlockExceptionsClassVisitor : public ClassVisitor {
941 public:
ResolveCatchBlockExceptionsClassVisitor(Thread * self)942 explicit ResolveCatchBlockExceptionsClassVisitor(Thread* self)
943 : hs_(self),
944 dex_file_records_(),
945 unprocessed_classes_(),
946 exception_types_to_resolve_(),
947 boot_images_start_(Runtime::Current()->GetHeap()->GetBootImagesStartAddress()),
948 boot_images_size_(Runtime::Current()->GetHeap()->GetBootImagesSize()) {}
949
operator ()(ObjPtr<mirror::Class> c)950 bool operator()(ObjPtr<mirror::Class> c) override REQUIRES_SHARED(Locks::mutator_lock_) {
951 // Filter out classes from boot images we're compiling against.
952 // These have been processed when we compiled those boot images.
953 if (reinterpret_cast32<uint32_t>(c.Ptr()) - boot_images_start_ < boot_images_size_) {
954 DCHECK(Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(c));
955 return true;
956 }
957 // Filter out classes without methods.
958 // These include primitive types and array types which have no dex file.
959 if (c->GetMethodsPtr() == nullptr) {
960 return true;
961 }
962 auto it = dex_file_records_.find(&c->GetDexFile());
963 if (it != dex_file_records_.end()) {
964 DexFileRecord& record = it->second;
965 DCHECK_EQ(c->GetDexCache(), record.GetDexCache().Get());
966 DCHECK_EQ(c->GetClassLoader(), record.GetClassLoader().Get());
967 if (record.IsProcessedClass(c)) {
968 return true;
969 }
970 }
971 unprocessed_classes_.push_back(c);
972 return true;
973 }
974
FindAndResolveExceptionTypes(Thread * self,ClassLinker * class_linker)975 void FindAndResolveExceptionTypes(Thread* self, ClassLinker* class_linker)
976 REQUIRES_SHARED(Locks::mutator_lock_) {
977 // If we try to resolve any exception types, we need to repeat the process.
978 // Even if we failed to resolve an exception type, we could have resolved its supertype
979 // or some implemented interfaces as a side-effect (the exception type could implement
980 // another unresolved interface) and we need to visit methods of such new resolved
981 // classes as they shall be recorded as image classes.
982 while (FindExceptionTypesToResolve(class_linker)) {
983 ResolveExceptionTypes(self, class_linker);
984 }
985 }
986
987 private:
988 class DexFileRecord {
989 public:
DexFileRecord(Handle<mirror::DexCache> dex_cache,Handle<mirror::ClassLoader> class_loader)990 DexFileRecord(Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader)
991 REQUIRES_SHARED(Locks::mutator_lock_)
992 : dex_cache_(dex_cache),
993 class_loader_(class_loader),
994 processed_classes_(/*start_bits=*/ dex_cache->GetDexFile()->NumClassDefs(),
995 /*expandable=*/ false,
996 Allocator::GetCallocAllocator()),
997 processed_exception_types_(/*start_bits=*/ dex_cache->GetDexFile()->NumTypeIds(),
998 /*expandable=*/ false,
999 Allocator::GetCallocAllocator()) {}
1000
GetDexCache()1001 Handle<mirror::DexCache> GetDexCache() {
1002 return dex_cache_;
1003 }
1004
GetClassLoader()1005 Handle<mirror::ClassLoader> GetClassLoader() {
1006 return class_loader_;
1007 }
1008
IsProcessedClass(ObjPtr<mirror::Class> c)1009 bool IsProcessedClass(ObjPtr<mirror::Class> c) REQUIRES_SHARED(Locks::mutator_lock_) {
1010 DCHECK_LT(c->GetDexClassDefIndex(), dex_cache_->GetDexFile()->NumClassDefs());
1011 return processed_classes_.IsBitSet(c->GetDexClassDefIndex());
1012 }
1013
MarkProcessedClass(ObjPtr<mirror::Class> c)1014 void MarkProcessedClass(ObjPtr<mirror::Class> c) REQUIRES_SHARED(Locks::mutator_lock_) {
1015 DCHECK_LT(c->GetDexClassDefIndex(), dex_cache_->GetDexFile()->NumClassDefs());
1016 processed_classes_.SetBit(c->GetDexClassDefIndex());
1017 }
1018
IsProcessedExceptionType(dex::TypeIndex type_idx)1019 bool IsProcessedExceptionType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_) {
1020 DCHECK_LT(type_idx.index_, dex_cache_->GetDexFile()->NumTypeIds());
1021 return processed_exception_types_.IsBitSet(type_idx.index_);
1022 }
1023
MarkProcessedExceptionType(dex::TypeIndex type_idx)1024 void MarkProcessedExceptionType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_) {
1025 DCHECK_LT(type_idx.index_, dex_cache_->GetDexFile()->NumTypeIds());
1026 processed_exception_types_.SetBit(type_idx.index_);
1027 }
1028
1029 private:
1030 Handle<mirror::DexCache> dex_cache_;
1031 Handle<mirror::ClassLoader> class_loader_;
1032 BitVector processed_classes_;
1033 BitVector processed_exception_types_;
1034 };
1035
1036 struct ExceptionTypeReference {
1037 dex::TypeIndex exception_type_idx;
1038 Handle<mirror::DexCache> dex_cache;
1039 Handle<mirror::ClassLoader> class_loader;
1040 };
1041
1042 bool FindExceptionTypesToResolve(ClassLinker* class_linker)
1043 REQUIRES_SHARED(Locks::mutator_lock_);
1044
ResolveExceptionTypes(Thread * self,ClassLinker * class_linker)1045 void ResolveExceptionTypes(Thread* self, ClassLinker* class_linker)
1046 REQUIRES_SHARED(Locks::mutator_lock_) {
1047 DCHECK(!exception_types_to_resolve_.empty());
1048 for (auto [exception_type_idx, dex_cache, class_loader] : exception_types_to_resolve_) {
1049 ObjPtr<mirror::Class> exception_class =
1050 class_linker->ResolveType(exception_type_idx, dex_cache, class_loader);
1051 if (exception_class == nullptr) {
1052 VLOG(compiler) << "Failed to resolve exception class "
1053 << dex_cache->GetDexFile()->GetTypeDescriptorView(exception_type_idx);
1054 self->ClearException();
1055 } else {
1056 DCHECK(GetClassRoot<mirror::Throwable>(class_linker)->IsAssignableFrom(exception_class));
1057 }
1058 }
1059 exception_types_to_resolve_.clear();
1060 }
1061
1062 VariableSizedHandleScope hs_;
1063 SafeMap<const DexFile*, DexFileRecord> dex_file_records_;
1064 std::vector<ObjPtr<mirror::Class>> unprocessed_classes_;
1065 std::vector<ExceptionTypeReference> exception_types_to_resolve_;
1066 const uint32_t boot_images_start_;
1067 const uint32_t boot_images_size_;
1068 };
1069
FindExceptionTypesToResolve(ClassLinker * class_linker)1070 bool ResolveCatchBlockExceptionsClassVisitor::FindExceptionTypesToResolve(
1071 ClassLinker* class_linker) {
1072 // Thread suspension is not allowed while the `ResolveCatchBlockExceptionsClassVisitor`
1073 // is using a `std::vector<ObjPtr<mirror::Class>>`.
1074 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
1075 DCHECK(unprocessed_classes_.empty());
1076 class_linker->VisitClasses(this);
1077 if (unprocessed_classes_.empty()) {
1078 return false;
1079 }
1080
1081 DCHECK(exception_types_to_resolve_.empty());
1082 const PointerSize pointer_size = class_linker->GetImagePointerSize();
1083 for (ObjPtr<mirror::Class> klass : unprocessed_classes_) {
1084 const DexFile* dex_file = &klass->GetDexFile();
1085 DexFileRecord& record = dex_file_records_.GetOrCreate(
1086 dex_file,
1087 // NO_THREAD_SAFETY_ANALYSIS: Called from unannotated `SafeMap<>::GetOrCreate()`.
1088 [&]() NO_THREAD_SAFETY_ANALYSIS {
1089 return DexFileRecord(hs_.NewHandle(klass->GetDexCache()),
1090 hs_.NewHandle(klass->GetClassLoader()));
1091 });
1092 DCHECK_EQ(klass->GetDexCache(), record.GetDexCache().Get());
1093 DCHECK_EQ(klass->GetClassLoader(), record.GetClassLoader().Get());
1094 DCHECK(!record.IsProcessedClass(klass));
1095 record.MarkProcessedClass(klass);
1096 for (ArtMethod& method : klass->GetDeclaredMethods(pointer_size)) {
1097 if (method.GetCodeItem() == nullptr) {
1098 continue; // native or abstract method
1099 }
1100 CodeItemDataAccessor accessor(method.DexInstructionData());
1101 if (accessor.TriesSize() == 0) {
1102 continue; // nothing to process
1103 }
1104 const uint8_t* handlers_ptr = accessor.GetCatchHandlerData();
1105 size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&handlers_ptr);
1106 for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
1107 CatchHandlerIterator iterator(handlers_ptr);
1108 for (; iterator.HasNext(); iterator.Next()) {
1109 dex::TypeIndex exception_type_idx = iterator.GetHandlerTypeIndex();
1110 if (exception_type_idx.IsValid() &&
1111 !record.IsProcessedExceptionType(exception_type_idx)) {
1112 record.MarkProcessedExceptionType(exception_type_idx);
1113 // Add to set of types to resolve if not resolved yet.
1114 ObjPtr<mirror::Class> type = class_linker->LookupResolvedType(
1115 exception_type_idx, record.GetDexCache().Get(), record.GetClassLoader().Get());
1116 if (type == nullptr) {
1117 exception_types_to_resolve_.push_back(
1118 {exception_type_idx, record.GetDexCache(), record.GetClassLoader()});
1119 }
1120 }
1121 }
1122 handlers_ptr = iterator.EndDataPointer();
1123 }
1124 }
1125 }
1126 unprocessed_classes_.clear();
1127 return !exception_types_to_resolve_.empty();
1128 }
1129
CanIncludeInCurrentImage(ObjPtr<mirror::Class> klass)1130 static inline bool CanIncludeInCurrentImage(ObjPtr<mirror::Class> klass)
1131 REQUIRES_SHARED(Locks::mutator_lock_) {
1132 DCHECK(klass != nullptr);
1133 gc::Heap* heap = Runtime::Current()->GetHeap();
1134 if (heap->GetBootImageSpaces().empty()) {
1135 return true; // We can include any class when compiling the primary boot image.
1136 }
1137 if (heap->ObjectIsInBootImageSpace(klass)) {
1138 return false; // Already included in the boot image we're compiling against.
1139 }
1140 return AotClassLinker::CanReferenceInBootImageExtensionOrAppImage(klass, heap);
1141 }
1142
1143 class RecordImageClassesVisitor : public ClassVisitor {
1144 public:
RecordImageClassesVisitor(HashSet<std::string> * image_classes)1145 explicit RecordImageClassesVisitor(HashSet<std::string>* image_classes)
1146 : image_classes_(image_classes) {}
1147
operator ()(ObjPtr<mirror::Class> klass)1148 bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
1149 bool resolved = klass->IsResolved();
1150 DCHECK(resolved || klass->IsErroneousUnresolved());
1151 bool can_include_in_image = LIKELY(resolved) && CanIncludeInCurrentImage(klass);
1152 std::string temp;
1153 std::string_view descriptor(klass->GetDescriptor(&temp));
1154 if (can_include_in_image) {
1155 image_classes_->insert(std::string(descriptor)); // Does nothing if already present.
1156 } else {
1157 auto it = image_classes_->find(descriptor);
1158 if (it != image_classes_->end()) {
1159 VLOG(compiler) << "Removing " << (resolved ? "unsuitable" : "unresolved")
1160 << " class from image classes: " << descriptor;
1161 image_classes_->erase(it);
1162 }
1163 }
1164 return true;
1165 }
1166
1167 private:
1168 HashSet<std::string>* const image_classes_;
1169 };
1170
1171 // Verify that classes which contain intrinsics methods are in the list of image classes.
VerifyClassesContainingIntrinsicsAreImageClasses(HashSet<std::string> * image_classes)1172 static void VerifyClassesContainingIntrinsicsAreImageClasses(HashSet<std::string>* image_classes) {
1173 #define CHECK_INTRINSIC_OWNER_CLASS(_, __, ___, ____, _____, ClassName, ______, _______) \
1174 CHECK(image_classes->find(std::string_view(ClassName)) != image_classes->end());
1175
1176 ART_INTRINSICS_LIST(CHECK_INTRINSIC_OWNER_CLASS)
1177 #undef CHECK_INTRINSIC_OWNER_CLASS
1178 }
1179
1180 // We need to put classes required by app class loaders to the boot image,
1181 // otherwise we would not be able to store app class loaders in app images.
AddClassLoaderClasses(HashSet<std::string> * image_classes)1182 static void AddClassLoaderClasses(/* out */ HashSet<std::string>* image_classes) {
1183 ScopedObjectAccess soa(Thread::Current());
1184 // Well known classes have been loaded and shall be added to image classes
1185 // by the `RecordImageClassesVisitor`. However, there are fields with array
1186 // types which we need to add to the image classes explicitly.
1187 ArtField* class_loader_array_fields[] = {
1188 WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders,
1189 // BaseDexClassLoader.sharedLibraryLoadersAfter has the same array type as above.
1190 WellKnownClasses::dalvik_system_DexPathList_dexElements,
1191 };
1192 for (ArtField* field : class_loader_array_fields) {
1193 const char* field_type_descriptor = field->GetTypeDescriptor();
1194 DCHECK_EQ(field_type_descriptor[0], '[');
1195 image_classes->insert(field_type_descriptor);
1196 }
1197 }
1198
VerifyClassLoaderClassesAreImageClasses(HashSet<std::string> * image_classes)1199 static void VerifyClassLoaderClassesAreImageClasses(/* out */ HashSet<std::string>* image_classes) {
1200 ScopedObjectAccess soa(Thread::Current());
1201 ScopedAssertNoThreadSuspension sants(__FUNCTION__);
1202 ObjPtr<mirror::Class> class_loader_classes[] = {
1203 WellKnownClasses::dalvik_system_BaseDexClassLoader.Get(),
1204 WellKnownClasses::dalvik_system_DelegateLastClassLoader.Get(),
1205 WellKnownClasses::dalvik_system_DexClassLoader.Get(),
1206 WellKnownClasses::dalvik_system_DexFile.Get(),
1207 WellKnownClasses::dalvik_system_DexPathList.Get(),
1208 WellKnownClasses::dalvik_system_DexPathList__Element.Get(),
1209 WellKnownClasses::dalvik_system_InMemoryDexClassLoader.Get(),
1210 WellKnownClasses::dalvik_system_PathClassLoader.Get(),
1211 WellKnownClasses::java_lang_BootClassLoader.Get(),
1212 WellKnownClasses::java_lang_ClassLoader.Get(),
1213 };
1214 for (ObjPtr<mirror::Class> klass : class_loader_classes) {
1215 std::string temp;
1216 std::string_view descriptor = klass->GetDescriptor(&temp);
1217 CHECK(image_classes->find(descriptor) != image_classes->end());
1218 }
1219 ArtField* class_loader_fields[] = {
1220 WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList,
1221 WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders,
1222 WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoadersAfter,
1223 WellKnownClasses::dalvik_system_DexFile_cookie,
1224 WellKnownClasses::dalvik_system_DexFile_fileName,
1225 WellKnownClasses::dalvik_system_DexPathList_dexElements,
1226 WellKnownClasses::dalvik_system_DexPathList__Element_dexFile,
1227 WellKnownClasses::java_lang_ClassLoader_parent,
1228 };
1229 for (ArtField* field : class_loader_fields) {
1230 std::string_view field_type_descriptor = field->GetTypeDescriptor();
1231 CHECK(image_classes->find(field_type_descriptor) != image_classes->end());
1232 }
1233 }
1234
1235 // Make a list of descriptors for classes to include in the image
LoadImageClasses(TimingLogger * timings,jobject class_loader,HashSet<std::string> * image_classes)1236 void CompilerDriver::LoadImageClasses(TimingLogger* timings,
1237 jobject class_loader,
1238 /*inout*/ HashSet<std::string>* image_classes) {
1239 CHECK(timings != nullptr);
1240 if (!GetCompilerOptions().IsGeneratingImage()) {
1241 return;
1242 }
1243
1244 TimingLogger::ScopedTiming t("LoadImageClasses", timings);
1245
1246 if (GetCompilerOptions().IsBootImage()) {
1247 // Image classes of intrinsics are loaded and shall be added
1248 // to image classes by the `RecordImageClassesVisitor`.
1249 // Add classes needed for storing class loaders in app images.
1250 AddClassLoaderClasses(image_classes);
1251 }
1252
1253 // Make a first pass to load all classes explicitly listed in the profile.
1254 Thread* self = Thread::Current();
1255 ScopedObjectAccess soa(self);
1256 StackHandleScope<2u> hs(self);
1257 Handle<mirror::ClassLoader> loader = hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader));
1258 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1259 CHECK(image_classes != nullptr);
1260 for (auto it = image_classes->begin(), end = image_classes->end(); it != end;) {
1261 const std::string& descriptor(*it);
1262 ObjPtr<mirror::Class> klass = class_linker->FindClass(self, descriptor.c_str(), loader);
1263 if (klass == nullptr) {
1264 VLOG(compiler) << "Failed to find class " << descriptor;
1265 it = image_classes->erase(it); // May cause some descriptors to be revisited.
1266 self->ClearException();
1267 } else {
1268 ++it;
1269 }
1270 }
1271
1272 // Resolve exception classes referenced by the loaded classes. The catch logic assumes
1273 // exceptions are resolved by the verifier when there is a catch block in an interested method.
1274 // Do this here so that exception classes appear to have been specified image classes.
1275 ResolveCatchBlockExceptionsClassVisitor resolve_exception_classes_visitor(self);
1276 resolve_exception_classes_visitor.FindAndResolveExceptionTypes(self, class_linker);
1277
1278 // We walk the roots looking for classes so that we'll pick up the
1279 // above classes plus any classes they depend on such super
1280 // classes, interfaces, and the required ClassLinker roots.
1281 RecordImageClassesVisitor visitor(image_classes);
1282 class_linker->VisitClasses(&visitor);
1283
1284 if (kIsDebugBuild && GetCompilerOptions().IsBootImage()) {
1285 VerifyClassesContainingIntrinsicsAreImageClasses(image_classes);
1286 VerifyClassLoaderClassesAreImageClasses(image_classes);
1287 }
1288
1289 if (GetCompilerOptions().IsBootImage()) {
1290 CHECK(!image_classes->empty());
1291 }
1292 }
1293
MaybeAddToImageClasses(Thread * self,ObjPtr<mirror::Class> klass,HashSet<std::string> * image_classes)1294 static void MaybeAddToImageClasses(Thread* self,
1295 ObjPtr<mirror::Class> klass,
1296 HashSet<std::string>* image_classes)
1297 REQUIRES_SHARED(Locks::mutator_lock_) {
1298 DCHECK_EQ(self, Thread::Current());
1299 DCHECK(klass->IsResolved());
1300 Runtime* runtime = Runtime::Current();
1301 gc::Heap* heap = runtime->GetHeap();
1302 if (heap->ObjectIsInBootImageSpace(klass)) {
1303 // We're compiling a boot image extension and the class is already
1304 // in the boot image we're compiling against.
1305 return;
1306 }
1307 const PointerSize pointer_size = runtime->GetClassLinker()->GetImagePointerSize();
1308 std::string temp;
1309 while (!klass->IsObjectClass()) {
1310 const char* descriptor = klass->GetDescriptor(&temp);
1311 if (image_classes->find(std::string_view(descriptor)) != image_classes->end()) {
1312 break; // Previously inserted.
1313 }
1314 image_classes->insert(descriptor);
1315 VLOG(compiler) << "Adding " << descriptor << " to image classes";
1316 for (size_t i = 0, num_interfaces = klass->NumDirectInterfaces(); i != num_interfaces; ++i) {
1317 ObjPtr<mirror::Class> interface = klass->GetDirectInterface(i);
1318 DCHECK(interface != nullptr);
1319 MaybeAddToImageClasses(self, interface, image_classes);
1320 }
1321 for (auto& m : klass->GetVirtualMethods(pointer_size)) {
1322 MaybeAddToImageClasses(self, m.GetDeclaringClass(), image_classes);
1323 }
1324 if (klass->IsArrayClass()) {
1325 MaybeAddToImageClasses(self, klass->GetComponentType(), image_classes);
1326 }
1327 klass = klass->GetSuperClass();
1328 }
1329 }
1330
1331 // Keeps all the data for the update together. Also doubles as the reference visitor.
1332 // Note: we can use object pointers because we suspend all threads.
1333 class ClinitImageUpdate {
1334 public:
ClinitImageUpdate(HashSet<std::string> * image_class_descriptors,Thread * self)1335 ClinitImageUpdate(HashSet<std::string>* image_class_descriptors,
1336 Thread* self) REQUIRES_SHARED(Locks::mutator_lock_)
1337 : hs_(self),
1338 image_class_descriptors_(image_class_descriptors),
1339 self_(self) {
1340 CHECK(image_class_descriptors != nullptr);
1341
1342 // Make sure nobody interferes with us.
1343 old_cause_ = self->StartAssertNoThreadSuspension("Boot image closure");
1344 }
1345
~ClinitImageUpdate()1346 ~ClinitImageUpdate() {
1347 // Allow others to suspend again.
1348 self_->EndAssertNoThreadSuspension(old_cause_);
1349 }
1350
1351 // Visitor for VisitReferences.
operator ()(ObjPtr<mirror::Object> object,MemberOffset field_offset,bool is_static) const1352 void operator()(ObjPtr<mirror::Object> object,
1353 MemberOffset field_offset,
1354 [[maybe_unused]] bool is_static) const REQUIRES_SHARED(Locks::mutator_lock_) {
1355 mirror::Object* ref = object->GetFieldObject<mirror::Object>(field_offset);
1356 if (ref != nullptr) {
1357 VisitClinitClassesObject(ref);
1358 }
1359 }
1360
1361 // java.lang.ref.Reference visitor for VisitReferences.
operator ()(ObjPtr<mirror::Class> klass,ObjPtr<mirror::Reference> ref) const1362 void operator()([[maybe_unused]] ObjPtr<mirror::Class> klass,
1363 [[maybe_unused]] ObjPtr<mirror::Reference> ref) const {}
1364
1365 // Ignore class native roots.
VisitRootIfNonNull(mirror::CompressedReference<mirror::Object> * root) const1366 void VisitRootIfNonNull(
1367 [[maybe_unused]] mirror::CompressedReference<mirror::Object>* root) const {}
VisitRoot(mirror::CompressedReference<mirror::Object> * root) const1368 void VisitRoot([[maybe_unused]] mirror::CompressedReference<mirror::Object>* root) const {}
1369
Walk()1370 void Walk() REQUIRES_SHARED(Locks::mutator_lock_) {
1371 // Find all the already-marked classes.
1372 WriterMutexLock mu(self_, *Locks::heap_bitmap_lock_);
1373 FindImageClassesVisitor visitor(this);
1374 Runtime::Current()->GetClassLinker()->VisitClasses(&visitor);
1375
1376 // Use the initial classes as roots for a search.
1377 for (Handle<mirror::Class> klass_root : image_classes_) {
1378 VisitClinitClassesObject(klass_root.Get());
1379 }
1380 ScopedAssertNoThreadSuspension ants(__FUNCTION__);
1381 for (Handle<mirror::Class> h_klass : to_insert_) {
1382 MaybeAddToImageClasses(self_, h_klass.Get(), image_class_descriptors_);
1383 }
1384 }
1385
1386 private:
1387 class FindImageClassesVisitor : public ClassVisitor {
1388 public:
FindImageClassesVisitor(ClinitImageUpdate * data)1389 explicit FindImageClassesVisitor(ClinitImageUpdate* data)
1390 : data_(data) {}
1391
operator ()(ObjPtr<mirror::Class> klass)1392 bool operator()(ObjPtr<mirror::Class> klass) override REQUIRES_SHARED(Locks::mutator_lock_) {
1393 bool resolved = klass->IsResolved();
1394 DCHECK(resolved || klass->IsErroneousUnresolved());
1395 bool can_include_in_image =
1396 LIKELY(resolved) && LIKELY(!klass->IsErroneous()) && CanIncludeInCurrentImage(klass);
1397 std::string temp;
1398 std::string_view descriptor(klass->GetDescriptor(&temp));
1399 auto it = data_->image_class_descriptors_->find(descriptor);
1400 if (it != data_->image_class_descriptors_->end()) {
1401 if (can_include_in_image) {
1402 data_->image_classes_.push_back(data_->hs_.NewHandle(klass));
1403 } else {
1404 VLOG(compiler) << "Removing " << (resolved ? "unsuitable" : "unresolved")
1405 << " class from image classes: " << descriptor;
1406 data_->image_class_descriptors_->erase(it);
1407 }
1408 } else if (can_include_in_image) {
1409 // Check whether the class is initialized and has a clinit or static fields.
1410 // Such classes must be kept too.
1411 if (klass->IsInitialized()) {
1412 PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
1413 if (klass->FindClassInitializer(pointer_size) != nullptr ||
1414 klass->NumStaticFields() != 0) {
1415 DCHECK(!Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(klass->GetDexCache()))
1416 << klass->PrettyDescriptor();
1417 data_->image_classes_.push_back(data_->hs_.NewHandle(klass));
1418 }
1419 }
1420 }
1421 return true;
1422 }
1423
1424 private:
1425 ClinitImageUpdate* const data_;
1426 };
1427
VisitClinitClassesObject(mirror::Object * object) const1428 void VisitClinitClassesObject(mirror::Object* object) const
1429 REQUIRES_SHARED(Locks::mutator_lock_) {
1430 DCHECK(object != nullptr);
1431 if (marked_objects_.find(object) != marked_objects_.end()) {
1432 // Already processed.
1433 return;
1434 }
1435
1436 // Mark it.
1437 marked_objects_.insert(object);
1438
1439 if (object->IsClass()) {
1440 // Add to the TODO list since MaybeAddToImageClasses may cause thread suspension. Thread
1441 // suspensionb is not safe to do in VisitObjects or VisitReferences.
1442 to_insert_.push_back(hs_.NewHandle(object->AsClass()));
1443 } else {
1444 // Else visit the object's class.
1445 VisitClinitClassesObject(object->GetClass());
1446 }
1447
1448 // If it is not a DexCache, visit all references.
1449 if (!object->IsDexCache()) {
1450 object->VisitReferences(*this, *this);
1451 }
1452 }
1453
1454 mutable VariableSizedHandleScope hs_;
1455 mutable std::vector<Handle<mirror::Class>> to_insert_;
1456 mutable HashSet<mirror::Object*> marked_objects_;
1457 HashSet<std::string>* const image_class_descriptors_;
1458 std::vector<Handle<mirror::Class>> image_classes_;
1459 Thread* const self_;
1460 const char* old_cause_;
1461
1462 DISALLOW_COPY_AND_ASSIGN(ClinitImageUpdate);
1463 };
1464
UpdateImageClasses(TimingLogger * timings,HashSet<std::string> * image_classes)1465 void CompilerDriver::UpdateImageClasses(TimingLogger* timings,
1466 /*inout*/ HashSet<std::string>* image_classes) {
1467 DCHECK(GetCompilerOptions().IsGeneratingImage());
1468 TimingLogger::ScopedTiming t("UpdateImageClasses", timings);
1469
1470 // Suspend all threads.
1471 ScopedSuspendAll ssa(__FUNCTION__);
1472
1473 ClinitImageUpdate update(image_classes, Thread::Current());
1474
1475 // Do the marking.
1476 update.Walk();
1477 }
1478
ProcessedInstanceField(bool resolved)1479 void CompilerDriver::ProcessedInstanceField(bool resolved) {
1480 if (!resolved) {
1481 stats_->UnresolvedInstanceField();
1482 } else {
1483 stats_->ResolvedInstanceField();
1484 }
1485 }
1486
ProcessedStaticField(bool resolved,bool local)1487 void CompilerDriver::ProcessedStaticField(bool resolved, bool local) {
1488 if (!resolved) {
1489 stats_->UnresolvedStaticField();
1490 } else if (local) {
1491 stats_->ResolvedLocalStaticField();
1492 } else {
1493 stats_->ResolvedStaticField();
1494 }
1495 }
1496
ComputeInstanceFieldInfo(uint32_t field_idx,const DexCompilationUnit * mUnit,bool is_put,const ScopedObjectAccess & soa)1497 ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
1498 const DexCompilationUnit* mUnit,
1499 bool is_put,
1500 const ScopedObjectAccess& soa) {
1501 // Try to resolve the field and compiling method's class.
1502 ArtField* resolved_field;
1503 ObjPtr<mirror::Class> referrer_class;
1504 Handle<mirror::DexCache> dex_cache(mUnit->GetDexCache());
1505 {
1506 Handle<mirror::ClassLoader> class_loader = mUnit->GetClassLoader();
1507 resolved_field = ResolveField(soa, dex_cache, class_loader, field_idx, /* is_static= */ false);
1508 referrer_class = resolved_field != nullptr
1509 ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader, mUnit) : nullptr;
1510 }
1511 bool can_link = false;
1512 if (resolved_field != nullptr && referrer_class != nullptr) {
1513 std::pair<bool, bool> fast_path = IsFastInstanceField(
1514 dex_cache.Get(), referrer_class, resolved_field, field_idx);
1515 can_link = is_put ? fast_path.second : fast_path.first;
1516 }
1517 ProcessedInstanceField(can_link);
1518 return can_link ? resolved_field : nullptr;
1519 }
1520
ComputeInstanceFieldInfo(uint32_t field_idx,const DexCompilationUnit * mUnit,bool is_put,MemberOffset * field_offset,bool * is_volatile)1521 bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
1522 bool is_put, MemberOffset* field_offset,
1523 bool* is_volatile) {
1524 ScopedObjectAccess soa(Thread::Current());
1525 ArtField* resolved_field = ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa);
1526
1527 if (resolved_field == nullptr) {
1528 // Conservative defaults.
1529 *is_volatile = true;
1530 *field_offset = MemberOffset(static_cast<size_t>(-1));
1531 return false;
1532 } else {
1533 *is_volatile = resolved_field->IsVolatile();
1534 *field_offset = resolved_field->GetOffset();
1535 return true;
1536 }
1537 }
1538
1539 class CompilationVisitor {
1540 public:
~CompilationVisitor()1541 virtual ~CompilationVisitor() {}
1542 virtual void Visit(size_t index) = 0;
1543 };
1544
1545 class ParallelCompilationManager {
1546 public:
ParallelCompilationManager(ClassLinker * class_linker,jobject class_loader,CompilerDriver * compiler,const DexFile * dex_file,ThreadPool * thread_pool)1547 ParallelCompilationManager(ClassLinker* class_linker,
1548 jobject class_loader,
1549 CompilerDriver* compiler,
1550 const DexFile* dex_file,
1551 ThreadPool* thread_pool)
1552 : index_(0),
1553 class_linker_(class_linker),
1554 class_loader_(class_loader),
1555 compiler_(compiler),
1556 dex_file_(dex_file),
1557 thread_pool_(thread_pool) {}
1558
GetClassLinker() const1559 ClassLinker* GetClassLinker() const {
1560 CHECK(class_linker_ != nullptr);
1561 return class_linker_;
1562 }
1563
GetClassLoader() const1564 jobject GetClassLoader() const {
1565 return class_loader_;
1566 }
1567
GetCompiler() const1568 CompilerDriver* GetCompiler() const {
1569 CHECK(compiler_ != nullptr);
1570 return compiler_;
1571 }
1572
GetDexFile() const1573 const DexFile* GetDexFile() const {
1574 CHECK(dex_file_ != nullptr);
1575 return dex_file_;
1576 }
1577
ForAll(size_t begin,size_t end,CompilationVisitor * visitor,size_t work_units)1578 void ForAll(size_t begin, size_t end, CompilationVisitor* visitor, size_t work_units)
1579 REQUIRES(!*Locks::mutator_lock_) {
1580 ForAllLambda(begin, end, [visitor](size_t index) { visitor->Visit(index); }, work_units);
1581 }
1582
1583 template <typename Fn>
ForAllLambda(size_t begin,size_t end,Fn fn,size_t work_units)1584 void ForAllLambda(size_t begin, size_t end, Fn fn, size_t work_units)
1585 REQUIRES(!*Locks::mutator_lock_) {
1586 Thread* self = Thread::Current();
1587 self->AssertNoPendingException();
1588 CHECK_GT(work_units, 0U);
1589
1590 index_.store(begin, std::memory_order_relaxed);
1591 for (size_t i = 0; i < work_units; ++i) {
1592 thread_pool_->AddTask(self, new ForAllClosureLambda<Fn>(this, end, fn));
1593 }
1594 thread_pool_->StartWorkers(self);
1595
1596 // Ensure we're suspended while we're blocked waiting for the other threads to finish (worker
1597 // thread destructor's called below perform join).
1598 CHECK_NE(self->GetState(), ThreadState::kRunnable);
1599
1600 // Wait for all the worker threads to finish.
1601 thread_pool_->Wait(self, true, false);
1602
1603 // And stop the workers accepting jobs.
1604 thread_pool_->StopWorkers(self);
1605 }
1606
NextIndex()1607 size_t NextIndex() {
1608 return index_.fetch_add(1, std::memory_order_seq_cst);
1609 }
1610
1611 private:
1612 template <typename Fn>
1613 class ForAllClosureLambda : public Task {
1614 public:
ForAllClosureLambda(ParallelCompilationManager * manager,size_t end,Fn fn)1615 ForAllClosureLambda(ParallelCompilationManager* manager, size_t end, Fn fn)
1616 : manager_(manager),
1617 end_(end),
1618 fn_(fn) {}
1619
Run(Thread * self)1620 void Run(Thread* self) override {
1621 while (true) {
1622 const size_t index = manager_->NextIndex();
1623 if (UNLIKELY(index >= end_)) {
1624 break;
1625 }
1626 fn_(index);
1627 self->AssertNoPendingException();
1628 }
1629 }
1630
Finalize()1631 void Finalize() override {
1632 delete this;
1633 }
1634
1635 private:
1636 ParallelCompilationManager* const manager_;
1637 const size_t end_;
1638 Fn fn_;
1639 };
1640
1641 AtomicInteger index_;
1642 ClassLinker* const class_linker_;
1643 const jobject class_loader_;
1644 CompilerDriver* const compiler_;
1645 const DexFile* const dex_file_;
1646 ThreadPool* const thread_pool_;
1647
1648 DISALLOW_COPY_AND_ASSIGN(ParallelCompilationManager);
1649 };
1650
1651 // A fast version of SkipClass above if the class pointer is available
1652 // that avoids the expensive FindInClassPath search.
SkipClass(jobject class_loader,const DexFile & dex_file,ObjPtr<mirror::Class> klass)1653 static bool SkipClass(jobject class_loader, const DexFile& dex_file, ObjPtr<mirror::Class> klass)
1654 REQUIRES_SHARED(Locks::mutator_lock_) {
1655 DCHECK(klass != nullptr);
1656 const DexFile& original_dex_file = klass->GetDexFile();
1657 if (&dex_file != &original_dex_file) {
1658 if (class_loader == nullptr) {
1659 LOG(WARNING) << "Skipping class " << klass->PrettyDescriptor() << " from "
1660 << dex_file.GetLocation() << " previously found in "
1661 << original_dex_file.GetLocation();
1662 }
1663 return true;
1664 }
1665 return false;
1666 }
1667
DCheckResolveException(mirror::Throwable * exception)1668 static void DCheckResolveException(mirror::Throwable* exception)
1669 REQUIRES_SHARED(Locks::mutator_lock_) {
1670 if (!kIsDebugBuild) {
1671 return;
1672 }
1673 std::string temp;
1674 const char* descriptor = exception->GetClass()->GetDescriptor(&temp);
1675 const char* expected_exceptions[] = {
1676 "Ljava/lang/ClassFormatError;",
1677 "Ljava/lang/ClassCircularityError;",
1678 "Ljava/lang/IllegalAccessError;",
1679 "Ljava/lang/IncompatibleClassChangeError;",
1680 "Ljava/lang/InstantiationError;",
1681 "Ljava/lang/LinkageError;",
1682 "Ljava/lang/NoClassDefFoundError;",
1683 "Ljava/lang/VerifyError;",
1684 };
1685 bool found = false;
1686 for (size_t i = 0; (found == false) && (i < arraysize(expected_exceptions)); ++i) {
1687 if (strcmp(descriptor, expected_exceptions[i]) == 0) {
1688 found = true;
1689 }
1690 }
1691 if (!found) {
1692 LOG(FATAL) << "Unexpected exception " << exception->Dump();
1693 }
1694 }
1695
1696 template <bool kApp>
1697 class ResolveTypeVisitor : public CompilationVisitor {
1698 public:
ResolveTypeVisitor(const ParallelCompilationManager * manager)1699 explicit ResolveTypeVisitor(const ParallelCompilationManager* manager) : manager_(manager) {
1700 }
Visit(size_t index)1701 void Visit(size_t index) override REQUIRES(!Locks::mutator_lock_) {
1702 const DexFile& dex_file = *manager_->GetDexFile();
1703 // For boot images we resolve all referenced types, such as arrays,
1704 // whereas for applications just those with classdefs.
1705 dex::TypeIndex type_idx = kApp ? dex_file.GetClassDef(index).class_idx_ : dex::TypeIndex(index);
1706 ClassLinker* class_linker = manager_->GetClassLinker();
1707 ScopedObjectAccess soa(Thread::Current());
1708 StackHandleScope<kApp ? 4u : 2u> hs(soa.Self());
1709 Handle<mirror::ClassLoader> class_loader(
1710 hs.NewHandle(soa.Decode<mirror::ClassLoader>(manager_->GetClassLoader())));
1711 // TODO: Fix tests that require `RegisterDexFile()` and use `FindDexCache()` in all cases.
1712 Handle<mirror::DexCache> dex_cache = hs.NewHandle(
1713 kApp ? class_linker->FindDexCache(soa.Self(), dex_file)
1714 : class_linker->RegisterDexFile(dex_file, class_loader.Get()));
1715 DCHECK(dex_cache != nullptr);
1716
1717 // Resolve the class.
1718 ObjPtr<mirror::Class> klass = class_linker->ResolveType(type_idx, dex_cache, class_loader);
1719 if (klass == nullptr) {
1720 mirror::Throwable* exception = soa.Self()->GetException();
1721 DCHECK(exception != nullptr);
1722 VLOG(compiler) << "Exception during type resolution: " << exception->Dump();
1723 if (exception->GetClass() == WellKnownClasses::java_lang_OutOfMemoryError.Get()) {
1724 // There's little point continuing compilation if the heap is exhausted.
1725 // Trying to do so would also introduce non-deterministic compilation results.
1726 LOG(FATAL) << "Out of memory during type resolution for compilation";
1727 }
1728 DCheckResolveException(exception);
1729 soa.Self()->ClearException();
1730 } else {
1731 if (kApp && manager_->GetCompiler()->GetCompilerOptions().IsCheckLinkageConditions()) {
1732 Handle<mirror::Class> hklass = hs.NewHandle(klass);
1733 bool is_fatal = manager_->GetCompiler()->GetCompilerOptions().IsCrashOnLinkageViolation();
1734 Handle<mirror::ClassLoader> defining_class_loader = hs.NewHandle(hklass->GetClassLoader());
1735 if (defining_class_loader.Get() != class_loader.Get()) {
1736 // Redefinition via different ClassLoaders.
1737 // This OptStat stuff is to enable logging from the APK scanner.
1738 if (is_fatal)
1739 LOG(FATAL) << "OptStat#" << hklass->PrettyClassAndClassLoader() << ": 1";
1740 else
1741 LOG(ERROR)
1742 << "LINKAGE VIOLATION: "
1743 << hklass->PrettyClassAndClassLoader()
1744 << " was redefined";
1745 }
1746 // Check that the current class is not a subclass of java.lang.ClassLoader.
1747 if (!hklass->IsInterface() &&
1748 hklass->IsSubClass(class_linker->FindClass(soa.Self(),
1749 "Ljava/lang/ClassLoader;",
1750 defining_class_loader))) {
1751 // Subclassing of java.lang.ClassLoader.
1752 // This OptStat stuff is to enable logging from the APK scanner.
1753 if (is_fatal) {
1754 LOG(FATAL) << "OptStat#" << hklass->PrettyClassAndClassLoader() << ": 1";
1755 } else {
1756 LOG(ERROR)
1757 << "LINKAGE VIOLATION: "
1758 << hklass->PrettyClassAndClassLoader()
1759 << " is a subclass of java.lang.ClassLoader";
1760 }
1761 }
1762 CHECK(hklass->IsResolved()) << hklass->PrettyClass();
1763 }
1764 }
1765 }
1766
1767 private:
1768 const ParallelCompilationManager* const manager_;
1769 };
1770
ResolveDexFile(jobject class_loader,const DexFile & dex_file,ThreadPool * thread_pool,size_t thread_count,TimingLogger * timings)1771 void CompilerDriver::ResolveDexFile(jobject class_loader,
1772 const DexFile& dex_file,
1773 ThreadPool* thread_pool,
1774 size_t thread_count,
1775 TimingLogger* timings) {
1776 ScopedTrace trace(__FUNCTION__);
1777 TimingLogger::ScopedTiming t("Resolve Types", timings);
1778 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1779
1780 // TODO: we could resolve strings here, although the string table is largely filled with class
1781 // and method names.
1782
1783 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
1784 // For boot images we resolve all referenced types, such as arrays,
1785 // whereas for applications just those with classdefs.
1786 if (GetCompilerOptions().IsBootImage() || GetCompilerOptions().IsBootImageExtension()) {
1787 ResolveTypeVisitor</*kApp=*/ false> visitor(&context);
1788 context.ForAll(0, dex_file.NumTypeIds(), &visitor, thread_count);
1789 } else {
1790 ResolveTypeVisitor</*kApp=*/ true> visitor(&context);
1791 context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count);
1792 }
1793 }
1794
SetVerified(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)1795 void CompilerDriver::SetVerified(jobject class_loader,
1796 const std::vector<const DexFile*>& dex_files,
1797 TimingLogger* timings) {
1798 // This can be run in parallel.
1799 for (const DexFile* dex_file : dex_files) {
1800 CHECK(dex_file != nullptr);
1801 SetVerifiedDexFile(class_loader,
1802 *dex_file,
1803 parallel_thread_pool_.get(),
1804 parallel_thread_count_,
1805 timings);
1806 }
1807 }
1808
LoadAndUpdateStatus(const ClassAccessor & accessor,ClassStatus status,Handle<mirror::ClassLoader> class_loader,Thread * self)1809 static void LoadAndUpdateStatus(const ClassAccessor& accessor,
1810 ClassStatus status,
1811 Handle<mirror::ClassLoader> class_loader,
1812 Thread* self)
1813 REQUIRES_SHARED(Locks::mutator_lock_) {
1814 StackHandleScope<1> hs(self);
1815 const char* descriptor = accessor.GetDescriptor();
1816 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1817 Handle<mirror::Class> cls(hs.NewHandle<mirror::Class>(
1818 class_linker->FindClass(self, descriptor, class_loader)));
1819 if (cls != nullptr) {
1820 // Check that the class is resolved with the current dex file. We might get
1821 // a boot image class, or a class in a different dex file for multidex, and
1822 // we should not update the status in that case.
1823 if (&cls->GetDexFile() == &accessor.GetDexFile()) {
1824 VLOG(compiler) << "Updating class status of " << std::string(descriptor) << " to " << status;
1825 ObjectLock<mirror::Class> lock(self, cls);
1826 mirror::Class::SetStatus(cls, status, self);
1827 }
1828 } else {
1829 DCHECK(self->IsExceptionPending());
1830 self->ClearException();
1831 }
1832 }
1833
FastVerify(jobject jclass_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)1834 bool CompilerDriver::FastVerify(jobject jclass_loader,
1835 const std::vector<const DexFile*>& dex_files,
1836 TimingLogger* timings) {
1837 CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
1838 verifier::VerifierDeps* verifier_deps = callbacks->GetVerifierDeps();
1839 // If there exist VerifierDeps that aren't the ones we just created to output, use them to verify.
1840 if (verifier_deps == nullptr || verifier_deps->OutputOnly()) {
1841 return false;
1842 }
1843 TimingLogger::ScopedTiming t("Fast Verify", timings);
1844
1845 ScopedObjectAccess soa(Thread::Current());
1846 StackHandleScope<2> hs(soa.Self());
1847 Handle<mirror::ClassLoader> class_loader(
1848 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
1849 std::string error_msg;
1850
1851 verifier_deps->ValidateDependenciesAndUpdateStatus(
1852 soa.Self(),
1853 class_loader,
1854 dex_files);
1855
1856 bool compiler_only_verifies =
1857 !GetCompilerOptions().IsAnyCompilationEnabled() &&
1858 !GetCompilerOptions().IsGeneratingImage();
1859
1860 const bool is_generating_image = GetCompilerOptions().IsGeneratingImage();
1861
1862 // We successfully validated the dependencies, now update class status
1863 // of verified classes. Note that the dependencies also record which classes
1864 // could not be fully verified; we could try again, but that would hurt verification
1865 // time. So instead we assume these classes still need to be verified at
1866 // runtime.
1867 for (const DexFile* dex_file : dex_files) {
1868 // Fetch the list of verified classes.
1869 const std::vector<bool>& verified_classes = verifier_deps->GetVerifiedClasses(*dex_file);
1870 DCHECK_EQ(verified_classes.size(), dex_file->NumClassDefs());
1871 for (ClassAccessor accessor : dex_file->GetClasses()) {
1872 ClassStatus status = verified_classes[accessor.GetClassDefIndex()]
1873 ? ClassStatus::kVerifiedNeedsAccessChecks
1874 : ClassStatus::kRetryVerificationAtRuntime;
1875 if (compiler_only_verifies) {
1876 // Just update the compiled_classes_ map. The compiler doesn't need to resolve
1877 // the type.
1878 ClassReference ref(dex_file, accessor.GetClassDefIndex());
1879 const ClassStatus existing = ClassStatus::kNotReady;
1880 // Note: when dex files are compiled inidividually, the class may have
1881 // been verified in a previous stage. This means this insertion can
1882 // fail, but that's OK.
1883 compiled_classes_.Insert(ref, existing, status);
1884 } else {
1885 if (is_generating_image &&
1886 status == ClassStatus::kVerifiedNeedsAccessChecks &&
1887 GetCompilerOptions().IsImageClass(accessor.GetDescriptor())) {
1888 // If the class will be in the image, we can rely on the ArtMethods
1889 // telling that they need access checks.
1890 VLOG(compiler) << "Promoting "
1891 << std::string(accessor.GetDescriptor())
1892 << " from needs access checks to verified given it is an image class";
1893 status = ClassStatus::kVerified;
1894 }
1895 // Update the class status, so later compilation stages know they don't need to verify
1896 // the class.
1897 LoadAndUpdateStatus(accessor, status, class_loader, soa.Self());
1898 }
1899
1900 // Vdex marks class as unverified for two reasons only:
1901 // 1. It has a hard failure, or
1902 // 2. One of its method needs lock counting.
1903 //
1904 // The optimizing compiler expects a method to not have a hard failure before
1905 // compiling it, so for simplicity just disable any compilation of methods
1906 // of these classes.
1907 if (status == ClassStatus::kRetryVerificationAtRuntime) {
1908 ClassReference ref(dex_file, accessor.GetClassDefIndex());
1909 callbacks->AddUncompilableClass(ref);
1910 }
1911 }
1912 }
1913 return true;
1914 }
1915
Verify(jobject jclass_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)1916 void CompilerDriver::Verify(jobject jclass_loader,
1917 const std::vector<const DexFile*>& dex_files,
1918 TimingLogger* timings) {
1919 if (FastVerify(jclass_loader, dex_files, timings)) {
1920 return;
1921 }
1922
1923 // If there is no existing `verifier_deps` (because of non-existing vdex), or
1924 // the existing `verifier_deps` is not valid anymore, create a new one. The
1925 // verifier will need it to record the new dependencies. Then dex2oat can update
1926 // the vdex file with these new dependencies.
1927 // Dex2oat creates the verifier deps.
1928 // Create the main VerifierDeps, and set it to this thread.
1929 verifier::VerifierDeps* main_verifier_deps =
1930 Runtime::Current()->GetCompilerCallbacks()->GetVerifierDeps();
1931 // Verifier deps can be null when unit testing.
1932 if (main_verifier_deps != nullptr) {
1933 Thread::Current()->SetVerifierDeps(main_verifier_deps);
1934 // Create per-thread VerifierDeps to avoid contention on the main one.
1935 // We will merge them after verification.
1936 for (ThreadPoolWorker* worker : parallel_thread_pool_->GetWorkers()) {
1937 worker->GetThread()->SetVerifierDeps(
1938 new verifier::VerifierDeps(GetCompilerOptions().GetDexFilesForOatFile()));
1939 }
1940 }
1941
1942 // Verification updates VerifierDeps and needs to run single-threaded to be deterministic.
1943 bool force_determinism = GetCompilerOptions().IsForceDeterminism();
1944 ThreadPool* verify_thread_pool =
1945 force_determinism ? single_thread_pool_.get() : parallel_thread_pool_.get();
1946 size_t verify_thread_count = force_determinism ? 1U : parallel_thread_count_;
1947 for (const DexFile* dex_file : dex_files) {
1948 CHECK(dex_file != nullptr);
1949 VerifyDexFile(jclass_loader,
1950 *dex_file,
1951 verify_thread_pool,
1952 verify_thread_count,
1953 timings);
1954 }
1955
1956 if (main_verifier_deps != nullptr) {
1957 // Merge all VerifierDeps into the main one.
1958 for (ThreadPoolWorker* worker : parallel_thread_pool_->GetWorkers()) {
1959 std::unique_ptr<verifier::VerifierDeps> thread_deps(worker->GetThread()->GetVerifierDeps());
1960 worker->GetThread()->SetVerifierDeps(nullptr); // We just took ownership.
1961 main_verifier_deps->MergeWith(std::move(thread_deps),
1962 GetCompilerOptions().GetDexFilesForOatFile());
1963 }
1964 Thread::Current()->SetVerifierDeps(nullptr);
1965 }
1966 }
1967
1968 class VerifyClassVisitor : public CompilationVisitor {
1969 public:
VerifyClassVisitor(const ParallelCompilationManager * manager,verifier::HardFailLogMode log_level)1970 VerifyClassVisitor(const ParallelCompilationManager* manager, verifier::HardFailLogMode log_level)
1971 : manager_(manager),
1972 log_level_(log_level),
1973 sdk_version_(Runtime::Current()->GetTargetSdkVersion()) {}
1974
Visit(size_t class_def_index)1975 void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) override {
1976 ScopedTrace trace(__FUNCTION__);
1977 ScopedObjectAccess soa(Thread::Current());
1978 const DexFile& dex_file = *manager_->GetDexFile();
1979 const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
1980 const char* descriptor = dex_file.GetClassDescriptor(class_def);
1981 ClassLinker* class_linker = manager_->GetClassLinker();
1982 jobject jclass_loader = manager_->GetClassLoader();
1983 StackHandleScope<3> hs(soa.Self());
1984 Handle<mirror::ClassLoader> class_loader(
1985 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
1986 Handle<mirror::Class> klass(
1987 hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader)));
1988 ClassReference ref(manager_->GetDexFile(), class_def_index);
1989 verifier::FailureKind failure_kind;
1990 if (klass == nullptr) {
1991 CHECK(soa.Self()->IsExceptionPending());
1992 soa.Self()->ClearException();
1993
1994 /*
1995 * At compile time, we can still structurally verify the class even if FindClass fails.
1996 * This is to ensure the class is structurally sound for compilation. An unsound class
1997 * will be rejected by the verifier and later skipped during compilation in the compiler.
1998 */
1999 Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache(
2000 soa.Self(), dex_file)));
2001 std::string error_msg;
2002 failure_kind =
2003 verifier::ClassVerifier::VerifyClass(soa.Self(),
2004 soa.Self()->GetVerifierDeps(),
2005 &dex_file,
2006 klass,
2007 dex_cache,
2008 class_loader,
2009 class_def,
2010 Runtime::Current()->GetCompilerCallbacks(),
2011 log_level_,
2012 sdk_version_,
2013 &error_msg);
2014 switch (failure_kind) {
2015 case verifier::FailureKind::kHardFailure: {
2016 manager_->GetCompiler()->SetHadHardVerifierFailure();
2017 break;
2018 }
2019 case verifier::FailureKind::kSoftFailure: {
2020 manager_->GetCompiler()->AddSoftVerifierFailure();
2021 break;
2022 }
2023 case verifier::FailureKind::kTypeChecksFailure: {
2024 // Don't record anything, we will do the type checks from the vdex
2025 // file at runtime.
2026 break;
2027 }
2028 case verifier::FailureKind::kAccessChecksFailure: {
2029 manager_->GetCompiler()->RecordClassStatus(ref, ClassStatus::kVerifiedNeedsAccessChecks);
2030 break;
2031 }
2032 case verifier::FailureKind::kNoFailure: {
2033 manager_->GetCompiler()->RecordClassStatus(ref, ClassStatus::kVerified);
2034 break;
2035 }
2036 }
2037 } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
2038 // Skip a duplicate class (as the resolved class is from another, earlier dex file).
2039 return; // Do not update state.
2040 } else {
2041 CHECK(klass->IsResolved()) << klass->PrettyClass();
2042 failure_kind = class_linker->VerifyClass(soa.Self(),
2043 soa.Self()->GetVerifierDeps(),
2044 klass,
2045 log_level_);
2046
2047 DCHECK_EQ(klass->IsErroneous(), failure_kind == verifier::FailureKind::kHardFailure);
2048 if (failure_kind == verifier::FailureKind::kHardFailure) {
2049 // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
2050 CHECK(soa.Self()->IsExceptionPending());
2051 soa.Self()->ClearException();
2052 manager_->GetCompiler()->SetHadHardVerifierFailure();
2053 } else if (failure_kind == verifier::FailureKind::kSoftFailure) {
2054 manager_->GetCompiler()->AddSoftVerifierFailure();
2055 }
2056
2057 CHECK(klass->ShouldVerifyAtRuntime() ||
2058 klass->IsVerifiedNeedsAccessChecks() ||
2059 klass->IsVerified() ||
2060 klass->IsErroneous())
2061 << klass->PrettyDescriptor() << ": state=" << klass->GetStatus();
2062
2063 // Class has a meaningful status for the compiler now, record it.
2064 ClassStatus status = klass->GetStatus();
2065 if (status == ClassStatus::kInitialized) {
2066 // Initialized classes shall be visibly initialized when loaded from the image.
2067 status = ClassStatus::kVisiblyInitialized;
2068 }
2069 manager_->GetCompiler()->RecordClassStatus(ref, status);
2070
2071 // It is *very* problematic if there are resolution errors in the boot classpath.
2072 //
2073 // It is also bad if classes fail verification. For example, we rely on things working
2074 // OK without verification when the decryption dialog is brought up. It is thus highly
2075 // recommended to compile the boot classpath with
2076 // --abort-on-hard-verifier-error --abort-on-soft-verifier-error
2077 // which is the default build system configuration.
2078 if (kIsDebugBuild) {
2079 if (manager_->GetCompiler()->GetCompilerOptions().IsBootImage() ||
2080 manager_->GetCompiler()->GetCompilerOptions().IsBootImageExtension()) {
2081 if (!klass->IsResolved() || klass->IsErroneous()) {
2082 LOG(FATAL) << "Boot classpath class " << klass->PrettyClass()
2083 << " failed to resolve/is erroneous: state= " << klass->GetStatus();
2084 UNREACHABLE();
2085 }
2086 }
2087 if (klass->IsVerified()) {
2088 DCHECK_EQ(failure_kind, verifier::FailureKind::kNoFailure);
2089 } else if (klass->IsVerifiedNeedsAccessChecks()) {
2090 DCHECK_EQ(failure_kind, verifier::FailureKind::kAccessChecksFailure);
2091 } else if (klass->ShouldVerifyAtRuntime()) {
2092 DCHECK_NE(failure_kind, verifier::FailureKind::kHardFailure);
2093 // This could either be due to:
2094 // - kTypeChecksFailure, or
2095 // - kSoftFailure, or
2096 // - the superclass or interfaces not being verified.
2097 } else {
2098 DCHECK_EQ(failure_kind, verifier::FailureKind::kHardFailure);
2099 }
2100 }
2101 }
2102 verifier::VerifierDeps::MaybeRecordVerificationStatus(soa.Self()->GetVerifierDeps(),
2103 dex_file,
2104 class_def,
2105 failure_kind);
2106 soa.Self()->AssertNoPendingException();
2107 }
2108
2109 private:
2110 const ParallelCompilationManager* const manager_;
2111 const verifier::HardFailLogMode log_level_;
2112 const uint32_t sdk_version_;
2113 };
2114
VerifyDexFile(jobject class_loader,const DexFile & dex_file,ThreadPool * thread_pool,size_t thread_count,TimingLogger * timings)2115 void CompilerDriver::VerifyDexFile(jobject class_loader,
2116 const DexFile& dex_file,
2117 ThreadPool* thread_pool,
2118 size_t thread_count,
2119 TimingLogger* timings) {
2120 TimingLogger::ScopedTiming t("Verify Dex File", timings);
2121 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2122 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
2123 bool abort_on_verifier_failures = GetCompilerOptions().AbortOnHardVerifierFailure()
2124 || GetCompilerOptions().AbortOnSoftVerifierFailure();
2125 verifier::HardFailLogMode log_level = abort_on_verifier_failures
2126 ? verifier::HardFailLogMode::kLogInternalFatal
2127 : verifier::HardFailLogMode::kLogWarning;
2128 VerifyClassVisitor visitor(&context, log_level);
2129 context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count);
2130
2131 // Make initialized classes visibly initialized.
2132 class_linker->MakeInitializedClassesVisiblyInitialized(Thread::Current(), /*wait=*/ true);
2133 }
2134
2135 class SetVerifiedClassVisitor : public CompilationVisitor {
2136 public:
SetVerifiedClassVisitor(const ParallelCompilationManager * manager)2137 explicit SetVerifiedClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {}
2138
Visit(size_t class_def_index)2139 void Visit(size_t class_def_index) REQUIRES(!Locks::mutator_lock_) override {
2140 ScopedTrace trace(__FUNCTION__);
2141 ScopedObjectAccess soa(Thread::Current());
2142 const DexFile& dex_file = *manager_->GetDexFile();
2143 const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
2144 const char* descriptor = dex_file.GetClassDescriptor(class_def);
2145 ClassLinker* class_linker = manager_->GetClassLinker();
2146 jobject jclass_loader = manager_->GetClassLoader();
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 // Class might have failed resolution. Then don't set it to verified.
2153 if (klass != nullptr) {
2154 // Only do this if the class is resolved. If even resolution fails, quickening will go very,
2155 // very wrong.
2156 if (klass->IsResolved() && !klass->IsErroneousResolved()) {
2157 if (klass->GetStatus() < ClassStatus::kVerified) {
2158 ObjectLock<mirror::Class> lock(soa.Self(), klass);
2159 // Set class status to verified.
2160 mirror::Class::SetStatus(klass, ClassStatus::kVerified, soa.Self());
2161 // Mark methods as pre-verified. If we don't do this, the interpreter will run with
2162 // access checks.
2163 InstructionSet instruction_set =
2164 manager_->GetCompiler()->GetCompilerOptions().GetInstructionSet();
2165 klass->SetSkipAccessChecksFlagOnAllMethods(GetInstructionSetPointerSize(instruction_set));
2166 }
2167 // Record the final class status if necessary.
2168 ClassReference ref(manager_->GetDexFile(), class_def_index);
2169 manager_->GetCompiler()->RecordClassStatus(ref, klass->GetStatus());
2170 }
2171 } else {
2172 Thread* self = soa.Self();
2173 DCHECK(self->IsExceptionPending());
2174 self->ClearException();
2175 }
2176 }
2177
2178 private:
2179 const ParallelCompilationManager* const manager_;
2180 };
2181
SetVerifiedDexFile(jobject class_loader,const DexFile & dex_file,ThreadPool * thread_pool,size_t thread_count,TimingLogger * timings)2182 void CompilerDriver::SetVerifiedDexFile(jobject class_loader,
2183 const DexFile& dex_file,
2184 ThreadPool* thread_pool,
2185 size_t thread_count,
2186 TimingLogger* timings) {
2187 TimingLogger::ScopedTiming t("Set Verified Dex File", timings);
2188 if (!compiled_classes_.HaveDexFile(&dex_file)) {
2189 compiled_classes_.AddDexFile(&dex_file);
2190 }
2191 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2192 ParallelCompilationManager context(class_linker, class_loader, this, &dex_file, thread_pool);
2193 SetVerifiedClassVisitor visitor(&context);
2194 context.ForAll(0, dex_file.NumClassDefs(), &visitor, thread_count);
2195 }
2196
2197 class InitializeClassVisitor : public CompilationVisitor {
2198 public:
InitializeClassVisitor(const ParallelCompilationManager * manager)2199 explicit InitializeClassVisitor(const ParallelCompilationManager* manager) : manager_(manager) {}
2200
Visit(size_t class_def_index)2201 void Visit(size_t class_def_index) override {
2202 ScopedTrace trace(__FUNCTION__);
2203 jobject jclass_loader = manager_->GetClassLoader();
2204 const DexFile& dex_file = *manager_->GetDexFile();
2205 const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
2206 const dex::TypeId& class_type_id = dex_file.GetTypeId(class_def.class_idx_);
2207 const char* descriptor = dex_file.GetStringData(class_type_id.descriptor_idx_);
2208
2209 ScopedObjectAccess soa(Thread::Current());
2210 StackHandleScope<3> hs(soa.Self());
2211 Handle<mirror::ClassLoader> class_loader(
2212 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
2213 Handle<mirror::Class> klass(
2214 hs.NewHandle(manager_->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader)));
2215
2216 if (klass != nullptr) {
2217 if (!SkipClass(manager_->GetClassLoader(), dex_file, klass.Get())) {
2218 TryInitializeClass(soa.Self(), klass, class_loader);
2219 }
2220 manager_->GetCompiler()->stats_->AddClassStatus(klass->GetStatus());
2221 }
2222 // Clear any class not found or verification exceptions.
2223 soa.Self()->ClearException();
2224 }
2225
2226 // A helper function for initializing klass.
TryInitializeClass(Thread * self,Handle<mirror::Class> klass,Handle<mirror::ClassLoader> & class_loader)2227 void TryInitializeClass(Thread* self,
2228 Handle<mirror::Class> klass,
2229 Handle<mirror::ClassLoader>& class_loader)
2230 REQUIRES_SHARED(Locks::mutator_lock_) {
2231 const DexFile& dex_file = klass->GetDexFile();
2232 const dex::ClassDef* class_def = klass->GetClassDef();
2233 const dex::TypeId& class_type_id = dex_file.GetTypeId(class_def->class_idx_);
2234 const char* descriptor = dex_file.GetStringData(class_type_id.descriptor_idx_);
2235 StackHandleScope<3> hs(self);
2236 AotClassLinker* const class_linker = down_cast<AotClassLinker*>(manager_->GetClassLinker());
2237 Runtime* const runtime = Runtime::Current();
2238 const CompilerOptions& compiler_options = manager_->GetCompiler()->GetCompilerOptions();
2239 const bool is_boot_image = compiler_options.IsBootImage();
2240 const bool is_boot_image_extension = compiler_options.IsBootImageExtension();
2241 const bool is_app_image = compiler_options.IsAppImage();
2242
2243 // For boot image extension, do not initialize classes defined
2244 // in dex files belonging to the boot image we're compiling against.
2245 if (is_boot_image_extension &&
2246 runtime->GetHeap()->ObjectIsInBootImageSpace(klass->GetDexCache())) {
2247 // Also return early and don't store the class status in the recorded class status.
2248 return;
2249 }
2250 // Do not initialize classes in boot space when compiling app (with or without image).
2251 if ((!is_boot_image && !is_boot_image_extension) && klass->IsBootStrapClassLoaded()) {
2252 // Also return early and don't store the class status in the recorded class status.
2253 return;
2254 }
2255
2256 ClassStatus old_status = klass->GetStatus();
2257 // Only try to initialize classes that were successfully verified.
2258 if (klass->IsVerified()) {
2259 // Attempt to initialize the class but bail if we either need to initialize the super-class
2260 // or static fields.
2261 class_linker->EnsureInitialized(self, klass, false, false);
2262 DCHECK(!self->IsExceptionPending());
2263 old_status = klass->GetStatus();
2264 if (!klass->IsInitialized()) {
2265 // We don't want non-trivial class initialization occurring on multiple threads due to
2266 // deadlock problems. For example, a parent class is initialized (holding its lock) that
2267 // refers to a sub-class in its static/class initializer causing it to try to acquire the
2268 // sub-class' lock. While on a second thread the sub-class is initialized (holding its lock)
2269 // after first initializing its parents, whose locks are acquired. This leads to a
2270 // parent-to-child and a child-to-parent lock ordering and consequent potential deadlock.
2271 // We need to use an ObjectLock due to potential suspension in the interpreting code. Rather
2272 // than use a special Object for the purpose we use the Class of java.lang.Class.
2273 Handle<mirror::Class> h_klass(hs.NewHandle(klass->GetClass()));
2274 ObjectLock<mirror::Class> lock(self, h_klass);
2275 // Attempt to initialize allowing initialization of parent classes but still not static
2276 // fields.
2277 // Initialize dependencies first only for app or boot image extension,
2278 // to make TryInitializeClass() recursive.
2279 bool try_initialize_with_superclasses =
2280 is_boot_image ? true : InitializeDependencies(klass, class_loader, self);
2281 if (try_initialize_with_superclasses) {
2282 class_linker->EnsureInitialized(self, klass, false, true);
2283 DCHECK(!self->IsExceptionPending());
2284 }
2285 // Otherwise it's in app image or boot image extension but superclasses
2286 // cannot be initialized, no need to proceed.
2287 old_status = klass->GetStatus();
2288
2289 bool too_many_encoded_fields = (!is_boot_image && !is_boot_image_extension) &&
2290 klass->NumStaticFields() > kMaxEncodedFields;
2291
2292 bool have_profile = (compiler_options.GetProfileCompilationInfo() != nullptr) &&
2293 !compiler_options.GetProfileCompilationInfo()->IsEmpty();
2294 // If the class was not initialized, we can proceed to see if we can initialize static
2295 // fields. Limit the max number of encoded fields.
2296 if (!klass->IsInitialized() &&
2297 (is_app_image || is_boot_image || is_boot_image_extension) &&
2298 try_initialize_with_superclasses && !too_many_encoded_fields &&
2299 compiler_options.IsImageClass(descriptor) &&
2300 // TODO(b/274077782): remove this test.
2301 (have_profile || !is_boot_image_extension)) {
2302 bool can_init_static_fields = false;
2303 if (is_boot_image || is_boot_image_extension) {
2304 // We need to initialize static fields, we only do this for image classes that aren't
2305 // marked with the $NoPreloadHolder (which implies this should not be initialized
2306 // early).
2307 can_init_static_fields = !std::string_view(descriptor).ends_with("$NoPreloadHolder;");
2308 } else {
2309 CHECK(is_app_image);
2310 // The boot image case doesn't need to recursively initialize the dependencies with
2311 // special logic since the class linker already does this.
2312 // Optimization will be disabled in debuggable build, because in debuggable mode we
2313 // want the <clinit> behavior to be observable for the debugger, so we don't do the
2314 // <clinit> at compile time.
2315 can_init_static_fields =
2316 ClassLinker::kAppImageMayContainStrings &&
2317 !self->IsExceptionPending() &&
2318 !compiler_options.GetDebuggable() &&
2319 (compiler_options.InitializeAppImageClasses() ||
2320 NoClinitInDependency(klass, self, &class_loader));
2321 // TODO The checking for clinit can be removed since it's already
2322 // checked when init superclass. Currently keep it because it contains
2323 // processing of intern strings. Will be removed later when intern strings
2324 // and clinit are both initialized.
2325 }
2326
2327 if (can_init_static_fields) {
2328 VLOG(compiler) << "Initializing: " << descriptor;
2329 // TODO multithreading support. We should ensure the current compilation thread has
2330 // exclusive access to the runtime and the transaction. To achieve this, we could use
2331 // a ReaderWriterMutex but we're holding the mutator lock so we fail the check of mutex
2332 // validity in Thread::AssertThreadSuspensionIsAllowable.
2333
2334 // Resolve and initialize the exception type before enabling the transaction in case
2335 // the transaction aborts and cannot resolve the type.
2336 // TransactionAbortError is not initialized ant not in boot image, needed only by
2337 // compiler and will be pruned by ImageWriter.
2338 Handle<mirror::Class> exception_class = hs.NewHandle(
2339 class_linker->FindClass(self, kTransactionAbortErrorDescriptor, class_loader));
2340 bool exception_initialized =
2341 class_linker->EnsureInitialized(self, exception_class, true, true);
2342 DCHECK(exception_initialized);
2343
2344 // Run the class initializer in transaction mode.
2345 class_linker->EnterTransactionMode(is_app_image, klass.Get());
2346
2347 bool success = class_linker->EnsureInitialized(self, klass, true, true);
2348 // TODO we detach transaction from runtime to indicate we quit the transactional
2349 // mode which prevents the GC from visiting objects modified during the transaction.
2350 // Ensure GC is not run so don't access freed objects when aborting transaction.
2351
2352 {
2353 ScopedAssertNoThreadSuspension ants("Transaction end");
2354
2355 if (success) {
2356 class_linker->ExitTransactionMode();
2357 DCHECK(!runtime->IsActiveTransaction());
2358
2359 if (is_boot_image || is_boot_image_extension) {
2360 // For boot image and boot image extension, we want to put the updated
2361 // status in the oat class. This is not the case for app image as we
2362 // want to keep the ability to load the oat file without the app image.
2363 old_status = klass->GetStatus();
2364 }
2365 } else {
2366 CHECK(self->IsExceptionPending());
2367 mirror::Throwable* exception = self->GetException();
2368 VLOG(compiler) << "Initialization of " << descriptor << " aborted because of "
2369 << exception->Dump();
2370 std::ostream* file_log = manager_->GetCompiler()->
2371 GetCompilerOptions().GetInitFailureOutput();
2372 if (file_log != nullptr) {
2373 *file_log << descriptor << "\n";
2374 *file_log << exception->Dump() << "\n";
2375 }
2376 self->ClearException();
2377 class_linker->RollbackAllTransactions();
2378 CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored";
2379 }
2380 }
2381
2382 if (!success && (is_boot_image || is_boot_image_extension)) {
2383 // On failure, still intern strings of static fields and seen in <clinit>, as these
2384 // will be created in the zygote. This is separated from the transaction code just
2385 // above as we will allocate strings, so must be allowed to suspend.
2386 // We only need to intern strings for boot image and boot image extension
2387 // because classes that failed to be initialized will not appear in app image.
2388 if (&klass->GetDexFile() == manager_->GetDexFile()) {
2389 InternStrings(klass, class_loader);
2390 } else {
2391 DCHECK(!is_boot_image) << "Boot image must have equal dex files";
2392 }
2393 }
2394 }
2395 }
2396 // Clear exception in case EnsureInitialized has caused one in the code above.
2397 // It's OK to clear the exception here since the compiler is supposed to be fault
2398 // tolerant and will silently not initialize classes that have exceptions.
2399 self->ClearException();
2400
2401 // If the class still isn't initialized, at least try some checks that initialization
2402 // would do so they can be skipped at runtime.
2403 if (!klass->IsInitialized() && class_linker->ValidateSuperClassDescriptors(klass)) {
2404 old_status = ClassStatus::kSuperclassValidated;
2405 } else {
2406 self->ClearException();
2407 }
2408 self->AssertNoPendingException();
2409 }
2410 }
2411 if (old_status == ClassStatus::kInitialized) {
2412 // Initialized classes shall be visibly initialized when loaded from the image.
2413 old_status = ClassStatus::kVisiblyInitialized;
2414 }
2415 // Record the final class status if necessary.
2416 ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
2417 // Back up the status before doing initialization for static encoded fields,
2418 // because the static encoded branch wants to keep the status to uninitialized.
2419 manager_->GetCompiler()->RecordClassStatus(ref, old_status);
2420
2421 if (kIsDebugBuild) {
2422 // Make sure the class initialization did not leave any local references.
2423 self->GetJniEnv()->AssertLocalsEmpty();
2424 }
2425
2426 if (!klass->IsInitialized() &&
2427 (is_boot_image || is_boot_image_extension) &&
2428 !compiler_options.IsPreloadedClass(PrettyDescriptor(descriptor))) {
2429 klass->SetInBootImageAndNotInPreloadedClasses();
2430 }
2431
2432 if (compiler_options.CompileArtTest()) {
2433 // For stress testing and unit-testing the clinit check in compiled code feature.
2434 if (kIsDebugBuild || std::string_view(descriptor).ends_with("$NoPreloadHolder;")) {
2435 klass->SetInBootImageAndNotInPreloadedClasses();
2436 }
2437 }
2438 }
2439
2440 private:
InternStrings(Handle<mirror::Class> klass,Handle<mirror::ClassLoader> class_loader)2441 void InternStrings(Handle<mirror::Class> klass, Handle<mirror::ClassLoader> class_loader)
2442 REQUIRES_SHARED(Locks::mutator_lock_) {
2443 DCHECK(manager_->GetCompiler()->GetCompilerOptions().IsBootImage() ||
2444 manager_->GetCompiler()->GetCompilerOptions().IsBootImageExtension());
2445 DCHECK(klass->IsVerified());
2446 DCHECK(!klass->IsInitialized());
2447
2448 StackHandleScope<1> hs(Thread::Current());
2449 Handle<mirror::DexCache> dex_cache = hs.NewHandle(klass->GetDexCache());
2450 const dex::ClassDef* class_def = klass->GetClassDef();
2451 ClassLinker* class_linker = manager_->GetClassLinker();
2452
2453 // Check encoded final field values for strings and intern.
2454 annotations::RuntimeEncodedStaticFieldValueIterator value_it(dex_cache,
2455 class_loader,
2456 manager_->GetClassLinker(),
2457 *class_def);
2458 for ( ; value_it.HasNext(); value_it.Next()) {
2459 if (value_it.GetValueType() == annotations::RuntimeEncodedStaticFieldValueIterator::kString) {
2460 // Resolve the string. This will intern the string.
2461 art::ObjPtr<mirror::String> resolved = class_linker->ResolveString(
2462 dex::StringIndex(value_it.GetJavaValue().i), dex_cache);
2463 CHECK(resolved != nullptr);
2464 }
2465 }
2466
2467 // Intern strings seen in <clinit>.
2468 ArtMethod* clinit = klass->FindClassInitializer(class_linker->GetImagePointerSize());
2469 if (clinit != nullptr) {
2470 for (const DexInstructionPcPair& inst : clinit->DexInstructions()) {
2471 if (inst->Opcode() == Instruction::CONST_STRING) {
2472 ObjPtr<mirror::String> s = class_linker->ResolveString(
2473 dex::StringIndex(inst->VRegB_21c()), dex_cache);
2474 CHECK(s != nullptr);
2475 } else if (inst->Opcode() == Instruction::CONST_STRING_JUMBO) {
2476 ObjPtr<mirror::String> s = class_linker->ResolveString(
2477 dex::StringIndex(inst->VRegB_31c()), dex_cache);
2478 CHECK(s != nullptr);
2479 }
2480 }
2481 }
2482 }
2483
ResolveTypesOfMethods(Thread * self,ArtMethod * m)2484 bool ResolveTypesOfMethods(Thread* self, ArtMethod* m)
2485 REQUIRES_SHARED(Locks::mutator_lock_) {
2486 // Return value of ResolveReturnType() is discarded because resolve will be done internally.
2487 ObjPtr<mirror::Class> rtn_type = m->ResolveReturnType();
2488 if (rtn_type == nullptr) {
2489 self->ClearException();
2490 return false;
2491 }
2492 const dex::TypeList* types = m->GetParameterTypeList();
2493 if (types != nullptr) {
2494 for (uint32_t i = 0; i < types->Size(); ++i) {
2495 dex::TypeIndex param_type_idx = types->GetTypeItem(i).type_idx_;
2496 ObjPtr<mirror::Class> param_type = m->ResolveClassFromTypeIndex(param_type_idx);
2497 if (param_type == nullptr) {
2498 self->ClearException();
2499 return false;
2500 }
2501 }
2502 }
2503 return true;
2504 }
2505
2506 // Pre resolve types mentioned in all method signatures before start a transaction
2507 // since ResolveType doesn't work in transaction mode.
PreResolveTypes(Thread * self,const Handle<mirror::Class> & klass)2508 bool PreResolveTypes(Thread* self, const Handle<mirror::Class>& klass)
2509 REQUIRES_SHARED(Locks::mutator_lock_) {
2510 PointerSize pointer_size = manager_->GetClassLinker()->GetImagePointerSize();
2511 for (ArtMethod& m : klass->GetMethods(pointer_size)) {
2512 if (!ResolveTypesOfMethods(self, &m)) {
2513 return false;
2514 }
2515 }
2516 if (klass->IsInterface()) {
2517 return true;
2518 } else if (klass->HasSuperClass()) {
2519 StackHandleScope<1> hs(self);
2520 MutableHandle<mirror::Class> super_klass(hs.NewHandle<mirror::Class>(klass->GetSuperClass()));
2521 for (int i = super_klass->GetVTableLength() - 1; i >= 0; --i) {
2522 ArtMethod* m = klass->GetVTableEntry(i, pointer_size);
2523 ArtMethod* super_m = super_klass->GetVTableEntry(i, pointer_size);
2524 if (!ResolveTypesOfMethods(self, m) || !ResolveTypesOfMethods(self, super_m)) {
2525 return false;
2526 }
2527 }
2528 for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
2529 super_klass.Assign(klass->GetIfTable()->GetInterface(i));
2530 if (klass->GetClassLoader() != super_klass->GetClassLoader()) {
2531 uint32_t num_methods = super_klass->NumVirtualMethods();
2532 for (uint32_t j = 0; j < num_methods; ++j) {
2533 ArtMethod* m = klass->GetIfTable()->GetMethodArray(i)->GetElementPtrSize<ArtMethod*>(
2534 j, pointer_size);
2535 ArtMethod* super_m = super_klass->GetVirtualMethod(j, pointer_size);
2536 if (!ResolveTypesOfMethods(self, m) || !ResolveTypesOfMethods(self, super_m)) {
2537 return false;
2538 }
2539 }
2540 }
2541 }
2542 }
2543 return true;
2544 }
2545
2546 // Initialize the klass's dependencies recursively before initializing itself.
2547 // Checking for interfaces is also necessary since interfaces that contain
2548 // default methods must be initialized before the class.
InitializeDependencies(const Handle<mirror::Class> & klass,Handle<mirror::ClassLoader> class_loader,Thread * self)2549 bool InitializeDependencies(const Handle<mirror::Class>& klass,
2550 Handle<mirror::ClassLoader> class_loader,
2551 Thread* self)
2552 REQUIRES_SHARED(Locks::mutator_lock_) {
2553 if (klass->HasSuperClass()) {
2554 StackHandleScope<1> hs(self);
2555 Handle<mirror::Class> super_class = hs.NewHandle(klass->GetSuperClass());
2556 if (!super_class->IsInitialized()) {
2557 this->TryInitializeClass(self, super_class, class_loader);
2558 if (!super_class->IsInitialized()) {
2559 return false;
2560 }
2561 }
2562 }
2563
2564 if (!klass->IsInterface()) {
2565 size_t num_interfaces = klass->GetIfTableCount();
2566 for (size_t i = 0; i < num_interfaces; ++i) {
2567 StackHandleScope<1> hs(self);
2568 Handle<mirror::Class> iface = hs.NewHandle(klass->GetIfTable()->GetInterface(i));
2569 if (iface->HasDefaultMethods() && !iface->IsInitialized()) {
2570 TryInitializeClass(self, iface, class_loader);
2571 if (!iface->IsInitialized()) {
2572 return false;
2573 }
2574 }
2575 }
2576 }
2577
2578 return PreResolveTypes(self, klass);
2579 }
2580
2581 // In this phase the classes containing class initializers are ignored. Make sure no
2582 // clinit appears in klass's super class chain and interfaces.
NoClinitInDependency(const Handle<mirror::Class> & klass,Thread * self,Handle<mirror::ClassLoader> * class_loader)2583 bool NoClinitInDependency(const Handle<mirror::Class>& klass,
2584 Thread* self,
2585 Handle<mirror::ClassLoader>* class_loader)
2586 REQUIRES_SHARED(Locks::mutator_lock_) {
2587 ArtMethod* clinit =
2588 klass->FindClassInitializer(manager_->GetClassLinker()->GetImagePointerSize());
2589 if (clinit != nullptr) {
2590 VLOG(compiler) << klass->PrettyClass() << ' ' << clinit->PrettyMethod(true);
2591 return false;
2592 }
2593 if (klass->HasSuperClass()) {
2594 ObjPtr<mirror::Class> super_class = klass->GetSuperClass();
2595 StackHandleScope<1> hs(self);
2596 Handle<mirror::Class> handle_scope_super(hs.NewHandle(super_class));
2597 if (!NoClinitInDependency(handle_scope_super, self, class_loader)) {
2598 return false;
2599 }
2600 }
2601
2602 uint32_t num_if = klass->NumDirectInterfaces();
2603 for (size_t i = 0; i < num_if; i++) {
2604 ObjPtr<mirror::Class> interface = klass->GetDirectInterface(i);
2605 DCHECK(interface != nullptr);
2606 StackHandleScope<1> hs(self);
2607 Handle<mirror::Class> handle_interface(hs.NewHandle(interface));
2608 if (!NoClinitInDependency(handle_interface, self, class_loader)) {
2609 return false;
2610 }
2611 }
2612
2613 return true;
2614 }
2615
2616 const ParallelCompilationManager* const manager_;
2617 };
2618
InitializeClasses(jobject jni_class_loader,const DexFile & dex_file,TimingLogger * timings)2619 void CompilerDriver::InitializeClasses(jobject jni_class_loader,
2620 const DexFile& dex_file,
2621 TimingLogger* timings) {
2622 TimingLogger::ScopedTiming t("InitializeNoClinit", timings);
2623
2624 // Initialization allocates objects and needs to run single-threaded to be deterministic.
2625 bool force_determinism = GetCompilerOptions().IsForceDeterminism();
2626 ThreadPool* init_thread_pool = force_determinism
2627 ? single_thread_pool_.get()
2628 : parallel_thread_pool_.get();
2629 size_t init_thread_count = force_determinism ? 1U : parallel_thread_count_;
2630
2631 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2632 ParallelCompilationManager context(
2633 class_linker, jni_class_loader, this, &dex_file, init_thread_pool);
2634
2635 if (GetCompilerOptions().IsBootImage() ||
2636 GetCompilerOptions().IsBootImageExtension() ||
2637 GetCompilerOptions().IsAppImage()) {
2638 // Set the concurrency thread to 1 to support initialization for images since transaction
2639 // doesn't support multithreading now.
2640 // TODO: remove this when transactional mode supports multithreading.
2641 init_thread_count = 1U;
2642 }
2643 InitializeClassVisitor visitor(&context);
2644 context.ForAll(0, dex_file.NumClassDefs(), &visitor, init_thread_count);
2645
2646 // Make initialized classes visibly initialized.
2647 class_linker->MakeInitializedClassesVisiblyInitialized(Thread::Current(), /*wait=*/ true);
2648 }
2649
InitializeClasses(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)2650 void CompilerDriver::InitializeClasses(jobject class_loader,
2651 const std::vector<const DexFile*>& dex_files,
2652 TimingLogger* timings) {
2653 for (const DexFile* dex_file : dex_files) {
2654 CHECK(dex_file != nullptr);
2655 InitializeClasses(class_loader, *dex_file, timings);
2656 }
2657 if (GetCompilerOptions().IsBootImage() || GetCompilerOptions().IsBootImageExtension()) {
2658 // Prune garbage objects created during aborted transactions.
2659 Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ true);
2660 }
2661 }
2662
2663 template <typename CompileFn>
CompileDexFile(CompilerDriver * driver,jobject class_loader,const DexFile & dex_file,ThreadPool * thread_pool,size_t thread_count,TimingLogger * timings,const char * timing_name,CompileFn compile_fn)2664 static void CompileDexFile(CompilerDriver* driver,
2665 jobject class_loader,
2666 const DexFile& dex_file,
2667 ThreadPool* thread_pool,
2668 size_t thread_count,
2669 TimingLogger* timings,
2670 const char* timing_name,
2671 CompileFn compile_fn) {
2672 TimingLogger::ScopedTiming t(timing_name, timings);
2673 ParallelCompilationManager context(Runtime::Current()->GetClassLinker(),
2674 class_loader,
2675 driver,
2676 &dex_file,
2677 thread_pool);
2678 const CompilerOptions& compiler_options = driver->GetCompilerOptions();
2679 bool have_profile = (compiler_options.GetProfileCompilationInfo() != nullptr);
2680 bool use_profile = CompilerFilter::DependsOnProfile(compiler_options.GetCompilerFilter());
2681 ProfileCompilationInfo::ProfileIndexType profile_index = (have_profile && use_profile)
2682 ? compiler_options.GetProfileCompilationInfo()->FindDexFile(dex_file)
2683 : ProfileCompilationInfo::MaxProfileIndex();
2684
2685 auto compile = [&context, &compile_fn, profile_index](size_t class_def_index) {
2686 const DexFile& dex_file = *context.GetDexFile();
2687 SCOPED_TRACE << "compile " << dex_file.GetLocation() << "@" << class_def_index;
2688 ClassLinker* class_linker = context.GetClassLinker();
2689 jobject jclass_loader = context.GetClassLoader();
2690 ClassReference ref(&dex_file, class_def_index);
2691 const dex::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
2692 ClassAccessor accessor(dex_file, class_def_index);
2693 CompilerDriver* const driver = context.GetCompiler();
2694 // Skip compiling classes with generic verifier failures since they will still fail at runtime
2695 DCHECK(driver->GetVerificationResults() != nullptr);
2696 if (driver->GetVerificationResults()->IsClassRejected(ref)) {
2697 return;
2698 }
2699 // Use a scoped object access to perform to the quick SkipClass check.
2700 ScopedObjectAccess soa(Thread::Current());
2701 StackHandleScope<3> hs(soa.Self());
2702 Handle<mirror::ClassLoader> class_loader(
2703 hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader)));
2704 Handle<mirror::Class> klass(
2705 hs.NewHandle(class_linker->FindClass(soa.Self(), accessor.GetDescriptor(), class_loader)));
2706 Handle<mirror::DexCache> dex_cache;
2707 if (klass == nullptr) {
2708 soa.Self()->AssertPendingException();
2709 soa.Self()->ClearException();
2710 dex_cache = hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file));
2711 } else if (SkipClass(jclass_loader, dex_file, klass.Get())) {
2712 // Skip a duplicate class (as the resolved class is from another, earlier dex file).
2713 return; // Do not update state.
2714 } else {
2715 dex_cache = hs.NewHandle(klass->GetDexCache());
2716 }
2717
2718 // Avoid suspension if there are no methods to compile.
2719 if (accessor.NumDirectMethods() + accessor.NumVirtualMethods() == 0) {
2720 return;
2721 }
2722
2723 // Go to native so that we don't block GC during compilation.
2724 ScopedThreadSuspension sts(soa.Self(), ThreadState::kNative);
2725
2726 // Compile direct and virtual methods.
2727 int64_t previous_method_idx = -1;
2728 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
2729 const uint32_t method_idx = method.GetIndex();
2730 if (method_idx == previous_method_idx) {
2731 // smali can create dex files with two encoded_methods sharing the same method_idx
2732 // http://code.google.com/p/smali/issues/detail?id=119
2733 continue;
2734 }
2735 previous_method_idx = method_idx;
2736 compile_fn(soa.Self(),
2737 driver,
2738 method.GetCodeItem(),
2739 method.GetAccessFlags(),
2740 method.GetInvokeType(class_def.access_flags_),
2741 class_def_index,
2742 method_idx,
2743 class_loader,
2744 dex_file,
2745 dex_cache,
2746 profile_index);
2747 }
2748 };
2749 context.ForAllLambda(0, dex_file.NumClassDefs(), compile, thread_count);
2750 }
2751
Compile(jobject class_loader,const std::vector<const DexFile * > & dex_files,TimingLogger * timings)2752 void CompilerDriver::Compile(jobject class_loader,
2753 const std::vector<const DexFile*>& dex_files,
2754 TimingLogger* timings) {
2755 if (kDebugProfileGuidedCompilation) {
2756 const ProfileCompilationInfo* profile_compilation_info =
2757 GetCompilerOptions().GetProfileCompilationInfo();
2758 LOG(INFO) << "[ProfileGuidedCompilation] " <<
2759 ((profile_compilation_info == nullptr)
2760 ? "null"
2761 : profile_compilation_info->DumpInfo(dex_files));
2762 }
2763
2764 for (const DexFile* dex_file : dex_files) {
2765 CHECK(dex_file != nullptr);
2766 CompileDexFile(this,
2767 class_loader,
2768 *dex_file,
2769 parallel_thread_pool_.get(),
2770 parallel_thread_count_,
2771 timings,
2772 "Compile Dex File Quick",
2773 CompileMethodQuick);
2774 const ArenaPool* const arena_pool = Runtime::Current()->GetArenaPool();
2775 const size_t arena_alloc = arena_pool->GetBytesAllocated();
2776 max_arena_alloc_ = std::max(arena_alloc, max_arena_alloc_);
2777 Runtime::Current()->ReclaimArenaPoolMemory();
2778 }
2779
2780 VLOG(compiler) << "Compile: " << GetMemoryUsageString(false);
2781 }
2782
AddCompiledMethod(const MethodReference & method_ref,CompiledMethod * const compiled_method)2783 void CompilerDriver::AddCompiledMethod(const MethodReference& method_ref,
2784 CompiledMethod* const compiled_method) {
2785 DCHECK(GetCompiledMethod(method_ref) == nullptr) << method_ref.PrettyMethod();
2786 MethodTable::InsertResult result = compiled_methods_.Insert(method_ref,
2787 /*expected*/ nullptr,
2788 compiled_method);
2789 CHECK(result == MethodTable::kInsertResultSuccess);
2790 DCHECK(GetCompiledMethod(method_ref) != nullptr) << method_ref.PrettyMethod();
2791 }
2792
RemoveCompiledMethod(const MethodReference & method_ref)2793 CompiledMethod* CompilerDriver::RemoveCompiledMethod(const MethodReference& method_ref) {
2794 CompiledMethod* ret = nullptr;
2795 CHECK(compiled_methods_.Remove(method_ref, &ret));
2796 return ret;
2797 }
2798
GetCompiledClass(const ClassReference & ref,ClassStatus * status) const2799 bool CompilerDriver::GetCompiledClass(const ClassReference& ref, ClassStatus* status) const {
2800 DCHECK(status != nullptr);
2801 // The table doesn't know if something wasn't inserted. For this case it will return
2802 // ClassStatus::kNotReady. To handle this, just assume anything we didn't try to verify
2803 // is not compiled.
2804 if (!compiled_classes_.Get(ref, status) ||
2805 *status < ClassStatus::kRetryVerificationAtRuntime) {
2806 return false;
2807 }
2808 return true;
2809 }
2810
GetClassStatus(const ClassReference & ref) const2811 ClassStatus CompilerDriver::GetClassStatus(const ClassReference& ref) const {
2812 ClassStatus status = ClassStatus::kNotReady;
2813 if (!GetCompiledClass(ref, &status)) {
2814 classpath_classes_.Get(ref, &status);
2815 }
2816 return status;
2817 }
2818
RecordClassStatus(const ClassReference & ref,ClassStatus status)2819 void CompilerDriver::RecordClassStatus(const ClassReference& ref, ClassStatus status) {
2820 switch (status) {
2821 case ClassStatus::kErrorResolved:
2822 case ClassStatus::kErrorUnresolved:
2823 case ClassStatus::kNotReady:
2824 case ClassStatus::kResolved:
2825 case ClassStatus::kRetryVerificationAtRuntime:
2826 case ClassStatus::kVerifiedNeedsAccessChecks:
2827 case ClassStatus::kVerified:
2828 case ClassStatus::kSuperclassValidated:
2829 case ClassStatus::kVisiblyInitialized:
2830 break; // Expected states.
2831 default:
2832 LOG(FATAL) << "Unexpected class status for class "
2833 << PrettyDescriptor(
2834 ref.dex_file->GetClassDescriptor(ref.dex_file->GetClassDef(ref.index)))
2835 << " of " << status;
2836 }
2837
2838 ClassStateTable::InsertResult result;
2839 ClassStateTable* table = &compiled_classes_;
2840 do {
2841 ClassStatus existing = ClassStatus::kNotReady;
2842 if (!table->Get(ref, &existing)) {
2843 // A classpath class.
2844 if (kIsDebugBuild) {
2845 // Check to make sure it's not a dex file for an oat file we are compiling since these
2846 // should always succeed. These do not include classes in for used libraries.
2847 for (const DexFile* dex_file : GetCompilerOptions().GetDexFilesForOatFile()) {
2848 CHECK_NE(ref.dex_file, dex_file) << ref.dex_file->GetLocation();
2849 }
2850 }
2851 if (!classpath_classes_.HaveDexFile(ref.dex_file)) {
2852 // Boot classpath dex file.
2853 return;
2854 }
2855 table = &classpath_classes_;
2856 table->Get(ref, &existing);
2857 }
2858 if (existing >= status) {
2859 // Existing status is already better than we expect, break.
2860 break;
2861 }
2862 // Update the status if we now have a greater one. This happens with vdex,
2863 // which records a class is verified, but does not resolve it.
2864 result = table->Insert(ref, existing, status);
2865 CHECK(result != ClassStateTable::kInsertResultInvalidDexFile) << ref.dex_file->GetLocation();
2866 } while (result != ClassStateTable::kInsertResultSuccess);
2867 }
2868
GetCompiledMethod(MethodReference ref) const2869 CompiledMethod* CompilerDriver::GetCompiledMethod(MethodReference ref) const {
2870 CompiledMethod* compiled_method = nullptr;
2871 compiled_methods_.Get(ref, &compiled_method);
2872 return compiled_method;
2873 }
2874
GetMemoryUsageString(bool extended) const2875 std::string CompilerDriver::GetMemoryUsageString(bool extended) const {
2876 std::ostringstream oss;
2877 const gc::Heap* const heap = Runtime::Current()->GetHeap();
2878 const size_t java_alloc = heap->GetBytesAllocated();
2879 oss << "arena alloc=" << PrettySize(max_arena_alloc_) << " (" << max_arena_alloc_ << "B)";
2880 oss << " java alloc=" << PrettySize(java_alloc) << " (" << java_alloc << "B)";
2881 #if defined(__BIONIC__) || defined(__GLIBC__) || defined(ANDROID_HOST_MUSL)
2882 const struct mallinfo info = mallinfo();
2883 const size_t allocated_space = static_cast<size_t>(info.uordblks);
2884 const size_t free_space = static_cast<size_t>(info.fordblks);
2885 oss << " native alloc=" << PrettySize(allocated_space) << " (" << allocated_space << "B)"
2886 << " free=" << PrettySize(free_space) << " (" << free_space << "B)";
2887 #endif
2888 compiled_method_storage_.DumpMemoryUsage(oss, extended);
2889 return oss.str();
2890 }
2891
InitializeThreadPools()2892 void CompilerDriver::InitializeThreadPools() {
2893 size_t parallel_count = parallel_thread_count_ > 0 ? parallel_thread_count_ - 1 : 0;
2894 parallel_thread_pool_.reset(
2895 ThreadPool::Create("Compiler driver thread pool", parallel_count));
2896 single_thread_pool_.reset(ThreadPool::Create("Single-threaded Compiler driver thread pool", 0));
2897 }
2898
FreeThreadPools()2899 void CompilerDriver::FreeThreadPools() {
2900 parallel_thread_pool_.reset();
2901 single_thread_pool_.reset();
2902 }
2903
SetClasspathDexFiles(const std::vector<const DexFile * > & dex_files)2904 void CompilerDriver::SetClasspathDexFiles(const std::vector<const DexFile*>& dex_files) {
2905 classpath_classes_.AddDexFiles(dex_files);
2906 }
2907
2908 } // namespace art
2909