<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[169358] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/169358">169358</a></dd>
<dt>Author</dt> <dd>darin@apple.com</dd>
<dt>Date</dt> <dd>2014-05-26 12:58:29 -0700 (Mon, 26 May 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Class name matching should use ASCII case-insensitive matching, not Unicode case folding
https://bugs.webkit.org/show_bug.cgi?id=133292
Reviewed by Anders Carlsson.
Source/WebCore:
Tests: fast/dom/getElementsByClassName/ASCII-case-insensitive.html
fast/dom/getElementsByClassName/case-sensitive.html
* dom/SpaceSplitString.cpp:
(WebCore::hasNonASCIIOrUpper): Deleted.
(WebCore::tokenizeSpaceSplitString): Use a for loop instead of while.
(WebCore::spaceSplitStringTable): Renamed from sharedDataMap; the new name is supposed
to help us see the analogy with the atomic string table.
(WebCore::SpaceSplitString::set): Removed unneeded special case for null and preflight
since AtomicString::convertToASCIILowercase now handles both of those. Changed to call
convertToASCIILowercase instead of foldCase, since we don't want to fold non-ASCII.
(WebCore::SpaceSplitString::spaceSplitStringContainsValue): Ditto.
(WebCore::SpaceSplitStringData::create): Marked this inline since it's only called in
one place and that place is in this file. Also used auto a bit and used get instead of
find since the value type is a simple pointer.
(WebCore::SpaceSplitStringData::destroy): Removed unneeded check for null. We never
create any SpaceSplitStringData with empty strings, and a null is a kind of empty string.
* dom/SpaceSplitString.h: Removed some unneeded includes and some unneeded uses of the
inline keyword. Changed types from size_t to unsigned in a couple places; we had a mix
of the types and there was no reason to use size_t there.
Source/WTF:
* wtf/text/AtomicString.cpp:
(WTF::AtomicString::addSlowCase): Change to take references instead of pointers since these
arguments can never be null.
(WTF::AtomicString::lower): Rearranged slightly to use PassRef in a more efficient but
slightly uglier way.
(WTF::AtomicString::convertToASCIILowercase): Added.
* wtf/text/AtomicString.h: Updated for above changes.
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::convertToASCIILowercase): Added.
* wtf/text/StringImpl.h: Updated for above.
* wtf/text/WTFString.cpp:
(WTF::String::convertToASCIILowercase): Added.
* wtf/text/WTFString.h: Updated for above.
LayoutTests:
* fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt: Added.
* fast/dom/getElementsByClassName/ASCII-case-insensitive.html: Added.
* fast/dom/getElementsByClassName/case-sensitive-expected.txt: Added.
* fast/dom/getElementsByClassName/case-sensitive.html: Added.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextAtomicStringcpp">trunk/Source/WTF/wtf/text/AtomicString.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextAtomicStringh">trunk/Source/WTF/wtf/text/AtomicString.h</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplcpp">trunk/Source/WTF/wtf/text/StringImpl.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplh">trunk/Source/WTF/wtf/text/StringImpl.h</a></li>
<li><a href="#trunkSourceWTFwtftextWTFStringcpp">trunk/Source/WTF/wtf/text/WTFString.cpp</a></li>
<li><a href="#trunkSourceWTFwtftextWTFStringh">trunk/Source/WTF/wtf/text/WTFString.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomSpaceSplitStringcpp">trunk/Source/WebCore/dom/SpaceSplitString.cpp</a></li>
<li><a href="#trunkSourceWebCoredomSpaceSplitStringh">trunk/Source/WebCore/dom/SpaceSplitString.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsfastdomgetElementsByClassNameASCIIcaseinsensitiveexpectedtxt">trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomgetElementsByClassNameASCIIcaseinsensitivehtml">trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive.html</a></li>
<li><a href="#trunkLayoutTestsfastdomgetElementsByClassNamecasesensitiveexpectedtxt">trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastdomgetElementsByClassNamecasesensitivehtml">trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive.html</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/LayoutTests/ChangeLog        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-05-26 Darin Adler <darin@apple.com>
+
+ Class name matching should use ASCII case-insensitive matching, not Unicode case folding
+ https://bugs.webkit.org/show_bug.cgi?id=133292
+
+ Reviewed by Anders Carlsson.
+
+ * fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt: Added.
+ * fast/dom/getElementsByClassName/ASCII-case-insensitive.html: Added.
+ * fast/dom/getElementsByClassName/case-sensitive-expected.txt: Added.
+ * fast/dom/getElementsByClassName/case-sensitive.html: Added.
+
</ins><span class="cx"> 2014-05-25 Filip Pizlo <fpizlo@apple.com>
</span><span class="cx">
</span><span class="cx"> Latest emscripten life benchmark is 4x slower because the DFG doesn't realize that arithmetic on booleans is a thing
</span></span></pre></div>
<a id="trunkLayoutTestsfastdomgetElementsByClassNameASCIIcaseinsensitiveexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt (0 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+FAIL getByClassName('a') should be a A. Was a.
+FAIL getByClassName('A') should be a A. Was A.
+PASS getByClassName('ä') is "ä"
+PASS getByClassName('Ä') is "Ä"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastdomgetElementsByClassNameASCIIcaseinsensitivehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive.html (0 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive.html         (rev 0)
+++ trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive.html        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+<!DOCTYPE html>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+<script src="../../../resources/js-test.js"></script>
+
+<div id="a" class="a"></div>
+<div id="ä" class="ä"></div>
+<div id="A" class="A"></div>
+<div id="Ä" class="Ä"></div>
+
+<script>
+
+function getByClassName(classNames)
+{
+ var nodes = document.getElementsByClassName(classNames);
+ var result = "";
+ for (var i = 0; i < nodes.length; ++i) {
+ if (i)
+ result += " ";
+ result += nodes[i].id;
+ }
+ return result;
+}
+
+shouldBeEqualToString("getByClassName('a')", "a A");
+shouldBeEqualToString("getByClassName('A')", "a A");
+shouldBeEqualToString("getByClassName('ä')", "ä");
+shouldBeEqualToString("getByClassName('Ä')", "Ä");
+
+</script>
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/dom/getElementsByClassName/ASCII-case-insensitive.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastdomgetElementsByClassNamecasesensitiveexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive-expected.txt (0 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive-expected.txt         (rev 0)
+++ trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive-expected.txt        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -0,0 +1,8 @@
</span><ins>+PASS getByClassName('a') is "a"
+PASS getByClassName('A') is "A"
+PASS getByClassName('ä') is "ä"
+PASS getByClassName('Ä') is "Ä"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive-expected.txt
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkLayoutTestsfastdomgetElementsByClassNamecasesensitivehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive.html (0 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive.html         (rev 0)
+++ trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive.html        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+<script src="../../../resources/js-test.js"></script>
+
+<div id="a" class="a"></div>
+<div id="ä" class="ä"></div>
+<div id="A" class="A"></div>
+<div id="Ä" class="Ä"></div>
+
+<script>
+
+function getByClassName(classNames)
+{
+ var nodes = document.getElementsByClassName(classNames);
+ var result = "";
+ for (var i = 0; i < nodes.length; ++i) {
+ if (i)
+ result += " ";
+ result += nodes[i].id;
+ }
+ return result;
+}
+
+shouldBeEqualToString("getByClassName('a')", "a");
+shouldBeEqualToString("getByClassName('A')", "A");
+shouldBeEqualToString("getByClassName('ä')", "ä");
+shouldBeEqualToString("getByClassName('Ä')", "Ä");
+
+</script>
</ins><span class="cx">Property changes on: trunk/LayoutTests/fast/dom/getElementsByClassName/case-sensitive.html
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/ChangeLog        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2014-05-26 Darin Adler <darin@apple.com>
+
+ Class name matching should use ASCII case-insensitive matching, not Unicode case folding
+ https://bugs.webkit.org/show_bug.cgi?id=133292
+
+ Reviewed by Anders Carlsson.
+
+ * wtf/text/AtomicString.cpp:
+ (WTF::AtomicString::addSlowCase): Change to take references instead of pointers since these
+ arguments can never be null.
+ (WTF::AtomicString::lower): Rearranged slightly to use PassRef in a more efficient but
+ slightly uglier way.
+ (WTF::AtomicString::convertToASCIILowercase): Added.
+ * wtf/text/AtomicString.h: Updated for above changes.
+
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::convertToASCIILowercase): Added.
+ * wtf/text/StringImpl.h: Updated for above.
+
+ * wtf/text/WTFString.cpp:
+ (WTF::String::convertToASCIILowercase): Added.
+ * wtf/text/WTFString.h: Updated for above.
+
</ins><span class="cx"> 2014-05-22 Zan Dobersek <zdobersek@igalia.com>
</span><span class="cx">
</span><span class="cx"> Add the partial specialization for VectorTraits<std::unique_ptr<P>>
</span></span></pre></div>
<a id="trunkSourceWTFwtftextAtomicStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/AtomicString.cpp (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/AtomicString.cpp        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/wtf/text/AtomicString.cpp        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2004-2008, 2013-2014 Apple Inc. All rights reserved.
</ins><span class="cx"> * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
</span><span class="cx"> * Copyright (C) 2012 Google Inc. All rights reserved.
</span><span class="cx"> *
</span><span class="lines">@@ -396,37 +396,37 @@
</span><span class="cx"> return addToStringTable<CharBuffer, CharBufferFromLiteralDataTranslator>(buffer);
</span><span class="cx"> }
</span><span class="cx">
</span><del>-PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* string)
</del><ins>+PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl& string)
</ins><span class="cx"> {
</span><del>- if (!string->length())
</del><ins>+ if (!string.length())
</ins><span class="cx"> return StringImpl::empty();
</span><span class="cx">
</span><del>- ASSERT_WITH_MESSAGE(!string->isAtomic(), "AtomicString should not hit the slow case if the string is already atomic.");
</del><ins>+ ASSERT_WITH_MESSAGE(!string.isAtomic(), "AtomicString should not hit the slow case if the string is already atomic.");
</ins><span class="cx">
</span><span class="cx"> AtomicStringTableLocker locker;
</span><del>- HashSet<StringImpl*>::AddResult addResult = stringTable().add(string);
</del><ins>+ auto addResult = stringTable().add(&string);
</ins><span class="cx">
</span><span class="cx"> if (addResult.isNewEntry) {
</span><del>- ASSERT(*addResult.iterator == string);
- string->setIsAtomic(true);
</del><ins>+ ASSERT(*addResult.iterator == &string);
+ string.setIsAtomic(true);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return *addResult.iterator;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-PassRefPtr<StringImpl> AtomicString::addSlowCase(AtomicStringTable* stringTable, StringImpl* string)
</del><ins>+PassRefPtr<StringImpl> AtomicString::addSlowCase(AtomicStringTable& stringTable, StringImpl& string)
</ins><span class="cx"> {
</span><del>- if (!string->length())
</del><ins>+ if (!string.length())
</ins><span class="cx"> return StringImpl::empty();
</span><span class="cx">
</span><del>- ASSERT_WITH_MESSAGE(!string->isAtomic(), "AtomicString should not hit the slow case if the string is already atomic.");
</del><ins>+ ASSERT_WITH_MESSAGE(!string.isAtomic(), "AtomicString should not hit the slow case if the string is already atomic.");
</ins><span class="cx">
</span><span class="cx"> AtomicStringTableLocker locker;
</span><del>- HashSet<StringImpl*>::AddResult addResult = stringTable->table().add(string);
</del><ins>+ auto addResult = stringTable.table().add(&string);
</ins><span class="cx">
</span><span class="cx"> if (addResult.isNewEntry) {
</span><del>- ASSERT(*addResult.iterator == string);
- string->setIsAtomic(true);
</del><ins>+ ASSERT(*addResult.iterator == &string);
+ string.setIsAtomic(true);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> return *addResult.iterator;
</span><span class="lines">@@ -474,15 +474,54 @@
</span><span class="cx"> if (UNLIKELY(!impl))
</span><span class="cx"> return AtomicString();
</span><span class="cx">
</span><del>- RefPtr<StringImpl> lowerImpl = impl->lower();
- AtomicString returnValue;
- if (LIKELY(lowerImpl == impl))
- returnValue.m_string = lowerImpl.release();
- else
- returnValue.m_string = addSlowCase(lowerImpl.get());
- return returnValue;
</del><ins>+ RefPtr<StringImpl> lowercasedString = impl->lower();
+ if (LIKELY(lowercasedString == impl))
+ return *this;
+
+ AtomicString result;
+ result.m_string = addSlowCase(*lowercasedString);
+ return result;
</ins><span class="cx"> }
</span><span class="cx">
</span><ins>+AtomicString AtomicString::convertToASCIILowercase() const
+{
+ StringImpl* impl = this->impl();
+ if (UNLIKELY(!impl))
+ return AtomicString();
+
+ // Convert short strings without allocating a new StringImpl, since
+ // there's a good chance these strings are already in the atomic
+ // string table and so no memory allocation will be required.
+ unsigned length;
+ const unsigned localBufferSize = 100;
+ if (impl->is8Bit() && (length = impl->length()) <= localBufferSize) {
+ const LChar* characters = impl->characters8();
+ unsigned failingIndex;
+ for (unsigned i = 0; i < length; ++i) {
+ if (UNLIKELY(isASCIIUpper(characters[i]))) {
+ failingIndex = i;
+ goto SlowPath;
+ }
+ }
+ return *this;
+SlowPath:
+ LChar localBuffer[localBufferSize];
+ for (unsigned i = 0; i < failingIndex; ++i)
+ localBuffer[i] = characters[i];
+ for (unsigned i = failingIndex; i < length; ++i)
+ localBuffer[i] = toASCIILower(characters[i]);
+ return AtomicString(localBuffer, length);
+ }
+
+ RefPtr<StringImpl> convertedString = impl->convertToASCIILowercase();
+ if (LIKELY(convertedString == impl))
+ return *this;
+
+ AtomicString result;
+ result.m_string = addSlowCase(*convertedString);
+ return result;
+}
+
</ins><span class="cx"> AtomicStringImpl* AtomicString::findSlowCase(StringImpl& string)
</span><span class="cx"> {
</span><span class="cx"> ASSERT_WITH_MESSAGE(!string.isAtomic(), "AtomicStringImpls should return from the fast case.");
</span></span></pre></div>
<a id="trunkSourceWTFwtftextAtomicStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/AtomicString.h (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/AtomicString.h        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/wtf/text/AtomicString.h        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2004, 2005, 2006, 2008, 2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="cx"> * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -141,9 +141,10 @@
</span><span class="cx"> bool endsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const
</span><span class="cx"> { return m_string.endsWith<matchLength>(prefix, caseSensitive); }
</span><span class="cx">
</span><ins>+ WTF_EXPORT_STRING_API AtomicString convertToASCIILowercase() const;
</ins><span class="cx"> WTF_EXPORT_STRING_API AtomicString lower() const;
</span><span class="cx"> AtomicString upper() const { return AtomicString(impl()->upper()); }
</span><del>-
</del><ins>+
</ins><span class="cx"> int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
</span><span class="cx"> double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
</span><span class="cx"> float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); }
</span><span class="lines">@@ -185,7 +186,7 @@
</span><span class="cx"> ASSERT_WITH_MESSAGE(!string || !string->length() || isInAtomicStringTable(string), "The atomic string comes from an other thread!");
</span><span class="cx"> return string;
</span><span class="cx"> }
</span><del>- return addSlowCase(string);
</del><ins>+ return addSlowCase(*string);
</ins><span class="cx"> }
</span><span class="cx"> WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addFromLiteralData(const char* characters, unsigned length);
</span><span class="cx"> #if USE(CF)
</span><span class="lines">@@ -199,7 +200,7 @@
</span><span class="cx"> ASSERT_WITH_MESSAGE(!string || !string->length() || isInAtomicStringTable(string), "The atomic string comes from an other thread!");
</span><span class="cx"> return string;
</span><span class="cx"> }
</span><del>- return addSlowCase(stringTableProvider.atomicStringTable(), string);
</del><ins>+ return addSlowCase(*stringTableProvider.atomicStringTable(), *string);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="lines">@@ -208,8 +209,8 @@
</span><span class="cx">
</span><span class="cx"> String m_string;
</span><span class="cx">
</span><del>- WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addSlowCase(StringImpl*);
- WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addSlowCase(AtomicStringTable*, StringImpl*);
</del><ins>+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addSlowCase(StringImpl&);
+ WTF_EXPORT_STRING_API static PassRefPtr<StringImpl> addSlowCase(AtomicStringTable&, StringImpl&);
</ins><span class="cx">
</span><span class="cx"> WTF_EXPORT_STRING_API static AtomicStringImpl* findSlowCase(StringImpl&);
</span><span class="cx"> WTF_EXPORT_STRING_API static AtomicString fromUTF8Internal(const char*, const char*);
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.cpp        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -2,7 +2,7 @@
</span><span class="cx"> * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
</span><span class="cx"> * (C) 1999 Antti Koivisto (koivisto@kde.org)
</span><span class="cx"> * (C) 2001 Dirk Mueller ( mueller@kde.org )
</span><del>- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013-2014 Apple Inc. All rights reserved.
</ins><span class="cx"> * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
</span><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -353,12 +353,12 @@
</span><span class="cx"> LChar character = m_data8[i];
</span><span class="cx"> if (UNLIKELY((character & ~0x7F) || isASCIIUpper(character))) {
</span><span class="cx"> failingIndex = i;
</span><del>- goto SlowPath8bitLower;
</del><ins>+ goto SlowPath;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> return *this;
</span><span class="cx">
</span><del>-SlowPath8bitLower:
</del><ins>+SlowPath:
</ins><span class="cx"> LChar* data8;
</span><span class="cx"> auto newImpl = createUninitializedInternalNonEmpty(m_length, data8);
</span><span class="cx">
</span><span class="lines">@@ -619,6 +619,8 @@
</span><span class="cx">
</span><span class="cx"> PassRef<StringImpl> StringImpl::foldCase()
</span><span class="cx"> {
</span><ins>+ // FIXME: Why doesn't this function have a preflight like the one in StringImpl::lower?
+
</ins><span class="cx"> if (m_length > static_cast<unsigned>(std::numeric_limits<int32_t>::max()))
</span><span class="cx"> CRASH();
</span><span class="cx"> int32_t length = m_length;
</span><span class="lines">@@ -673,6 +675,44 @@
</span><span class="cx"> return newImpl.releaseNonNull();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+PassRef<StringImpl> StringImpl::convertToASCIILowercase()
+{
+ if (is8Bit()) {
+ unsigned failingIndex;
+ for (unsigned i = 0; i < m_length; ++i) {
+ LChar character = m_data8[i];
+ if (UNLIKELY(isASCIIUpper(character))) {
+ failingIndex = i;
+ goto SlowPath;
+ }
+ }
+ return *this;
+
+SlowPath:
+ LChar* data8;
+ PassRef<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data8);
+ for (unsigned i = 0; i < failingIndex; ++i)
+ data8[i] = m_data8[i];
+ for (unsigned i = failingIndex; i < m_length; ++i)
+ data8[i] = toASCIILower(m_data8[i]);
+ return newImpl;
+ }
+
+ bool noUpper = true;
+ for (unsigned i = 0; i < m_length; ++i) {
+ if (UNLIKELY(isASCIIUpper(m_data16[i])))
+ noUpper = false;
+ }
+ if (noUpper)
+ return *this;
+
+ UChar* data16;
+ PassRef<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data16);
+ for (unsigned i = 0; i < m_length; ++i)
+ data16[i] = toASCIILower(m_data16[i]);
+ return newImpl;
+}
+
</ins><span class="cx"> template <class UCharPredicate>
</span><span class="cx"> inline PassRef<StringImpl> StringImpl::stripMatchedCharacters(UCharPredicate predicate)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.h (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.h        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/wtf/text/StringImpl.h        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
</span><del>- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2005-2010, 2013-2014 Apple Inc. All rights reserved.
</ins><span class="cx"> * Copyright (C) 2009 Google Inc. All rights reserved.
</span><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -628,6 +628,7 @@
</span><span class="cx"> double toDouble(bool* ok = 0);
</span><span class="cx"> float toFloat(bool* ok = 0);
</span><span class="cx">
</span><ins>+ WTF_EXPORT_STRING_API PassRef<StringImpl> convertToASCIILowercase();
</ins><span class="cx"> WTF_EXPORT_STRING_API PassRef<StringImpl> lower();
</span><span class="cx"> WTF_EXPORT_STRING_API PassRef<StringImpl> upper();
</span><span class="cx"> WTF_EXPORT_STRING_API PassRef<StringImpl> lower(const AtomicString& localeIdentifier);
</span><span class="lines">@@ -635,6 +636,7 @@
</span><span class="cx">
</span><span class="cx"> WTF_EXPORT_STRING_API PassRef<StringImpl> fill(UChar);
</span><span class="cx"> // FIXME: Do we need fill(char) or can we just do the right thing if UChar is ASCII?
</span><ins>+
</ins><span class="cx"> PassRef<StringImpl> foldCase();
</span><span class="cx">
</span><span class="cx"> PassRef<StringImpl> stripWhiteSpace();
</span></span></pre></div>
<a id="trunkSourceWTFwtftextWTFStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/WTFString.cpp (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/WTFString.cpp        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/wtf/text/WTFString.cpp        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -335,6 +335,14 @@
</span><span class="cx"> return String(StringImpl::createSubstringSharingImpl(m_impl, offset, length));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+String String::convertToASCIILowercase() const
+{
+ // FIXME: Should this function, and the many others like it, be inlined?
+ if (!m_impl)
+ return String();
+ return m_impl->convertToASCIILowercase();
+}
+
</ins><span class="cx"> String String::lower() const
</span><span class="cx"> {
</span><span class="cx"> if (!m_impl)
</span></span></pre></div>
<a id="trunkSourceWTFwtftextWTFStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/WTFString.h (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/WTFString.h        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WTF/wtf/text/WTFString.h        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -310,7 +310,10 @@
</span><span class="cx"> String left(unsigned len) const { return substring(0, len); }
</span><span class="cx"> String right(unsigned len) const { return substring(length() - len, len); }
</span><span class="cx">
</span><del>- // Returns a lowercase/uppercase version of the string
</del><ins>+ // Returns a lowercase/uppercase version of the string.
+ // The convertToASCIILowercase is useful in many contexts such as HTML where we don't
+ // want to do any conversion for non-ASCII letters.
+ WTF_EXPORT_STRING_API String convertToASCIILowercase() const;
</ins><span class="cx"> WTF_EXPORT_STRING_API String lower() const;
</span><span class="cx"> WTF_EXPORT_STRING_API String upper() const;
</span><span class="cx">
</span><span class="lines">@@ -325,7 +328,8 @@
</span><span class="cx"> WTF_EXPORT_STRING_API String removeCharacters(CharacterMatchFunctionPtr) const;
</span><span class="cx"> template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters() const;
</span><span class="cx">
</span><del>- // Return the string with case folded for case insensitive comparison.
</del><ins>+ // Returns the string with case folded for case insensitive comparison.
+ // Use convertToASCIILowercase instead if ASCII case insensitive comparison is desired.
</ins><span class="cx"> WTF_EXPORT_STRING_API String foldCase() const;
</span><span class="cx">
</span><span class="cx"> WTF_EXPORT_STRING_API static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WebCore/ChangeLog        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2014-05-26 Darin Adler <darin@apple.com>
+
+ Class name matching should use ASCII case-insensitive matching, not Unicode case folding
+ https://bugs.webkit.org/show_bug.cgi?id=133292
+
+ Reviewed by Anders Carlsson.
+
+ Tests: fast/dom/getElementsByClassName/ASCII-case-insensitive.html
+ fast/dom/getElementsByClassName/case-sensitive.html
+
+ * dom/SpaceSplitString.cpp:
+ (WebCore::hasNonASCIIOrUpper): Deleted.
+ (WebCore::tokenizeSpaceSplitString): Use a for loop instead of while.
+ (WebCore::spaceSplitStringTable): Renamed from sharedDataMap; the new name is supposed
+ to help us see the analogy with the atomic string table.
+ (WebCore::SpaceSplitString::set): Removed unneeded special case for null and preflight
+ since AtomicString::convertToASCIILowercase now handles both of those. Changed to call
+ convertToASCIILowercase instead of foldCase, since we don't want to fold non-ASCII.
+ (WebCore::SpaceSplitString::spaceSplitStringContainsValue): Ditto.
+ (WebCore::SpaceSplitStringData::create): Marked this inline since it's only called in
+ one place and that place is in this file. Also used auto a bit and used get instead of
+ find since the value type is a simple pointer.
+ (WebCore::SpaceSplitStringData::destroy): Removed unneeded check for null. We never
+ create any SpaceSplitStringData with empty strings, and a null is a kind of empty string.
+
+ * dom/SpaceSplitString.h: Removed some unneeded includes and some unneeded uses of the
+ inline keyword. Changed types from size_t to unsigned in a couple places; we had a mix
+ of the types and there was no reason to use size_t there.
+
</ins><span class="cx"> 2014-05-26 Javier Fernandez <jfernandez@igalia.com>
</span><span class="cx">
</span><span class="cx"> [CSS Grid Layout] Implementation of the "grid" shorthand.
</span></span></pre></div>
<a id="trunkSourceWebCoredomSpaceSplitStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SpaceSplitString.cpp (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SpaceSplitString.cpp        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WebCore/dom/SpaceSplitString.cpp        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx"> * Copyright (C) 2007 David Smith (catfish.man@gmail.com)
</span><del>- * Copyright (C) 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007, 2008, 2011-2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="cx"> * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -22,42 +22,18 @@
</span><span class="cx"> #include "SpaceSplitString.h"
</span><span class="cx">
</span><span class="cx"> #include "HTMLParserIdioms.h"
</span><del>-#include <wtf/ASCIICType.h>
</del><span class="cx"> #include <wtf/HashMap.h>
</span><ins>+#include <wtf/NeverDestroyed.h>
</ins><span class="cx"> #include <wtf/text/AtomicStringHash.h>
</span><del>-#include <wtf/text/StringBuilder.h>
</del><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> COMPILE_ASSERT(!(sizeof(SpaceSplitStringData) % sizeof(uintptr_t)), SpaceSplitStringDataTailIsAlignedToWordSize);
</span><span class="cx">
</span><del>-template <typename CharacterType>
-static inline bool hasNonASCIIOrUpper(const CharacterType* characters, unsigned length)
-{
- bool hasUpper = false;
- CharacterType ored = 0;
- for (unsigned i = 0; i < length; i++) {
- CharacterType c = characters[i];
- hasUpper |= isASCIIUpper(c);
- ored |= c;
- }
- return hasUpper || (ored & ~0x7F);
-}
-
-static inline bool hasNonASCIIOrUpper(const String& string)
-{
- unsigned length = string.length();
-
- if (string.is8Bit())
- return hasNonASCIIOrUpper(string.characters8(), length);
- return hasNonASCIIOrUpper(string.characters16(), length);
-}
-
</del><span class="cx"> template <typename CharacterType, typename TokenProcessor>
</span><span class="cx"> static inline void tokenizeSpaceSplitString(TokenProcessor& tokenProcessor, const CharacterType* characters, unsigned length)
</span><span class="cx"> {
</span><del>- unsigned start = 0;
- while (true) {
</del><ins>+ for (unsigned start = 0; ; ) {
</ins><span class="cx"> while (start < length && isHTMLSpace(characters[start]))
</span><span class="cx"> ++start;
</span><span class="cx"> if (start >= length)
</span><span class="lines">@@ -78,11 +54,11 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!string.isNull());
</span><span class="cx">
</span><del>- const StringImpl* stringImpl = string.impl();
- if (stringImpl->is8Bit())
- tokenizeSpaceSplitString(tokenProcessor, stringImpl->characters8(), stringImpl->length());
</del><ins>+ const StringImpl& stringImpl = *string.impl();
+ if (stringImpl.is8Bit())
+ tokenizeSpaceSplitString(tokenProcessor, stringImpl.characters8(), stringImpl.length());
</ins><span class="cx"> else
</span><del>- tokenizeSpaceSplitString(tokenProcessor, stringImpl->characters16(), stringImpl->length());
</del><ins>+ tokenizeSpaceSplitString(tokenProcessor, stringImpl.characters16(), stringImpl.length());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool SpaceSplitStringData::containsAll(SpaceSplitStringData& other)
</span><span class="lines">@@ -100,7 +76,7 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-struct SpaceSplitStringDataMapKeyTrait : public HashTraits<AtomicString>
</del><ins>+struct SpaceSplitStringTableKeyTraits : public HashTraits<AtomicString>
</ins><span class="cx"> {
</span><span class="cx"> // The number 200 for typicalNumberOfSpaceSplitString was based on the typical number of unique class names
</span><span class="cx"> // on typical websites on August 2013.
</span><span class="lines">@@ -108,26 +84,17 @@
</span><span class="cx"> static const int minimumTableSize = WTF::HashTableCapacityForSize<typicalNumberOfSpaceSplitString>::value;
</span><span class="cx"> };
</span><span class="cx">
</span><del>-typedef HashMap<AtomicString, SpaceSplitStringData*, DefaultHash<AtomicString>::Hash, SpaceSplitStringDataMapKeyTrait> SpaceSplitStringDataMap;
</del><ins>+typedef HashMap<AtomicString, SpaceSplitStringData*, AtomicStringHash, SpaceSplitStringTableKeyTraits> SpaceSplitStringTable;
</ins><span class="cx">
</span><del>-static SpaceSplitStringDataMap& sharedDataMap()
</del><ins>+static SpaceSplitStringTable& spaceSplitStringTable()
</ins><span class="cx"> {
</span><del>- DEPRECATED_DEFINE_STATIC_LOCAL(SpaceSplitStringDataMap, map, ());
- return map;
</del><ins>+ static NeverDestroyed<SpaceSplitStringTable> table;
+ return table;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void SpaceSplitString::set(const AtomicString& inputString, bool shouldFoldCase)
</span><span class="cx"> {
</span><del>- if (inputString.isNull()) {
- clear();
- return;
- }
-
- AtomicString string(inputString);
- if (shouldFoldCase && hasNonASCIIOrUpper(string))
- string = string.string().foldCase();
-
- m_data = SpaceSplitStringData::create(string);
</del><ins>+ m_data = SpaceSplitStringData::create(shouldFoldCase ? inputString.convertToASCIILowercase() : inputString);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> class TokenIsEqualToCStringTokenProcessor {
</span><span class="lines">@@ -162,12 +129,8 @@
</span><span class="cx"> if (inputString.isNull())
</span><span class="cx"> return false;
</span><span class="cx">
</span><del>- String string = inputString;
- if (shouldFoldCase && hasNonASCIIOrUpper(string))
- string = string.foldCase();
-
</del><span class="cx"> TokenIsEqualToCStringTokenProcessor tokenProcessor(value, valueLength);
</span><del>- tokenizeSpaceSplitString(tokenProcessor, string);
</del><ins>+ tokenizeSpaceSplitString(tokenProcessor, shouldFoldCase ? inputString.impl()->convertToASCIILowercase() : inputString);
</ins><span class="cx"> return tokenProcessor.referenceStringWasFound();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -176,8 +139,7 @@
</span><span class="cx"> public:
</span><span class="cx"> TokenCounter() : m_tokenCount(0) { }
</span><span class="cx">
</span><del>- template <typename CharacterType>
- bool processToken(const CharacterType*, unsigned)
</del><ins>+ template<typename CharacterType> bool processToken(const CharacterType*, unsigned)
</ins><span class="cx"> {
</span><span class="cx"> ++m_tokenCount;
</span><span class="cx"> return true;
</span><span class="lines">@@ -194,8 +156,7 @@
</span><span class="cx"> public:
</span><span class="cx"> TokenAtomicStringInitializer(AtomicString* memory) : m_memoryBucket(memory) { }
</span><span class="cx">
</span><del>- template <typename CharacterType>
- bool processToken(const CharacterType* characters, unsigned length)
</del><ins>+ template<typename CharacterType> bool processToken(const CharacterType* characters, unsigned length)
</ins><span class="cx"> {
</span><span class="cx"> new (NotNull, m_memoryBucket) AtomicString(characters, length);
</span><span class="cx"> ++m_memoryBucket;
</span><span class="lines">@@ -203,11 +164,12 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const AtomicString* nextMemoryBucket() const { return m_memoryBucket; }
</span><ins>+
</ins><span class="cx"> private:
</span><span class="cx"> AtomicString* m_memoryBucket;
</span><span class="cx"> };
</span><span class="cx">
</span><del>-PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& keyString, unsigned tokenCount)
</del><ins>+inline PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& keyString, unsigned tokenCount)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(tokenCount);
</span><span class="cx">
</span><span class="lines">@@ -230,10 +192,9 @@
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> ASSERT(!keyString.isNull());
</span><span class="cx">
</span><del>- SpaceSplitStringDataMap& spaceSplitStringDataCache = sharedDataMap();
- SpaceSplitStringDataMap::iterator iterator = spaceSplitStringDataCache.find(keyString);
- if (iterator != spaceSplitStringDataCache.end())
- return iterator->value;
</del><ins>+ auto& table = spaceSplitStringTable();
+ if (SpaceSplitStringData* data = table.get(keyString))
+ return data;
</ins><span class="cx">
</span><span class="cx"> // Nothing in the cache? Let's create a new SpaceSplitStringData if the input has something useful.
</span><span class="cx"> // 1) We find the number of strings in the input to know how much size we need to allocate.
</span><span class="lines">@@ -245,7 +206,7 @@
</span><span class="cx"> return nullptr;
</span><span class="cx">
</span><span class="cx"> RefPtr<SpaceSplitStringData> spaceSplitStringData = create(keyString, tokenCount);
</span><del>- spaceSplitStringDataCache.add(keyString, spaceSplitStringData.get());
</del><ins>+ table.add(keyString, spaceSplitStringData.get());
</ins><span class="cx"> return spaceSplitStringData.release();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -254,8 +215,7 @@
</span><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx">
</span><del>- if (!spaceSplitString->m_keyString.isNull())
- sharedDataMap().remove(spaceSplitString->m_keyString);
</del><ins>+ spaceSplitStringTable().remove(spaceSplitString->m_keyString);
</ins><span class="cx">
</span><span class="cx"> unsigned i = 0;
</span><span class="cx"> unsigned size = spaceSplitString->size();
</span></span></pre></div>
<a id="trunkSourceWebCoredomSpaceSplitStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/SpaceSplitString.h (169357 => 169358)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/SpaceSplitString.h        2014-05-26 18:01:45 UTC (rev 169357)
+++ trunk/Source/WebCore/dom/SpaceSplitString.h        2014-05-26 19:58:29 UTC (rev 169358)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2007, 2008, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2007-2014 Apple Inc. All rights reserved.
</ins><span class="cx"> *
</span><span class="cx"> * This library is free software; you can redistribute it and/or
</span><span class="cx"> * modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -21,9 +21,7 @@
</span><span class="cx"> #ifndef SpaceSplitString_h
</span><span class="cx"> #define SpaceSplitString_h
</span><span class="cx">
</span><del>-#include <wtf/Assertions.h>
</del><span class="cx"> #include <wtf/MainThread.h>
</span><del>-#include <wtf/Noncopyable.h>
</del><span class="cx"> #include <wtf/text/AtomicString.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -51,26 +49,26 @@
</span><span class="cx"> unsigned size() const { return m_size; }
</span><span class="cx"> static ptrdiff_t sizeMemoryOffset() { return OBJECT_OFFSETOF(SpaceSplitStringData, m_size); }
</span><span class="cx">
</span><del>- const AtomicString& operator[](size_t i)
</del><ins>+ const AtomicString& operator[](unsigned i)
</ins><span class="cx"> {
</span><span class="cx"> RELEASE_ASSERT(i < m_size);
</span><span class="cx"> return tokenArrayStart()[i];
</span><span class="cx"> }
</span><span class="cx">
</span><del>- inline void ref()
</del><ins>+ void ref()
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> ASSERT(m_refCount);
</span><span class="cx"> ++m_refCount;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- inline void deref()
</del><ins>+ void deref()
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(isMainThread());
</span><span class="cx"> ASSERT(m_refCount);
</span><span class="cx"> unsigned tempRefCount = m_refCount - 1;
</span><span class="cx"> if (!tempRefCount) {
</span><del>- SpaceSplitStringData::destroy(this);
</del><ins>+ destroy(this);
</ins><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx"> m_refCount = tempRefCount;
</span><span class="lines">@@ -89,7 +87,7 @@
</span><span class="cx"> ASSERT_WITH_MESSAGE(m_size, "SpaceSplitStringData should never be empty by definition. There is no difference between empty and null.");
</span><span class="cx"> }
</span><span class="cx">
</span><del>- inline ~SpaceSplitStringData() { }
</del><ins>+ ~SpaceSplitStringData() { }
</ins><span class="cx"> static void destroy(SpaceSplitStringData*);
</span><span class="cx">
</span><span class="cx"> AtomicString* tokenArrayStart() { return reinterpret_cast<AtomicString*>(this + 1); }
</span><span class="lines">@@ -112,9 +110,9 @@
</span><span class="cx"> bool contains(const AtomicString& string) const { return m_data && m_data->contains(string); }
</span><span class="cx"> bool containsAll(const SpaceSplitString& names) const { return !names.m_data || (m_data && m_data->containsAll(*names.m_data)); }
</span><span class="cx">
</span><del>- size_t size() const { return m_data ? m_data->size() : 0; }
</del><ins>+ unsigned size() const { return m_data ? m_data->size() : 0; }
</ins><span class="cx"> bool isEmpty() const { return !m_data; }
</span><del>- const AtomicString& operator[](size_t i) const
</del><ins>+ const AtomicString& operator[](unsigned i) const
</ins><span class="cx"> {
</span><span class="cx"> ASSERT_WITH_SECURITY_IMPLICATION(m_data);
</span><span class="cx"> return (*m_data)[i];
</span><span class="lines">@@ -128,7 +126,6 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> private:
</span><del>-
</del><span class="cx"> RefPtr<SpaceSplitStringData> m_data;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre>
</div>
</div>
</body>
</html>