Modified: trunk/Source/WTF/ChangeLog (202187 => 202188)
--- trunk/Source/WTF/ChangeLog 2016-06-18 00:09:12 UTC (rev 202187)
+++ trunk/Source/WTF/ChangeLog 2016-06-18 00:25:44 UTC (rev 202188)
@@ -1,3 +1,16 @@
+2016-06-17 Chris Dumez <cdu...@apple.com>
+
+ Optimize parseCacheHeader() by using StringView
+ https://bugs.webkit.org/show_bug.cgi?id=158891
+
+ Reviewed by Darin Adler.
+
+ Add a StringView::find() overload which takes a CharacterMatchFunction
+ to match the one on String.
+
+ * wtf/text/StringView.h:
+ (WTF::StringView::find):
+
2016-06-17 Mark Lam <mark....@apple.com>
OOM Assertion failure in JSON.stringify.
Modified: trunk/Source/WTF/wtf/text/StringView.h (202187 => 202188)
--- trunk/Source/WTF/wtf/text/StringView.h 2016-06-18 00:09:12 UTC (rev 202187)
+++ trunk/Source/WTF/wtf/text/StringView.h 2016-06-18 00:25:44 UTC (rev 202188)
@@ -45,6 +45,8 @@
namespace WTF {
+using CharacterMatchFunction = bool (*)(UChar);
+
// StringView is a non-owning reference to a string, similar to the proposed std::string_view.
// Whether the string is 8-bit or 16-bit is encoded in the upper bit of the length member.
// This means that strings longer than 2 gigacharacters cannot be represented.
@@ -110,6 +112,7 @@
StringView substring(unsigned start, unsigned length = std::numeric_limits<unsigned>::max()) const;
size_t find(UChar, unsigned start = 0) const;
+ size_t find(CharacterMatchFunction, unsigned start = 0) const;
WTF_EXPORT_STRING_API size_t find(StringView, unsigned start) const;
@@ -500,6 +503,13 @@
return WTF::find(characters16(), length(), character, start);
}
+inline size_t StringView::find(CharacterMatchFunction matchFunction, unsigned start) const
+{
+ if (is8Bit())
+ return WTF::find(characters8(), m_length, matchFunction, start);
+ return WTF::find(characters16(), length(), matchFunction, start);
+}
+
#if !CHECK_STRINGVIEW_LIFETIME
inline void StringView::invalidate(const StringImpl&)
{
Modified: trunk/Source/WebCore/ChangeLog (202187 => 202188)
--- trunk/Source/WebCore/ChangeLog 2016-06-18 00:09:12 UTC (rev 202187)
+++ trunk/Source/WebCore/ChangeLog 2016-06-18 00:25:44 UTC (rev 202188)
@@ -1,3 +1,22 @@
+2016-06-17 Chris Dumez <cdu...@apple.com>
+
+ Optimize parseCacheHeader() by using StringView
+ https://bugs.webkit.org/show_bug.cgi?id=158891
+
+ Reviewed by Darin Adler.
+
+ Optimize parseCacheHeader() and avoid some temporary String allocations
+ by using StringView. We now strip the whitespaces in the input string
+ at the beginning of the function, at the same as as we strip the
+ control characters. We are then able to leverage StringView in the
+ rest of the function to get substrings without the need for extra
+ String allocations.
+
+ * platform/network/CacheValidation.cpp:
+ (WebCore::isControlCharacterOrSpace):
+ (WebCore::trimToNextSeparator):
+ (WebCore::parseCacheHeader):
+
2016-06-17 Brent Fulgham <bfulg...@apple.com>
Unreviewed clean-up after r202186.
Modified: trunk/Source/WebCore/platform/network/CacheValidation.cpp (202187 => 202188)
--- trunk/Source/WebCore/platform/network/CacheValidation.cpp 2016-06-18 00:09:12 UTC (rev 202187)
+++ trunk/Source/WebCore/platform/network/CacheValidation.cpp 2016-06-18 00:25:44 UTC (rev 202188)
@@ -34,6 +34,7 @@
#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include <wtf/CurrentTime.h>
+#include <wtf/text/StringView.h>
namespace WebCore {
@@ -202,21 +203,22 @@
}
}
-inline bool isControlCharacter(UChar c)
+inline bool isControlCharacterOrSpace(UChar character)
{
- return c < ' ' || c == 127;
+ return character <= ' ' || character == 127;
}
-inline String trimToNextSeparator(const String& str)
+inline StringView trimToNextSeparator(StringView string)
{
- return str.substring(0, str.find(isCacheHeaderSeparator));
+ return string.substring(0, string.find(isCacheHeaderSeparator));
}
static Vector<std::pair<String, String>> parseCacheHeader(const String& header)
{
Vector<std::pair<String, String>> result;
- const String safeHeader = header.removeCharacters(isControlCharacter);
+ String safeHeaderString = header.removeCharacters(isControlCharacterOrSpace);
+ StringView safeHeader = safeHeaderString;
unsigned max = safeHeader.length();
unsigned pos = 0;
while (pos < max) {
@@ -224,30 +226,30 @@
size_t nextEqualSignPosition = safeHeader.find('=', pos);
if (nextEqualSignPosition == notFound && nextCommaPosition == notFound) {
// Add last directive to map with empty string as value
- result.append(std::make_pair(trimToNextSeparator(safeHeader.substring(pos, max - pos).stripWhiteSpace()), ""));
+ result.append({ trimToNextSeparator(safeHeader.substring(pos, max - pos)).toString(), emptyString() });
return result;
}
if (nextCommaPosition != notFound && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition == notFound)) {
// Add directive to map with empty string as value
- result.append(std::make_pair(trimToNextSeparator(safeHeader.substring(pos, nextCommaPosition - pos).stripWhiteSpace()), ""));
+ result.append({ trimToNextSeparator(safeHeader.substring(pos, nextCommaPosition - pos)).toString(), emptyString() });
pos += nextCommaPosition - pos + 1;
continue;
}
// Get directive name, parse right hand side of equal sign, then add to map
- String directive = trimToNextSeparator(safeHeader.substring(pos, nextEqualSignPosition - pos).stripWhiteSpace());
+ String directive = trimToNextSeparator(safeHeader.substring(pos, nextEqualSignPosition - pos)).toString();
pos += nextEqualSignPosition - pos + 1;
- String value = safeHeader.substring(pos, max - pos).stripWhiteSpace();
+ StringView value = safeHeader.substring(pos, max - pos);
if (value[0] == '"') {
// The value is a quoted string
size_t nextDoubleQuotePosition = value.find('"', 1);
if (nextDoubleQuotePosition == notFound) {
// Parse error; just use the rest as the value
- result.append(std::make_pair(directive, trimToNextSeparator(value.substring(1, value.length() - 1).stripWhiteSpace())));
+ result.append({ directive, trimToNextSeparator(value.substring(1, value.length() - 1)).toString() });
return result;
}
// Store the value as a quoted string without quotes
- result.append(std::make_pair(directive, value.substring(1, nextDoubleQuotePosition - 1).stripWhiteSpace()));
+ result.append({ directive, value.substring(1, nextDoubleQuotePosition - 1).toString() });
pos += (safeHeader.find('"', pos) - pos) + nextDoubleQuotePosition + 1;
// Move past next comma, if there is one
size_t nextCommaPosition2 = safeHeader.find(',', pos);
@@ -260,11 +262,11 @@
size_t nextCommaPosition2 = value.find(',');
if (nextCommaPosition2 == notFound) {
// The rest is the value; no change to value needed
- result.append(std::make_pair(directive, trimToNextSeparator(value)));
+ result.append({ directive, trimToNextSeparator(value).toString() });
return result;
}
// The value is delimited by the next comma
- result.append(std::make_pair(directive, trimToNextSeparator(value.substring(0, nextCommaPosition2).stripWhiteSpace())));
+ result.append({ directive, trimToNextSeparator(value.substring(0, nextCommaPosition2)).toString() });
pos += (safeHeader.find(',', pos) - pos) + 1;
}
return result;