diff options
Diffstat (limited to 'dex2oat/dex2oat.cc')
| -rw-r--r-- | dex2oat/dex2oat.cc | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 7ba165e2cb..28e1d94e8b 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -61,19 +61,20 @@ #include "driver/compiler_driver.h" #include "driver/compiler_options.h" #include "elf_file.h" -#include "elf_writer.h" -#include "elf_writer_quick.h" #include "gc/space/image_space.h" #include "gc/space/space-inl.h" #include "gc/verification.h" -#include "image_writer.h" #include "interpreter/unstarted_runtime.h" #include "java_vm_ext.h" #include "jit/profile_compilation_info.h" #include "leb128.h" #include "linker/buffered_output_stream.h" +#include "linker/elf_writer.h" +#include "linker/elf_writer_quick.h" #include "linker/file_output_stream.h" +#include "linker/image_writer.h" #include "linker/multi_oat_relative_patcher.h" +#include "linker/oat_writer.h" #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/object-inl.h" @@ -81,7 +82,6 @@ #include "nativehelper/ScopedLocalRef.h" #include "oat_file.h" #include "oat_file_assistant.h" -#include "oat_writer.h" #include "os.h" #include "runtime.h" #include "runtime_options.h" @@ -712,6 +712,10 @@ class Dex2Oat FINAL { } } + bool VerifyProfileData() { + return profile_compilation_info_->VerifyProfileData(dex_files_); + } + void ParseInstructionSetVariant(const StringPiece& option, ParserOptions* parser_options) { DCHECK(option.starts_with("--instruction-set-variant=")); StringPiece str = option.substr(strlen("--instruction-set-variant=")).data(); @@ -1455,8 +1459,9 @@ class Dex2Oat FINAL { // Note: we're only invalidating the magic data in the file, as dex2oat needs the rest of // the information to remain valid. if (update_input_vdex_) { - std::unique_ptr<BufferedOutputStream> vdex_out = std::make_unique<BufferedOutputStream>( - std::make_unique<FileOutputStream>(vdex_files_.back().get())); + std::unique_ptr<linker::BufferedOutputStream> vdex_out = + std::make_unique<linker::BufferedOutputStream>( + std::make_unique<linker::FileOutputStream>(vdex_files_.back().get())); if (!vdex_out->WriteFully(&VdexFile::Header::kVdexInvalidMagic, arraysize(VdexFile::Header::kVdexInvalidMagic))) { PLOG(ERROR) << "Failed to invalidate vdex header. File: " << vdex_out->GetLocation(); @@ -1865,6 +1870,9 @@ class Dex2Oat FINAL { swap_fd_, profile_compilation_info_.get())); driver_->SetDexFilesForOatFile(dex_files_); + if (!IsBootImage()) { + driver_->SetClasspathDexFiles(class_loader_context_->FlattenOpenedDexFiles()); + } const bool compile_individually = ShouldCompileDexFilesIndividually(); if (compile_individually) { @@ -2023,14 +2031,14 @@ class Dex2Oat FINAL { VLOG(compiler) << "App image base=" << reinterpret_cast<void*>(image_base_); } - image_writer_.reset(new ImageWriter(*driver_, - image_base_, - compiler_options_->GetCompilePic(), - IsAppImage(), - image_storage_mode_, - oat_filenames_, - dex_file_oat_index_map_, - dirty_image_objects_.get())); + image_writer_.reset(new linker::ImageWriter(*driver_, + image_base_, + compiler_options_->GetCompilePic(), + IsAppImage(), + image_storage_mode_, + oat_filenames_, + dex_file_oat_index_map_, + dirty_image_objects_.get())); // We need to prepare method offsets in the image address space for direct method patching. TimingLogger::ScopedTiming t2("dex2oat Prepare image address space", timings_); @@ -2043,7 +2051,7 @@ class Dex2Oat FINAL { // Initialize the writers with the compiler driver, image writer, and their // dex files. The writers were created without those being there yet. for (size_t i = 0, size = oat_files_.size(); i != size; ++i) { - std::unique_ptr<OatWriter>& oat_writer = oat_writers_[i]; + std::unique_ptr<linker::OatWriter>& oat_writer = oat_writers_[i]; std::vector<const DexFile*>& dex_files = dex_files_per_oat_file_[i]; oat_writer->Initialize(driver_.get(), image_writer_.get(), dex_files); } @@ -2054,8 +2062,9 @@ class Dex2Oat FINAL { verifier::VerifierDeps* verifier_deps = callbacks_->GetVerifierDeps(); for (size_t i = 0, size = oat_files_.size(); i != size; ++i) { File* vdex_file = vdex_files_[i].get(); - std::unique_ptr<BufferedOutputStream> vdex_out = - std::make_unique<BufferedOutputStream>(std::make_unique<FileOutputStream>(vdex_file)); + std::unique_ptr<linker::BufferedOutputStream> vdex_out = + std::make_unique<linker::BufferedOutputStream>( + std::make_unique<linker::FileOutputStream>(vdex_file)); if (!oat_writers_[i]->WriteVerifierDeps(vdex_out.get(), verifier_deps)) { LOG(ERROR) << "Failed to write verifier dependencies into VDEX " << vdex_file->GetPath(); @@ -2079,8 +2088,8 @@ class Dex2Oat FINAL { TimingLogger::ScopedTiming t2("dex2oat Write ELF", timings_); linker::MultiOatRelativePatcher patcher(instruction_set_, instruction_set_features_.get()); for (size_t i = 0, size = oat_files_.size(); i != size; ++i) { - std::unique_ptr<ElfWriter>& elf_writer = elf_writers_[i]; - std::unique_ptr<OatWriter>& oat_writer = oat_writers_[i]; + std::unique_ptr<linker::ElfWriter>& elf_writer = elf_writers_[i]; + std::unique_ptr<linker::OatWriter>& oat_writer = oat_writers_[i]; oat_writer->PrepareLayout(&patcher); @@ -2113,16 +2122,14 @@ class Dex2Oat FINAL { for (size_t i = 0, size = oat_files_.size(); i != size; ++i) { std::unique_ptr<File>& oat_file = oat_files_[i]; - std::unique_ptr<ElfWriter>& elf_writer = elf_writers_[i]; - std::unique_ptr<OatWriter>& oat_writer = oat_writers_[i]; - - oat_writer->AddMethodDebugInfos(debug::MakeTrampolineInfos(oat_writer->GetOatHeader())); + std::unique_ptr<linker::ElfWriter>& elf_writer = elf_writers_[i]; + std::unique_ptr<linker::OatWriter>& oat_writer = oat_writers_[i]; // We need to mirror the layout of the ELF file in the compressed debug-info. // Therefore PrepareDebugInfo() relies on the SetLoadedSectionSizes() call further above. elf_writer->PrepareDebugInfo(oat_writer->GetMethodDebugInfo()); - OutputStream*& rodata = rodata_[i]; + linker::OutputStream*& rodata = rodata_[i]; DCHECK(rodata != nullptr); if (!oat_writer->WriteRodata(rodata)) { LOG(ERROR) << "Failed to write .rodata section to the ELF file " << oat_file->GetPath(); @@ -2131,7 +2138,7 @@ class Dex2Oat FINAL { elf_writer->EndRoData(rodata); rodata = nullptr; - OutputStream* text = elf_writer->StartText(); + linker::OutputStream* text = elf_writer->StartText(); if (!oat_writer->WriteCode(text)) { LOG(ERROR) << "Failed to write .text section to the ELF file " << oat_file->GetPath(); return false; @@ -2363,27 +2370,6 @@ class Dex2Oat FINAL { return dex_files_size >= very_large_threshold_; } - std::vector<std::string> GetClassPathLocations(const std::string& class_path) { - // This function is used only for apps and for an app we have exactly one oat file. - DCHECK(!IsBootImage()); - DCHECK_EQ(oat_writers_.size(), 1u); - std::vector<std::string> dex_files_canonical_locations; - for (const std::string& location : oat_writers_[0]->GetSourceLocations()) { - dex_files_canonical_locations.push_back(DexFile::GetDexCanonicalLocation(location.c_str())); - } - - std::vector<std::string> parsed; - Split(class_path, ':', &parsed); - auto kept_it = std::remove_if(parsed.begin(), - parsed.end(), - [dex_files_canonical_locations](const std::string& location) { - return ContainsElement(dex_files_canonical_locations, - DexFile::GetDexCanonicalLocation(location.c_str())); - }); - parsed.erase(kept_it, parsed.end()); - return parsed; - } - bool PrepareImageClasses() { // If --image-classes was specified, calculate the full list of classes to include in the image. if (image_classes_filename_ != nullptr) { @@ -2530,13 +2516,13 @@ class Dex2Oat FINAL { elf_writers_.reserve(oat_files_.size()); oat_writers_.reserve(oat_files_.size()); for (const std::unique_ptr<File>& oat_file : oat_files_) { - elf_writers_.emplace_back(CreateElfWriterQuick(instruction_set_, - instruction_set_features_.get(), - compiler_options_.get(), - oat_file.get())); + elf_writers_.emplace_back(linker::CreateElfWriterQuick(instruction_set_, + instruction_set_features_.get(), + compiler_options_.get(), + oat_file.get())); elf_writers_.back()->Start(); const bool do_dexlayout = DoDexLayoutOptimizations(); - oat_writers_.emplace_back(new OatWriter( + oat_writers_.emplace_back(new linker::OatWriter( IsBootImage(), timings_, do_dexlayout ? profile_compilation_info_.get() : nullptr)); } } @@ -2699,7 +2685,7 @@ class Dex2Oat FINAL { return false; } - if (!ElfWriter::Fixup(oat_file.get(), oat_data_begins[i])) { + if (!linker::ElfWriter::Fixup(oat_file.get(), oat_data_begins[i])) { oat_file->Erase(); LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath(); return false; @@ -2902,11 +2888,11 @@ class Dex2Oat FINAL { std::vector<const DexFile*> dex_files_; std::string no_inline_from_string_; - std::vector<std::unique_ptr<ElfWriter>> elf_writers_; - std::vector<std::unique_ptr<OatWriter>> oat_writers_; - std::vector<OutputStream*> rodata_; - std::vector<std::unique_ptr<OutputStream>> vdex_out_; - std::unique_ptr<ImageWriter> image_writer_; + std::vector<std::unique_ptr<linker::ElfWriter>> elf_writers_; + std::vector<std::unique_ptr<linker::OatWriter>> oat_writers_; + std::vector<linker::OutputStream*> rodata_; + std::vector<std::unique_ptr<linker::OutputStream>> vdex_out_; + std::unique_ptr<linker::ImageWriter> image_writer_; std::unique_ptr<CompilerDriver> driver_; std::vector<std::unique_ptr<MemMap>> opened_dex_files_maps_; @@ -3121,6 +3107,19 @@ static dex2oat::ReturnCode Dex2oat(int argc, char** argv) { return setup_code; } + // TODO: Due to the cyclic dependencies, profile loading and verifying are + // being done separately. Refactor and place the two next to each other. + // If verification fails, we don't abort the compilation and instead log an + // error. + // TODO(b/62602192, b/65260586): We should consider aborting compilation when + // the profile verification fails. + // Note: If dex2oat fails, installd will remove the oat files causing the app + // to fallback to apk with possible in-memory extraction. We want to avoid + // that, and thus we're lenient towards profile corruptions. + if (dex2oat->UseProfile()) { + dex2oat->VerifyProfileData(); + } + // Helps debugging on device. Can be used to determine which dalvikvm instance invoked a dex2oat // instance. Used by tools/bisection_search/bisection_search.py. VLOG(compiler) << "Running dex2oat (parent PID = " << getppid() << ")"; |