From 425d08c654c7893782b1215f9b2715bc1d90bd07 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 19 Aug 2009 17:54:29 +0000 Subject: Switch raw_svector_ostream to use the vector as the ostream buffer. - This avoids unnecessary malloc/free overhead in the common case, and unnecessary copying from the ostream buffer into the output vector. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79434 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/raw_ostream.cpp | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'lib/Support/raw_ostream.cpp') diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index e7e4ad3..30bc76b 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -95,6 +95,8 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, OutBufEnd = OutBufStart+Size; OutBufCur = OutBufStart; BufferMode = Mode; + + assert(OutBufStart <= OutBufEnd && "Invalid size!"); } raw_ostream &raw_ostream::operator<<(unsigned long N) { @@ -478,15 +480,41 @@ void raw_string_ostream::write_impl(const char *Ptr, size_t Size) { // raw_svector_ostream //===----------------------------------------------------------------------===// +// The raw_svector_ostream implementation uses the SmallVector itself as the +// buffer for the raw_ostream. We guarantee that the raw_ostream buffer is +// always pointing past the end of the vector, but within the vector +// capacity. This allows raw_ostream to write directly into the correct place, +// and we only need to set the vector size when the data is flushed. + raw_svector_ostream::raw_svector_ostream(SmallVectorImpl &O) : OS(O) { + // Set up the initial external buffer. We enforce that the buffer must have at + // least 128 bytes free; raw_ostream itself only requires 64, but we want to + // make sure that we don't grow the buffer unnecessarily on destruction (when + // the data is flushed). See the FIXME below. + if (OS.capacity() - OS.size() < 128) + llvm_report_error("Invalid argument, must have at least 128 bytes free!"); + SetBuffer(OS.end(), OS.capacity() - OS.size()); } raw_svector_ostream::~raw_svector_ostream() { + // FIXME: Prevent resizing during this flush(). flush(); } void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) { - OS.append(Ptr, Ptr + Size); + assert(Ptr == OS.end() && OS.size() + Size <= OS.capacity() && + "Invalid write_impl() call!"); + + // We don't need to copy the bytes, just commit the bytes to the + // SmallVector. + OS.set_size(OS.size() + Size); + + // Grow the vector if necessary. + if (OS.capacity() - OS.size() < 64) + OS.reserve(OS.capacity() * 2); + + // Update the buffer position. + SetBuffer(OS.end(), OS.capacity() - OS.size()); } uint64_t raw_svector_ostream::current_pos() { return OS.size(); } -- cgit v1.1