Merge "Do not hold breakpoint lock when running the verifier" into lmp-dev
diff --git a/compiler/dex/quick/x86/int_x86.cc b/compiler/dex/quick/x86/int_x86.cc
index 7e9cd80..00a2621 100755
--- a/compiler/dex/quick/x86/int_x86.cc
+++ b/compiler/dex/quick/x86/int_x86.cc
@@ -2813,8 +2813,8 @@
LoadValueDirectFixed(rl_rhs, t_reg);
if (is_two_addr) {
// Can we do this directly into memory?
- rl_result = UpdateLocTyped(rl_dest, kCoreReg);
rl_rhs = LoadValue(rl_rhs, kCoreReg);
+ rl_result = UpdateLocTyped(rl_dest, kCoreReg);
if (rl_result.location != kLocPhysReg) {
// Okay, we can do this into memory
OpMemReg(op, rl_result, t_reg.GetReg());
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 1fde12e..703e63f 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -17,6 +17,7 @@
#include "elf_writer_quick.h"
#include "base/logging.h"
+#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "buffered_output_stream.h"
#include "driver/compiler_driver.h"
@@ -38,6 +39,113 @@
return ((binding) << 4) + ((type) & 0xf);
}
+class ElfFilePiece {
+ public:
+ virtual ~ElfFilePiece() {}
+
+ virtual bool Write(File* elf_file) {
+ if (static_cast<off_t>(offset_) != lseek(elf_file->Fd(), offset_, SEEK_SET)) {
+ PLOG(ERROR) << "Failed to seek to " << GetDescription() << " offset " << offset_ << " for "
+ << elf_file->GetPath();
+ return false;
+ }
+
+ return DoActualWrite(elf_file);
+ }
+
+ static bool Compare(ElfFilePiece* a, ElfFilePiece* b) {
+ return a->offset_ < b->offset_;
+ }
+
+ protected:
+ explicit ElfFilePiece(Elf32_Word offset) : offset_(offset) {}
+
+ virtual std::string GetDescription() = 0;
+ virtual bool DoActualWrite(File* elf_file) = 0;
+
+ Elf32_Word offset_;
+};
+
+class ElfFileMemoryPiece : public ElfFilePiece {
+ public:
+ ElfFileMemoryPiece(const std::string& name, Elf32_Word offset, const void* data, Elf32_Word size)
+ : ElfFilePiece(offset), dbg_name_(name), data_(data), size_(size) {}
+
+ bool DoActualWrite(File* elf_file) OVERRIDE {
+ DCHECK(data_ != nullptr || size_ == 0U) << dbg_name_ << " " << size_;
+
+ if (!elf_file->WriteFully(data_, size_)) {
+ PLOG(ERROR) << "Failed to write " << dbg_name_ << " for " << elf_file->GetPath();
+ return false;
+ }
+
+ return true;
+ }
+
+ std::string GetDescription() OVERRIDE {
+ return dbg_name_;
+ }
+
+ private:
+ const std::string& dbg_name_;
+ const void *data_;
+ Elf32_Word size_;
+};
+
+class ElfFileRodataPiece : public ElfFilePiece {
+ public:
+ ElfFileRodataPiece(Elf32_Word offset, OatWriter* oat_writer) : ElfFilePiece(offset),
+ oat_writer_(oat_writer) {}
+
+ bool DoActualWrite(File* elf_file) OVERRIDE {
+ std::unique_ptr<BufferedOutputStream> output_stream(
+ new BufferedOutputStream(new FileOutputStream(elf_file)));
+ if (!oat_writer_->Write(output_stream.get())) {
+ PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file->GetPath();
+ return false;
+ }
+
+ return true;
+ }
+
+ std::string GetDescription() OVERRIDE {
+ return ".rodata";
+ }
+
+ private:
+ OatWriter* oat_writer_;
+};
+
+class ElfFileOatTextPiece : public ElfFilePiece {
+ public:
+ ElfFileOatTextPiece(Elf32_Word offset, OatWriter* oat_writer) : ElfFilePiece(offset),
+ oat_writer_(oat_writer) {}
+
+ bool DoActualWrite(File* elf_file) OVERRIDE {
+ // All data is written by the ElfFileRodataPiece right now, as the oat writer writes in one
+ // piece. This is for future flexibility.
+ UNUSED(oat_writer_);
+ return true;
+ }
+
+ std::string GetDescription() OVERRIDE {
+ return ".text";
+ }
+
+ private:
+ OatWriter* oat_writer_;
+};
+
+static bool WriteOutFile(const std::vector<ElfFilePiece*>& pieces, File* elf_file) {
+ // TODO It would be nice if this checked for overlap.
+ for (auto it = pieces.begin(); it != pieces.end(); ++it) {
+ if (!(*it)->Write(elf_file)) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool ElfWriterQuick::ElfBuilder::Write() {
// The basic layout of the elf file. Order may be different in final output.
// +-------------------------+
@@ -291,7 +399,7 @@
}
Elf32_Word base_offset = sizeof(Elf32_Ehdr) + sizeof(program_headers);
- std::vector<ElfFilePiece> pieces;
+ std::vector<ElfFilePiece*> pieces;
// Get the layout in the sections.
//
@@ -382,8 +490,9 @@
it->section_.sh_addr = 0;
it->section_.sh_size = it->GetBuffer()->size();
it->section_.sh_link = it->GetLink();
- pieces.push_back(ElfFilePiece(it->name_, it->section_.sh_offset,
- it->GetBuffer()->data(), it->GetBuffer()->size()));
+
+ // We postpone adding an ElfFilePiece to keep the order in "pieces."
+
prev = it->section_;
if (debug_logging_) {
LOG(INFO) << it->name_ << " off=" << it->section_.sh_offset
@@ -458,73 +567,49 @@
elf_header_.e_shstrndx = shstrtab_builder_.section_index_;
// Add the rest of the pieces to the list.
- pieces.push_back(ElfFilePiece("Elf Header", 0, &elf_header_, sizeof(elf_header_)));
- pieces.push_back(ElfFilePiece("Program headers", phdr_offset,
- &program_headers, sizeof(program_headers)));
- pieces.push_back(ElfFilePiece(".dynamic", dynamic_builder_.section_.sh_offset,
- dynamic.data(), dynamic_builder_.section_.sh_size));
- pieces.push_back(ElfFilePiece(".dynsym", dynsym_builder_.section_.sh_offset,
- dynsym.data(), dynsym.size() * sizeof(Elf32_Sym)));
- pieces.push_back(ElfFilePiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset,
- dynstr.c_str(), dynstr.size()));
- pieces.push_back(ElfFilePiece(".hash", hash_builder_.section_.sh_offset,
- hash.data(), hash.size() * sizeof(Elf32_Word)));
- pieces.push_back(ElfFilePiece(".rodata", rodata_builder_.section_.sh_offset,
- nullptr, rodata_builder_.section_.sh_size));
- pieces.push_back(ElfFilePiece(".text", text_builder_.section_.sh_offset,
- nullptr, text_builder_.section_.sh_size));
+ pieces.push_back(new ElfFileMemoryPiece("Elf Header", 0, &elf_header_, sizeof(elf_header_)));
+ pieces.push_back(new ElfFileMemoryPiece("Program headers", phdr_offset,
+ &program_headers, sizeof(program_headers)));
+ pieces.push_back(new ElfFileMemoryPiece(".dynamic", dynamic_builder_.section_.sh_offset,
+ dynamic.data(), dynamic_builder_.section_.sh_size));
+ pieces.push_back(new ElfFileMemoryPiece(".dynsym", dynsym_builder_.section_.sh_offset,
+ dynsym.data(), dynsym.size() * sizeof(Elf32_Sym)));
+ pieces.push_back(new ElfFileMemoryPiece(".dynstr", dynsym_builder_.strtab_.section_.sh_offset,
+ dynstr.c_str(), dynstr.size()));
+ pieces.push_back(new ElfFileMemoryPiece(".hash", hash_builder_.section_.sh_offset,
+ hash.data(), hash.size() * sizeof(Elf32_Word)));
+ pieces.push_back(new ElfFileRodataPiece(rodata_builder_.section_.sh_offset, oat_writer_));
+ pieces.push_back(new ElfFileOatTextPiece(text_builder_.section_.sh_offset, oat_writer_));
if (IncludingDebugSymbols()) {
- pieces.push_back(ElfFilePiece(".symtab", symtab_builder_.section_.sh_offset,
- symtab.data(), symtab.size() * sizeof(Elf32_Sym)));
- pieces.push_back(ElfFilePiece(".strtab", symtab_builder_.strtab_.section_.sh_offset,
- strtab.c_str(), strtab.size()));
+ pieces.push_back(new ElfFileMemoryPiece(".symtab", symtab_builder_.section_.sh_offset,
+ symtab.data(), symtab.size() * sizeof(Elf32_Sym)));
+ pieces.push_back(new ElfFileMemoryPiece(".strtab", symtab_builder_.strtab_.section_.sh_offset,
+ strtab.c_str(), strtab.size()));
}
- pieces.push_back(ElfFilePiece(".shstrtab", shstrtab_builder_.section_.sh_offset,
- &shstrtab[0], shstrtab.size()));
+ pieces.push_back(new ElfFileMemoryPiece(".shstrtab", shstrtab_builder_.section_.sh_offset,
+ &shstrtab[0], shstrtab.size()));
for (uint32_t i = 0; i < section_ptrs.size(); ++i) {
- // Just add all the sections in induvidually since they are all over the
+ // Just add all the sections in individually since they are all over the
// place on the heap/stack.
Elf32_Word cur_off = sections_offset + i * sizeof(Elf32_Shdr);
- pieces.push_back(ElfFilePiece("section table piece", cur_off,
- section_ptrs[i], sizeof(Elf32_Shdr)));
+ pieces.push_back(new ElfFileMemoryPiece("section table piece", cur_off,
+ section_ptrs[i], sizeof(Elf32_Shdr)));
}
- if (!WriteOutFile(pieces)) {
+ // Postponed debug info.
+ for (auto it = other_builders_.begin(); it != other_builders_.end(); ++it) {
+ pieces.push_back(new ElfFileMemoryPiece(it->name_, it->section_.sh_offset,
+ it->GetBuffer()->data(), it->GetBuffer()->size()));
+ }
+
+ if (!WriteOutFile(pieces, elf_file_)) {
LOG(ERROR) << "Unable to write to file " << elf_file_->GetPath();
- return false;
- }
- // write out the actual oat file data.
- Elf32_Word oat_data_offset = rodata_builder_.section_.sh_offset;
- if (static_cast<off_t>(oat_data_offset) != lseek(elf_file_->Fd(), oat_data_offset, SEEK_SET)) {
- PLOG(ERROR) << "Failed to seek to .rodata offset " << oat_data_offset
- << " for " << elf_file_->GetPath();
- return false;
- }
- std::unique_ptr<BufferedOutputStream> output_stream(
- new BufferedOutputStream(new FileOutputStream(elf_file_)));
- if (!oat_writer_->Write(output_stream.get())) {
- PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath();
+
+ STLDeleteElements(&pieces); // Have to manually clean pieces.
return false;
}
- return true;
-}
-
-bool ElfWriterQuick::ElfBuilder::WriteOutFile(const std::vector<ElfFilePiece>& pieces) {
- // TODO It would be nice if this checked for overlap.
- for (auto it = pieces.begin(); it != pieces.end(); ++it) {
- if (it->data_) {
- if (static_cast<off_t>(it->offset_) != lseek(elf_file_->Fd(), it->offset_, SEEK_SET)) {
- PLOG(ERROR) << "Failed to seek to " << it->dbg_name_ << " offset location "
- << it->offset_ << " for " << elf_file_->GetPath();
- return false;
- }
- if (!elf_file_->WriteFully(it->data_, it->size_)) {
- PLOG(ERROR) << "Failed to write " << it->dbg_name_ << " for " << elf_file_->GetPath();
- return false;
- }
- }
- }
+ STLDeleteElements(&pieces); // Have to manually clean pieces.
return true;
}
diff --git a/compiler/elf_writer_quick.h b/compiler/elf_writer_quick.h
index a0d36df..0c22ae2 100644
--- a/compiler/elf_writer_quick.h
+++ b/compiler/elf_writer_quick.h
@@ -291,22 +291,7 @@
// oatlastword
void SetupRequiredSymbols();
void AssignSectionStr(ElfSectionBuilder *builder, std::string* strtab);
- struct ElfFilePiece {
- ElfFilePiece(const std::string& name, Elf32_Word offset, const void* data, Elf32_Word size)
- : dbg_name_(name), offset_(offset), data_(data), size_(size) {}
- ~ElfFilePiece() {}
- const std::string& dbg_name_;
- Elf32_Word offset_;
- const void *data_;
- Elf32_Word size_;
- static bool Compare(ElfFilePiece a, ElfFilePiece b) {
- return a.offset_ < b.offset_;
- }
- };
-
- // Write each of the pieces out to the file.
- bool WriteOutFile(const std::vector<ElfFilePiece>& pieces);
bool IncludingDebugSymbols() { return add_symbols_ && symtab_builder_.GetSize() > 1; }
};
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index e55e358..05a940cb 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1224,6 +1224,7 @@
} else {
oat_file.reset(new File(oat_fd, oat_location));
oat_file->DisableAutoClose();
+ oat_file->SetLength(0);
}
if (oat_file.get() == nullptr) {
PLOG(ERROR) << "Failed to create oat file: " << oat_location;
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 7787a94..01c8978 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -292,7 +292,7 @@
std::unique_ptr<const OatFile> oat_file(OatFile::Open(oat_filename, oat_filename, nullptr,
false, &error_msg));
if (oat_file.get() == nullptr) {
- if (kVerboseLogging) {
+ if (kReasonLogging) {
LOG(INFO) << "DexFile_isDexOptNeeded failed to open oat file '" << oat_filename
<< "' for file location '" << filename << "': " << error_msg;
}
@@ -319,13 +319,13 @@
return kUpToDate;
} else if (should_relocate_if_possible &&
ClassLinker::VerifyOatImageChecksum(oat_file.get(), target_instruction_set)) {
- if (kVerboseLogging) {
+ if (kReasonLogging) {
LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
<< " needs to be relocated for " << filename;
}
return kPatchoatNeeded;
} else {
- if (kVerboseLogging) {
+ if (kReasonLogging) {
LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
<< " is out of date for " << filename;
}
@@ -343,13 +343,13 @@
} else if (location_checksum == oat_dex_file->GetDexFileLocationChecksum()
&& should_relocate_if_possible
&& ClassLinker::VerifyOatImageChecksum(oat_file.get(), target_instruction_set)) {
- if (kVerboseLogging) {
+ if (kReasonLogging) {
LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
<< " needs to be relocated for " << filename;
}
return kPatchoatNeeded;
} else {
- if (kVerboseLogging) {
+ if (kReasonLogging) {
LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
<< " is out of date for " << filename;
}
@@ -357,7 +357,7 @@
}
}
} else {
- if (kVerboseLogging) {
+ if (kReasonLogging) {
LOG(INFO) << "DexFile_isDexOptNeeded file " << oat_filename
<< " does not contain " << filename;
}
@@ -367,9 +367,10 @@
static jbyte IsDexOptNeededInternal(JNIEnv* env, const char* filename,
const char* pkgname, const char* instruction_set, const jboolean defer) {
- // TODO disable this logging.
- const bool kVerboseLogging = false; // Spammy logging.
- const bool kReasonLogging = true; // Logging of reason for returning JNI_TRUE.
+ // Spammy logging for kUpToDate
+ const bool kVerboseLogging = false;
+ // Logging of reason for returning kDexoptNeeded or kPatchoatNeeded.
+ const bool kReasonLogging = true;
if ((filename == nullptr) || !OS::FileExists(filename)) {
LOG(ERROR) << "DexFile_isDexOptNeeded file '" << filename << "' does not exist";