<!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>[183458] 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/183458">183458</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2015-04-27 22:54:02 -0700 (Mon, 27 Apr 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>RegExp matches arrays should use contiguous indexing.
&lt;https://webkit.org/b/144286&gt;

Reviewed by Geoffrey Garen.

We had a custom Structure being used for RegExp matches arrays that would
put the arrays into SlowPutArrayStorageShape mode. This was just left
from when matches arrays were custom, lazily initialized objects.

This change removes that Structure and switches the matches arrays to
using the default ContiguousShape Structure. This allows the FTL JIT
to compile the inner loop of the Octane/regexp benchmark.

Also made a version of initializeIndex() [inline] that takes the indexing
type in an argument, allowing createRegExpMatchesArray() to initialize
the entire array without branching on the indexing type for each entry.

~3% progression on Octane/regexp.

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::mapStructure):
(JSC::JSGlobalObject::regExpMatchesArrayStructure): Deleted.
* runtime/JSObject.h:
(JSC::JSObject::initializeIndex):
* runtime/RegExpMatchesArray.cpp:
(JSC::createRegExpMatchesArray):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeRegExpMatchesArraycpp">trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (183457 => 183458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-04-28 05:33:12 UTC (rev 183457)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-04-28 05:54:02 UTC (rev 183458)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2015-04-27  Andreas Kling  &lt;akling@apple.com&gt;
+
+        RegExp matches arrays should use contiguous indexing.
+        &lt;https://webkit.org/b/144286&gt;
+
+        Reviewed by Geoffrey Garen.
+
+        We had a custom Structure being used for RegExp matches arrays that would
+        put the arrays into SlowPutArrayStorageShape mode. This was just left
+        from when matches arrays were custom, lazily initialized objects.
+
+        This change removes that Structure and switches the matches arrays to
+        using the default ContiguousShape Structure. This allows the FTL JIT
+        to compile the inner loop of the Octane/regexp benchmark.
+
+        Also made a version of initializeIndex() [inline] that takes the indexing
+        type in an argument, allowing createRegExpMatchesArray() to initialize
+        the entire array without branching on the indexing type for each entry.
+
+        ~3% progression on Octane/regexp.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::mapStructure):
+        (JSC::JSGlobalObject::regExpMatchesArrayStructure): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::initializeIndex):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::createRegExpMatchesArray):
+
</ins><span class="cx"> 2015-04-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         FTL failed to initialize arguments.callee on the slow path as well as the fast path
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (183457 => 183458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-04-28 05:33:12 UTC (rev 183457)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2015-04-28 05:54:02 UTC (rev 183458)
</span><span class="lines">@@ -305,8 +305,6 @@
</span><span class="cx">     for (unsigned i = 0; i &lt; NumberOfIndexingShapes; ++i)
</span><span class="cx">         m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
</span><span class="cx"> 
</span><del>-    m_regExpMatchesArrayStructure.set(vm, this, Structure::create(vm, this, m_arrayPrototype.get(), TypeInfo(ObjectType, StructureFlags), JSArray::info(), ArrayWithSlowPutArrayStorage));
-    
</del><span class="cx">     RegExp* emptyRegex = RegExp::create(vm, &quot;&quot;, NoFlags);
</span><span class="cx">     
</span><span class="cx">     m_regExpPrototype.set(vm, this, RegExpPrototype::create(vm, RegExpPrototype::createStructure(vm, this, m_objectPrototype.get()), emptyRegex));
</span><span class="lines">@@ -764,7 +762,6 @@
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_boundFunctionStructure);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_namedFunctionStructure);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_symbolObjectStructure);
</span><del>-    visitor.append(&amp;thisObject-&gt;m_regExpMatchesArrayStructure);
</del><span class="cx">     visitor.append(&amp;thisObject-&gt;m_regExpStructure);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_consoleStructure);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_dollarVMStructure);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (183457 => 183458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2015-04-28 05:33:12 UTC (rev 183457)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2015-04-28 05:54:02 UTC (rev 183458)
</span><span class="lines">@@ -232,7 +232,6 @@
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_namedFunctionStructure;
</span><span class="cx">     PropertyOffset m_functionNameOffset;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_privateNameStructure;
</span><del>-    WriteBarrier&lt;Structure&gt; m_regExpMatchesArrayStructure;
</del><span class="cx">     WriteBarrier&lt;Structure&gt; m_regExpStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_consoleStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_dollarVMStructure;
</span><span class="lines">@@ -474,7 +473,6 @@
</span><span class="cx">     Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
</span><span class="cx">     Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
</span><span class="cx">     Structure* mapStructure() const { return m_mapStructure.get(); }
</span><del>-    Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
</del><span class="cx">     Structure* regExpStructure() const { return m_regExpStructure.get(); }
</span><span class="cx">     Structure* setStructure() const { return m_setStructure.get(); }
</span><span class="cx">     Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (183457 => 183458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2015-04-28 05:33:12 UTC (rev 183457)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2015-04-28 05:54:02 UTC (rev 183458)
</span><span class="lines">@@ -364,10 +364,15 @@
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-        
</del><ins>+
</ins><span class="cx">     void initializeIndex(VM&amp; vm, unsigned i, JSValue v)
</span><span class="cx">     {
</span><del>-        switch (indexingType()) {
</del><ins>+        initializeIndex(vm, i, v, indexingType());
+    }
+
+    void initializeIndex(VM&amp; vm, unsigned i, JSValue v, IndexingType indexingType)
+    {
+        switch (indexingType) {
</ins><span class="cx">         case ALL_UNDECIDED_INDEXING_TYPES: {
</span><span class="cx">             setIndexQuicklyToUndecided(vm, i, v);
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeRegExpMatchesArraycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp (183457 => 183458)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp        2015-04-28 05:33:12 UTC (rev 183457)
+++ trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp        2015-04-28 05:54:02 UTC (rev 183458)
</span><span class="lines">@@ -35,16 +35,16 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(result);
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><del>-    JSArray* array = JSArray::tryCreateUninitialized(vm, exec-&gt;lexicalGlobalObject()-&gt;regExpMatchesArrayStructure(), regExp-&gt;numSubpatterns() + 1);
</del><ins>+    JSArray* array = JSArray::tryCreateUninitialized(vm, exec-&gt;lexicalGlobalObject()-&gt;arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), regExp-&gt;numSubpatterns() + 1);
</ins><span class="cx">     RELEASE_ASSERT(array);
</span><span class="cx"> 
</span><span class="cx">     SamplingRegion samplingRegion(&quot;Reifying substring properties&quot;);
</span><span class="cx"> 
</span><del>-    array-&gt;putDirectIndex(exec, 0, jsSubstring(exec, input, result.start, result.end - result.start));
</del><ins>+    array-&gt;initializeIndex(vm, 0, jsSubstring(exec, input, result.start, result.end - result.start), ArrayWithContiguous);
</ins><span class="cx"> 
</span><span class="cx">     if (unsigned numSubpatterns = regExp-&gt;numSubpatterns()) {
</span><span class="cx">         Vector&lt;int, 32&gt; subpatternResults;
</span><del>-        int position = regExp-&gt;match(exec-&gt;vm(), input-&gt;value(exec), result.start, subpatternResults);
</del><ins>+        int position = regExp-&gt;match(vm, input-&gt;value(exec), result.start, subpatternResults);
</ins><span class="cx">         ASSERT_UNUSED(position, position &gt;= 0 &amp;&amp; static_cast&lt;size_t&gt;(position) == result.start);
</span><span class="cx">         ASSERT(result.start == static_cast&lt;size_t&gt;(subpatternResults[0]));
</span><span class="cx">         ASSERT(result.end == static_cast&lt;size_t&gt;(subpatternResults[1]));
</span><span class="lines">@@ -52,14 +52,14 @@
</span><span class="cx">         for (unsigned i = 1; i &lt;= numSubpatterns; ++i) {
</span><span class="cx">             int start = subpatternResults[2 * i];
</span><span class="cx">             if (start &gt;= 0)
</span><del>-                array-&gt;putDirectIndex(exec, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start));
</del><ins>+                array-&gt;initializeIndex(vm, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous);
</ins><span class="cx">             else
</span><del>-                array-&gt;putDirectIndex(exec, i, jsUndefined());
</del><ins>+                array-&gt;initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    array-&gt;putDirect(exec-&gt;vm(), exec-&gt;propertyNames().index, jsNumber(result.start));
-    array-&gt;putDirect(exec-&gt;vm(), exec-&gt;propertyNames().input, input);
</del><ins>+    array-&gt;putDirect(vm, vm.propertyNames-&gt;index, jsNumber(result.start));
+    array-&gt;putDirect(vm, vm.propertyNames-&gt;input, input);
</ins><span class="cx"> 
</span><span class="cx">     return array;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>