[url] Avoid scanning for whitespace twice during ResolveRelative
For calls to url::ResolveRelative, if the input is not in fact relative, we call RemoveURLWhitespace twice on the same buffer. This is not necessary. On a test of loading 100 identical ~1mb data URL images, this patch speeds up the renderer by ~8% on Linux. BUG=657978 Review-Url: https://codereview.chromium.org/2540893004 Cr-Commit-Position: refs/heads/master@{#435604}
This commit is contained in:
@@ -294,6 +294,7 @@ TEST(GURLTest, Resolve) {
|
|||||||
{"http://www.google.com/foo/", "/bar", true, "http://www.google.com/bar"},
|
{"http://www.google.com/foo/", "/bar", true, "http://www.google.com/bar"},
|
||||||
{"http://www.google.com/foo", "bar", true, "http://www.google.com/bar"},
|
{"http://www.google.com/foo", "bar", true, "http://www.google.com/bar"},
|
||||||
{"http://www.google.com/", "http://images.google.com/foo.html", true, "http://images.google.com/foo.html"},
|
{"http://www.google.com/", "http://images.google.com/foo.html", true, "http://images.google.com/foo.html"},
|
||||||
|
{"http://www.google.com/", "http://images.\tgoogle.\ncom/\rfoo.html", true, "http://images.google.com/foo.html"},
|
||||||
{"http://www.google.com/blah/bloo?c#d", "../../../hello/./world.html?a#b", true, "http://www.google.com/hello/world.html?a#b"},
|
{"http://www.google.com/blah/bloo?c#d", "../../../hello/./world.html?a#b", true, "http://www.google.com/hello/world.html?a#b"},
|
||||||
{"http://www.google.com/foo#bar", "#com", true, "http://www.google.com/foo#com"},
|
{"http://www.google.com/foo#bar", "#com", true, "http://www.google.com/foo#com"},
|
||||||
{"http://www.google.com/", "Https:images.google.com", true, "https://images.google.com/"},
|
{"http://www.google.com/", "Https:images.google.com", true, "https://images.google.com/"},
|
||||||
|
@@ -19,6 +19,13 @@ namespace url {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Pass this enum through for methods which would like to know if whitespace
|
||||||
|
// removal is necessary.
|
||||||
|
enum WhitespaceRemovalPolicy {
|
||||||
|
REMOVE_WHITESPACE,
|
||||||
|
DO_NOT_REMOVE_WHITESPACE,
|
||||||
|
};
|
||||||
|
|
||||||
const int kNumStandardURLSchemes = 10;
|
const int kNumStandardURLSchemes = 10;
|
||||||
const SchemeWithType kStandardURLSchemes[kNumStandardURLSchemes] = {
|
const SchemeWithType kStandardURLSchemes[kNumStandardURLSchemes] = {
|
||||||
{kHttpScheme, SCHEME_WITH_PORT},
|
{kHttpScheme, SCHEME_WITH_PORT},
|
||||||
@@ -154,19 +161,19 @@ bool DoFindAndCompareScheme(const CHAR* str,
|
|||||||
return DoCompareSchemeComponent(spec, our_scheme, compare);
|
return DoCompareSchemeComponent(spec, our_scheme, compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename CHAR>
|
template <typename CHAR>
|
||||||
bool DoCanonicalize(const CHAR* in_spec,
|
bool DoCanonicalize(const CHAR* spec,
|
||||||
int in_spec_len,
|
int spec_len,
|
||||||
bool trim_path_end,
|
bool trim_path_end,
|
||||||
|
WhitespaceRemovalPolicy whitespace_policy,
|
||||||
CharsetConverter* charset_converter,
|
CharsetConverter* charset_converter,
|
||||||
CanonOutput* output,
|
CanonOutput* output,
|
||||||
Parsed* output_parsed) {
|
Parsed* output_parsed) {
|
||||||
// Remove any whitespace from the middle of the relative URL, possibly
|
// Remove any whitespace from the middle of the relative URL if necessary.
|
||||||
// copying to the new buffer.
|
// Possibly this will result in copying to the new buffer.
|
||||||
RawCanonOutputT<CHAR> whitespace_buffer;
|
RawCanonOutputT<CHAR> whitespace_buffer;
|
||||||
int spec_len;
|
if (whitespace_policy == REMOVE_WHITESPACE)
|
||||||
const CHAR* spec = RemoveURLWhitespace(in_spec, in_spec_len,
|
spec = RemoveURLWhitespace(spec, spec_len, &whitespace_buffer, &spec_len);
|
||||||
&whitespace_buffer, &spec_len);
|
|
||||||
|
|
||||||
Parsed parsed_input;
|
Parsed parsed_input;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -287,7 +294,8 @@ bool DoResolveRelative(const char* base_spec,
|
|||||||
// based on base_parsed_authority instead of base_parsed) and needs to be
|
// based on base_parsed_authority instead of base_parsed) and needs to be
|
||||||
// re-created.
|
// re-created.
|
||||||
DoCanonicalize(temporary_output.data(), temporary_output.length(), true,
|
DoCanonicalize(temporary_output.data(), temporary_output.length(), true,
|
||||||
charset_converter, output, output_parsed);
|
REMOVE_WHITESPACE, charset_converter, output,
|
||||||
|
output_parsed);
|
||||||
return did_resolve_succeed;
|
return did_resolve_succeed;
|
||||||
}
|
}
|
||||||
} else if (is_relative) {
|
} else if (is_relative) {
|
||||||
@@ -300,8 +308,9 @@ bool DoResolveRelative(const char* base_spec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not relative, canonicalize the input.
|
// Not relative, canonicalize the input.
|
||||||
return DoCanonicalize(relative, relative_length, true, charset_converter,
|
return DoCanonicalize(relative, relative_length, true,
|
||||||
output, output_parsed);
|
DO_NOT_REMOVE_WHITESPACE, charset_converter, output,
|
||||||
|
output_parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename CHAR>
|
template<typename CHAR>
|
||||||
@@ -348,8 +357,8 @@ bool DoReplaceComponents(const char* spec,
|
|||||||
RawCanonOutput<128> recanonicalized;
|
RawCanonOutput<128> recanonicalized;
|
||||||
Parsed recanonicalized_parsed;
|
Parsed recanonicalized_parsed;
|
||||||
DoCanonicalize(scheme_replaced.data(), scheme_replaced.length(), true,
|
DoCanonicalize(scheme_replaced.data(), scheme_replaced.length(), true,
|
||||||
charset_converter,
|
REMOVE_WHITESPACE, charset_converter, &recanonicalized,
|
||||||
&recanonicalized, &recanonicalized_parsed);
|
&recanonicalized_parsed);
|
||||||
|
|
||||||
// Recurse using the version with the scheme already replaced. This will now
|
// Recurse using the version with the scheme already replaced. This will now
|
||||||
// use the replacement rules for the new scheme.
|
// use the replacement rules for the new scheme.
|
||||||
@@ -535,8 +544,8 @@ bool Canonicalize(const char* spec,
|
|||||||
CharsetConverter* charset_converter,
|
CharsetConverter* charset_converter,
|
||||||
CanonOutput* output,
|
CanonOutput* output,
|
||||||
Parsed* output_parsed) {
|
Parsed* output_parsed) {
|
||||||
return DoCanonicalize(spec, spec_len, trim_path_end, charset_converter,
|
return DoCanonicalize(spec, spec_len, trim_path_end, REMOVE_WHITESPACE,
|
||||||
output, output_parsed);
|
charset_converter, output, output_parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canonicalize(const base::char16* spec,
|
bool Canonicalize(const base::char16* spec,
|
||||||
@@ -545,8 +554,8 @@ bool Canonicalize(const base::char16* spec,
|
|||||||
CharsetConverter* charset_converter,
|
CharsetConverter* charset_converter,
|
||||||
CanonOutput* output,
|
CanonOutput* output,
|
||||||
Parsed* output_parsed) {
|
Parsed* output_parsed) {
|
||||||
return DoCanonicalize(spec, spec_len, trim_path_end, charset_converter,
|
return DoCanonicalize(spec, spec_len, trim_path_end, REMOVE_WHITESPACE,
|
||||||
output, output_parsed);
|
charset_converter, output, output_parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ResolveRelative(const char* base_spec,
|
bool ResolveRelative(const char* base_spec,
|
||||||
|
Reference in New Issue
Block a user