aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-08-13 15:44:52 +0000
committerDan Gohman <gohman@apple.com>2009-08-13 15:44:52 +0000
commit072828e99bb310b69349dd1c0c1701f6ff655e02 (patch)
tree454bfbd24e64505c541c1355a0ced1e5c09ac0c3 /lib
parent7efa530000dcac8292d83b9ac3557b3ff7e4e7da (diff)
downloadexternal_llvm-072828e99bb310b69349dd1c0c1701f6ff655e02.zip
external_llvm-072828e99bb310b69349dd1c0c1701f6ff655e02.tar.gz
external_llvm-072828e99bb310b69349dd1c0c1701f6ff655e02.tar.bz2
Fix the buffer handling logic so that write_impl is always called with
a full buffer, rather than often being called with a slightly-less-than-full buffer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78907 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Support/raw_ostream.cpp45
1 files changed, 25 insertions, 20 deletions
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index e3ab0c6..11a11bd 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -164,17 +164,32 @@ raw_ostream &raw_ostream::write(unsigned char C) {
raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
// Group exceptional cases into a single branch.
if (BUILTIN_EXPECT(OutBufCur+Size > OutBufEnd, false)) {
- if (Unbuffered) {
- write_impl(Ptr, Size);
- return *this;
- }
-
- if (!OutBufStart)
+ if (BUILTIN_EXPECT(!OutBufStart, false)) {
+ if (Unbuffered) {
+ write_impl(Ptr, Size);
+ return *this;
+ }
+ // Set up a buffer and start over.
SetBufferSize();
- else
+ 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);
}
-
+
+ copy_to_buffer(Ptr, Size);
+
+ return *this;
+}
+
+void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
// Handle short strings specially, memcpy isn't very good at very short
// strings.
switch (Size) {
@@ -184,21 +199,11 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH
case 0: break;
default:
- // Normally the string to emit is shorter than the buffer.
- if (Size <= unsigned(OutBufEnd-OutBufCur)) {
- memcpy(OutBufCur, Ptr, Size);
- break;
- }
-
- // Otherwise we are emitting a string larger than our buffer. We
- // know we already flushed, so just write it out directly.
- write_impl(Ptr, Size);
- Size = 0;
+ memcpy(OutBufCur, Ptr, Size);
break;
}
- OutBufCur += Size;
- return *this;
+ OutBufCur += Size;
}
// Formatted output.