summaryrefslogtreecommitdiff
path: root/compiler/oat_writer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/oat_writer.cc')
-rw-r--r--compiler/oat_writer.cc133
1 files changed, 81 insertions, 52 deletions
diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc
index bebd5f5ae2..a9da09c82c 100644
--- a/compiler/oat_writer.cc
+++ b/compiler/oat_writer.cc
@@ -483,6 +483,7 @@ bool OatWriter::WriteAndOpenDexFiles(
const InstructionSetFeatures* instruction_set_features,
SafeMap<std::string, std::string>* key_value_store,
bool verify,
+ bool update_input_vdex,
/*out*/ std::unique_ptr<MemMap>* opened_dex_files_map,
/*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files) {
CHECK(write_state_ == WriteState::kAddingDexFileSources);
@@ -511,15 +512,15 @@ bool OatWriter::WriteAndOpenDexFiles(
if (kIsVdexEnabled) {
std::unique_ptr<BufferedOutputStream> vdex_out(
MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(vdex_file)));
-
// Write DEX files into VDEX, mmap and open them.
- if (!WriteDexFiles(vdex_out.get(), vdex_file) ||
+ if (!WriteDexFiles(vdex_out.get(), vdex_file, update_input_vdex) ||
!OpenDexFiles(vdex_file, verify, &dex_files_map, &dex_files)) {
return false;
}
} else {
+ DCHECK(!update_input_vdex);
// Write DEX files into OAT, mmap and open them.
- if (!WriteDexFiles(oat_rodata, vdex_file) ||
+ if (!WriteDexFiles(oat_rodata, vdex_file, update_input_vdex) ||
!OpenDexFiles(vdex_file, verify, &dex_files_map, &dex_files)) {
return false;
}
@@ -1468,30 +1469,32 @@ bool OatWriter::VisitDexMethods(DexMethodVisitor* visitor) {
if (UNLIKELY(!visitor->StartClass(dex_file, class_def_index))) {
return false;
}
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
- const uint8_t* class_data = dex_file->GetClassData(class_def);
- if (class_data != nullptr) { // ie not an empty class, such as a marker interface
- ClassDataItemIterator it(*dex_file, class_data);
- while (it.HasNextStaticField()) {
- it.Next();
- }
- while (it.HasNextInstanceField()) {
- it.Next();
- }
- size_t class_def_method_index = 0u;
- while (it.HasNextDirectMethod()) {
- if (!visitor->VisitMethod(class_def_method_index, it)) {
- return false;
+ if (compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
+ const uint8_t* class_data = dex_file->GetClassData(class_def);
+ if (class_data != nullptr) { // ie not an empty class, such as a marker interface
+ ClassDataItemIterator it(*dex_file, class_data);
+ while (it.HasNextStaticField()) {
+ it.Next();
}
- ++class_def_method_index;
- it.Next();
- }
- while (it.HasNextVirtualMethod()) {
- if (UNLIKELY(!visitor->VisitMethod(class_def_method_index, it))) {
- return false;
+ while (it.HasNextInstanceField()) {
+ it.Next();
+ }
+ size_t class_def_method_index = 0u;
+ while (it.HasNextDirectMethod()) {
+ if (!visitor->VisitMethod(class_def_method_index, it)) {
+ return false;
+ }
+ ++class_def_method_index;
+ it.Next();
+ }
+ while (it.HasNextVirtualMethod()) {
+ if (UNLIKELY(!visitor->VisitMethod(class_def_method_index, it))) {
+ return false;
+ }
+ ++class_def_method_index;
+ it.Next();
}
- ++class_def_method_index;
- it.Next();
}
}
if (UNLIKELY(!visitor->EndClass())) {
@@ -1548,6 +1551,9 @@ size_t OatWriter::InitOatClasses(size_t offset) {
}
size_t OatWriter::InitOatMaps(size_t offset) {
+ if (!compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ return offset;
+ }
InitMapMethodVisitor visitor(this, offset);
bool success = VisitDexMethods(&visitor);
DCHECK(success);
@@ -1594,6 +1600,9 @@ size_t OatWriter::InitOatCode(size_t offset) {
}
size_t OatWriter::InitOatCodeDexFiles(size_t offset) {
+ if (!compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ return offset;
+ }
InitCodeMethodVisitor code_visitor(this, offset, vdex_quickening_info_offset_);
bool success = VisitDexMethods(&code_visitor);
DCHECK(success);
@@ -1745,19 +1754,24 @@ bool OatWriter::WriteQuickeningInfo(OutputStream* vdex_out) {
return false;
}
- WriteQuickeningInfoMethodVisitor visitor(this, vdex_out, start_offset);
- if (!VisitDexMethods(&visitor)) {
- PLOG(ERROR) << "Failed to write the vdex quickening info. File: " << vdex_out->GetLocation();
- return false;
- }
+ if (compiler_driver_->GetCompilerOptions().IsAnyMethodCompilationEnabled()) {
+ WriteQuickeningInfoMethodVisitor visitor(this, vdex_out, start_offset);
+ if (!VisitDexMethods(&visitor)) {
+ PLOG(ERROR) << "Failed to write the vdex quickening info. File: " << vdex_out->GetLocation();
+ return false;
+ }
- if (!vdex_out->Flush()) {
- PLOG(ERROR) << "Failed to flush stream after writing quickening info."
- << " File: " << vdex_out->GetLocation();
- return false;
+ if (!vdex_out->Flush()) {
+ PLOG(ERROR) << "Failed to flush stream after writing quickening info."
+ << " File: " << vdex_out->GetLocation();
+ return false;
+ }
+ size_quickening_info_ = visitor.GetNumberOfWrittenBytes();
+ } else {
+ // We know we did not quicken.
+ size_quickening_info_ = 0;
}
- size_quickening_info_ = visitor.GetNumberOfWrittenBytes();
vdex_size_ += size_quickening_info_;
return true;
}
@@ -2096,47 +2110,56 @@ bool OatWriter::ValidateDexFileHeader(const uint8_t* raw_header, const char* loc
return true;
}
-bool OatWriter::WriteDexFiles(OutputStream* out, File* file) {
+bool OatWriter::WriteDexFiles(OutputStream* out, File* file, bool update_input_vdex) {
TimingLogger::ScopedTiming split("Write Dex files", timings_);
vdex_dex_files_offset_ = vdex_size_;
// Write dex files.
for (OatDexFile& oat_dex_file : oat_dex_files_) {
- if (!WriteDexFile(out, file, &oat_dex_file)) {
+ if (!WriteDexFile(out, file, &oat_dex_file, update_input_vdex)) {
return false;
}
}
- // Close sources.
+ CloseSources();
+ return true;
+}
+
+void OatWriter::CloseSources() {
for (OatDexFile& oat_dex_file : oat_dex_files_) {
oat_dex_file.source_.Clear(); // Get rid of the reference, it's about to be invalidated.
}
zipped_dex_files_.clear();
zip_archives_.clear();
raw_dex_files_.clear();
- return true;
}
-bool OatWriter::WriteDexFile(OutputStream* out, File* file, OatDexFile* oat_dex_file) {
+bool OatWriter::WriteDexFile(OutputStream* out,
+ File* file,
+ OatDexFile* oat_dex_file,
+ bool update_input_vdex) {
if (!SeekToDexFile(out, file, oat_dex_file)) {
return false;
}
if (profile_compilation_info_ != nullptr) {
+ DCHECK(!update_input_vdex);
if (!LayoutAndWriteDexFile(out, oat_dex_file)) {
return false;
}
} else if (oat_dex_file->source_.IsZipEntry()) {
+ DCHECK(!update_input_vdex);
if (!WriteDexFile(out, file, oat_dex_file, oat_dex_file->source_.GetZipEntry())) {
return false;
}
} else if (oat_dex_file->source_.IsRawFile()) {
+ DCHECK(!update_input_vdex);
if (!WriteDexFile(out, file, oat_dex_file, oat_dex_file->source_.GetRawFile())) {
return false;
}
} else {
DCHECK(oat_dex_file->source_.IsRawData());
- if (!WriteDexFile(out, oat_dex_file, oat_dex_file->source_.GetRawData())) {
+ if (!WriteDexFile(out, oat_dex_file, oat_dex_file->source_.GetRawData(), update_input_vdex)) {
return false;
}
}
@@ -2146,6 +2169,7 @@ bool OatWriter::WriteDexFile(OutputStream* out, File* file, OatDexFile* oat_dex_
DCHECK_EQ(vdex_size_, oat_dex_file->dex_file_offset_);
vdex_size_ += oat_dex_file->dex_file_size_;
} else {
+ DCHECK(!update_input_vdex);
DCHECK_EQ(oat_size_, oat_dex_file->dex_file_offset_);
oat_size_ += oat_dex_file->dex_file_size_;
}
@@ -2216,7 +2240,7 @@ bool OatWriter::LayoutAndWriteDexFile(OutputStream* out, OatDexFile* oat_dex_fil
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())) {
+ if (!WriteDexFile(out, oat_dex_file, mem_map->Begin(), /* update_input_vdex */ false)) {
return false;
}
// Set the checksum of the new oat dex file to be the original file's checksum.
@@ -2373,22 +2397,27 @@ bool OatWriter::WriteDexFile(OutputStream* out,
bool OatWriter::WriteDexFile(OutputStream* out,
OatDexFile* oat_dex_file,
- const uint8_t* dex_file) {
+ const uint8_t* dex_file,
+ bool update_input_vdex) {
// Note: The raw data has already been checked to contain the header
// and all the data that the header specifies as the file size.
DCHECK(dex_file != nullptr);
DCHECK(ValidateDexFileHeader(dex_file, oat_dex_file->GetLocation()));
const UnalignedDexFileHeader* header = AsUnalignedDexFileHeader(dex_file);
- if (!out->WriteFully(dex_file, header->file_size_)) {
- PLOG(ERROR) << "Failed to write dex file " << oat_dex_file->GetLocation()
- << " to " << out->GetLocation();
- return false;
- }
- if (!out->Flush()) {
- PLOG(ERROR) << "Failed to flush stream after writing dex file."
- << " File: " << oat_dex_file->GetLocation();
- return false;
+ if (update_input_vdex) {
+ // The vdex already contains the dex code, no need to write it again.
+ } else {
+ if (!out->WriteFully(dex_file, header->file_size_)) {
+ PLOG(ERROR) << "Failed to write dex file " << oat_dex_file->GetLocation()
+ << " to " << out->GetLocation();
+ return false;
+ }
+ if (!out->Flush()) {
+ PLOG(ERROR) << "Failed to flush stream after writing dex file."
+ << " File: " << oat_dex_file->GetLocation();
+ return false;
+ }
}
// Update dex file size and resize class offsets in the OatDexFile.