diff options
Diffstat (limited to 'compiler/driver/compiler_driver.cc')
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index cd1f466f0f..e03ddea85b 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -2272,6 +2272,7 @@ class InitializeClassVisitor : public CompilationVisitor { const char* descriptor = dex_file.StringDataByIdx(class_type_id.descriptor_idx_); ScopedObjectAccessUnchecked soa(Thread::Current()); StackHandleScope<3> hs(soa.Self()); + const bool is_boot_image = manager_->GetCompiler()->GetCompilerOptions().IsBootImage(); mirror::Class::Status old_status = klass->GetStatus();; // Only try to initialize classes that were successfully verified. @@ -2293,32 +2294,27 @@ class InitializeClassVisitor : public CompilationVisitor { ObjectLock<mirror::Class> lock(soa.Self(), h_klass); // Attempt to initialize allowing initialization of parent classes but still not static // fields. - bool is_superclass_initialized = true; - if (!manager_->GetCompiler()->GetCompilerOptions().IsAppImage()) { - // If not an app image case, the compiler won't initialize too much things and do a fast - // fail, don't check dependencies. - manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true); - } else { - // For app images, do the initialization recursively and resolve types encountered to make - // sure the compiler runs without error. - is_superclass_initialized = InitializeDependencies(klass, class_loader, soa.Self()); - if (is_superclass_initialized) { - manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true); - } - } + manager_->GetClassLinker()->EnsureInitialized(soa.Self(), klass, false, true); old_status = klass->GetStatus(); - // If superclass cannot be initialized, no need to proceed. + // If the class was not initialized, we can proceed to see if we can initialize static + // fields. if (!klass->IsInitialized() && - is_superclass_initialized && manager_->GetCompiler()->IsImageClass(descriptor)) { bool can_init_static_fields = false; - if (manager_->GetCompiler()->GetCompilerOptions().IsBootImage()) { + if (is_boot_image) { // We need to initialize static fields, we only do this for image classes that aren't - // marked with the $NoPreloadHolder (which implies this should not be initialized early). + // marked with the $NoPreloadHolder (which implies this should not be initialized + // early). can_init_static_fields = !StringPiece(descriptor).ends_with("$NoPreloadHolder;"); } else { - can_init_static_fields = manager_->GetCompiler()->GetCompilerOptions().IsAppImage() && + // The boot image case doesn't need to recursively initialize the dependencies with + // special logic since the class linker already does this. + bool is_superclass_initialized = + InitializeDependencies(klass, class_loader, soa.Self()); + can_init_static_fields = + manager_->GetCompiler()->GetCompilerOptions().IsAppImage() && !soa.Self()->IsExceptionPending() && + is_superclass_initialized && NoClinitInDependency(klass, soa.Self(), &class_loader); // TODO The checking for clinit can be removed since it's already // checked when init superclass. Currently keep it because it contains @@ -2361,6 +2357,10 @@ class InitializeClassVisitor : public CompilationVisitor { soa.Self()->ClearException(); transaction.Rollback(); CHECK_EQ(old_status, klass->GetStatus()) << "Previous class status not restored"; + } else if (is_boot_image) { + // For boot image, we want to put the updated status in the oat class since we can't + // reject the image anyways. + old_status = klass->GetStatus(); } } @@ -2370,6 +2370,8 @@ class InitializeClassVisitor : public CompilationVisitor { // above as we will allocate strings, so must be allowed to suspend. if (&klass->GetDexFile() == manager_->GetDexFile()) { InternStrings(klass, class_loader); + } else { + DCHECK(!is_boot_image) << "Boot image must have equal dex files"; } } } |