Move logic to get profile class descriptors to profile info
Move and simplify logic used to get a descriptor set for app image
creation. Code is covered by TestLayoutAppImage in dex2oat_test.
Motivation:
If we are class unloading in dex2oat, we won't have all the dex files
registered at once.
Bug: 63467744
Test: test-art-host
Change-Id: I1e3616ee0a731061c347677713dba07e603eaa08
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 476ce68..0dbecb7 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1497,10 +1497,9 @@
Runtime* runtime = Runtime::Current();
CHECK(runtime != nullptr);
// Filter out class path classes since we don't want to include these in the image.
- std::set<DexCacheResolvedClasses> resolved_classes(
- profile_compilation_info_->GetResolvedClasses(dex_files_));
- image_classes_.reset(new std::unordered_set<std::string>(
- runtime->GetClassLinker()->GetClassDescriptorsForResolvedClasses(resolved_classes)));
+ image_classes_.reset(
+ new std::unordered_set<std::string>(
+ profile_compilation_info_->GetClassDescriptors(dex_files_)));
VLOG(compiler) << "Loaded " << image_classes_->size()
<< " image class descriptors from profile";
if (VLOG_IS_ON(compiler)) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6133dd7..f34ed14 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -8980,51 +8980,6 @@
return ret;
}
-std::unordered_set<std::string> ClassLinker::GetClassDescriptorsForResolvedClasses(
- const std::set<DexCacheResolvedClasses>& classes) {
- ScopedTrace trace(__PRETTY_FUNCTION__);
- std::unordered_set<std::string> ret;
- Thread* const self = Thread::Current();
- std::unordered_map<std::string, const DexFile*> location_to_dex_file;
- ScopedObjectAccess soa(self);
- ScopedAssertNoThreadSuspension ants(__FUNCTION__);
- ReaderMutexLock mu(self, *Locks::dex_lock_);
- for (const ClassLinker::DexCacheData& data : GetDexCachesData()) {
- if (!self->IsJWeakCleared(data.weak_root)) {
- ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(data.weak_root);
- if (dex_cache != nullptr) {
- const DexFile* dex_file = dex_cache->GetDexFile();
- // There could be duplicates if two dex files with the same location are mapped.
- location_to_dex_file.emplace(dex_file->GetLocation(), dex_file);
- }
- }
- }
- for (const DexCacheResolvedClasses& info : classes) {
- const std::string& location = info.GetDexLocation();
- auto found = location_to_dex_file.find(location);
- if (found != location_to_dex_file.end()) {
- const DexFile* dex_file = found->second;
- VLOG(profiler) << "Found opened dex file for " << dex_file->GetLocation() << " with "
- << info.GetClasses().size() << " classes";
- DCHECK_EQ(dex_file->GetLocationChecksum(), info.GetLocationChecksum());
- for (dex::TypeIndex type_idx : info.GetClasses()) {
- if (!dex_file->IsTypeIndexValid(type_idx)) {
- // Something went bad. The profile is probably corrupted. Abort and return an emtpy set.
- LOG(WARNING) << "Corrupted profile: invalid type index "
- << type_idx.index_ << " in dex " << location;
- return std::unordered_set<std::string>();
- }
- const DexFile::TypeId& type_id = dex_file->GetTypeId(type_idx);
- const char* descriptor = dex_file->GetTypeDescriptor(type_id);
- ret.insert(descriptor);
- }
- } else {
- VLOG(class_linker) << "Failed to find opened dex file for location " << location;
- }
- }
- return ret;
-}
-
class ClassLinker::FindVirtualMethodHolderVisitor : public ClassVisitor {
public:
FindVirtualMethodHolderVisitor(const ArtMethod* method, PointerSize pointer_size)
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 4a99c66..cb28187 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -614,11 +614,6 @@
std::set<DexCacheResolvedClasses> GetResolvedClasses(bool ignore_boot_classes)
REQUIRES(!Locks::dex_lock_);
- // Returns the class descriptors for loaded dex files.
- std::unordered_set<std::string> GetClassDescriptorsForResolvedClasses(
- const std::set<DexCacheResolvedClasses>& classes)
- REQUIRES(!Locks::dex_lock_);
-
static bool IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
ObjPtr<mirror::ClassLoader> class_loader)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index 45c3792..0b7063d 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -1652,4 +1652,27 @@
return &(inline_cache->FindOrAdd(dex_pc, DexPcData(&arena_))->second);
}
+std::unordered_set<std::string> ProfileCompilationInfo::GetClassDescriptors(
+ const std::vector<const DexFile*>& dex_files) {
+ std::unordered_set<std::string> ret;
+ for (const DexFile* dex_file : dex_files) {
+ const DexFileData* data = FindDexData(dex_file);
+ if (data != nullptr) {
+ for (dex::TypeIndex type_idx : data->class_set) {
+ if (!dex_file->IsTypeIndexValid(type_idx)) {
+ // Something went bad. The profile is probably corrupted. Abort and return an emtpy set.
+ LOG(WARNING) << "Corrupted profile: invalid type index "
+ << type_idx.index_ << " in dex " << dex_file->GetLocation();
+ return std::unordered_set<std::string>();
+ }
+ const DexFile::TypeId& type_id = dex_file->GetTypeId(type_idx);
+ ret.insert(dex_file->GetTypeDescriptor(type_id));
+ }
+ } else {
+ VLOG(compiler) << "Failed to find profile data for " << dex_file->GetLocation();
+ }
+ }
+ return ret;
+}
+
} // namespace art
diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h
index 079ce8d..4ab8be8 100644
--- a/runtime/jit/profile_compilation_info.h
+++ b/runtime/jit/profile_compilation_info.h
@@ -380,6 +380,9 @@
ArenaAllocator* GetArena() { return &arena_; }
+ // Return all of the class descriptors in the profile for a set of dex files.
+ std::unordered_set<std::string> GetClassDescriptors(const std::vector<const DexFile*>& dex_files);
+
private:
enum ProfileLoadSatus {
kProfileLoadWouldOverwiteData,