//路径:/art/runtime/oat_file_assistant.cc OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() { if (!status_attempted_) { status_attempted_ = true; //打开oat文件 const OatFile* file = GetFile(); if (file == nullptr) { // Check to see if there is a vdex file we can make use of. std::string error_msg; std::string vdex_filename = GetVdexFilename(filename_); //打开vdex文件 std::unique_ptr<VdexFile> vdex = VdexFile::Open(vdex_filename, /*writeable*/false, /*low_4gb*/false, /*unquicken*/false, &error_msg); if (vdex == nullptr) { status_ = kOatCannotOpen; VLOG(oat) << "unable to open vdex file " << vdex_filename << ": " << error_msg; } else { //检查vdex文件是否是最新的 if (oat_file_assistant_->DexChecksumUpToDate(*vdex, &error_msg)) { // The vdex file does not contain enough information to determine // whether it is up to date with respect to the boot image, so we // assume it is out of date. VLOG(oat) << error_msg; status_ = kOatBootImageOutOfDate; } else { status_ = kOatDexOutOfDate; } } } else { status_ = oat_file_assistant_->GivenOatFileStatus(*file); VLOG(oat) << file->GetLocation() << " is " << status_ << " with filter " << file->GetCompilerFilter(); } } return status_; }
//路径:/art/runtime/oat_file.cc const OatFile::OatDexFile* OatFile::GetOatDexFile(constchar* dex_location, constuint32_t* dex_location_checksum, std::string* error_msg)const{ const OatFile::OatDexFile* oat_dex_file = nullptr; StringPiece key(dex_location); //通过key在oat_dex_files_map中找到dex文件所在位置 auto primary_it = oat_dex_files_.find(key); if (primary_it != oat_dex_files_.end()) {//dex文件不唯一 oat_dex_file = primary_it->second; DCHECK(oat_dex_file != nullptr); } else { // This dex_location is not one of the dex locations directly mentioned in the // oat file. The correct lookup is via the canonical location but first see in // the secondary_oat_dex_files_ whether we've looked up this location before. MutexLock mu(Thread::Current(), secondary_lookup_lock_); auto secondary_lb = secondary_oat_dex_files_.lower_bound(key); if (secondary_lb != secondary_oat_dex_files_.end() && key == secondary_lb->first) { oat_dex_file = secondary_lb->second; // May be null. } else { // We haven't seen this dex_location before, we must check the canonical location. std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location); if (dex_canonical_location != dex_location) { StringPiece canonical_key(dex_canonical_location); auto canonical_it = oat_dex_files_.find(canonical_key); if (canonical_it != oat_dex_files_.end()) { oat_dex_file = canonical_it->second; } // else keep null. } // else keep null.
// Copy the key to the string_cache_ and store the result in secondary map. string_cache_.emplace_back(key.data(), key.length()); StringPiece key_copy(string_cache_.back()); secondary_oat_dex_files_.PutBefore(secondary_lb, key_copy, oat_dex_file); } } //oat_dex_file获取失败 if (oat_dex_file == nullptr) { if (error_msg != nullptr) { std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location); *error_msg = "Failed to find OatDexFile for DexFile " + std::string(dex_location) + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation(); } returnnullptr; } //验证oat_dex_file文件的校验码 if (dex_location_checksum != nullptr && oat_dex_file->GetDexFileLocationChecksum() != *dex_location_checksum) { if (error_msg != nullptr) { std::string dex_canonical_location = DexFile::GetDexCanonicalLocation(dex_location); std::string checksum = StringPrintf("0x%08x", oat_dex_file->GetDexFileLocationChecksum()); std::string required_checksum = StringPrintf("0x%08x", *dex_location_checksum); *error_msg = "OatDexFile for DexFile " + std::string(dex_location) + " (canonical path " + dex_canonical_location + ") in OatFile " + GetLocation() + " has checksum " + checksum + " but " + required_checksum + " was required"; } returnnullptr; } return oat_dex_file; }