diff options
author | Brian Carlstrom <bdc@google.com> | 2013-08-26 18:57:31 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2013-08-26 22:33:11 -0700 |
commit | c6dfdacea2fd9e268f70328805b0366cdd6b7b9e (patch) | |
tree | 8c6032e2276a3962054dd450025dcf3cc817e43f /compiler | |
parent | b8a874ca3b13007f4bf688963483ffb3c76e0d7d (diff) | |
download | android_art-c6dfdacea2fd9e268f70328805b0366cdd6b7b9e.tar.gz android_art-c6dfdacea2fd9e268f70328805b0366cdd6b7b9e.tar.bz2 android_art-c6dfdacea2fd9e268f70328805b0366cdd6b7b9e.zip |
Add buffering to ELF file generation
Bug: 10496017
Change-Id: I3cbad249e0fb33f726bd0a504b3b6bd9b4f759c8
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/Android.mk | 1 | ||||
-rw-r--r-- | compiler/buffered_output_stream.cc | 59 | ||||
-rw-r--r-- | compiler/buffered_output_stream.h | 54 | ||||
-rw-r--r-- | compiler/elf_writer_quick.cc | 3 | ||||
-rw-r--r-- | compiler/output_stream_test.cc | 16 | ||||
-rw-r--r-- | compiler/sea_ir/debug/dot_gen.h | 1 |
6 files changed, 133 insertions, 1 deletions
diff --git a/compiler/Android.mk b/compiler/Android.mk index 0abe9ba3b3..8eb8db7140 100644 --- a/compiler/Android.mk +++ b/compiler/Android.mk @@ -83,6 +83,7 @@ LIBART_COMPILER_SRC_FILES := \ utils/mips/managed_register_mips.cc \ utils/x86/assembler_x86.cc \ utils/x86/managed_register_x86.cc \ + buffered_output_stream.cc \ elf_fixup.cc \ elf_stripper.cc \ elf_writer.cc \ diff --git a/compiler/buffered_output_stream.cc b/compiler/buffered_output_stream.cc new file mode 100644 index 0000000000..81a58f6284 --- /dev/null +++ b/compiler/buffered_output_stream.cc @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "buffered_output_stream.h" + +#include <string.h> + +namespace art { + +BufferedOutputStream::BufferedOutputStream(OutputStream* out) + : OutputStream(out->GetLocation()), out_(out), used_(0) {} + +bool BufferedOutputStream::WriteFully(const void* buffer, int64_t byte_count) { + if (byte_count > kBufferSize) { + Flush(); + return out_->WriteFully(buffer, byte_count); + } + if (used_ + byte_count > kBufferSize) { + bool success = Flush(); + if (!success) { + return false; + } + } + const uint8_t* src = reinterpret_cast<const uint8_t*>(buffer); + memcpy(&buffer_[used_], src, byte_count); + used_ += byte_count; + return true; +} + +bool BufferedOutputStream::Flush() { + bool success = true; + if (used_ > 0) { + success = out_->WriteFully(&buffer_[0], used_); + used_ = 0; + } + return success; +} + +off_t BufferedOutputStream::Seek(off_t offset, Whence whence) { + if (!Flush()) { + return -1; + } + return out_->Seek(offset, whence); +} + +} // namespace art diff --git a/compiler/buffered_output_stream.h b/compiler/buffered_output_stream.h new file mode 100644 index 0000000000..7d874fbc5c --- /dev/null +++ b/compiler/buffered_output_stream.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_BUFFERED_OUTPUT_STREAM_H_ +#define ART_COMPILER_BUFFERED_OUTPUT_STREAM_H_ + +#include "output_stream.h" + +#include "globals.h" + +namespace art { + +class BufferedOutputStream : public OutputStream { + public: + explicit BufferedOutputStream(OutputStream* out); + + virtual ~BufferedOutputStream() { + delete out_; + } + + virtual bool WriteFully(const void* buffer, int64_t byte_count); + + virtual off_t Seek(off_t offset, Whence whence); + + private: + static const size_t kBufferSize = 8 * KB; + + bool Flush(); + + OutputStream* const out_; + + uint8_t buffer_[kBufferSize]; + + size_t used_; + + DISALLOW_COPY_AND_ASSIGN(BufferedOutputStream); +}; + +} // namespace art + +#endif // ART_COMPILER_BUFFERED_OUTPUT_STREAM_H_ diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc index 014c51ea64..60c8f076de 100644 --- a/compiler/elf_writer_quick.cc +++ b/compiler/elf_writer_quick.cc @@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/unix_file/fd_file.h" +#include "buffered_output_stream.h" #include "driver/compiler_driver.h" #include "file_output_stream.h" #include "globals.h" @@ -619,7 +620,7 @@ bool ElfWriterQuick::Write(OatWriter& oat_writer, << " for " << elf_file_->GetPath(); return false; } - FileOutputStream output_stream(elf_file_); + BufferedOutputStream output_stream(new FileOutputStream(elf_file_)); if (!oat_writer.Write(output_stream)) { PLOG(ERROR) << "Failed to write .rodata and .text for " << elf_file_->GetPath(); return false; diff --git a/compiler/output_stream_test.cc b/compiler/output_stream_test.cc index d5e97558c0..a957ee375a 100644 --- a/compiler/output_stream_test.cc +++ b/compiler/output_stream_test.cc @@ -15,6 +15,7 @@ */ #include "base/logging.h" +#include "buffered_output_stream.h" #include "common_test.h" #include "file_output_stream.h" #include "vector_output_stream.h" @@ -70,6 +71,21 @@ TEST_F(OutputStreamTest, File) { CheckTestOutput(actual); } +TEST_F(OutputStreamTest, Buffered) { + ScratchFile tmp; + UniquePtr<FileOutputStream> file_output_stream(new FileOutputStream(tmp.GetFile())); + CHECK(file_output_stream.get() != NULL); + BufferedOutputStream buffered_output_stream(file_output_stream.release()); + SetOutputStream(buffered_output_stream); + GenerateTestOutput(); + UniquePtr<File> in(OS::OpenFileForReading(tmp.GetFilename().c_str())); + EXPECT_TRUE(in.get() != NULL); + std::vector<uint8_t> actual(in->GetLength()); + bool readSuccess = in->ReadFully(&actual[0], actual.size()); + EXPECT_TRUE(readSuccess); + CheckTestOutput(actual); +} + TEST_F(OutputStreamTest, Vector) { std::vector<uint8_t> output; VectorOutputStream output_stream("test vector output", output); diff --git a/compiler/sea_ir/debug/dot_gen.h b/compiler/sea_ir/debug/dot_gen.h index f2ab8c4384..d7d21ad05a 100644 --- a/compiler/sea_ir/debug/dot_gen.h +++ b/compiler/sea_ir/debug/dot_gen.h @@ -104,6 +104,7 @@ class DotConversion { LOG(INFO) << "Starting to write SEA string to file " << filename << std::endl; DotGenerationVisitor dgv = DotGenerationVisitor(&options_, types); graph->Accept(&dgv); + // TODO: UniquePtr to close file properly. Switch to BufferedOutputStream. art::File* file = art::OS::CreateEmptyFile(filename.c_str()); art::FileOutputStream fos(file); std::string graph_as_string = dgv.GetResult(); |