<!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>[184865] trunk/Source/JavaScriptCore</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/184865">184865</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2015-05-26 11:54:01 -0700 (Tue, 26 May 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>String.prototype.charAt() should use StringView.
&lt;https://webkit.org/b/145352&gt;

Reviewed by Darin Adler.

Remove the jsSingleCharacterSubstring() function since it's actually completely
counter-productive: it could create a single-character string that would retain
a much larger string for the duration of its lifetime.

This made sense before StringImpl learned to put its characters at the tail end
of its own allocation. Now that it does, it's far better to just create a new
single-character StringImpl.

With that out of the way, we can make String.prototype.charAt() use StringView
to avoid reifying substring JSStrings (and avoid some ref churn too.)

* runtime/JSString.cpp:
(JSC::JSRopeString::getIndexSlowCase):
* runtime/JSString.h:
(JSC::JSString::getIndex):
(JSC::jsSingleCharacterSubstring): Deleted.
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncCharAt):
(JSC::stringProtoFuncSplit):</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="#trunkSourceJavaScriptCoreruntimeStringPrototypecpp">trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (184864 => 184865)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-05-26 18:52:34 UTC (rev 184864)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-05-26 18:54:01 UTC (rev 184865)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2015-05-26  Andreas Kling  &lt;akling@apple.com&gt;
+
+        String.prototype.charAt() should use StringView.
+        &lt;https://webkit.org/b/145352&gt;
+
+        Reviewed by Darin Adler.
+
+        Remove the jsSingleCharacterSubstring() function since it's actually completely
+        counter-productive: it could create a single-character string that would retain
+        a much larger string for the duration of its lifetime.
+
+        This made sense before StringImpl learned to put its characters at the tail end
+        of its own allocation. Now that it does, it's far better to just create a new
+        single-character StringImpl.
+
+        With that out of the way, we can make String.prototype.charAt() use StringView
+        to avoid reifying substring JSStrings (and avoid some ref churn too.)
+
+        * runtime/JSString.cpp:
+        (JSC::JSRopeString::getIndexSlowCase):
+        * runtime/JSString.h:
+        (JSC::JSString::getIndex):
+        (JSC::jsSingleCharacterSubstring): Deleted.
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncCharAt):
+        (JSC::stringProtoFuncSplit):
+
</ins><span class="cx"> 2015-05-26  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [ES6] Implement Array.prototype.copyWithin
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.cpp (184864 => 184865)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.cpp        2015-05-26 18:52:34 UTC (rev 184864)
+++ trunk/Source/JavaScriptCore/runtime/JSString.cpp        2015-05-26 18:54:01 UTC (rev 184865)
</span><span class="lines">@@ -374,7 +374,7 @@
</span><span class="cx">         return jsEmptyString(exec);
</span><span class="cx">     ASSERT(!isRope());
</span><span class="cx">     RELEASE_ASSERT(i &lt; m_value.length());
</span><del>-    return jsSingleCharacterSubstring(exec, m_value, i);
</del><ins>+    return jsSingleCharacterString(exec, m_value[i]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.h (184864 => 184865)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.h        2015-05-26 18:52:34 UTC (rev 184864)
+++ trunk/Source/JavaScriptCore/runtime/JSString.h        2015-05-26 18:54:01 UTC (rev 184865)
</span><span class="lines">@@ -45,7 +45,6 @@
</span><span class="cx"> 
</span><span class="cx"> JSString* jsSingleCharacterString(VM*, UChar);
</span><span class="cx"> JSString* jsSingleCharacterString(ExecState*, UChar);
</span><del>-JSString* jsSingleCharacterSubstring(ExecState*, const String&amp;, unsigned offset);
</del><span class="cx"> JSString* jsSubstring(VM*, const String&amp;, unsigned offset, unsigned length);
</span><span class="cx"> JSString* jsSubstring(ExecState*, const String&amp;, unsigned offset, unsigned length);
</span><span class="cx"> 
</span><span class="lines">@@ -444,16 +443,6 @@
</span><span class="cx">     return JSString::create(*vm, String(&amp;c, 1).impl());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String&amp; s, unsigned offset)
-{
-    VM* vm = &amp;exec-&gt;vm();
-    ASSERT(offset &lt; static_cast&lt;unsigned&gt;(s.length()));
-    UChar c = s.characterAt(offset);
-    if (c &lt;= maxSingleCharacterString)
-        return vm-&gt;smallStrings.singleCharacterString(c);
-    return JSString::create(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, 1));
-}
-
</del><span class="cx"> inline JSString* jsNontrivialString(VM* vm, const String&amp; s)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(s.length() &gt; 1);
</span><span class="lines">@@ -507,7 +496,7 @@
</span><span class="cx">     if (isRope())
</span><span class="cx">         return static_cast&lt;JSRopeString*&gt;(this)-&gt;getIndexSlowCase(exec, i);
</span><span class="cx">     ASSERT(i &lt; m_value.length());
</span><del>-    return jsSingleCharacterSubstring(exec, m_value, i);
</del><ins>+    return jsSingleCharacterString(exec, m_value[i]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> inline JSString* jsString(VM* vm, const String&amp; s)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStringPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp (184864 => 184865)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2015-05-26 18:52:34 UTC (rev 184864)
+++ trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2015-05-26 18:54:01 UTC (rev 184865)
</span><span class="lines">@@ -785,18 +785,17 @@
</span><span class="cx">     JSValue thisValue = exec-&gt;thisValue();
</span><span class="cx">     if (!checkObjectCoercible(thisValue))
</span><span class="cx">         return throwVMTypeError(exec);
</span><del>-    String s = thisValue.toString(exec)-&gt;value(exec);
-    unsigned len = s.length();
</del><ins>+    StringView string = thisValue.toString(exec)-&gt;view(exec);
</ins><span class="cx">     JSValue a0 = exec-&gt;argument(0);
</span><span class="cx">     if (a0.isUInt32()) {
</span><span class="cx">         uint32_t i = a0.asUInt32();
</span><del>-        if (i &lt; len)
-            return JSValue::encode(jsSingleCharacterSubstring(exec, s, i));
</del><ins>+        if (i &lt; string.length())
+            return JSValue::encode(jsSingleCharacterString(exec, string[i]));
</ins><span class="cx">         return JSValue::encode(jsEmptyString(exec));
</span><span class="cx">     }
</span><span class="cx">     double dpos = a0.toInteger(exec);
</span><del>-    if (dpos &gt;= 0 &amp;&amp; dpos &lt; len)
-        return JSValue::encode(jsSingleCharacterSubstring(exec, s, static_cast&lt;unsigned&gt;(dpos)));
</del><ins>+    if (dpos &gt;= 0 &amp;&amp; dpos &lt; string.length())
+        return JSValue::encode(jsSingleCharacterString(exec, string[static_cast&lt;unsigned&gt;(dpos)]));
</ins><span class="cx">     return JSValue::encode(jsEmptyString(exec));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1246,7 +1245,7 @@
</span><span class="cx">             ASSERT(limit);
</span><span class="cx"> 
</span><span class="cx">             do {
</span><del>-                result-&gt;putDirectIndex(exec, position, jsSingleCharacterSubstring(exec, input, position));
</del><ins>+                result-&gt;putDirectIndex(exec, position, jsSingleCharacterString(exec, input[position]));
</ins><span class="cx">             } while (++position &lt; limit);
</span><span class="cx"> 
</span><span class="cx">             return JSValue::encode(result);
</span></span></pre>
</div>
</div>

</body>
</html>