<!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>[199209] 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/199209">199209</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-04-07 19:11:48 -0700 (Thu, 07 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Implementing caching transition puts that need to reallocate with indexing storage
https://bugs.webkit.org/show_bug.cgi?id=130914

Reviewed by Saam Barati.

Source/JavaScriptCore:

This enables the IC's put_by_id path to handle reallocating the out-of-line storage even if
the butterfly has indexing storage. Like the DFG, we do this by calling operations that
reallocate the butterfly. Those use JSObject API and do all of the nasty work for us, like
triggering a barrier.

This does a bunch of refactoring to how PolymorphicAccess makes calls. It's a lot easier to
do it now because the hard work is hidden under AccessGenerationState methods. This means
that custom accessors now share logic with put_by_id transitions.

* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::succeed):
(JSC::AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling):
(JSC::AccessGenerationState::preserveLiveRegistersToStackForCall):
(JSC::AccessGenerationState::originalCallSiteIndex):
(JSC::AccessGenerationState::emitExplicitExceptionHandler):
(JSC::AccessCase::AccessCase):
(JSC::AccessCase::transition):
(JSC::AccessCase::generate):
(JSC::PolymorphicAccess::regenerate):
* bytecode/PolymorphicAccess.h:
(JSC::AccessGenerationState::needsToRestoreRegistersIfException):
(JSC::AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite):
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* jit/JITOperations.cpp:
* jit/JITOperations.h:

LayoutTests:

* js/regress/put-by-id-transition-with-indexing-header-expected.txt: Added.
* js/regress/put-by-id-transition-with-indexing-header.html: Added.
* js/regress/script-tests/put-by-id-transition-with-indexing-header.js: Added.
(allocate):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccessh">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationsh">trunk/Source/JavaScriptCore/dfg/DFGOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregressputbyidtransitionwithindexingheaderexpectedtxt">trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregressputbyidtransitionwithindexingheaderhtml">trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestsputbyidtransitionwithindexingheaderjs">trunk/LayoutTests/js/regress/script-tests/put-by-id-transition-with-indexing-header.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/LayoutTests/ChangeLog        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-04-07  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Implementing caching transition puts that need to reallocate with indexing storage
+        https://bugs.webkit.org/show_bug.cgi?id=130914
+
+        Reviewed by Saam Barati.
+
+        * js/regress/put-by-id-transition-with-indexing-header-expected.txt: Added.
+        * js/regress/put-by-id-transition-with-indexing-header.html: Added.
+        * js/regress/script-tests/put-by-id-transition-with-indexing-header.js: Added.
+        (allocate):
+
</ins><span class="cx"> 2016-04-07  Ada Chan  &lt;adachan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Roll out the css change in mediaControlsApple.css that has been causing assertions in layout for multiple tests
</span></span></pre></div>
<a id="trunkLayoutTestsjsregressputbyidtransitionwithindexingheaderexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header-expected.txt (0 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header-expected.txt        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/put-by-id-transition-with-indexing-header
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressputbyidtransitionwithindexingheaderhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header.html (0 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/put-by-id-transition-with-indexing-header.html        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/put-by-id-transition-with-indexing-header.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestsputbyidtransitionwithindexingheaderjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/put-by-id-transition-with-indexing-header.js (0 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/put-by-id-transition-with-indexing-header.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/put-by-id-transition-with-indexing-header.js        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -0,0 +1,84 @@
</span><ins>+(function() {
+    function allocate() {
+        return {};
+    };
+    
+    for (var i = 0; i &lt; 1000; ++i) {
+        var o;
+        var n = 100;
+        for (var j = 0; j &lt; n; ++j) {
+            o = allocate();
+            o[0] = i + 0;
+            o[1] = i + 1;
+            o[2] = i + 2;
+            o[3] = i + 3;
+            o[4] = i + 4;
+            o[5] = i + 5;
+            o[6] = i + 6;
+            o[7] = i + 7;
+            o[8] = i + 8;
+            o[9] = i + 9;
+            o[10] = i + 10;
+            o[11] = i + 11;
+            o.f = j + 0;
+            o.g = j + 1;
+            o.h = j + 2;
+            o.i = j + 3;
+            o.j = j + 4;
+            o.k = j + 5;
+            o.l = j + 6;
+            o.m = j + 7;
+            o.n = j + 8;
+            o.o = j + 9;
+            o.p = j + 10;
+            o.q = j + 11;
+            o.r = j + 12;
+            o.s = j + 13;
+            o.t = j + 14;
+            o.u = j + 15;
+            o.v = j + 16;
+            o.w = j + 17;
+        }
+        
+        for (var j = 0; j &lt; 11; ++j) {
+            if (o[j] != i + j)
+                throw &quot;Error: bad value at o[&quot; + j + &quot;]: &quot; + o[j];
+        }
+        if (o.f != n - 1 + 0)
+            throw &quot;Error: bad value at o.f: &quot; + o.f;
+        if (o.g != n - 1 + 1)
+            throw &quot;Error: bad value at o.f: &quot; + o.g;
+        if (o.h != n - 1 + 2)
+            throw &quot;Error: bad value at o.f: &quot; + o.h;
+        if (o.i != n - 1 + 3)
+            throw &quot;Error: bad value at o.f: &quot; + o.i;
+        if (o.j != n - 1 + 4)
+            throw &quot;Error: bad value at o.f: &quot; + o.j;
+        if (o.k != n - 1 + 5)
+            throw &quot;Error: bad value at o.f: &quot; + o.k;
+        if (o.l != n - 1 + 6)
+            throw &quot;Error: bad value at o.f: &quot; + o.l;
+        if (o.m != n - 1 + 7)
+            throw &quot;Error: bad value at o.f: &quot; + o.m;
+        if (o.n != n - 1 + 8)
+            throw &quot;Error: bad value at o.f: &quot; + o.n;
+        if (o.o != n - 1 + 9)
+            throw &quot;Error: bad value at o.f: &quot; + o.o;
+        if (o.p != n - 1 + 10)
+            throw &quot;Error: bad value at o.f: &quot; + o.p;
+        if (o.q != n - 1 + 11)
+            throw &quot;Error: bad value at o.f: &quot; + o.q;
+        if (o.r != n - 1 + 12)
+            throw &quot;Error: bad value at o.f: &quot; + o.r;
+        if (o.s != n - 1 + 13)
+            throw &quot;Error: bad value at o.f: &quot; + o.s;
+        if (o.t != n - 1 + 14)
+            throw &quot;Error: bad value at o.f: &quot; + o.t;
+        if (o.u != n - 1 + 15)
+            throw &quot;Error: bad value at o.f: &quot; + o.u;
+        if (o.v != n - 1 + 16)
+            throw &quot;Error: bad value at o.f: &quot; + o.v;
+        if (o.w != n - 1 + 17)
+            throw &quot;Error: bad value at o.f: &quot; + o.w;
+    }
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2016-04-07  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Implementing caching transition puts that need to reallocate with indexing storage
+        https://bugs.webkit.org/show_bug.cgi?id=130914
+
+        Reviewed by Saam Barati.
+
+        This enables the IC's put_by_id path to handle reallocating the out-of-line storage even if
+        the butterfly has indexing storage. Like the DFG, we do this by calling operations that
+        reallocate the butterfly. Those use JSObject API and do all of the nasty work for us, like
+        triggering a barrier.
+
+        This does a bunch of refactoring to how PolymorphicAccess makes calls. It's a lot easier to
+        do it now because the hard work is hidden under AccessGenerationState methods. This means
+        that custom accessors now share logic with put_by_id transitions.
+
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::AccessGenerationState::succeed):
+        (JSC::AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling):
+        (JSC::AccessGenerationState::preserveLiveRegistersToStackForCall):
+        (JSC::AccessGenerationState::originalCallSiteIndex):
+        (JSC::AccessGenerationState::emitExplicitExceptionHandler):
+        (JSC::AccessCase::AccessCase):
+        (JSC::AccessCase::transition):
+        (JSC::AccessCase::generate):
+        (JSC::PolymorphicAccess::regenerate):
+        * bytecode/PolymorphicAccess.h:
+        (JSC::AccessGenerationState::needsToRestoreRegistersIfException):
+        (JSC::AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+
</ins><span class="cx"> 2016-04-07  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Remote Inspector: When disallowing remote inspection on a debuggable, a listing is still sent to debuggers
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx">     success.append(jit-&gt;jump());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling()
</del><ins>+void AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling(const RegisterSet&amp; extra)
</ins><span class="cx"> {
</span><span class="cx">     if (!m_calculatedRegistersForCallAndExceptionHandling) {
</span><span class="cx">         m_calculatedRegistersForCallAndExceptionHandling = true;
</span><span class="lines">@@ -82,11 +82,14 @@
</span><span class="cx"> 
</span><span class="cx">         m_liveRegistersForCall = RegisterSet(m_liveRegistersToPreserveAtExceptionHandlingCallSite, allocator-&gt;usedRegisters());
</span><span class="cx">         m_liveRegistersForCall.exclude(RegisterSet::registersToNotSaveForJSCall());
</span><ins>+        m_liveRegistersForCall.merge(extra);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AccessGenerationState::preserveLiveRegistersToStackForCall()
</del><ins>+void AccessGenerationState::preserveLiveRegistersToStackForCall(const RegisterSet&amp; extra)
</ins><span class="cx"> {
</span><ins>+    calculateLiveRegistersForCallAndExceptionHandling(extra);
+    
</ins><span class="cx">     unsigned extraStackPadding = 0;
</span><span class="cx">     unsigned numberOfStackBytesUsedForRegisterPreservation = ScratchRegisterAllocator::preserveRegistersToStackForCall(*jit, liveRegistersForCall(), extraStackPadding);
</span><span class="cx">     if (m_numberOfStackBytesUsedForRegisterPreservation != std::numeric_limits&lt;unsigned&gt;::max())
</span><span class="lines">@@ -155,6 +158,38 @@
</span><span class="cx"> 
</span><span class="cx"> CallSiteIndex AccessGenerationState::originalCallSiteIndex() const { return stubInfo-&gt;callSiteIndex; }
</span><span class="cx"> 
</span><ins>+void AccessGenerationState::emitExplicitExceptionHandler()
+{
+    restoreScratch();
+    jit-&gt;copyCalleeSavesToVMCalleeSavesBuffer();
+    if (needsToRestoreRegistersIfException()) {
+        // To the JIT that produces the original exception handling
+        // call site, they will expect the OSR exit to be arrived
+        // at from genericUnwind. Therefore we must model what genericUnwind
+        // does here. I.e, set callFrameForCatch and copy callee saves.
+
+        jit-&gt;storePtr(GPRInfo::callFrameRegister, jit-&gt;vm()-&gt;addressOfCallFrameForCatch());
+        CCallHelpers::Jump jumpToOSRExitExceptionHandler = jit-&gt;jump();
+
+        // We don't need to insert a new exception handler in the table
+        // because we're doing a manual exception check here. i.e, we'll
+        // never arrive here from genericUnwind().
+        HandlerInfo originalHandler = originalExceptionHandler();
+        jit-&gt;addLinkTask(
+            [=] (LinkBuffer&amp; linkBuffer) {
+                linkBuffer.link(jumpToOSRExitExceptionHandler, originalHandler.nativeCode);
+            });
+    } else {
+        jit-&gt;setupArguments(CCallHelpers::TrustedImmPtr(jit-&gt;vm()), GPRInfo::callFrameRegister);
+        CCallHelpers::Call lookupExceptionHandlerCall = jit-&gt;call();
+        jit-&gt;addLinkTask(
+            [=] (LinkBuffer&amp; linkBuffer) {
+                linkBuffer.link(lookupExceptionHandlerCall, lookupExceptionHandler);
+            });
+        jit-&gt;jumpToExceptionHandler();
+    }
+}
+
</ins><span class="cx"> AccessCase::AccessCase()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -243,13 +278,6 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Skip optimizing the case where we need realloc, and the structure has
-    // indexing storage.
-    // FIXME: We shouldn't skip this! Implement it!
-    // https://bugs.webkit.org/show_bug.cgi?id=130914
-    if (oldStructure-&gt;couldHaveIndexingHeader())
-        return nullptr;
-
</del><span class="cx">     std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
</span><span class="cx"> 
</span><span class="cx">     result-&gt;m_type = Transition;
</span><span class="lines">@@ -778,7 +806,6 @@
</span><span class="cx"> 
</span><span class="cx">         // Stuff for custom getters/setters.
</span><span class="cx">         CCallHelpers::Call operationCall;
</span><del>-        CCallHelpers::Call lookupExceptionHandlerCall;
</del><span class="cx"> 
</span><span class="cx">         // Stuff for JS getters/setters.
</span><span class="cx">         CCallHelpers::DataLabelPtr addressOfLinkFunctionCheck;
</span><span class="lines">@@ -790,11 +817,8 @@
</span><span class="cx"> 
</span><span class="cx">         // This also does the necessary calculations of whether or not we're an
</span><span class="cx">         // exception handling call site.
</span><del>-        state.calculateLiveRegistersForCallAndExceptionHandling();
</del><span class="cx">         state.preserveLiveRegistersToStackForCall();
</span><span class="cx"> 
</span><del>-        // Need to make sure that whenever this call is made in the future, we remember the
-        // place that we made it from.
</del><span class="cx">         jit.store32(
</span><span class="cx">             CCallHelpers::TrustedImm32(state.callSiteIndexForExceptionHandlingOrOriginal().bits()),
</span><span class="cx">             CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
</span><span class="lines">@@ -917,7 +941,7 @@
</span><span class="cx">                 GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister);
</span><span class="cx">             state.restoreLiveRegistersFromStackForCall(isGetter());
</span><span class="cx"> 
</span><del>-            state.callbacks.append(
</del><ins>+            jit.addLinkTask(
</ins><span class="cx">                 [=, &amp;vm] (LinkBuffer&amp; linkBuffer) {
</span><span class="cx">                     m_rareData-&gt;callLinkInfo-&gt;setCallLocations(
</span><span class="cx">                         linkBuffer.locationOfNearCall(slowPathCall),
</span><span class="lines">@@ -961,6 +985,11 @@
</span><span class="cx">             jit.storePtr(GPRInfo::callFrameRegister, &amp;vm.topCallFrame);
</span><span class="cx"> 
</span><span class="cx">             operationCall = jit.call();
</span><ins>+            jit.addLinkTask(
+                [=] (LinkBuffer&amp; linkBuffer) {
+                    linkBuffer.link(operationCall, FunctionPtr(m_rareData-&gt;customAccessor.opaque));
+                });
+
</ins><span class="cx">             if (m_type == CustomValueGetter || m_type == CustomAccessorGetter)
</span><span class="cx">                 jit.setupResults(valueRegs);
</span><span class="cx">             jit.reclaimSpaceOnStackForCCall();
</span><span class="lines">@@ -968,43 +997,11 @@
</span><span class="cx">             CCallHelpers::Jump noException =
</span><span class="cx">                 jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
</span><span class="cx"> 
</span><del>-            bool didSetLookupExceptionHandler = false;
</del><span class="cx">             state.restoreLiveRegistersFromStackForCallWithThrownException();
</span><del>-            state.restoreScratch();
-            jit.copyCalleeSavesToVMCalleeSavesBuffer();
-            if (state.needsToRestoreRegistersIfException()) {
-                // To the JIT that produces the original exception handling
-                // call site, they will expect the OSR exit to be arrived
-                // at from genericUnwind. Therefore we must model what genericUnwind
-                // does here. I.e, set callFrameForCatch and copy callee saves.
-
-                jit.storePtr(GPRInfo::callFrameRegister, vm.addressOfCallFrameForCatch());
-                CCallHelpers::Jump jumpToOSRExitExceptionHandler = jit.jump();
-
-                // We don't need to insert a new exception handler in the table
-                // because we're doing a manual exception check here. i.e, we'll
-                // never arrive here from genericUnwind().
-                HandlerInfo originalHandler = state.originalExceptionHandler();
-                state.callbacks.append(
-                    [=] (LinkBuffer&amp; linkBuffer) {
-                        linkBuffer.link(jumpToOSRExitExceptionHandler, originalHandler.nativeCode);
-                    });
-            } else {
-                jit.setupArguments(CCallHelpers::TrustedImmPtr(&amp;vm), GPRInfo::callFrameRegister);
-                lookupExceptionHandlerCall = jit.call();
-                didSetLookupExceptionHandler = true;
-                jit.jumpToExceptionHandler();
-            }
</del><ins>+            state.emitExplicitExceptionHandler();
</ins><span class="cx">         
</span><span class="cx">             noException.link(&amp;jit);
</span><span class="cx">             state.restoreLiveRegistersFromStackForCall(isGetter());
</span><del>-
-            state.callbacks.append(
-                [=] (LinkBuffer&amp; linkBuffer) {
-                    linkBuffer.link(operationCall, FunctionPtr(m_rareData-&gt;customAccessor.opaque));
-                    if (didSetLookupExceptionHandler)
-                        linkBuffer.link(lookupExceptionHandlerCall, lookupExceptionHandler);
-                });
</del><span class="cx">         }
</span><span class="cx">         state.succeed();
</span><span class="cx">         return;
</span><span class="lines">@@ -1041,7 +1038,6 @@
</span><span class="cx">     case Transition: {
</span><span class="cx">         // AccessCase::transition() should have returned null.
</span><span class="cx">         RELEASE_ASSERT(GPRInfo::numberOfRegisters &gt;= 6 || !structure()-&gt;outOfLineCapacity() || structure()-&gt;outOfLineCapacity() == newStructure()-&gt;outOfLineCapacity());
</span><del>-        RELEASE_ASSERT(!structure()-&gt;couldHaveIndexingHeader());
</del><span class="cx"> 
</span><span class="cx">         if (InferredType* type = newStructure()-&gt;inferredTypeFor(ident.impl())) {
</span><span class="cx">             if (verbose)
</span><span class="lines">@@ -1054,6 +1050,7 @@
</span><span class="cx">         
</span><span class="cx">         bool allocating = newStructure()-&gt;outOfLineCapacity() != structure()-&gt;outOfLineCapacity();
</span><span class="cx">         bool reallocating = allocating &amp;&amp; structure()-&gt;outOfLineCapacity();
</span><ins>+        bool allocatingInline = allocating &amp;&amp; !structure()-&gt;couldHaveIndexingHeader();
</ins><span class="cx"> 
</span><span class="cx">         ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters);
</span><span class="cx">         allocator.lock(baseGPR);
</span><span class="lines">@@ -1063,12 +1060,12 @@
</span><span class="cx">         allocator.lock(valueRegs);
</span><span class="cx">         allocator.lock(scratchGPR);
</span><span class="cx"> 
</span><del>-        GPRReg scratchGPR2 = allocator.allocateScratchGPR();
-        GPRReg scratchGPR3;
-        if (allocating)
</del><ins>+        GPRReg scratchGPR2 = InvalidGPRReg;
+        GPRReg scratchGPR3 = InvalidGPRReg;
+        if (allocatingInline) {
+            scratchGPR2 = allocator.allocateScratchGPR();
</ins><span class="cx">             scratchGPR3 = allocator.allocateScratchGPR();
</span><del>-        else
-            scratchGPR3 = InvalidGPRReg;
</del><ins>+        }
</ins><span class="cx"> 
</span><span class="cx">         ScratchRegisterAllocator::PreservedState preservedState =
</span><span class="cx">             allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall);
</span><span class="lines">@@ -1079,47 +1076,102 @@
</span><span class="cx"> 
</span><span class="cx">         if (allocating) {
</span><span class="cx">             size_t newSize = newStructure()-&gt;outOfLineCapacity() * sizeof(JSValue);
</span><del>-            CopiedAllocator* copiedAllocator = &amp;vm.heap.storageAllocator();
</del><ins>+            
+            if (allocatingInline) {
+                CopiedAllocator* copiedAllocator = &amp;vm.heap.storageAllocator();
</ins><span class="cx"> 
</span><del>-            if (!reallocating) {
-                jit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR);
-                slowPath.append(
-                    jit.branchSubPtr(
-                        CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR));
-                jit.storePtr(scratchGPR, &amp;copiedAllocator-&gt;m_currentRemaining);
-                jit.negPtr(scratchGPR);
-                jit.addPtr(
-                    CCallHelpers::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR);
-                jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR);
-            } else {
-                size_t oldSize = structure()-&gt;outOfLineCapacity() * sizeof(JSValue);
-                ASSERT(newSize &gt; oldSize);
</del><ins>+                if (!reallocating) {
+                    jit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR);
+                    slowPath.append(
+                        jit.branchSubPtr(
+                            CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR));
+                    jit.storePtr(scratchGPR, &amp;copiedAllocator-&gt;m_currentRemaining);
+                    jit.negPtr(scratchGPR);
+                    jit.addPtr(
+                        CCallHelpers::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR);
+                    jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR);
+                } else {
+                    // Handle the case where we are reallocating (i.e. the old structure/butterfly
+                    // already had out-of-line property storage).
+                    size_t oldSize = structure()-&gt;outOfLineCapacity() * sizeof(JSValue);
+                    ASSERT(newSize &gt; oldSize);
</ins><span class="cx">             
</span><del>-                jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3);
-                jit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR);
-                slowPath.append(
-                    jit.branchSubPtr(
-                        CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR));
-                jit.storePtr(scratchGPR, &amp;copiedAllocator-&gt;m_currentRemaining);
-                jit.negPtr(scratchGPR);
-                jit.addPtr(
-                    CCallHelpers::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR);
-                jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR);
-                // We have scratchGPR = new storage, scratchGPR3 = old storage,
-                // scratchGPR2 = available
-                for (size_t offset = 0; offset &lt; oldSize; offset += sizeof(void*)) {
-                    jit.loadPtr(
-                        CCallHelpers::Address(
-                            scratchGPR3,
-                            -static_cast&lt;ptrdiff_t&gt;(
-                                offset + sizeof(JSValue) + sizeof(void*))),
-                        scratchGPR2);
-                    jit.storePtr(
-                        scratchGPR2,
-                        CCallHelpers::Address(
-                            scratchGPR,
-                            -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
</del><ins>+                    jit.loadPtr(CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR3);
+                    jit.loadPtr(&amp;copiedAllocator-&gt;m_currentRemaining, scratchGPR);
+                    slowPath.append(
+                        jit.branchSubPtr(
+                            CCallHelpers::Signed, CCallHelpers::TrustedImm32(newSize), scratchGPR));
+                    jit.storePtr(scratchGPR, &amp;copiedAllocator-&gt;m_currentRemaining);
+                    jit.negPtr(scratchGPR);
+                    jit.addPtr(
+                        CCallHelpers::AbsoluteAddress(&amp;copiedAllocator-&gt;m_currentPayloadEnd), scratchGPR);
+                    jit.addPtr(CCallHelpers::TrustedImm32(sizeof(JSValue)), scratchGPR);
+                    // We have scratchGPR = new storage, scratchGPR3 = old storage,
+                    // scratchGPR2 = available
+                    for (size_t offset = 0; offset &lt; oldSize; offset += sizeof(void*)) {
+                        jit.loadPtr(
+                            CCallHelpers::Address(
+                                scratchGPR3,
+                                -static_cast&lt;ptrdiff_t&gt;(
+                                    offset + sizeof(JSValue) + sizeof(void*))),
+                            scratchGPR2);
+                        jit.storePtr(
+                            scratchGPR2,
+                            CCallHelpers::Address(
+                                scratchGPR,
+                                -static_cast&lt;ptrdiff_t&gt;(offset + sizeof(JSValue) + sizeof(void*))));
+                    }
</ins><span class="cx">                 }
</span><ins>+            } else {
+                // Handle the case where we are allocating out-of-line using an operation.
+                RegisterSet extraRegistersToPreserve;
+                extraRegistersToPreserve.set(baseGPR);
+                extraRegistersToPreserve.set(valueRegs);
+                state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve);
+                
+                jit.store32(
+                    CCallHelpers::TrustedImm32(
+                        state.callSiteIndexForExceptionHandlingOrOriginal().bits()),
+                    CCallHelpers::tagFor(static_cast&lt;VirtualRegister&gt;(JSStack::ArgumentCount)));
+                
+                jit.makeSpaceOnStackForCCall();
+                
+                if (!reallocating) {
+                    jit.setupArgumentsWithExecState(baseGPR);
+                    
+                    CCallHelpers::Call operationCall = jit.call();
+                    jit.addLinkTask(
+                        [=] (LinkBuffer&amp; linkBuffer) {
+                            linkBuffer.link(
+                                operationCall,
+                                FunctionPtr(operationReallocateButterflyToHavePropertyStorageWithInitialCapacity));
+                        });
+                } else {
+                    // Handle the case where we are reallocating (i.e. the old structure/butterfly
+                    // already had out-of-line property storage).
+                    jit.setupArgumentsWithExecState(
+                        baseGPR, CCallHelpers::TrustedImm32(newSize / sizeof(JSValue)));
+                    
+                    CCallHelpers::Call operationCall = jit.call();
+                    jit.addLinkTask(
+                        [=] (LinkBuffer&amp; linkBuffer) {
+                            linkBuffer.link(
+                                operationCall,
+                                FunctionPtr(operationReallocateButterflyToGrowPropertyStorage));
+                        });
+                }
+                
+                jit.reclaimSpaceOnStackForCCall();
+                jit.move(GPRInfo::returnValueGPR, scratchGPR);
+                
+                CCallHelpers::Jump noException =
+                    jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck);
+                
+                state.restoreLiveRegistersFromStackForCallWithThrownException();
+                state.emitExplicitExceptionHandler();
+                
+                noException.link(&amp;jit);
+                state.restoreLiveRegistersFromStackForCall();
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -1138,7 +1190,9 @@
</span><span class="cx">                 CCallHelpers::Address(scratchGPR, offsetInButterfly(m_offset) * sizeof(JSValue)));
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        if (allocating) {
</del><ins>+        // If we had allocated using an operation then we would have already executed the store
+        // barrier and we would have already stored the butterfly into the object.
+        if (allocatingInline) {
</ins><span class="cx">             CCallHelpers::Jump ownerIsRememberedOrInEden = jit.jumpIfIsRememberedOrInEden(baseGPR);
</span><span class="cx">             WriteBarrierBuffer&amp; writeBarrierBuffer = jit.vm()-&gt;heap.writeBarrierBuffer();
</span><span class="cx">             jit.load32(writeBarrierBuffer.currentIndexAddress(), scratchGPR2);
</span><span class="lines">@@ -1146,10 +1200,10 @@
</span><span class="cx">                 jit.branch32(
</span><span class="cx">                     CCallHelpers::AboveOrEqual, scratchGPR2,
</span><span class="cx">                     CCallHelpers::TrustedImm32(writeBarrierBuffer.capacity())));
</span><del>-
</del><ins>+            
</ins><span class="cx">             jit.add32(CCallHelpers::TrustedImm32(1), scratchGPR2);
</span><span class="cx">             jit.store32(scratchGPR2, writeBarrierBuffer.currentIndexAddress());
</span><del>-
</del><ins>+            
</ins><span class="cx">             jit.move(CCallHelpers::TrustedImmPtr(writeBarrierBuffer.buffer()), scratchGPR3);
</span><span class="cx">             // We use an offset of -sizeof(void*) because we already added 1 to scratchGPR2.
</span><span class="cx">             jit.storePtr(
</span><span class="lines">@@ -1158,14 +1212,14 @@
</span><span class="cx">                     scratchGPR3, scratchGPR2, CCallHelpers::ScalePtr,
</span><span class="cx">                     static_cast&lt;int32_t&gt;(-sizeof(void*))));
</span><span class="cx">             ownerIsRememberedOrInEden.link(&amp;jit);
</span><ins>+            
+            // We set the new butterfly and the structure last. Doing it this way ensures that
+            // whatever we had done up to this point is forgotten if we choose to branch to slow
+            // path.
+            
+            jit.storePtr(scratchGPR, CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()));
</ins><span class="cx">         }
</span><span class="cx">         
</span><del>-        // We set the new butterfly and the structure last. Doing it this way ensures that whatever
-        // we had done up to this point is forgotten if we choose to branch to slow path.
-        
-        if (allocating)
-            jit.storePtr(scratchGPR, CCallHelpers::Address(baseGPR, JSObject::butterflyOffset()));
-        
</del><span class="cx">         uint32_t structureBits = bitwise_cast&lt;uint32_t&gt;(newStructure()-&gt;id());
</span><span class="cx">         jit.store32(
</span><span class="cx">             CCallHelpers::TrustedImm32(structureBits),
</span><span class="lines">@@ -1174,12 +1228,16 @@
</span><span class="cx">         allocator.restoreReusedRegistersByPopping(jit, preservedState);
</span><span class="cx">         state.succeed();
</span><span class="cx">         
</span><del>-        if (allocator.didReuseRegisters()) {
-            slowPath.link(&amp;jit);
-            allocator.restoreReusedRegistersByPopping(jit, preservedState);
-            state.failAndIgnore.append(jit.jump());
</del><ins>+        // We will have a slow path if we were allocating without the help of an operation.
+        if (allocatingInline) {
+            if (allocator.didReuseRegisters()) {
+                slowPath.link(&amp;jit);
+                allocator.restoreReusedRegistersByPopping(jit, preservedState);
+                state.failAndIgnore.append(jit.jump());
+            } else
+                state.failAndIgnore.append(slowPath);
</ins><span class="cx">         } else
</span><del>-            state.failAndIgnore.append(slowPath);
</del><ins>+            RELEASE_ASSERT(slowPath.empty());
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -1485,7 +1543,7 @@
</span><span class="cx"> 
</span><span class="cx">         HandlerInfo oldHandler = state.originalExceptionHandler();
</span><span class="cx">         CallSiteIndex newExceptionHandlingCallSite = state.callSiteIndexForExceptionHandling();
</span><del>-        state.callbacks.append(
</del><ins>+        jit.addLinkTask(
</ins><span class="cx">             [=] (LinkBuffer&amp; linkBuffer) {
</span><span class="cx">                 linkBuffer.link(jumpToOSRExitExceptionHandler, oldHandler.nativeCode);
</span><span class="cx"> 
</span><span class="lines">@@ -1519,9 +1577,6 @@
</span><span class="cx">         failure,
</span><span class="cx">         stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase));
</span><span class="cx">     
</span><del>-    for (auto callback : state.callbacks)
-        callback(linkBuffer);
-
</del><span class="cx">     if (verbose)
</span><span class="cx">         dataLog(*codeBlock, &quot; &quot;, stubInfo.codeOrigin, &quot;: Generating polymorphic access stub for &quot;, listDump(cases), &quot;\n&quot;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -376,7 +376,6 @@
</span><span class="cx">     GPRReg baseGPR { InvalidGPRReg };
</span><span class="cx">     JSValueRegs valueRegs;
</span><span class="cx">     GPRReg scratchGPR { InvalidGPRReg };
</span><del>-    Vector&lt;std::function&lt;void(LinkBuffer&amp;)&gt;&gt; callbacks;
</del><span class="cx">     const Identifier* ident;
</span><span class="cx">     std::unique_ptr&lt;WatchpointsOnStructureStubInfo&gt; watchpoints;
</span><span class="cx">     Vector&lt;WriteBarrier&lt;JSCell&gt;&gt; weakReferences;
</span><span class="lines">@@ -386,11 +385,11 @@
</span><span class="cx">     void restoreScratch();
</span><span class="cx">     void succeed();
</span><span class="cx"> 
</span><del>-    void calculateLiveRegistersForCallAndExceptionHandling();
</del><ins>+    void calculateLiveRegistersForCallAndExceptionHandling(const RegisterSet&amp; extra = RegisterSet());
</ins><span class="cx"> 
</span><del>-    void preserveLiveRegistersToStackForCall();
</del><ins>+    void preserveLiveRegistersToStackForCall(const RegisterSet&amp; extra = RegisterSet());
</ins><span class="cx"> 
</span><del>-    void restoreLiveRegistersFromStackForCall(bool isGetter);
</del><ins>+    void restoreLiveRegistersFromStackForCall(bool isGetter = false);
</ins><span class="cx">     void restoreLiveRegistersFromStackForCallWithThrownException();
</span><span class="cx">     void restoreLiveRegistersFromStackForCall(const RegisterSet&amp; dontRestore);
</span><span class="cx"> 
</span><span class="lines">@@ -419,6 +418,8 @@
</span><span class="cx">     bool needsToRestoreRegistersIfException() const { return m_needsToRestoreRegistersIfException; }
</span><span class="cx">     CallSiteIndex originalCallSiteIndex() const;
</span><span class="cx">     
</span><ins>+    void emitExplicitExceptionHandler();
+    
</ins><span class="cx"> private:
</span><span class="cx">     const RegisterSet&amp; liveRegistersToPreserveAtExceptionHandlingCallSite()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -1112,29 +1112,6 @@
</span><span class="cx">         Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
-{
-    VM&amp; vm = exec-&gt;vm();
-    NativeCallFrameTracer tracer(&amp;vm, exec);
-
-    ASSERT(!object-&gt;structure()-&gt;outOfLineCapacity());
-    DeferGC deferGC(vm.heap);
-    Butterfly* result = object-&gt;growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
-    object-&gt;setButterflyWithoutChangingStructure(vm, result);
-    return reinterpret_cast&lt;char*&gt;(result);
-}
-
-char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
-{
-    VM&amp; vm = exec-&gt;vm();
-    NativeCallFrameTracer tracer(&amp;vm, exec);
-
-    DeferGC deferGC(vm.heap);
-    Butterfly* result = object-&gt;growOutOfLineStorage(vm, object-&gt;structure()-&gt;outOfLineCapacity(), newSize);
-    object-&gt;setButterflyWithoutChangingStructure(vm, result);
-    return reinterpret_cast&lt;char*&gt;(result);
-}
-
</del><span class="cx"> char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.h (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.h        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -124,8 +124,6 @@
</span><span class="cx"> int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState*, JSGlobalObject*, JSCell*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState*) WTF_INTERNAL;
</span><span class="cx"> char* JIT_OPERATION operationAllocatePropertyStorage(ExecState*, size_t newSize) WTF_INTERNAL;
</span><del>-char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL;
-char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*, JSObject*, size_t newSize) WTF_INTERNAL;
</del><span class="cx"> char* JIT_OPERATION operationEnsureInt32(ExecState*, JSCell*);
</span><span class="cx"> char* JIT_OPERATION operationEnsureDouble(ExecState*, JSCell*);
</span><span class="cx"> char* JIT_OPERATION operationEnsureContiguous(ExecState*, JSCell*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -2030,6 +2030,29 @@
</span><span class="cx">     genericUnwind(vm, exec);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    ASSERT(!object-&gt;structure()-&gt;outOfLineCapacity());
+    DeferGC deferGC(vm.heap);
+    Butterfly* result = object-&gt;growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
+    object-&gt;setButterflyWithoutChangingStructure(vm, result);
+    return reinterpret_cast&lt;char*&gt;(result);
+}
+
+char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+
+    DeferGC deferGC(vm.heap);
+    Butterfly* result = object-&gt;growOutOfLineStorage(vm, object-&gt;structure()-&gt;outOfLineCapacity(), newSize);
+    object-&gt;setButterflyWithoutChangingStructure(vm, result);
+    return reinterpret_cast&lt;char*&gt;(result);
+}
+
</ins><span class="cx"> void JIT_OPERATION operationFlushWriteBarrierBuffer(ExecState* exec, JSCell* cell)
</span><span class="cx"> {
</span><span class="cx">     VM* vm = &amp;exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (199208 => 199209)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-04-08 01:27:42 UTC (rev 199208)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-04-08 02:11:48 UTC (rev 199209)
</span><span class="lines">@@ -377,6 +377,9 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationGetFromScope(ExecState*, Instruction* bytecodePC) WTF_INTERNAL;
</span><span class="cx"> void JIT_OPERATION operationPutToScope(ExecState*, Instruction* bytecodePC) WTF_INTERNAL;
</span><span class="cx"> 
</span><ins>+char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState*, JSObject*) WTF_INTERNAL;
+char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState*, JSObject*, size_t newSize) WTF_INTERNAL;
+
</ins><span class="cx"> void JIT_OPERATION operationFlushWriteBarrierBuffer(ExecState*, JSCell*);
</span><span class="cx"> void JIT_OPERATION operationWriteBarrier(ExecState*, JSCell*, JSCell*);
</span><span class="cx"> void JIT_OPERATION operationUnconditionalWriteBarrier(ExecState*, JSCell*);
</span></span></pre>
</div>
</div>

</body>
</html>