aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-03-17 01:13:35 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-03-17 01:13:35 +0000
commitd17d74bb80d9da1712a066df40122e8584dad227 (patch)
tree52f6ed729f4c3fc9424adad8dad5b1dd81f01809
parent6b233395025069f63156ea2b524cdb708a14731f (diff)
raw_ostream: Rework implementation of unbuffered streams so outputting
a single character requires only one branch to follow slow path. - Never use a buffer when writing on an unbuffered stream. - Move default buffer size to header. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67066 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/raw_ostream.h33
-rw-r--r--lib/Support/raw_ostream.cpp16
2 files changed, 30 insertions, 19 deletions
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index aa6a8b9f9f..4db6737f6d 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -31,10 +31,16 @@ namespace llvm {
/// a chunk at a time.
class raw_ostream {
private:
- /// \invariant { The buffer is uninitialized (OutBufStart,
- /// OutBufEnd, and OutBufCur are non-zero), or none of them are zero
- /// and there are at least 64 total bytes in the buffer. }
-
+ /// The buffer is handled in such a way that the buffer is
+ /// uninitialized, unbuffered, or out of space when OutBufCur >=
+ /// OutBufEnd. Thus a single comparison suffices to determine if we
+ /// need to take the slow path to write a single character.
+ ///
+ /// The buffer is in one of three states:
+ /// 1. Unbuffered (Unbuffered == true)
+ /// 1. Uninitialized (Unbuffered == false && OutBufStart == 0).
+ /// 2. Buffered (Unbuffered == false && OutBufStart != 0 &&
+ /// OutBufEnd - OutBufStart >= 64).
char *OutBufStart, *OutBufEnd, *OutBufCur;
bool Unbuffered;
@@ -54,7 +60,7 @@ public:
/// SetBufferSize - Set the internal buffer size to the specified amount
/// instead of the default.
- void SetBufferSize(unsigned Size) {
+ void SetBufferSize(unsigned Size=4096) {
assert(Size >= 64 &&
"Buffer size must be somewhat large for invariants to hold");
flush();
@@ -63,16 +69,19 @@ public:
OutBufStart = new char[Size];
OutBufEnd = OutBufStart+Size;
OutBufCur = OutBufStart;
+ Unbuffered = false;
}
/// SetUnbuffered - Set the streams buffering status. When
/// unbuffered the stream will flush after every write. This routine
/// will also flush the buffer immediately when the stream is being
/// set to unbuffered.
- void SetUnbuffered(bool unbuffered) {
- Unbuffered = unbuffered;
- if (Unbuffered)
- flush();
+ void SetUnbuffered() {
+ flush();
+
+ delete [] OutBufStart;
+ OutBufStart = OutBufEnd = OutBufCur = 0;
+ Unbuffered = true;
}
unsigned GetNumBytesInBuffer() const {
@@ -92,8 +101,6 @@ public:
if (OutBufCur >= OutBufEnd)
return write(C);
*OutBufCur++ = C;
- if (Unbuffered)
- flush_nonempty();
return *this;
}
@@ -101,8 +108,6 @@ public:
if (OutBufCur >= OutBufEnd)
return write(C);
*OutBufCur++ = C;
- if (Unbuffered)
- flush_nonempty();
return *this;
}
@@ -110,8 +115,6 @@ public:
if (OutBufCur >= OutBufEnd)
return write(C);
*OutBufCur++ = C;
- if (Unbuffered)
- flush_nonempty();
return *this;
}
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 3b33ad67b1..6aec9478fa 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -123,8 +123,13 @@ void raw_ostream::flush_nonempty() {
}
raw_ostream &raw_ostream::write(unsigned char C) {
+ if (Unbuffered) {
+ write_impl(reinterpret_cast<char*>(&C), 1);
+ return *this;
+ }
+
if (!OutBufStart)
- SetBufferSize(4096);
+ SetBufferSize();
else if (OutBufCur >= OutBufEnd)
flush_nonempty();
@@ -133,8 +138,13 @@ raw_ostream &raw_ostream::write(unsigned char C) {
}
raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) {
+ if (Unbuffered) {
+ write_impl(Ptr, Size);
+ return *this;
+ }
+
if (!OutBufStart)
- SetBufferSize(4096);
+ SetBufferSize();
else if (OutBufCur+Size > OutBufEnd)
flush_nonempty();
@@ -161,8 +171,6 @@ raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) {
}
OutBufCur += Size;
- if (Unbuffered)
- flush();
return *this;
}