diff options
Diffstat (limited to 'compiler/image_writer.cc')
| -rw-r--r-- | compiler/image_writer.cc | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index a47e711c28..9c38445276 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -803,6 +803,13 @@ bool ImageWriter::PruneAppImageClassInternal( result = result || PruneAppImageClassInternal(klass->GetSuperClass(), &my_early_exit, visited); + // Remove the class if the dex file is not in the set of dex files. This happens for classes that + // are from uses library if there is no profile. b/30688277 + mirror::DexCache* dex_cache = klass->GetDexCache(); + if (dex_cache != nullptr) { + result = result || + dex_file_oat_index_map_.find(dex_cache->GetDexFile()) == dex_file_oat_index_map_.end(); + } // Erase the element we stored earlier since we are exiting the function. auto it = visited->find(klass); DCHECK(it != visited->end()); @@ -1106,11 +1113,15 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots(size_t oat_index) const { } // build an Object[] of the roots needed to restore the runtime + int32_t image_roots_size = ImageHeader::NumberOfImageRoots(compile_app_image_); auto image_roots(hs.NewHandle( - ObjectArray<Object>::Alloc(self, object_array_class.Get(), ImageHeader::kImageRootsMax))); + ObjectArray<Object>::Alloc(self, object_array_class.Get(), image_roots_size))); image_roots->Set<false>(ImageHeader::kDexCaches, dex_caches.Get()); image_roots->Set<false>(ImageHeader::kClassRoots, class_linker->GetClassRoots()); - for (int i = 0; i < ImageHeader::kImageRootsMax; i++) { + // image_roots[ImageHeader::kClassLoader] will be set later for app image. + static_assert(ImageHeader::kClassLoader + 1u == ImageHeader::kImageRootsMax, + "Class loader should be the last image root."); + for (int32_t i = 0; i < ImageHeader::kImageRootsMax - 1; ++i) { CHECK(image_roots->Get(i) != nullptr); } return image_roots.Get(); @@ -1532,6 +1543,12 @@ void ImageWriter::CalculateNewObjectOffsets() { } // Process the work stack in case anything was added by TryAssignBinSlot. ProcessWorkStack(&work_stack); + + // Store the class loader in the class roots. + CHECK_EQ(class_loaders_.size(), 1u); + CHECK_EQ(image_roots.size(), 1u); + CHECK(*class_loaders_.begin() != nullptr); + image_roots[0]->Set<false>(ImageHeader::kClassLoader, *class_loaders_.begin()); } // Verify that all objects have assigned image bin slots. |