From 0b49084e0c80239d891a1a74eb866419ea7d5ebe Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Wed, 25 May 2016 15:05:59 -0700 Subject: Prune class path classes from profile Fixes a theoretical case where classes not in the app, but in the in the class path could have been included in the image. The dex caches for these classes are not properly handled and need to be pruned. Not including the classes in the image classes makes sure the that class linker automatically prunes them and frees the dex cache with the explicit garbage collection. Bug: 28452385 (cherry picked from commit 8d26c5967674d2eab21f65eeac9f1adcf88fce38) Change-Id: Ic33076f0a76cf1ae727c61a340ceaadf9e7e7d08 --- compiler/image_writer.cc | 3 +++ dex2oat/dex2oat.cc | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index be720ad2f3..eaeacc59dd 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -437,6 +437,9 @@ void ImageWriter::PrepareDexCacheArraySlots() { continue; } const DexFile* dex_file = dex_cache->GetDexFile(); + CHECK(dex_file_oat_index_map_.find(dex_file) != dex_file_oat_index_map_.end()) + << "Dex cache should have been pruned " << dex_file->GetLocation() + << "; possibly in class path"; DexCacheArraysLayout layout(target_ptr_size_, dex_file); DCHECK(layout.Valid()); size_t oat_index = GetOatIndexForDexCache(dex_cache); diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 9f6f4530c7..cce83f32b5 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -1269,6 +1269,21 @@ class Dex2Oat FINAL { CHECK(runtime != nullptr); std::set resolved_classes( profile_compilation_info_->GetResolvedClasses()); + + // Filter out class path classes since we don't want to include these in the image. + std::unordered_set dex_files_locations; + for (const DexFile* dex_file : dex_files_) { + dex_files_locations.insert(dex_file->GetLocation()); + } + for (auto it = resolved_classes.begin(); it != resolved_classes.end(); ) { + if (dex_files_locations.find(it->GetDexLocation()) == dex_files_locations.end()) { + VLOG(compiler) << "Removed profile samples for non-app dex file " << it->GetDexLocation(); + it = resolved_classes.erase(it); + } else { + ++it; + } + } + image_classes_.reset(new std::unordered_set( runtime->GetClassLinker()->GetClassDescriptorsForProfileKeys(resolved_classes))); VLOG(compiler) << "Loaded " << image_classes_->size() @@ -2443,6 +2458,7 @@ class Dex2Oat FINAL { bool multi_image_; bool is_host_; std::string android_root_; + // Dex files we are compiling, does not include the class path dex files. std::vector dex_files_; std::string no_inline_from_string_; std::vector dex_caches_; -- cgit v1.2.3-59-g8ed1b