| Index: third_party/WebKit/Source/core/editing/VisibleUnits.cpp | 
| diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp | 
| index 358c9b1ae37eaa29b6eab16bc94b8caa69b7b1c1..608c7a8930a09407150b2b42390d8c7caf9b8fe2 100644 | 
| --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp | 
| +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp | 
| @@ -666,16 +666,17 @@ static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT | 
| const PositionTemplate<Strategy> start = PositionTemplate<Strategy>::editingPositionOf(boundary, 0).parentAnchoredEquivalent(); | 
| const PositionTemplate<Strategy> end = pos.parentAnchoredEquivalent(); | 
|  | 
| -    Vector<UChar, 1024> string; | 
| +    ForwardsTextBuffer suffixString; | 
| unsigned suffixLength = 0; | 
|  | 
| if (requiresContextForWordBoundary(characterBefore(c))) { | 
| TextIteratorAlgorithm<Strategy> forwardsIterator(end, PositionTemplate<Strategy>::afterNode(boundary)); | 
| while (!forwardsIterator.atEnd()) { | 
| -            Vector<UChar, 1024> characters; | 
| +            // TODO(xiaochengh): Eliminate this intermediate buffer. | 
| +            ForwardsTextBuffer characters; | 
| forwardsIterator.copyTextTo(characters); | 
| int i = endOfFirstWordBoundaryContext(characters.data(), characters.size()); | 
| -            string.append(characters.data(), i); | 
| +            suffixString.pushRange(characters.data(), i); | 
| suffixLength += i; | 
| if (static_cast<unsigned>(i) < characters.size()) | 
| break; | 
| @@ -683,6 +684,9 @@ static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT | 
| } | 
| } | 
|  | 
| +    BackwardsTextBuffer string; | 
| +    string.pushRange(suffixString.data(), suffixString.size()); | 
| + | 
| SimplifiedBackwardsTextIteratorAlgorithm<Strategy> it(start, end); | 
| unsigned next = 0; | 
| bool needMoreContext = false; | 
| @@ -690,16 +694,12 @@ static VisiblePositionTemplate<Strategy> previousBoundary(const VisiblePositionT | 
| bool inTextSecurityMode = it.isInTextSecurityMode(); | 
| // iterate to get chunks until the searchFunction returns a non-zero | 
| // value. | 
| -        // TODO(xiaochengh): Iterative prepending has quadratic running time | 
| -        // in the worst case. Should improve it to linear. | 
| if (!inTextSecurityMode) { | 
| it.copyTextTo(string); | 
| } else { | 
| // Treat bullets used in the text security mode as regular | 
| // characters when looking for boundaries | 
| -            Vector<UChar, 1024> iteratorString; | 
| -            iteratorString.fill('x', it.length()); | 
| -            string.prepend(iteratorString.data(), iteratorString.size()); | 
| +            string.pushCharacters('x', it.length()); | 
| } | 
| // TODO(xiaochengh): The following line takes O(string.size()) time, | 
| // which makes the while loop take quadratic time in the worst case. | 
| @@ -746,19 +746,18 @@ static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl | 
| Document& d = boundary->document(); | 
| const PositionTemplate<Strategy> start(pos.parentAnchoredEquivalent()); | 
|  | 
| -    Vector<UChar, 1024> string; | 
| +    BackwardsTextBuffer prefixString; | 
| unsigned prefixLength = 0; | 
|  | 
| if (requiresContextForWordBoundary(characterAfter(c))) { | 
| SimplifiedBackwardsTextIteratorAlgorithm<Strategy> backwardsIterator(PositionTemplate<Strategy>::firstPositionInNode(&d), start); | 
| while (!backwardsIterator.atEnd()) { | 
| -            Vector<UChar, 1024> characters; | 
| +            // TODO(xiaochengh): Eliminate this intermediate buffer. | 
| +            BackwardsTextBuffer characters; | 
| backwardsIterator.copyTextTo(characters); | 
| int length = characters.size(); | 
| int i = startOfLastWordBoundaryContext(characters.data(), length); | 
| -            // TODO(xiaochengh): Iterative prepending has quadratic running | 
| -            // time in the worst case. Should improve it to linear. | 
| -            string.prepend(characters.data() + i, length - i); | 
| +            prefixString.pushRange(characters.data() + i, length - i); | 
| prefixLength += length - i; | 
| if (i > 0) | 
| break; | 
| @@ -766,6 +765,9 @@ static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl | 
| } | 
| } | 
|  | 
| +    ForwardsTextBuffer string; | 
| +    string.pushRange(prefixString.data(), prefixString.size()); | 
| + | 
| const PositionTemplate<Strategy> searchStart = PositionTemplate<Strategy>::editingPositionOf(start.anchorNode(), start.offsetInContainerNode()); | 
| const PositionTemplate<Strategy> searchEnd = PositionTemplate<Strategy>::lastPositionInNode(boundary); | 
| TextIteratorAlgorithm<Strategy> it(searchStart, searchEnd, TextIteratorEmitsCharactersBetweenAllVisiblePositions); | 
| @@ -783,9 +785,7 @@ static VisiblePositionTemplate<Strategy> nextBoundary(const VisiblePositionTempl | 
| } else { | 
| // Treat bullets used in the text security mode as regular | 
| // characters when looking for boundaries | 
| -            Vector<UChar, 1024> iteratorString; | 
| -            iteratorString.fill('x', it.length()); | 
| -            string.append(iteratorString.data(), iteratorString.size()); | 
| +            string.pushCharacters('x', it.length()); | 
| } | 
| next = searchFunction(string.data(), string.size(), offset, MayHaveMoreContext, needMoreContext); | 
| if (next != string.size()) | 
|  |