Remove OatWriter buffering to memory for ElfWriterQuick

This allows the oat contents to be directly written to the file.

Change-Id: Ibc7ddf57477b152f07784b52f7334be73fd22833
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index 9de96d2..f2db5d8 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -19,8 +19,10 @@
 #include "base/logging.h"
 #include "base/unix_file/fd_file.h"
 #include "driver/compiler_driver.h"
+#include "file_output_stream.h"
 #include "globals.h"
 #include "oat.h"
+#include "oat_writer.h"
 #include "utils.h"
 
 namespace art {
@@ -31,16 +33,16 @@
 ElfWriterQuick::~ElfWriterQuick() {}
 
 bool ElfWriterQuick::Create(File* elf_file,
-                            std::vector<uint8_t>& oat_contents,
+                            OatWriter& oat_writer,
                             const std::vector<const DexFile*>& dex_files,
                             const std::string& android_root,
                             bool is_host,
                             const CompilerDriver& driver) {
   ElfWriterQuick elf_writer(driver, elf_file);
-  return elf_writer.Write(oat_contents, dex_files, android_root, is_host);
+  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
 }
 
-bool ElfWriterQuick::Write(std::vector<uint8_t>& oat_contents,
+bool ElfWriterQuick::Write(OatWriter& oat_writer,
                            const std::vector<const DexFile*>& dex_files_unused,
                            const std::string& android_root_unused,
                            bool is_host_unused) {
@@ -193,9 +195,9 @@
   // .rodata
   uint32_t oat_data_alignment = kPageSize;
   uint32_t oat_data_offset = expected_offset = RoundUp(expected_offset, oat_data_alignment);
-  const OatHeader* oat_header = reinterpret_cast<OatHeader*>(&oat_contents[0]);
-  CHECK(oat_header->IsValid());
-  uint32_t oat_data_size = oat_header->GetExecutableOffset();
+  const OatHeader& oat_header = oat_writer.GetOatHeader();
+  CHECK(oat_header.IsValid());
+  uint32_t oat_data_size = oat_header.GetExecutableOffset();
   expected_offset += oat_data_size;
   if (debug) {
     LOG(INFO) << "oat_data_offset=" << oat_data_offset << std::hex << " " << oat_data_offset;
@@ -206,9 +208,9 @@
   uint32_t oat_exec_alignment = kPageSize;
   CHECK_ALIGNED(expected_offset, kPageSize);
   uint32_t oat_exec_offset = expected_offset = RoundUp(expected_offset, oat_exec_alignment);
-  uint32_t oat_exec_size = oat_contents.size() - oat_data_size;
+  uint32_t oat_exec_size = oat_writer.GetSize() - oat_data_size;
   expected_offset += oat_exec_size;
-  CHECK_EQ(oat_data_offset + oat_contents.size(), expected_offset);
+  CHECK_EQ(oat_data_offset + oat_writer.GetSize(), expected_offset);
   if (debug) {
     LOG(INFO) << "oat_exec_offset=" << oat_exec_offset << std::hex << " " << oat_exec_offset;
     LOG(INFO) << "oat_exec_size=" << oat_exec_size << std::hex << " " << oat_exec_size;
@@ -617,13 +619,14 @@
                 << " for " << elf_file_->GetPath();
     return false;
   }
-  if (!elf_file_->WriteFully(&oat_contents[0], oat_contents.size())) {
+  FileOutputStream output_stream(elf_file_);
+  if (!oat_writer.Write(output_stream)) {
     PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath();
     return false;
   }
 
   // .dynamic
-  DCHECK_LE(oat_data_offset + oat_contents.size(), dynamic_offset);
+  DCHECK_LE(oat_data_offset + oat_writer.GetSize(), dynamic_offset);
   if (static_cast<off_t>(dynamic_offset) != lseek(elf_file_->Fd(), dynamic_offset, SEEK_SET)) {
     PLOG(ERROR) << "Failed to seek to .dynamic offset " << dynamic_offset
                 << " for " << elf_file_->GetPath();