Chromium Code Reviews| Index: third_party/WebKit/Source/wtf/text/StringBuilder.cpp |
| diff --git a/third_party/WebKit/Source/wtf/text/StringBuilder.cpp b/third_party/WebKit/Source/wtf/text/StringBuilder.cpp |
| index e1922ae1bc21f92362cc71e10faff7116bf4a6ff..10d09e5d7ecba08c91a4de15caf5ed4fcb8610ea 100644 |
| --- a/third_party/WebKit/Source/wtf/text/StringBuilder.cpp |
| +++ b/third_party/WebKit/Source/wtf/text/StringBuilder.cpp |
| @@ -102,13 +102,10 @@ unsigned StringBuilder::capacity() const |
| void StringBuilder::reserveCapacity(unsigned newCapacity) |
| { |
| - if (m_is8Bit) { |
| - ensureBuffer8(); |
| - m_buffer8->reserveCapacity(newCapacity); |
| - } else { |
| - ensureBuffer16(); |
| - m_buffer16->reserveCapacity(newCapacity); |
| - } |
| + if (m_is8Bit) |
| + ensureBuffer8(newCapacity); |
| + else |
| + ensureBuffer16(newCapacity); |
| } |
| void StringBuilder::resize(unsigned newSize) |
| @@ -124,18 +121,28 @@ void StringBuilder::resize(unsigned newSize) |
| m_buffer16->resize(newSize); |
| } |
| -void StringBuilder::createBuffer8() |
| +void StringBuilder::createBuffer8(unsigned addedSize) |
| { |
| DCHECK(!hasBuffer()); |
| DCHECK(m_is8Bit); |
| m_buffer8 = new Buffer8; |
| + // createBuffer is called right before appending addedSize more bytes. We |
| + // want to ensure we have enough space to fit m_string plus the added |
| + // size. |
| + // |
| + // We also ensure that we have at least the initialBufferSize of extra space |
| + // for appending new bytes to avoid future mallocs for appending short |
| + // strings or single characters. This is a no-op if m_length == 0 since |
| + // initialBufferSize() is the same as the inline capacity of the vector. |
| + // This allows doing append(string); append('\0') without extra mallocs. |
| + m_buffer8->reserveInitialCapacity(m_length + std::max(addedSize, initialBufferSize())); |
|
haraken
2016/07/01 02:01:03
I don't quite see any reason you want to take std:
|
| m_length = 0; |
| // Must keep a ref to the string since append will clear it. |
| String string(m_string); |
| append(string); |
| } |
| -void StringBuilder::createBuffer16() |
| +void StringBuilder::createBuffer16(unsigned addedSize) |
| { |
| DCHECK(m_is8Bit || !hasBuffer()); |
| Buffer8 buffer8; |
| @@ -145,6 +152,8 @@ void StringBuilder::createBuffer16() |
| delete m_buffer8; |
| } |
| m_buffer16 = new Buffer16; |
| + // See createBuffer8's call to reserveInitialCapacity for why we do this. |
| + m_buffer16->reserveInitialCapacity(m_length + std::max(addedSize, initialBufferSize())); |
| m_is8Bit = false; |
| m_length = 0; |
| if (!buffer8.isEmpty()) { |
| @@ -169,7 +178,7 @@ void StringBuilder::append(const UChar* characters, unsigned length) |
| return; |
| } |
| - ensureBuffer16(); |
| + ensureBuffer16(length); |
| m_string = String(); |
| m_buffer16->append(characters, length); |
| m_length += length; |
| @@ -182,14 +191,14 @@ void StringBuilder::append(const LChar* characters, unsigned length) |
| DCHECK(characters); |
| if (m_is8Bit) { |
| - ensureBuffer8(); |
| + ensureBuffer8(length); |
| m_string = String(); |
| m_buffer8->append(characters, length); |
| m_length += length; |
| return; |
| } |
| - ensureBuffer16(); |
| + ensureBuffer16(length); |
| m_string = String(); |
| m_buffer16->reserveCapacity(m_buffer16->size() + length); |
| for (size_t i = 0; i < length; ++i) |