Commit ebe03e92 authored by Albert J. Wong's avatar Albert J. Wong Committed by Commit Bot

Remove refcount thrash in ReplaceUnmatchedSurrogates().

This CL is broken out of
https://chromium-review.googlesource.com/c/chromium/src/+/1557854

Bug: 1083392
Change-Id: I58e449d5aa856a32fc24348f4bf5ccd34e5bc685
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2296820
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Auto-Submit: Albert J. Wong <ajwong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#788591}
parent 415cd34a
...@@ -551,7 +551,7 @@ static bool HasUnmatchedSurrogates(const String& string) { ...@@ -551,7 +551,7 @@ static bool HasUnmatchedSurrogates(const String& string) {
} }
// Replace unmatched surrogates with REPLACEMENT CHARACTER U+FFFD. // Replace unmatched surrogates with REPLACEMENT CHARACTER U+FFFD.
String ReplaceUnmatchedSurrogates(const String& string) { String ReplaceUnmatchedSurrogates(String string) {
// This roughly implements http://heycam.github.io/webidl/#dfn-obtain-unicode // This roughly implements http://heycam.github.io/webidl/#dfn-obtain-unicode
// but since Blink strings are 16-bits internally, the output is simply // but since Blink strings are 16-bits internally, the output is simply
// re-encoded to UTF-16. // re-encoded to UTF-16.
...@@ -574,8 +574,8 @@ String ReplaceUnmatchedSurrogates(const String& string) { ...@@ -574,8 +574,8 @@ String ReplaceUnmatchedSurrogates(const String& string) {
unsigned i = 0; unsigned i = 0;
// 4. Initialize U to be an empty sequence of Unicode characters. // 4. Initialize U to be an empty sequence of Unicode characters.
StringBuilder u; StringBuffer<UChar> result(n);
u.ReserveCapacity(n); UChar* u = result.Characters();
// 5. While i < n: // 5. While i < n:
while (i < n) { while (i < n) {
...@@ -585,17 +585,17 @@ String ReplaceUnmatchedSurrogates(const String& string) { ...@@ -585,17 +585,17 @@ String ReplaceUnmatchedSurrogates(const String& string) {
if (U16_IS_SINGLE(c)) { if (U16_IS_SINGLE(c)) {
// c < 0xD800 or c > 0xDFFF // c < 0xD800 or c > 0xDFFF
// Append to U the Unicode character with code point c. // Append to U the Unicode character with code point c.
u.Append(c); u[i] = c;
} else if (U16_IS_TRAIL(c)) { } else if (U16_IS_TRAIL(c)) {
// 0xDC00 <= c <= 0xDFFF // 0xDC00 <= c <= 0xDFFF
// Append to U a U+FFFD REPLACEMENT CHARACTER. // Append to U a U+FFFD REPLACEMENT CHARACTER.
u.Append(kReplacementCharacter); u[i] = kReplacementCharacter;
} else { } else {
// 0xD800 <= c <= 0xDBFF // 0xD800 <= c <= 0xDBFF
DCHECK(U16_IS_LEAD(c)); DCHECK(U16_IS_LEAD(c));
if (i == n - 1) { if (i == n - 1) {
// 1. If i = n-1, then append to U a U+FFFD REPLACEMENT CHARACTER. // 1. If i = n-1, then append to U a U+FFFD REPLACEMENT CHARACTER.
u.Append(kReplacementCharacter); u[i] = kReplacementCharacter;
} else { } else {
// 2. Otherwise, i < n-1: // 2. Otherwise, i < n-1:
DCHECK_LT(i, n - 1); DCHECK_LT(i, n - 1);
...@@ -607,13 +607,12 @@ String ReplaceUnmatchedSurrogates(const String& string) { ...@@ -607,13 +607,12 @@ String ReplaceUnmatchedSurrogates(const String& string) {
// ..2. Let b be d & 0x3FF. // ..2. Let b be d & 0x3FF.
// ..3. Append to U the Unicode character with code point // ..3. Append to U the Unicode character with code point
// 2^16+2^10*a+b. // 2^16+2^10*a+b.
u.Append(U16_GET_SUPPLEMENTARY(c, d)); u[i++] = c;
// Blink: This is equivalent to u.append(c); u.append(d); u[i] = d;
++i;
} else { } else {
// 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+FFFD // 3. Otherwise, d < 0xDC00 or d > 0xDFFF. Append to U a U+FFFD
// REPLACEMENT CHARACTER. // REPLACEMENT CHARACTER.
u.Append(kReplacementCharacter); u[i] = kReplacementCharacter;
} }
} }
} }
...@@ -622,8 +621,8 @@ String ReplaceUnmatchedSurrogates(const String& string) { ...@@ -622,8 +621,8 @@ String ReplaceUnmatchedSurrogates(const String& string) {
} }
// 6. Return U. // 6. Return U.
DCHECK_EQ(u.length(), string.length()); DCHECK_EQ(i, string.length());
return u.ToString(); return String::Adopt(result);
} }
XPathNSResolver* ToXPathNSResolver(ScriptState* script_state, XPathNSResolver* ToXPathNSResolver(ScriptState* script_state,
......
...@@ -325,7 +325,7 @@ inline base::Optional<base::Time> ToCoreNullableDate( ...@@ -325,7 +325,7 @@ inline base::Optional<base::Time> ToCoreNullableDate(
} }
// USVString conversion helper. // USVString conversion helper.
CORE_EXPORT String ReplaceUnmatchedSurrogates(const String&); CORE_EXPORT String ReplaceUnmatchedSurrogates(String);
// FIXME: Remove the special casing for XPathNSResolver. // FIXME: Remove the special casing for XPathNSResolver.
XPathNSResolver* ToXPathNSResolver(ScriptState*, v8::Local<v8::Value>); XPathNSResolver* ToXPathNSResolver(ScriptState*, v8::Local<v8::Value>);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment