<!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>[167220] trunk/Source</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/167220">167220</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-04-14 01:46:27 -0700 (Mon, 14 Apr 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[JSC] Improve the call site of string comparison in some hot path
https://bugs.webkit.org/show_bug.cgi?id=131605

Reviewed by Darin Adler.

Source/JavaScriptCore:

When resolved, the String of a JSString is never null. It can be empty but not null.
The null value is reserved for ropes but those would be resolved when getting the value.

Consequently, we should use the equal() operation that do not handle null values.
Using the StringImpl directly is already common in StringPrototype but it was not used here for some reason.

* jit/JITOperations.cpp:
* runtime/JSCJSValueInlines.h:
(JSC::JSValue::equalSlowCaseInline):
(JSC::JSValue::strictEqualSlowCaseInline):
(JSC::JSValue::pureStrictEqual):

Source/WebCore:

* dom/NodeRareData.h:
(WebCore::NodeListsNodeData::NodeListCacheMapEntryHash::equal):
We should use the right comparison operation depending on the Hash Traits.

Source/WTF:

* wtf/text/StringImpl.cpp:
(WTF::stringImplContentEqual):
Inline that function to reduce the call overhead for JSC.
This is only inlined twice, it is not catastrophic for our binary.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCJSValueInlinesh">trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtftextStringImplcpp">trunk/Source/WTF/wtf/text/StringImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoredomNodeRareDatah">trunk/Source/WebCore/dom/NodeRareData.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2014-04-14  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Improve the call site of string comparison in some hot path
+        https://bugs.webkit.org/show_bug.cgi?id=131605
+
+        Reviewed by Darin Adler.
+
+        When resolved, the String of a JSString is never null. It can be empty but not null.
+        The null value is reserved for ropes but those would be resolved when getting the value.
+
+        Consequently, we should use the equal() operation that do not handle null values.
+        Using the StringImpl directly is already common in StringPrototype but it was not used here for some reason.
+
+        * jit/JITOperations.cpp:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::equalSlowCaseInline):
+        (JSC::JSValue::strictEqualSlowCaseInline):
+        (JSC::JSValue::pureStrictEqual):
+
</ins><span class="cx"> 2014-04-08  Oliver Hunt  &lt;oliver@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rewrite Function.bind as a builtin
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -912,7 +912,7 @@
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span><span class="cx">     NativeCallFrameTracer tracer(vm, exec);
</span><span class="cx"> 
</span><del>-    bool result = asString(left)-&gt;value(exec) == asString(right)-&gt;value(exec);
</del><ins>+    bool result = WTF::equal(*asString(left)-&gt;value(exec).impl(), *asString(right)-&gt;value(exec).impl());
</ins><span class="cx"> #if USE(JSVALUE64)
</span><span class="cx">     return JSValue::encode(jsBoolean(result));
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCJSValueInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;JSCellInlines.h&quot;
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><ins>+#include &lt;wtf/text/StringImpl.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -738,7 +739,7 @@
</span><span class="cx">         bool s1 = v1.isString();
</span><span class="cx">         bool s2 = v2.isString();
</span><span class="cx">         if (s1 &amp;&amp; s2)
</span><del>-            return asString(v1)-&gt;value(exec) == asString(v2)-&gt;value(exec);
</del><ins>+            return WTF::equal(*asString(v1)-&gt;value(exec).impl(), *asString(v2)-&gt;value(exec).impl());
</ins><span class="cx"> 
</span><span class="cx">         if (v1.isUndefinedOrNull()) {
</span><span class="cx">             if (v2.isUndefinedOrNull())
</span><span class="lines">@@ -800,7 +801,7 @@
</span><span class="cx">     ASSERT(v1.isCell() &amp;&amp; v2.isCell());
</span><span class="cx"> 
</span><span class="cx">     if (v1.asCell()-&gt;isString() &amp;&amp; v2.asCell()-&gt;isString())
</span><del>-        return asString(v1)-&gt;value(exec) == asString(v2)-&gt;value(exec);
</del><ins>+        return WTF::equal(*asString(v1)-&gt;value(exec).impl(), *asString(v2)-&gt;value(exec).impl());
</ins><span class="cx"> 
</span><span class="cx">     return v1 == v2;
</span><span class="cx"> }
</span><span class="lines">@@ -835,7 +836,7 @@
</span><span class="cx">         const StringImpl* v2String = asString(v2)-&gt;tryGetValueImpl();
</span><span class="cx">         if (!v1String || !v2String)
</span><span class="cx">             return MixedTriState;
</span><del>-        return triState(WTF::equal(v1String, v2String));
</del><ins>+        return triState(WTF::equal(*v1String, *v2String));
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     return triState(v1 == v2);
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/WTF/ChangeLog        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2014-04-14  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Improve the call site of string comparison in some hot path
+        https://bugs.webkit.org/show_bug.cgi?id=131605
+
+        Reviewed by Darin Adler.
+
+        * wtf/text/StringImpl.cpp:
+        (WTF::stringImplContentEqual):
+        Inline that function to reduce the call overhead for JSC.
+        This is only inlined twice, it is not catastrophic for our binary.
+
</ins><span class="cx"> 2014-04-13  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Relax adoption requirements of RefCounted objects that are NeverDestroyed
</span></span></pre></div>
<a id="trunkSourceWTFwtftextStringImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/text/StringImpl.cpp        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -1764,7 +1764,7 @@
</span><span class="cx">     return newImpl;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline bool stringImplContentEqual(const StringImpl&amp; a, const StringImpl&amp; b)
</del><ins>+static ALWAYS_INLINE bool stringImplContentEqual(const StringImpl&amp; a, const StringImpl&amp; b)
</ins><span class="cx"> {
</span><span class="cx">     unsigned aLength = a.length();
</span><span class="cx">     unsigned bLength = b.length();
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/WebCore/ChangeLog        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2014-04-14  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        [JSC] Improve the call site of string comparison in some hot path
+        https://bugs.webkit.org/show_bug.cgi?id=131605
+
+        Reviewed by Darin Adler.
+
+        * dom/NodeRareData.h:
+        (WebCore::NodeListsNodeData::NodeListCacheMapEntryHash::equal):
+        We should use the right comparison operation depending on the Hash Traits.
+
</ins><span class="cx"> 2014-04-14  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Merge MemoryPressureHandler{Mac,IOS}.mm
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeRareDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/NodeRareData.h (167219 => 167220)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/NodeRareData.h        2014-04-14 08:45:23 UTC (rev 167219)
+++ trunk/Source/WebCore/dom/NodeRareData.h        2014-04-14 08:46:27 UTC (rev 167220)
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">         {
</span><span class="cx">             return DefaultHash&lt;StringType&gt;::Hash::hash(entry.second) + entry.first;
</span><span class="cx">         }
</span><del>-        static bool equal(const std::pair&lt;unsigned char, StringType&gt;&amp; a, const std::pair&lt;unsigned char, StringType&gt;&amp; b) { return a == b; }
</del><ins>+        static bool equal(const std::pair&lt;unsigned char, StringType&gt;&amp; a, const std::pair&lt;unsigned char, StringType&gt;&amp; b) { return a.first == b.first &amp;&amp; DefaultHash&lt;StringType&gt;::Hash::equal(a.second, b.second); }
</ins><span class="cx">         static const bool safeToCompareToEmptyOrDeleted = DefaultHash&lt;StringType&gt;::Hash::safeToCompareToEmptyOrDeleted;
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>