Add new --layout-profile compiler-filter for dex2oat.
New compiler filter makes dex2oat call into dexlayout.
Added basic test for --layout-profile filter to make sure dex2oat runs
to completion and file is valid. Contests of file are not checked.
Test: mm test-art-host-gtest-dexlayout_test
Bug: 29921113
Change-Id: I4bd0dea3d3f1284c155d1d9dea80a48062e67770
diff --git a/compiler/Android.bp b/compiler/Android.bp
index e2a450d..1737376 100644
--- a/compiler/Android.bp
+++ b/compiler/Android.bp
@@ -254,7 +254,10 @@
},
},
},
- shared_libs: ["libart"],
+ shared_libs: [
+ "libart",
+ "libart-dexlayout",
+ ],
}
art_cc_library {
@@ -291,7 +294,10 @@
},
},
},
- shared_libs: ["libartd"],
+ shared_libs: [
+ "libartd",
+ "libartd-dexlayout"
+ ],
}
art_cc_library {
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index fcb8979..5629dff 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -211,7 +211,9 @@
&driver->GetCompilerOptions(),
oat_file.GetFile()));
elf_writers.back()->Start();
- oat_writers.emplace_back(new OatWriter(/*compiling_boot_image*/true, &timings));
+ oat_writers.emplace_back(new OatWriter(/*compiling_boot_image*/true,
+ &timings,
+ /*profile_compilation_info*/nullptr));
}
std::vector<OutputStream*> rodata;
diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc
index 102637f..9458576 100644
--- a/compiler/oat_test.cc
+++ b/compiler/oat_test.cc
@@ -125,7 +125,9 @@
SafeMap<std::string, std::string>& key_value_store,
bool verify) {
TimingLogger timings("WriteElf", false, false);
- OatWriter oat_writer(/*compiling_boot_image*/false, &timings);
+ OatWriter oat_writer(/*compiling_boot_image*/false,
+ &timings,
+ /*profile_compilation_info*/nullptr);
for (const DexFile* dex_file : dex_files) {
ArrayRef<const uint8_t> raw_dex_file(
reinterpret_cast<const uint8_t*>(&dex_file->GetHeader()),
@@ -145,7 +147,9 @@
SafeMap<std::string, std::string>& key_value_store,
bool verify) {
TimingLogger timings("WriteElf", false, false);
- OatWriter oat_writer(/*compiling_boot_image*/false, &timings);
+ OatWriter oat_writer(/*compiling_boot_image*/false,
+ &timings,
+ /*profile_compilation_info*/nullptr);
for (const char* dex_filename : dex_filenames) {
if (!oat_writer.AddDexFileSource(dex_filename, dex_filename)) {
return false;
@@ -161,7 +165,9 @@
SafeMap<std::string, std::string>& key_value_store,
bool verify) {
TimingLogger timings("WriteElf", false, false);
- OatWriter oat_writer(/*compiling_boot_image*/false, &timings);
+ OatWriter oat_writer(/*compiling_boot_image*/false,
+ &timings,
+ /*profile_compilation_info*/nullptr);
if (!oat_writer.AddZippedDexFilesSource(std::move(zip_fd), location)) {
return false;
}
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index bde00cf..eed9d11 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -33,6 +33,7 @@
#include "debug/method_debug_info.h"
#include "dex/verification_results.h"
#include "dex_file-inl.h"
+#include "dexlayout.h"
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
#include "gc/space/image_space.h"
@@ -276,7 +277,7 @@
DCHECK_EQ(static_cast<off_t>(file_offset + offset_), out->Seek(0, kSeekCurrent)) \
<< "file_offset=" << file_offset << " offset_=" << offset_
-OatWriter::OatWriter(bool compiling_boot_image, TimingLogger* timings)
+OatWriter::OatWriter(bool compiling_boot_image, TimingLogger* timings, ProfileCompilationInfo* info)
: write_state_(WriteState::kAddingDexFileSources),
timings_(timings),
raw_dex_files_(),
@@ -337,7 +338,8 @@
size_oat_class_method_bitmaps_(0),
size_oat_class_method_offsets_(0),
relative_patcher_(nullptr),
- absolute_patch_locations_() {
+ absolute_patch_locations_(),
+ profile_compilation_info_(info) {
}
bool OatWriter::AddDexFileSource(const char* filename,
@@ -2081,7 +2083,11 @@
if (!SeekToDexFile(out, file, oat_dex_file)) {
return false;
}
- if (oat_dex_file->source_.IsZipEntry()) {
+ if (profile_compilation_info_ != nullptr) {
+ if (!LayoutAndWriteDexFile(out, oat_dex_file)) {
+ return false;
+ }
+ } else if (oat_dex_file->source_.IsZipEntry()) {
if (!WriteDexFile(out, file, oat_dex_file, oat_dex_file->source_.GetZipEntry())) {
return false;
}
@@ -2146,6 +2152,39 @@
return true;
}
+bool OatWriter::LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_file) {
+ TimingLogger::ScopedTiming split("Dex Layout", timings_);
+ std::string error_msg;
+ std::string location(oat_dex_file->GetLocation());
+ std::unique_ptr<const DexFile> dex_file;
+ if (oat_dex_file->source_.IsZipEntry()) {
+ ZipEntry* zip_entry = oat_dex_file->source_.GetZipEntry();
+ std::unique_ptr<MemMap> mem_map(
+ zip_entry->ExtractToMemMap(location.c_str(), "classes.dex", &error_msg));
+ dex_file = DexFile::Open(location,
+ zip_entry->GetCrc32(),
+ std::move(mem_map),
+ /* verify */ true,
+ /* verify_checksum */ true,
+ &error_msg);
+ } else {
+ DCHECK(oat_dex_file->source_.IsRawFile());
+ File* raw_file = oat_dex_file->source_.GetRawFile();
+ dex_file = DexFile::OpenDex(raw_file->Fd(), location, /* verify_checksum */ true, &error_msg);
+ }
+ Options options;
+ options.output_to_memmap_ = true;
+ DexLayout dex_layout(options, profile_compilation_info_, nullptr);
+ dex_layout.ProcessDexFile(location.c_str(), dex_file.get(), 0);
+ std::unique_ptr<MemMap> mem_map(dex_layout.GetAndReleaseMemMap());
+ if (!WriteDexFile(out, oat_dex_file, mem_map->Begin())) {
+ return false;
+ }
+ // Set the checksum of the new oat dex file to be the original file's checksum.
+ oat_dex_file->dex_file_location_checksum_ = dex_file->GetLocationChecksum();
+ return true;
+}
+
bool OatWriter::WriteDexFile(OutputStream* out,
File* file,
OatDexFile* oat_dex_file,
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index b92ba76..f9671d7 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -38,6 +38,7 @@
class CompiledMethod;
class CompilerDriver;
class ImageWriter;
+class ProfileCompilationInfo;
class OutputStream;
class TimingLogger;
class TypeLookupTable;
@@ -110,7 +111,7 @@
kDefault = kCreate
};
- OatWriter(bool compiling_boot_image, TimingLogger* timings);
+ OatWriter(bool compiling_boot_image, TimingLogger* timings, ProfileCompilationInfo* info);
// To produce a valid oat file, the user must first add sources with any combination of
// - AddDexFileSource(),
@@ -258,6 +259,7 @@
bool WriteDexFiles(OutputStream* out, File* file);
bool WriteDexFile(OutputStream* out, File* file, OatDexFile* oat_dex_file);
bool SeekToDexFile(OutputStream* out, File* file, OatDexFile* oat_dex_file);
+ bool LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_file);
bool WriteDexFile(OutputStream* out,
File* file,
OatDexFile* oat_dex_file,
@@ -422,6 +424,9 @@
// The locations of absolute patches relative to the start of the executable section.
dchecked_vector<uintptr_t> absolute_patch_locations_;
+ // Profile info used to generate new layout of files.
+ ProfileCompilationInfo* profile_compilation_info_;
+
DISALLOW_COPY_AND_ASSIGN(OatWriter);
};