<!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  &lt;darin@apple.com&gt;
+
+        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  &lt;fpizlo@apple.com&gt;
</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 &quot;ä&quot;
+PASS getByClassName('Ä') is &quot;Ä&quot;
+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>+&lt;!DOCTYPE html&gt;
+&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
+
+&lt;script src=&quot;../../../resources/js-test.js&quot;&gt;&lt;/script&gt;
+
+&lt;div id=&quot;a&quot; class=&quot;a&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;ä&quot; class=&quot;ä&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;A&quot; class=&quot;A&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;Ä&quot; class=&quot;Ä&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+
+function getByClassName(classNames)
+{
+    var nodes = document.getElementsByClassName(classNames);
+    var result = &quot;&quot;;
+    for (var i = 0; i &lt; nodes.length; ++i) {
+        if (i)
+            result += &quot; &quot;;
+        result += nodes[i].id;
+    }
+    return result;
+}
+
+shouldBeEqualToString(&quot;getByClassName('a')&quot;, &quot;a A&quot;);
+shouldBeEqualToString(&quot;getByClassName('A')&quot;, &quot;a A&quot;);
+shouldBeEqualToString(&quot;getByClassName('ä')&quot;, &quot;ä&quot;);
+shouldBeEqualToString(&quot;getByClassName('Ä')&quot;, &quot;Ä&quot;);
+
+&lt;/script&gt;
</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 &quot;a&quot;
+PASS getByClassName('A') is &quot;A&quot;
+PASS getByClassName('ä') is &quot;ä&quot;
+PASS getByClassName('Ä') is &quot;Ä&quot;
+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>+&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot;&gt;
+&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot;&gt;
+
+&lt;script src=&quot;../../../resources/js-test.js&quot;&gt;&lt;/script&gt;
+
+&lt;div id=&quot;a&quot; class=&quot;a&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;ä&quot; class=&quot;ä&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;A&quot; class=&quot;A&quot;&gt;&lt;/div&gt;
+&lt;div id=&quot;Ä&quot; class=&quot;Ä&quot;&gt;&lt;/div&gt;
+
+&lt;script&gt;
+
+function getByClassName(classNames)
+{
+    var nodes = document.getElementsByClassName(classNames);
+    var result = &quot;&quot;;
+    for (var i = 0; i &lt; nodes.length; ++i) {
+        if (i)
+            result += &quot; &quot;;
+        result += nodes[i].id;
+    }
+    return result;
+}
+
+shouldBeEqualToString(&quot;getByClassName('a')&quot;, &quot;a&quot;);
+shouldBeEqualToString(&quot;getByClassName('A')&quot;, &quot;A&quot;);
+shouldBeEqualToString(&quot;getByClassName('ä')&quot;, &quot;ä&quot;);
+shouldBeEqualToString(&quot;getByClassName('Ä')&quot;, &quot;Ä&quot;);
+
+&lt;/script&gt;
</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  &lt;darin@apple.com&gt;
+
+        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  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add the partial specialization for VectorTraits&lt;std::unique_ptr&lt;P&gt;&gt;
</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 &lt;paroga@paroga.com&gt;
</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&lt;CharBuffer, CharBufferFromLiteralDataTranslator&gt;(buffer);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-PassRefPtr&lt;StringImpl&gt; AtomicString::addSlowCase(StringImpl* string)
</del><ins>+PassRefPtr&lt;StringImpl&gt; AtomicString::addSlowCase(StringImpl&amp; string)
</ins><span class="cx"> {
</span><del>-    if (!string-&gt;length())
</del><ins>+    if (!string.length())
</ins><span class="cx">         return StringImpl::empty();
</span><span class="cx"> 
</span><del>-    ASSERT_WITH_MESSAGE(!string-&gt;isAtomic(), &quot;AtomicString should not hit the slow case if the string is already atomic.&quot;);
</del><ins>+    ASSERT_WITH_MESSAGE(!string.isAtomic(), &quot;AtomicString should not hit the slow case if the string is already atomic.&quot;);
</ins><span class="cx"> 
</span><span class="cx">     AtomicStringTableLocker locker;
</span><del>-    HashSet&lt;StringImpl*&gt;::AddResult addResult = stringTable().add(string);
</del><ins>+    auto addResult = stringTable().add(&amp;string);
</ins><span class="cx"> 
</span><span class="cx">     if (addResult.isNewEntry) {
</span><del>-        ASSERT(*addResult.iterator == string);
-        string-&gt;setIsAtomic(true);
</del><ins>+        ASSERT(*addResult.iterator == &amp;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&lt;StringImpl&gt; AtomicString::addSlowCase(AtomicStringTable* stringTable, StringImpl* string)
</del><ins>+PassRefPtr&lt;StringImpl&gt; AtomicString::addSlowCase(AtomicStringTable&amp; stringTable, StringImpl&amp; string)
</ins><span class="cx"> {
</span><del>-    if (!string-&gt;length())
</del><ins>+    if (!string.length())
</ins><span class="cx">         return StringImpl::empty();
</span><span class="cx"> 
</span><del>-    ASSERT_WITH_MESSAGE(!string-&gt;isAtomic(), &quot;AtomicString should not hit the slow case if the string is already atomic.&quot;);
</del><ins>+    ASSERT_WITH_MESSAGE(!string.isAtomic(), &quot;AtomicString should not hit the slow case if the string is already atomic.&quot;);
</ins><span class="cx"> 
</span><span class="cx">     AtomicStringTableLocker locker;
</span><del>-    HashSet&lt;StringImpl*&gt;::AddResult addResult = stringTable-&gt;table().add(string);
</del><ins>+    auto addResult = stringTable.table().add(&amp;string);
</ins><span class="cx"> 
</span><span class="cx">     if (addResult.isNewEntry) {
</span><del>-        ASSERT(*addResult.iterator == string);
-        string-&gt;setIsAtomic(true);
</del><ins>+        ASSERT(*addResult.iterator == &amp;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&lt;StringImpl&gt; lowerImpl = impl-&gt;lower();
-    AtomicString returnValue;
-    if (LIKELY(lowerImpl == impl))
-        returnValue.m_string = lowerImpl.release();
-    else
-        returnValue.m_string = addSlowCase(lowerImpl.get());
-    return returnValue;
</del><ins>+    RefPtr&lt;StringImpl&gt; lowercasedString = impl-&gt;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-&gt;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-&gt;is8Bit() &amp;&amp; (length = impl-&gt;length()) &lt;= localBufferSize) {
+        const LChar* characters = impl-&gt;characters8();
+        unsigned failingIndex;
+        for (unsigned i = 0; i &lt; length; ++i) {
+            if (UNLIKELY(isASCIIUpper(characters[i]))) {
+                failingIndex = i;
+                goto SlowPath;
+            }
+        }
+        return *this;
+SlowPath:
+        LChar localBuffer[localBufferSize];
+        for (unsigned i = 0; i &lt; failingIndex; ++i)
+            localBuffer[i] = characters[i];
+        for (unsigned i = failingIndex; i &lt; length; ++i)
+            localBuffer[i] = toASCIILower(characters[i]);
+        return AtomicString(localBuffer, length);
+    }
+
+    RefPtr&lt;StringImpl&gt; convertedString = impl-&gt;convertToASCIILowercase();
+    if (LIKELY(convertedString == impl))
+        return *this;
+
+    AtomicString result;
+    result.m_string = addSlowCase(*convertedString);
+    return result;
+}
+
</ins><span class="cx"> AtomicStringImpl* AtomicString::findSlowCase(StringImpl&amp; string)
</span><span class="cx"> {
</span><span class="cx">     ASSERT_WITH_MESSAGE(!string.isAtomic(), &quot;AtomicStringImpls should return from the fast case.&quot;);
</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 (&amp;prefix)[matchLength], bool caseSensitive = true) const
</span><span class="cx">         { return m_string.endsWith&lt;matchLength&gt;(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()-&gt;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-&gt;length() || isInAtomicStringTable(string), &quot;The atomic string comes from an other thread!&quot;);
</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&lt;StringImpl&gt; 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-&gt;length() || isInAtomicStringTable(string), &quot;The atomic string comes from an other thread!&quot;);
</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&lt;StringImpl&gt; addSlowCase(StringImpl*);
-    WTF_EXPORT_STRING_API static PassRefPtr&lt;StringImpl&gt; addSlowCase(AtomicStringTable*, StringImpl*);
</del><ins>+    WTF_EXPORT_STRING_API static PassRefPtr&lt;StringImpl&gt; addSlowCase(StringImpl&amp;);
+    WTF_EXPORT_STRING_API static PassRefPtr&lt;StringImpl&gt; addSlowCase(AtomicStringTable&amp;, StringImpl&amp;);
</ins><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_STRING_API static AtomicStringImpl* findSlowCase(StringImpl&amp;);
</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 &amp; ~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&lt;StringImpl&gt; 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 &gt; static_cast&lt;unsigned&gt;(std::numeric_limits&lt;int32_t&gt;::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&lt;StringImpl&gt; StringImpl::convertToASCIILowercase()
+{
+    if (is8Bit()) {
+        unsigned failingIndex;
+        for (unsigned i = 0; i &lt; m_length; ++i) {
+            LChar character = m_data8[i];
+            if (UNLIKELY(isASCIIUpper(character))) {
+                failingIndex = i;
+                goto SlowPath;
+            }
+        }
+        return *this;
+
+SlowPath:
+        LChar* data8;
+        PassRef&lt;StringImpl&gt; newImpl = createUninitializedInternalNonEmpty(m_length, data8);
+        for (unsigned i = 0; i &lt; failingIndex; ++i)
+            data8[i] = m_data8[i];
+        for (unsigned i = failingIndex; i &lt; m_length; ++i)
+            data8[i] = toASCIILower(m_data8[i]);
+        return newImpl;
+    }
+
+    bool noUpper = true;
+    for (unsigned i = 0; i &lt; m_length; ++i) {
+        if (UNLIKELY(isASCIIUpper(m_data16[i])))
+            noUpper = false;
+    }
+    if (noUpper)
+        return *this;
+
+    UChar* data16;
+    PassRef&lt;StringImpl&gt; newImpl = createUninitializedInternalNonEmpty(m_length, data16);
+    for (unsigned i = 0; i &lt; m_length; ++i)
+        data16[i] = toASCIILower(m_data16[i]);
+    return newImpl;
+}
+
</ins><span class="cx"> template &lt;class UCharPredicate&gt;
</span><span class="cx"> inline PassRef&lt;StringImpl&gt; 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&lt;StringImpl&gt; convertToASCIILowercase();
</ins><span class="cx">     WTF_EXPORT_STRING_API PassRef&lt;StringImpl&gt; lower();
</span><span class="cx">     WTF_EXPORT_STRING_API PassRef&lt;StringImpl&gt; upper();
</span><span class="cx">     WTF_EXPORT_STRING_API PassRef&lt;StringImpl&gt; lower(const AtomicString&amp; localeIdentifier);
</span><span class="lines">@@ -635,6 +636,7 @@
</span><span class="cx"> 
</span><span class="cx">     WTF_EXPORT_STRING_API PassRef&lt;StringImpl&gt; 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&lt;StringImpl&gt; foldCase();
</span><span class="cx"> 
</span><span class="cx">     PassRef&lt;StringImpl&gt; 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-&gt;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&lt;bool isSpecialCharacter(UChar)&gt; 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  &lt;darin@apple.com&gt;
+
+        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  &lt;jfernandez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Grid Layout] Implementation of the &quot;grid&quot; 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 &quot;SpaceSplitString.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;HTMLParserIdioms.h&quot;
</span><del>-#include &lt;wtf/ASCIICType.h&gt;
</del><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><ins>+#include &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/AtomicStringHash.h&gt;
</span><del>-#include &lt;wtf/text/StringBuilder.h&gt;
</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 &lt;typename CharacterType&gt;
-static inline bool hasNonASCIIOrUpper(const CharacterType* characters, unsigned length)
-{
-    bool hasUpper = false;
-    CharacterType ored = 0;
-    for (unsigned i = 0; i &lt; length; i++) {
-        CharacterType c = characters[i];
-        hasUpper |= isASCIIUpper(c);
-        ored |= c;
-    }
-    return hasUpper || (ored &amp; ~0x7F);
-}
-
-static inline bool hasNonASCIIOrUpper(const String&amp; string)
-{
-    unsigned length = string.length();
-
-    if (string.is8Bit())
-        return hasNonASCIIOrUpper(string.characters8(), length);
-    return hasNonASCIIOrUpper(string.characters16(), length);
-}
-
</del><span class="cx"> template &lt;typename CharacterType, typename TokenProcessor&gt;
</span><span class="cx"> static inline void tokenizeSpaceSplitString(TokenProcessor&amp; 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 &lt; length &amp;&amp; isHTMLSpace(characters[start]))
</span><span class="cx">             ++start;
</span><span class="cx">         if (start &gt;= 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-&gt;is8Bit())
-        tokenizeSpaceSplitString(tokenProcessor, stringImpl-&gt;characters8(), stringImpl-&gt;length());
</del><ins>+    const StringImpl&amp; stringImpl = *string.impl();
+    if (stringImpl.is8Bit())
+        tokenizeSpaceSplitString(tokenProcessor, stringImpl.characters8(), stringImpl.length());
</ins><span class="cx">     else
</span><del>-        tokenizeSpaceSplitString(tokenProcessor, stringImpl-&gt;characters16(), stringImpl-&gt;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&amp; 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&lt;AtomicString&gt;
</del><ins>+struct SpaceSplitStringTableKeyTraits : public HashTraits&lt;AtomicString&gt;
</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&lt;typicalNumberOfSpaceSplitString&gt;::value;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-typedef HashMap&lt;AtomicString, SpaceSplitStringData*, DefaultHash&lt;AtomicString&gt;::Hash, SpaceSplitStringDataMapKeyTrait&gt; SpaceSplitStringDataMap;
</del><ins>+typedef HashMap&lt;AtomicString, SpaceSplitStringData*, AtomicStringHash, SpaceSplitStringTableKeyTraits&gt; SpaceSplitStringTable;
</ins><span class="cx"> 
</span><del>-static SpaceSplitStringDataMap&amp; sharedDataMap()
</del><ins>+static SpaceSplitStringTable&amp; spaceSplitStringTable()
</ins><span class="cx"> {
</span><del>-    DEPRECATED_DEFINE_STATIC_LOCAL(SpaceSplitStringDataMap, map, ());
-    return map;
</del><ins>+    static NeverDestroyed&lt;SpaceSplitStringTable&gt; table;
+    return table;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void SpaceSplitString::set(const AtomicString&amp; inputString, bool shouldFoldCase)
</span><span class="cx"> {
</span><del>-    if (inputString.isNull()) {
-        clear();
-        return;
-    }
-
-    AtomicString string(inputString);
-    if (shouldFoldCase &amp;&amp; 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 &amp;&amp; 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()-&gt;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 &lt;typename CharacterType&gt;
-    bool processToken(const CharacterType*, unsigned)
</del><ins>+    template&lt;typename CharacterType&gt; 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 &lt;typename CharacterType&gt;
-    bool processToken(const CharacterType* characters, unsigned length)
</del><ins>+    template&lt;typename CharacterType&gt; 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&lt;SpaceSplitStringData&gt; SpaceSplitStringData::create(const AtomicString&amp; keyString, unsigned tokenCount)
</del><ins>+inline PassRefPtr&lt;SpaceSplitStringData&gt; SpaceSplitStringData::create(const AtomicString&amp; 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&amp; spaceSplitStringDataCache = sharedDataMap();
-    SpaceSplitStringDataMap::iterator iterator = spaceSplitStringDataCache.find(keyString);
-    if (iterator != spaceSplitStringDataCache.end())
-        return iterator-&gt;value;
</del><ins>+    auto&amp; 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&lt;SpaceSplitStringData&gt; 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-&gt;m_keyString.isNull())
-        sharedDataMap().remove(spaceSplitString-&gt;m_keyString);
</del><ins>+    spaceSplitStringTable().remove(spaceSplitString-&gt;m_keyString);
</ins><span class="cx"> 
</span><span class="cx">     unsigned i = 0;
</span><span class="cx">     unsigned size = spaceSplitString-&gt;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 &lt;wtf/Assertions.h&gt;
</del><span class="cx"> #include &lt;wtf/MainThread.h&gt;
</span><del>-#include &lt;wtf/Noncopyable.h&gt;
</del><span class="cx"> #include &lt;wtf/text/AtomicString.h&gt;
</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&amp; operator[](size_t i)
</del><ins>+    const AtomicString&amp; operator[](unsigned i)
</ins><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(i &lt; 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, &quot;SpaceSplitStringData should never be empty by definition. There is no difference between empty and null.&quot;);
</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&lt;AtomicString*&gt;(this + 1); }
</span><span class="lines">@@ -112,9 +110,9 @@
</span><span class="cx">     bool contains(const AtomicString&amp; string) const { return m_data &amp;&amp; m_data-&gt;contains(string); }
</span><span class="cx">     bool containsAll(const SpaceSplitString&amp; names) const { return !names.m_data || (m_data &amp;&amp; m_data-&gt;containsAll(*names.m_data)); }
</span><span class="cx"> 
</span><del>-    size_t size() const { return m_data ? m_data-&gt;size() : 0; }
</del><ins>+    unsigned size() const { return m_data ? m_data-&gt;size() : 0; }
</ins><span class="cx">     bool isEmpty() const { return !m_data; }
</span><del>-    const AtomicString&amp; operator[](size_t i) const
</del><ins>+    const AtomicString&amp; 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&lt;SpaceSplitStringData&gt; m_data;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>