[llvm-commits] [llvm] r79434 - in /llvm/trunk: include/llvm/Support/raw_ostream.h lib/Support/raw_ostream.cpp

Daniel Dunbar daniel at zuster.org
Wed Aug 19 10:54:29 PDT 2009


Author: ddunbar
Date: Wed Aug 19 12:54:29 2009
New Revision: 79434

URL: http://llvm.org/viewvc/llvm-project?rev=79434&view=rev
Log:
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.

Modified:
    llvm/trunk/include/llvm/Support/raw_ostream.h
    llvm/trunk/lib/Support/raw_ostream.cpp

Modified: llvm/trunk/include/llvm/Support/raw_ostream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/raw_ostream.h?rev=79434&r1=79433&r2=79434&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/raw_ostream.h (original)
+++ llvm/trunk/include/llvm/Support/raw_ostream.h Wed Aug 19 12:54:29 2009
@@ -452,6 +452,10 @@
   /// counting the bytes currently in the buffer.
   virtual uint64_t current_pos();
 public:
+  /// Construct a new raw_svector_ostream.
+  ///
+  /// \arg O - The vector to write to; this *must* have at least 128 bytes of
+  /// free space in it.
   explicit raw_svector_ostream(SmallVectorImpl<char> &O);
   ~raw_svector_ostream();
 };

Modified: llvm/trunk/lib/Support/raw_ostream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/raw_ostream.cpp?rev=79434&r1=79433&r2=79434&view=diff

==============================================================================
--- llvm/trunk/lib/Support/raw_ostream.cpp (original)
+++ llvm/trunk/lib/Support/raw_ostream.cpp Wed Aug 19 12:54:29 2009
@@ -95,6 +95,8 @@
   OutBufEnd = OutBufStart+Size;
   OutBufCur = OutBufStart;
   BufferMode = Mode;
+
+  assert(OutBufStart <= OutBufEnd && "Invalid size!");
 }
 
 raw_ostream &raw_ostream::operator<<(unsigned long N) {
@@ -478,15 +480,41 @@
 //  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<char> &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(); }





More information about the llvm-commits mailing list