summaryrefslogtreecommitdiff
path: root/dex2oat/dex2oat.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dex2oat/dex2oat.cc')
-rw-r--r--dex2oat/dex2oat.cc113
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() << ")";