diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 80ea7407b44..b8839e2943b 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -265,15 +265,19 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) { return write(Ptr, Size); } - // Write out the data in buffer-sized blocks until the remainder - // fits within the buffer. - do { - size_t NumBytes = OutBufEnd - OutBufCur; - copy_to_buffer(Ptr, NumBytes); - flush_nonempty(); - Ptr += NumBytes; - Size -= NumBytes; - } while (OutBufCur+Size > OutBufEnd); + // If the buffer is empty at this point we have a string that is larger + // than the buffer. It's better to write it unbuffered in this case. + if (BUILTIN_EXPECT(OutBufCur == OutBufStart, false)) { + write_impl(Ptr, Size); + return *this; + } + + // We don't have enough space in the buffer to fit the string in. Insert as + // much as possible, flush and start over with the remainder. + size_t NumBytes = OutBufEnd - OutBufCur; + copy_to_buffer(Ptr, NumBytes); + flush_nonempty(); + return write(Ptr + NumBytes, Size - NumBytes); } copy_to_buffer(Ptr, Size);