diff options
-rw-r--r-- | dex2oat/dex2oat.cc | 7 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer.cc | 12 | ||||
-rw-r--r-- | runtime/vdex_file.cc | 6 | ||||
-rw-r--r-- | runtime/vdex_file.h | 4 |
4 files changed, 26 insertions, 3 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index f4c3e2a094..4b083030ed 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -2614,7 +2614,12 @@ class Dex2Oat final { bool AddDexFileSources() { TimingLogger::ScopedTiming t2("AddDexFileSources", timings_); - if (input_vdex_file_ != nullptr && input_vdex_file_->HasDexSection()) { + if (input_vdex_file_ != nullptr && input_vdex_file_->HasDexSection() && + // If we don't want compact dex in the vdex then we have to make sure + // the input vdex only has standard dex files, because we can convert + // dex to cdex but not the other way around. + (compact_dex_level_ == CompactDexLevel::kCompactDexLevelFast || + input_vdex_file_->HasOnlyStandardDexFiles())) { DCHECK_EQ(oat_writers_.size(), 1u); const std::string& name = zip_location_.empty() ? dex_locations_[0] : zip_location_; DCHECK(!name.empty()); diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 222a5f4a5f..23c209b721 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -490,8 +490,16 @@ bool OatWriter::AddVdexDexFilesSource(const VdexFile& vdex_file, const char* loc return false; } - if (!DexFileLoader::IsMagicValid(current_dex_data)) { - LOG(ERROR) << "Invalid magic in vdex file created from " << location; + if (StandardDexFile::IsMagicValid(current_dex_data)) { + // Standard dex is always ok - we'll run dexlayout to convert it to cdex if needed. + } else if (compact_dex_level_ == CompactDexLevel::kCompactDexLevelFast && + CompactDexFile::IsMagicValid(current_dex_data)) { + // Compact dex is ok if we want compact dex in the output, but not + // otherwise since we cannot convert it to standard dex. + } else { + LOG(ERROR) << "Invalid magic in vdex file created from " << location << " - want " + << (compact_dex_level_ == CompactDexLevel::kCompactDexLevelFast ? "dex or cdex" : + "dex"); return false; } // We used `zipped_dex_file_locations_` to keep the strings in memory. diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc index bdead55390..9bcde00531 100644 --- a/runtime/vdex_file.cc +++ b/runtime/vdex_file.cc @@ -384,6 +384,12 @@ bool VdexFile::MatchesDexFileChecksums(const std::vector<const DexFile::Header*> return true; } +bool VdexFile::HasOnlyStandardDexFiles() const { + // All are the same so it's enough to check the first one. + const uint8_t* dex_file_start = GetNextDexFileData(nullptr, 0); + return dex_file_start == nullptr || StandardDexFile::IsMagicValid(dex_file_start); +} + static ObjPtr<mirror::Class> FindClassAndClearException(ClassLinker* class_linker, Thread* self, const char* name, diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h index a35d720f71..fe65c07bac 100644 --- a/runtime/vdex_file.h +++ b/runtime/vdex_file.h @@ -296,6 +296,10 @@ class VdexFile { // order must match too. bool MatchesDexFileChecksums(const std::vector<const DexFile::Header*>& dex_headers) const; + // Returns true if all dex files are standard dex rather than compact dex. + // Also returns true if there are no dex files at all. + bool HasOnlyStandardDexFiles() const; + ClassStatus ComputeClassStatus(Thread* self, Handle<mirror::Class> cls) const REQUIRES_SHARED(Locks::mutator_lock_); |