<!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>[170818] 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/170818">170818</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2014-07-04 20:36:36 -0700 (Fri, 04 Jul 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Fast path for jsStringWithCache() when asked for the same string repeatedly.
&lt;https://webkit.org/b/134635&gt;

Source/JavaScriptCore:
Also moved the whole thing from WebCore to JavaScriptCore since it
makes more sense here, and inline the lightweight checks, leaving only
the hashmap stuff out of line.

Reviewed by Darin Adler.

* runtime/JSString.cpp:
(JSC::jsStringWithCacheSlowCase):
* runtime/JSString.h:
(JSC::jsStringWithCache):
* runtime/VM.h:

Source/WebCore:
Reviewed by Darin Adler.

* WebCore.exp.in:
* bindings/js/JSDOMBinding.cpp:
(WebCore::jsStringWithCache): Deleted.
* bindings/js/JSDOMBinding.h:
(WebCore::JSValueTraits&lt;String&gt;::arrayJSValue):
(WebCore::jsStringWithCache): Deleted.
* bridge/c/c_utility.cpp:
(JSC::Bindings::convertNPVariantToValue):
* loader/cache/CachedResourceHandle.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSStringcpp">trunk/Source/JavaScriptCore/runtime/JSString.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSStringh">trunk/Source/JavaScriptCore/runtime/JSString.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingcpp">trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSDOMBindingh">trunk/Source/WebCore/bindings/js/JSDOMBinding.h</a></li>
<li><a href="#trunkSourceWebCorebridgecc_utilitycpp">trunk/Source/WebCore/bridge/c/c_utility.cpp</a></li>
<li><a href="#trunkSourceWebKitWebKitvcxprojWebKitExportGeneratorWebKitExportsdefin">trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-07-04  Andreas Kling  &lt;akling@apple.com&gt;
+
+        Fast path for jsStringWithCache() when asked for the same string repeatedly.
+        &lt;https://webkit.org/b/134635&gt;
+
+        Also moved the whole thing from WebCore to JavaScriptCore since it
+        makes more sense here, and inline the lightweight checks, leaving only
+        the hashmap stuff out of line.
+
+        Reviewed by Darin Adler.
+
+        * runtime/JSString.cpp:
+        (JSC::jsStringWithCacheSlowCase):
+        * runtime/JSString.h:
+        (JSC::jsStringWithCache):
+        * runtime/VM.h:
+
</ins><span class="cx"> 2014-07-03  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add WTF::move()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.cpp (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.cpp        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/JavaScriptCore/runtime/JSString.cpp        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -374,4 +374,13 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSString* jsStringWithCacheSlowCase(VM&amp; vm, StringImpl&amp; stringImpl)
+{
+    auto addResult = vm.stringCache.add(&amp;stringImpl, nullptr);
+    if (addResult.isNewEntry)
+        addResult.iterator-&gt;value = jsString(&amp;vm, String(stringImpl));
+    vm.lastCachedString = addResult.iterator-&gt;value.get();
+    return vm.lastCachedString.get();
+}
+
</ins><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.h (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.h        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/JavaScriptCore/runtime/JSString.h        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -516,6 +516,34 @@
</span><span class="cx">     inline JSString* jsNontrivialString(ExecState* exec, const String&amp; s) { return jsNontrivialString(&amp;exec-&gt;vm(), s); }
</span><span class="cx">     inline JSString* jsOwnedString(ExecState* exec, const String&amp; s) { return jsOwnedString(&amp;exec-&gt;vm(), s); }
</span><span class="cx"> 
</span><ins>+    JS_EXPORT_PRIVATE JSString* jsStringWithCacheSlowCase(VM&amp;, StringImpl&amp;);
+
+    ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const String&amp; s)
+    {
+        VM&amp; vm = exec-&gt;vm();
+        StringImpl* stringImpl = s.impl();
+        if (!stringImpl || !stringImpl-&gt;length())
+            return jsEmptyString(&amp;vm);
+
+        if (stringImpl-&gt;length() == 1) {
+            UChar singleCharacter = (*stringImpl)[0u];
+            if (singleCharacter &lt;= maxSingleCharacterString)
+                return vm.smallStrings.singleCharacterString(static_cast&lt;unsigned char&gt;(singleCharacter));
+        }
+
+        if (JSString* lastCachedString = vm.lastCachedString.get()) {
+            if (lastCachedString-&gt;tryGetValueImpl() == stringImpl)
+                return lastCachedString;
+        }
+
+        return jsStringWithCacheSlowCase(vm, *stringImpl);
+    }
+
+    ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const AtomicString&amp; s)
+    {
+        return jsStringWithCache(exec, s.string());
+    }
+
</ins><span class="cx">     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot&amp; slot)
</span><span class="cx">     {
</span><span class="cx">         if (propertyName == exec-&gt;propertyNames().length) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -297,6 +297,7 @@
</span><span class="cx">         DateInstanceCache dateInstanceCache;
</span><span class="cx">         WTF::SimpleStats machineCodeBytesPerBytecodeWordForBaselineJIT;
</span><span class="cx">         WeakGCMap&lt;StringImpl*, JSString, PtrHash&lt;StringImpl*&gt;&gt; stringCache;
</span><ins>+        Weak&lt;JSString&gt; lastCachedString;
</ins><span class="cx"> 
</span><span class="cx">         AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/WebCore/ChangeLog        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2014-07-04  Andreas Kling  &lt;akling@apple.com&gt;
+
+        Fast path for jsStringWithCache() when asked for the same string repeatedly.
+        &lt;https://webkit.org/b/134635&gt;
+
+        Reviewed by Darin Adler.
+
+        * WebCore.exp.in:
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::jsStringWithCache): Deleted.
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::JSValueTraits&lt;String&gt;::arrayJSValue):
+        (WebCore::jsStringWithCache): Deleted.
+        * bridge/c/c_utility.cpp:
+        (JSC::Bindings::convertNPVariantToValue):
+        * loader/cache/CachedResourceHandle.h:
+
</ins><span class="cx"> 2014-07-04  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Subpixel rendering: ebay.com rotating billboard on the main page has cut off buttons.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -766,7 +766,6 @@
</span><span class="cx"> __ZN7WebCore17SubresourceLoader6createEPNS_5FrameEPNS_14CachedResourceERKNS_15ResourceRequestERKNS_21ResourceLoaderOptionsE
</span><span class="cx"> __ZN7WebCore17cacheDOMStructureEPNS_17JSDOMGlobalObjectEPN3JSC9StructureEPKNS2_9ClassInfoE
</span><span class="cx"> __ZN7WebCore17encodeForFileNameERKN3WTF6StringE
</span><del>-__ZN7WebCore17jsStringWithCacheEPN3JSC9ExecStateERKN3WTF6StringE
</del><span class="cx"> __ZN7WebCore17languageDidChangeEv
</span><span class="cx"> __ZN7WebCore17openTemporaryFileERKN3WTF6StringERi
</span><span class="cx"> __ZN7WebCore17sRGBColorSpaceRefEv
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.cpp        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -63,25 +63,6 @@
</span><span class="cx">     return DOMObjectHashTableMap::mapFor(vm).get(staticTable);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSC::JSValue jsStringWithCache(JSC::ExecState* exec, const String&amp; s)
-{
-    JSC::VM&amp; vm = exec-&gt;vm();
-    StringImpl* stringImpl = s.impl();
-    if (!stringImpl || !stringImpl-&gt;length())
-        return jsEmptyString(&amp;vm);
-
-    if (stringImpl-&gt;length() == 1) {
-        UChar singleCharacter = (*stringImpl)[0u];
-        if (singleCharacter &lt;= JSC::maxSingleCharacterString)
-            return vm.smallStrings.singleCharacterString(static_cast&lt;unsigned char&gt;(singleCharacter));
-    }
-
-    auto addResult = vm.stringCache.add(stringImpl, nullptr);
-    if (addResult.isNewEntry)
-        addResult.iterator-&gt;value = JSC::jsString(&amp;vm, String(stringImpl));
-    return JSC::JSValue(addResult.iterator-&gt;value.get());
-}
-
</del><span class="cx"> JSValue jsStringOrNull(ExecState* exec, const String&amp; s)
</span><span class="cx"> {
</span><span class="cx">     if (s.isNull())
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSDOMBindingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSDOMBinding.h (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/WebCore/bindings/js/JSDOMBinding.h        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -268,12 +268,7 @@
</span><span class="cx"> // Convert a DOM implementation exception code into a JavaScript exception in the execution state.
</span><span class="cx"> void setDOMException(JSC::ExecState*, ExceptionCode);
</span><span class="cx"> 
</span><del>-JSC::JSValue jsStringWithCache(JSC::ExecState*, const String&amp;);
</del><span class="cx"> JSC::JSValue jsString(JSC::ExecState*, const URL&amp;); // empty if the URL is null
</span><del>-inline JSC::JSValue jsStringWithCache(JSC::ExecState* exec, const AtomicString&amp; s)
-{
-    return jsStringWithCache(exec, s.string());
-}
</del><span class="cx"> 
</span><span class="cx"> JSC::JSValue jsStringOrNull(JSC::ExecState*, const String&amp;); // null if the string is null
</span><span class="cx"> JSC::JSValue jsStringOrNull(JSC::ExecState*, const URL&amp;); // null if the URL is null
</span><span class="lines">@@ -423,7 +418,7 @@
</span><span class="cx"> template&lt;&gt; struct JSValueTraits&lt;String&gt; {
</span><span class="cx">     static JSC::JSValue arrayJSValue(JSC::ExecState* exec, JSDOMGlobalObject*, const String&amp; value)
</span><span class="cx">     {
</span><del>-        return jsStringWithCache(exec, value);
</del><ins>+        return JSC::jsStringWithCache(exec, value);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebridgecc_utilitycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bridge/c/c_utility.cpp (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bridge/c/c_utility.cpp        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/WebCore/bridge/c/c_utility.cpp        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -122,7 +122,7 @@
</span><span class="cx">     if (type == NPVariantType_Double)
</span><span class="cx">         return jsNumber(NPVARIANT_TO_DOUBLE(*variant));
</span><span class="cx">     if (type == NPVariantType_String)
</span><del>-        return WebCore::jsStringWithCache(exec, convertNPStringToUTF16(&amp;variant-&gt;value.stringValue));
</del><ins>+        return jsStringWithCache(exec, convertNPStringToUTF16(&amp;variant-&gt;value.stringValue));
</ins><span class="cx">     if (type == NPVariantType_Object) {
</span><span class="cx">         NPObject* obj = variant-&gt;value.objectValue;
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceWebKitWebKitvcxprojWebKitExportGeneratorWebKitExportsdefin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in (170817 => 170818)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in        2014-07-05 03:03:01 UTC (rev 170817)
+++ trunk/Source/WebKit/WebKit.vcxproj/WebKitExportGenerator/WebKitExports.def.in        2014-07-05 03:36:36 UTC (rev 170818)
</span><span class="lines">@@ -237,7 +237,6 @@
</span><span class="cx">         symbolWithPointer(?isActiveInsertionPoint@WebCore@@YA_NPBVNode@1@@Z, ?isActiveInsertionPoint@WebCore@@YA_NPEBVNode@1@@Z)
</span><span class="cx">         symbolWithPointer(?isPreloaded@CachedResourceLoader@WebCore@@QBE_NABVString@WTF@@@Z, ?isPreloaded@CachedResourceLoader@WebCore@@QEBA_NAEBVString@WTF@@@Z)
</span><span class="cx">         symbolWithPointer(?jsArray@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@PAVJSDOMGlobalObject@1@V?$PassRefPtr@VDOMStringList@WebCore@@@WTF@@@Z, ?jsArray@WebCore@@YA?AVJSValue@JSC@@PEAVExecState@3@PEAVJSDOMGlobalObject@1@V?$PassRefPtr@VDOMStringList@WebCore@@@WTF@@@Z)
</span><del>-        symbolWithPointer(?jsStringWithCache@WebCore@@YA?AVJSValue@JSC@@PAVExecState@3@ABVString@WTF@@@Z, ?jsStringWithCache@WebCore@@YA?AVJSValue@JSC@@PEAVExecState@3@AEBVString@WTF@@@Z)
</del><span class="cx">         symbolWithPointer(?lastChangeWasUserEdit@HTMLTextFormControlElement@WebCore@@QBE_NXZ, ?lastChangeWasUserEdit@HTMLTextFormControlElement@WebCore@@QEBA_NXZ)
</span><span class="cx">         symbolWithPointer(?synchronousScrollingReasonsAsText@Page@WebCore@@QAE?AVString@WTF@@XZ, ?synchronousScrollingReasonsAsText@Page@WebCore@@QEAA?AVString@WTF@@XZ)
</span><span class="cx">         symbolWithPointer(?markerTextForListItem@WebCore@@YA?AVString@WTF@@PAVElement@1@@Z, ?markerTextForListItem@WebCore@@YA?AVString@WTF@@PEAVElement@1@@Z)
</span></span></pre>
</div>
</div>

</body>
</html>