1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

raw_svector_ostream: grow and reserve atomically

Including the scratch buffer size in the initial reservation eliminates the
subsequent malloc+move operation and offers a healthier constant growth with
less memory wastage.

When doing this, take care to avoid invalidating the source buffer.

llvm-svn: 212816
This commit is contained in:
Alp Toker 2014-07-11 14:02:04 +00:00
parent 6090374181
commit 0d0baf0938

View File

@ -729,24 +729,26 @@ void raw_svector_ostream::resync() {
}
void raw_svector_ostream::write_impl(const char *Ptr, size_t Size) {
// If we're writing bytes from the end of the buffer into the smallvector, we
// don't need to copy the bytes, just commit the bytes because they are
// already in the right place.
if (Ptr == OS.end()) {
assert(OS.size() + Size <= OS.capacity() && "Invalid write_impl() call!");
OS.set_size(OS.size() + Size);
size_t NewSize = OS.size() + Size;
size_t NewReservation = NewSize + 64;
bool NoOverlap = Ptr + Size < OS.begin() || Ptr > OS.begin() + OS.capacity();
if (NoOverlap) {
assert(!GetNumBytesInBuffer());
OS.reserve(NewReservation);
memcpy(OS.end(), Ptr, Size);
OS.set_size(NewSize);
} else if (Ptr == OS.end()) {
// Grow the buffer to include the scratch area without copying.
assert(NewSize <= OS.capacity() && "Invalid write_impl() call!");
OS.set_size(NewSize);
OS.reserve(NewReservation);
} else {
assert(GetNumBytesInBuffer() == 0 &&
"Should be writing from buffer if some bytes in it");
// Otherwise, do copy the bytes.
OS.append(Ptr, Ptr + Size);
OS.reserve(NewReservation);
}
// 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());
}