<!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>[193371] 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/193371">193371</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2015-12-03 13:09:41 -0800 (Thu, 03 Dec 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>FTL::OSRExitDescriptor should use less memory by having a companion object that dies after compilation
https://bugs.webkit.org/show_bug.cgi?id=151795

Reviewed by Geoffrey Garen.

There were a few fields on FTL::OSRExitDescriptor that are only
needed during compilation. This patch introduces OSRExitDescriptorImpl 
which is a struct that we create for each OSRExitDescriptor. The difference is 
that OSRExitDescriptorImpl lives off of FTL::State so it dies after we compile.
This way no unnecessary fields persist after the compilation.

* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLExceptionHandlerManager.cpp:
(JSC::FTL::ExceptionHandlerManager::lazySlowPathExceptionTarget):
(JSC::FTL::ExceptionHandlerManager::getCallOSRExitCommon):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitArgumentsForPatchpointIfWillCatchException):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitDescriptor):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
(JSC::FTL::DFG::LowerDFGToLLVM::emitOSRExitCall):
(JSC::FTL::DFG::LowerDFGToLLVM::buildExitArguments):
* ftl/FTLOSRExit.cpp:
(JSC::FTL::OSRExitDescriptor::OSRExitDescriptor):
(JSC::FTL::OSRExitDescriptor::validateReferences):
(JSC::FTL::OSRExitDescriptor::emitOSRExit):
(JSC::FTL::OSRExitDescriptor::emitOSRExitLater):
(JSC::FTL::OSRExitDescriptor::prepareOSRExitHandle):
(JSC::FTL::OSRExit::OSRExit):
(JSC::FTL::OSRExit::codeLocationForRepatch):
(JSC::FTL::OSRExit::gatherRegistersToSpillForCallIfException):
(JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
(JSC::FTL::exceptionTypeWillArriveAtOSRExitFromGenericUnwind):
(JSC::FTL::OSRExit::willArriveAtOSRExitFromGenericUnwind):
(JSC::FTL::OSRExit::willArriveAtOSRExitFromCallOperation):
(JSC::FTL::OSRExitDescriptor::isExceptionHandler): Deleted.
* ftl/FTLOSRExit.h:
(JSC::FTL::OSRExitDescriptorImpl::OSRExitDescriptorImpl):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileFTLOSRExit):
* ftl/FTLState.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCompilecpp">trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLExceptionHandlerManagercpp">trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitcpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExith">trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp">trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLStateh">trunk/Source/JavaScriptCore/ftl/FTLState.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2015-12-03  Saam barati  &lt;sbarati@apple.com&gt;
+
+        FTL::OSRExitDescriptor should use less memory by having a companion object that dies after compilation
+        https://bugs.webkit.org/show_bug.cgi?id=151795
+
+        Reviewed by Geoffrey Garen.
+
+        There were a few fields on FTL::OSRExitDescriptor that are only
+        needed during compilation. This patch introduces OSRExitDescriptorImpl 
+        which is a struct that we create for each OSRExitDescriptor. The difference is 
+        that OSRExitDescriptorImpl lives off of FTL::State so it dies after we compile.
+        This way no unnecessary fields persist after the compilation.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLExceptionHandlerManager.cpp:
+        (JSC::FTL::ExceptionHandlerManager::lazySlowPathExceptionTarget):
+        (JSC::FTL::ExceptionHandlerManager::getCallOSRExitCommon):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileInvalidationPoint):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitArgumentsForPatchpointIfWillCatchException):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitDescriptor):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
+        (JSC::FTL::DFG::LowerDFGToLLVM::emitOSRExitCall):
+        (JSC::FTL::DFG::LowerDFGToLLVM::buildExitArguments):
+        * ftl/FTLOSRExit.cpp:
+        (JSC::FTL::OSRExitDescriptor::OSRExitDescriptor):
+        (JSC::FTL::OSRExitDescriptor::validateReferences):
+        (JSC::FTL::OSRExitDescriptor::emitOSRExit):
+        (JSC::FTL::OSRExitDescriptor::emitOSRExitLater):
+        (JSC::FTL::OSRExitDescriptor::prepareOSRExitHandle):
+        (JSC::FTL::OSRExit::OSRExit):
+        (JSC::FTL::OSRExit::codeLocationForRepatch):
+        (JSC::FTL::OSRExit::gatherRegistersToSpillForCallIfException):
+        (JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
+        (JSC::FTL::exceptionTypeWillArriveAtOSRExitFromGenericUnwind):
+        (JSC::FTL::OSRExit::willArriveAtOSRExitFromGenericUnwind):
+        (JSC::FTL::OSRExit::willArriveAtOSRExitFromCallOperation):
+        (JSC::FTL::OSRExitDescriptor::isExceptionHandler): Deleted.
+        * ftl/FTLOSRExit.h:
+        (JSC::FTL::OSRExitDescriptorImpl::OSRExitDescriptorImpl):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileFTLOSRExit):
+        * ftl/FTLState.h:
+
</ins><span class="cx"> 2015-12-03  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix 64-bit Windows build after r193125.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCompilecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -482,23 +482,28 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     RELEASE_ASSERT(state.jitCode-&gt;osrExit.size() == 0);
</span><ins>+    HashMap&lt;OSRExitDescriptor*, OSRExitDescriptorImpl*&gt; genericUnwindOSRExitDescriptors;
</ins><span class="cx">     for (unsigned i = 0; i &lt; state.jitCode-&gt;osrExitDescriptors.size(); i++) {
</span><del>-        OSRExitDescriptor&amp; exitDescriptor = state.jitCode-&gt;osrExitDescriptors[i];
-        auto iter = recordMap.find(exitDescriptor.m_stackmapID);
</del><ins>+        OSRExitDescriptor* exitDescriptor = &amp;state.jitCode-&gt;osrExitDescriptors[i];
+        auto iter = recordMap.find(exitDescriptor-&gt;m_stackmapID);
</ins><span class="cx">         if (iter == recordMap.end()) {
</span><span class="cx">             // It was optimized out.
</span><span class="cx">             continue;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (unsigned j = exitDescriptor.m_values.size(); j--;)
-            exitDescriptor.m_values[j] = exitDescriptor.m_values[j].withLocalsOffset(localsOffset);
-        for (ExitTimeObjectMaterialization* materialization : exitDescriptor.m_materializations)
</del><ins>+        OSRExitDescriptorImpl&amp; exitDescriptorImpl = state.osrExitDescriptorImpls[i];
+        if (exceptionTypeWillArriveAtOSRExitFromGenericUnwind(exitDescriptorImpl.m_exceptionType))
+            genericUnwindOSRExitDescriptors.add(exitDescriptor, &amp;exitDescriptorImpl);
+
+        for (unsigned j = exitDescriptor-&gt;m_values.size(); j--;)
+            exitDescriptor-&gt;m_values[j] = exitDescriptor-&gt;m_values[j].withLocalsOffset(localsOffset);
+        for (ExitTimeObjectMaterialization* materialization : exitDescriptor-&gt;m_materializations)
</ins><span class="cx">             materialization-&gt;accountForLocalsOffset(localsOffset);
</span><span class="cx"> 
</span><span class="cx">         for (unsigned j = 0; j &lt; iter-&gt;value.size(); j++) {
</span><span class="cx">             {
</span><span class="cx">                 uint32_t stackmapRecordIndex = iter-&gt;value[j].index;
</span><del>-                OSRExit exit(&amp;exitDescriptor, stackmapRecordIndex);
</del><ins>+                OSRExit exit(exitDescriptor, exitDescriptorImpl, stackmapRecordIndex);
</ins><span class="cx">                 state.jitCode-&gt;osrExit.append(exit);
</span><span class="cx">                 state.finalizer-&gt;osrExit.append(OSRExitCompilationInfo());
</span><span class="cx">             }
</span><span class="lines">@@ -506,29 +511,29 @@
</span><span class="cx">             OSRExit&amp; exit = state.jitCode-&gt;osrExit.last();
</span><span class="cx">             if (exit.willArriveAtExitFromIndirectExceptionCheck()) {
</span><span class="cx">                 StackMaps::Record&amp; record = iter-&gt;value[j].record;
</span><del>-                RELEASE_ASSERT(exit.m_descriptor-&gt;m_semanticCodeOriginForCallFrameHeader.isSet());
-                CallSiteIndex callSiteIndex = state.jitCode-&gt;common.addUniqueCallSiteIndex(exit.m_descriptor-&gt;m_semanticCodeOriginForCallFrameHeader);
</del><ins>+                RELEASE_ASSERT(exitDescriptorImpl.m_semanticCodeOriginForCallFrameHeader.isSet());
+                CallSiteIndex callSiteIndex = state.jitCode-&gt;common.addUniqueCallSiteIndex(exitDescriptorImpl.m_semanticCodeOriginForCallFrameHeader);
</ins><span class="cx">                 exit.m_exceptionHandlerCallSiteIndex = callSiteIndex;
</span><span class="cx"> 
</span><span class="cx">                 OSRExit* callOperationExit = nullptr;
</span><del>-                if (exitDescriptor.m_exceptionType == ExceptionType::BinaryOpGenerator) {
</del><ins>+                if (exitDescriptorImpl.m_exceptionType == ExceptionType::BinaryOpGenerator) {
</ins><span class="cx">                     exceptionHandlerManager.addNewCallOperationExit(iter-&gt;value[j].index, state.jitCode-&gt;osrExit.size() - 1);
</span><span class="cx">                     callOperationExit = &amp;exit;
</span><span class="cx">                 } else
</span><span class="cx">                     exceptionHandlerManager.addNewExit(iter-&gt;value[j].index, state.jitCode-&gt;osrExit.size() - 1);
</span><span class="cx">                 
</span><del>-                if (exitDescriptor.m_exceptionType == ExceptionType::GetById || exitDescriptor.m_exceptionType == ExceptionType::PutById) {
</del><ins>+                if (exitDescriptorImpl.m_exceptionType == ExceptionType::GetById || exitDescriptorImpl.m_exceptionType == ExceptionType::PutById) {
</ins><span class="cx">                     // We create two different OSRExits for GetById and PutById.
</span><span class="cx">                     // One exit that will be arrived at from the genericUnwind exception handler path,
</span><span class="cx">                     // and the other that will be arrived at from the callOperation exception handler path.
</span><span class="cx">                     // This code here generates the second callOperation variant.
</span><span class="cx">                     uint32_t stackmapRecordIndex = iter-&gt;value[j].index;
</span><del>-                    OSRExit exit(&amp;exitDescriptor, stackmapRecordIndex);
-                    if (exitDescriptor.m_exceptionType == ExceptionType::GetById)
</del><ins>+                    OSRExit exit(exitDescriptor, exitDescriptorImpl, stackmapRecordIndex);
+                    if (exitDescriptorImpl.m_exceptionType == ExceptionType::GetById)
</ins><span class="cx">                         exit.m_exceptionType = ExceptionType::GetByIdCallOperation;
</span><span class="cx">                     else
</span><span class="cx">                         exit.m_exceptionType = ExceptionType::PutByIdCallOperation;
</span><del>-                    CallSiteIndex callSiteIndex = state.jitCode-&gt;common.addUniqueCallSiteIndex(exit.m_descriptor-&gt;m_semanticCodeOriginForCallFrameHeader);
</del><ins>+                    CallSiteIndex callSiteIndex = state.jitCode-&gt;common.addUniqueCallSiteIndex(exitDescriptorImpl.m_semanticCodeOriginForCallFrameHeader);
</ins><span class="cx">                     exit.m_exceptionHandlerCallSiteIndex = callSiteIndex;
</span><span class="cx"> 
</span><span class="cx">                     state.jitCode-&gt;osrExit.append(exit);
</span><span class="lines">@@ -543,19 +548,19 @@
</span><span class="cx">                 //
</span><span class="cx">                 // We set the registers needing spillage here because they need to be set
</span><span class="cx">                 // before we generate OSR exits so the exit knows to do the proper recovery.
</span><del>-                if (exitDescriptor.m_exceptionType == ExceptionType::JSCall) {
</del><ins>+                if (exitDescriptorImpl.m_exceptionType == ExceptionType::JSCall) {
</ins><span class="cx">                     // Call patchpoints might have values we want to do value recovery
</span><span class="cx">                     // on inside volatile registers. We need to collect the volatile
</span><span class="cx">                     // registers we want to do value recovery on here because they must
</span><span class="cx">                     // be preserved to the stack before the call, that way the OSR exit
</span><span class="cx">                     // exception handler can recover them into the proper registers.
</span><span class="cx">                     exit.gatherRegistersToSpillForCallIfException(stackmaps, record);
</span><del>-                } else if (exitDescriptor.m_exceptionType == ExceptionType::GetById) {
</del><ins>+                } else if (exitDescriptorImpl.m_exceptionType == ExceptionType::GetById) {
</ins><span class="cx">                     GPRReg result = record.locations[0].directGPR();
</span><span class="cx">                     GPRReg base = record.locations[1].directGPR();
</span><span class="cx">                     if (base == result)
</span><span class="cx">                         callOperationExit-&gt;registersToPreserveForCallThatMightThrow.set(base);
</span><del>-                } else if (exitDescriptor.m_exceptionType == ExceptionType::BinaryOpGenerator) {
</del><ins>+                } else if (exitDescriptorImpl.m_exceptionType == ExceptionType::BinaryOpGenerator) {
</ins><span class="cx">                     GPRReg result = record.locations[0].directGPR();
</span><span class="cx">                     GPRReg left = record.locations[1].directGPR();
</span><span class="cx">                     GPRReg right = record.locations[2].directGPR();
</span><span class="lines">@@ -592,7 +597,7 @@
</span><span class="cx">             exit.m_patchableCodeOffset = linkBuffer-&gt;offsetOf(info.m_thunkJump);
</span><span class="cx"> 
</span><span class="cx">             if (exit.willArriveAtOSRExitFromGenericUnwind()) {
</span><del>-                HandlerInfo newHandler = exit.m_descriptor-&gt;m_baselineExceptionHandler;
</del><ins>+                HandlerInfo newHandler = genericUnwindOSRExitDescriptors.get(exit.m_descriptor)-&gt;m_baselineExceptionHandler;
</ins><span class="cx">                 newHandler.start = exit.m_exceptionHandlerCallSiteIndex.bits();
</span><span class="cx">                 newHandler.end = exit.m_exceptionHandlerCallSiteIndex.bits() + 1;
</span><span class="cx">                 newHandler.nativeCode = info.m_thunkAddress;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLExceptionHandlerManagercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLExceptionHandlerManager.cpp        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx">         return CodeLocationLabel();
</span><span class="cx"> 
</span><span class="cx">     size_t osrExitIndex = findResult-&gt;value;
</span><del>-    RELEASE_ASSERT(m_state.jitCode-&gt;osrExit[osrExitIndex].m_descriptor-&gt;m_exceptionType == ExceptionType::LazySlowPath);
</del><ins>+    RELEASE_ASSERT(m_state.jitCode-&gt;osrExit[osrExitIndex].m_exceptionType == ExceptionType::LazySlowPath);
</ins><span class="cx">     OSRExitCompilationInfo&amp; info = m_state.finalizer-&gt;osrExit[osrExitIndex];
</span><span class="cx">     RELEASE_ASSERT(info.m_thunkLabel.isSet());
</span><span class="cx">     return m_state.finalizer-&gt;exitThunksLinkBuffer-&gt;locationOf(info.m_thunkLabel);
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     size_t osrExitIndex = findResult-&gt;value;
</span><span class="cx">     OSRExit* exit = &amp;m_state.jitCode-&gt;osrExit[osrExitIndex];
</span><del>-    RELEASE_ASSERT(exit-&gt;m_descriptor-&gt;m_exceptionType == ExceptionType::JSCall);
</del><ins>+    RELEASE_ASSERT(exit-&gt;m_exceptionType == ExceptionType::JSCall);
</ins><span class="cx">     return exit; 
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -5376,7 +5376,7 @@
</span><span class="cx"> 
</span><span class="cx">         OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(UncountableInvalidation, ExceptionType::None, noValue(), nullptr, m_origin);
</span><span class="cx">         
</span><del>-        StackmapArgumentList arguments = buildExitArguments(exitDescriptor, FormattedValue());
</del><ins>+        StackmapArgumentList arguments = buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last(), FormattedValue());
</ins><span class="cx">         callStackmap(exitDescriptor, arguments);
</span><span class="cx">         
</span><span class="cx">         exitDescriptor-&gt;m_isInvalidationPoint = true;
</span><span class="lines">@@ -9265,13 +9265,16 @@
</span><span class="cx">         if (!willCatchException)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(Uncountable, exceptionType, noValue(), nullptr, m_origin.withForExitAndExitOK(opCatchOrigin, true));
-        exitDescriptor-&gt;m_semanticCodeOriginForCallFrameHeader = codeOriginDescriptionOfCallSite();
-        exitDescriptor-&gt;m_baselineExceptionHandler = *exceptionHandler;
</del><ins>+        appendOSRExitDescriptor(Uncountable, exceptionType, noValue(), nullptr, m_origin.withForExitAndExitOK(opCatchOrigin, true));
+        OSRExitDescriptor* exitDescriptor = &amp;m_ftlState.jitCode-&gt;osrExitDescriptors.last();
</ins><span class="cx">         exitDescriptor-&gt;m_stackmapID = m_stackmapIDs - 1;
</span><span class="cx"> 
</span><ins>+        OSRExitDescriptorImpl&amp; exitDescriptorImpl = m_ftlState.osrExitDescriptorImpls.last();
+        exitDescriptorImpl.m_semanticCodeOriginForCallFrameHeader = codeOriginDescriptionOfCallSite();
+        exitDescriptorImpl.m_baselineExceptionHandler = *exceptionHandler;
+
</ins><span class="cx">         StackmapArgumentList freshList =
</span><del>-            buildExitArguments(exitDescriptor, noValue(), offsetOfExitArguments);
</del><ins>+            buildExitArguments(exitDescriptor, exitDescriptorImpl, noValue(), offsetOfExitArguments);
</ins><span class="cx">         arguments.appendVector(freshList);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -9294,11 +9297,13 @@
</span><span class="cx"> 
</span><span class="cx">     OSRExitDescriptor* appendOSRExitDescriptor(ExitKind kind, ExceptionType exceptionType, FormattedValue lowValue, Node* highValue, NodeOrigin origin)
</span><span class="cx">     {
</span><del>-        return &amp;m_ftlState.jitCode-&gt;osrExitDescriptors.alloc(
-            kind, exceptionType, lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
-            origin.forExit, origin.semantic,
</del><ins>+        OSRExitDescriptor&amp; result = m_ftlState.jitCode-&gt;osrExitDescriptors.alloc(
+            lowValue.format(), m_graph.methodOfGettingAValueProfileFor(highValue),
</ins><span class="cx">             availabilityMap().m_locals.numberOfArguments(),
</span><span class="cx">             availabilityMap().m_locals.numberOfLocals());
</span><ins>+        m_ftlState.osrExitDescriptorImpls.alloc(
+            kind, origin.forExit, origin.semantic, exceptionType);
+        return &amp;result;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void appendOSRExit(
</span><span class="lines">@@ -9370,14 +9375,15 @@
</span><span class="cx">         OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(
</span><span class="cx">             kind, isExceptionHandler ? ExceptionType::CCallException : ExceptionType::None, lowValue,
</span><span class="cx">             highValue, origin);
</span><ins>+        OSRExitDescriptorImpl* exitDescriptorImpl = &amp;m_ftlState.osrExitDescriptorImpls.last();
</ins><span class="cx">         
</span><span class="cx">         unsigned offset = value-&gt;numChildren();
</span><del>-        value-&gt;appendAnys(buildExitArguments(exitDescriptor, lowValue));
</del><ins>+        value-&gt;appendAnys(buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last(), lowValue));
</ins><span class="cx"> 
</span><span class="cx">         State* state = &amp;m_ftlState;
</span><span class="cx">         value-&gt;setGenerator(
</span><span class="cx">             [=] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp; params) {
</span><del>-                exitDescriptor-&gt;emitOSRExit(*state, jit, params, offset);
</del><ins>+                exitDescriptor-&gt;emitOSRExit(*state, exitDescriptorImpl, jit, params, offset);
</ins><span class="cx">             });
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="lines">@@ -9385,29 +9391,29 @@
</span><span class="cx"> #if !FTL_USES_B3
</span><span class="cx">     void emitOSRExitCall(OSRExitDescriptor* exitDescriptor, FormattedValue lowValue)
</span><span class="cx">     {
</span><del>-        callStackmap(exitDescriptor, buildExitArguments(exitDescriptor, lowValue));
</del><ins>+        callStackmap(exitDescriptor, buildExitArguments(exitDescriptor, m_ftlState.osrExitDescriptorImpls.last(), lowValue));
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     StackmapArgumentList buildExitArguments(
</span><del>-        OSRExitDescriptor* exitDescriptor, FormattedValue lowValue,
</del><ins>+        OSRExitDescriptor* exitDescriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl, FormattedValue lowValue,
</ins><span class="cx">         unsigned offsetOfExitArgumentsInStackmapLocations = 0)
</span><span class="cx">     {
</span><span class="cx">         StackmapArgumentList result;
</span><span class="cx">         buildExitArguments(
</span><del>-            exitDescriptor, result, lowValue, offsetOfExitArgumentsInStackmapLocations);
</del><ins>+            exitDescriptor, exitDescriptorImpl, result, lowValue, offsetOfExitArgumentsInStackmapLocations);
</ins><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void buildExitArguments(
</span><del>-        OSRExitDescriptor* exitDescriptor, StackmapArgumentList&amp; arguments, FormattedValue lowValue,
</del><ins>+        OSRExitDescriptor* exitDescriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl, StackmapArgumentList&amp; arguments, FormattedValue lowValue,
</ins><span class="cx">         unsigned offsetOfExitArgumentsInStackmapLocations = 0)
</span><span class="cx">     {
</span><span class="cx">         if (!!lowValue)
</span><span class="cx">             arguments.append(lowValue.value());
</span><span class="cx">         
</span><span class="cx">         AvailabilityMap availabilityMap = this-&gt;availabilityMap();
</span><del>-        availabilityMap.pruneByLiveness(m_graph, exitDescriptor-&gt;m_codeOrigin);
</del><ins>+        availabilityMap.pruneByLiveness(m_graph, exitDescriptorImpl.m_codeOrigin);
</ins><span class="cx">         
</span><span class="cx">         HashMap&lt;Node*, ExitTimeObjectMaterialization*&gt; map;
</span><span class="cx">         availabilityMap.forEachAvailability(
</span><span class="lines">@@ -9434,7 +9440,7 @@
</span><span class="cx">             if (Options::validateFTLOSRExitLiveness()) {
</span><span class="cx">                 DFG_ASSERT(
</span><span class="cx">                     m_graph, m_node,
</span><del>-                    (!(availability.isDead() &amp;&amp; m_graph.isLiveInBytecode(VirtualRegister(operand), exitDescriptor-&gt;m_codeOrigin))) || m_graph.m_plan.mode == FTLForOSREntryMode);
</del><ins>+                    (!(availability.isDead() &amp;&amp; m_graph.isLiveInBytecode(VirtualRegister(operand), exitDescriptorImpl.m_codeOrigin))) || m_graph.m_plan.mode == FTLForOSREntryMode);
</ins><span class="cx">             }
</span><span class="cx">             ExitValue exitValue = exitValueForAvailability(arguments, map, availability);
</span><span class="cx">             if (exitValue.hasIndexInStackmapLocations())
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExit.cpp        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -45,26 +45,15 @@
</span><span class="cx"> using namespace DFG;
</span><span class="cx"> 
</span><span class="cx"> OSRExitDescriptor::OSRExitDescriptor(
</span><del>-    ExitKind exitKind, ExceptionType exceptionType, DataFormat profileDataFormat,
-    MethodOfGettingAValueProfile valueProfile, CodeOrigin codeOrigin,
-    CodeOrigin originForProfile, unsigned numberOfArguments,
-    unsigned numberOfLocals)
-    : m_kind(exitKind)
-    , m_exceptionType(exceptionType)
-    , m_codeOrigin(codeOrigin)
-    , m_codeOriginForExitProfile(originForProfile)
-    , m_profileDataFormat(profileDataFormat)
</del><ins>+    DataFormat profileDataFormat, MethodOfGettingAValueProfile valueProfile,
+    unsigned numberOfArguments, unsigned numberOfLocals)
+    : m_profileDataFormat(profileDataFormat)
</ins><span class="cx">     , m_valueProfile(valueProfile)
</span><span class="cx">     , m_values(numberOfArguments, numberOfLocals)
</span><span class="cx">     , m_isInvalidationPoint(false)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool OSRExitDescriptor::isExceptionHandler() const
-{
-    return m_exceptionType != ExceptionType::None;
-}
-
</del><span class="cx"> void OSRExitDescriptor::validateReferences(const TrackedReferences&amp; trackedReferences)
</span><span class="cx"> {
</span><span class="cx">     for (unsigned i = m_values.size(); i--;)
</span><span class="lines">@@ -76,17 +65,17 @@
</span><span class="cx"> 
</span><span class="cx"> #if FTL_USES_B3
</span><span class="cx"> RefPtr&lt;OSRExitHandle&gt; OSRExitDescriptor::emitOSRExit(
</span><del>-    State&amp; state, CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params, unsigned offset)
</del><ins>+    State&amp; state, OSRExitDescriptorImpl* exitDescriptorImpl, CCallHelpers&amp; jit, const StackmapGenerationParams&amp; params, unsigned offset)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;OSRExitHandle&gt; handle = prepareOSRExitHandle(state, params, offset);
</del><ins>+    RefPtr&lt;OSRExitHandle&gt; handle = prepareOSRExitHandle(state, exitDescriptorImpl, params, offset);
</ins><span class="cx">     handle-&gt;emitExitThunk(jit);
</span><span class="cx">     return handle;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;OSRExitHandle&gt; OSRExitDescriptor::emitOSRExitLater(
</span><del>-    State&amp; state, const StackmapGenerationParams&amp; params, unsigned offset)
</del><ins>+    State&amp; state, OSRExitDescriptorImpl* exitDescriptorImpl, const StackmapGenerationParams&amp; params, unsigned offset)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;OSRExitHandle&gt; handle = prepareOSRExitHandle(state, params, offset);
</del><ins>+    RefPtr&lt;OSRExitHandle&gt; handle = prepareOSRExitHandle(state, exitDescriptorImpl, params, offset);
</ins><span class="cx">     params.context-&gt;latePaths.append(
</span><span class="cx">         createSharedTask&lt;Air::GenerationContext::LatePathFunction&gt;(
</span><span class="cx">             [handle] (CCallHelpers&amp; jit, Air::GenerationContext&amp;) {
</span><span class="lines">@@ -96,11 +85,11 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;OSRExitHandle&gt; OSRExitDescriptor::prepareOSRExitHandle(
</span><del>-    State&amp; state, const StackmapGenerationParams&amp; params, unsigned offset)
</del><ins>+    State&amp; state, OSRExitDescriptorImpl* exitDescriptorImpl, const StackmapGenerationParams&amp; params, unsigned offset)
</ins><span class="cx"> {
</span><span class="cx">     unsigned index = state.jitCode-&gt;osrExit.size();
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; handle = adoptRef(
</span><del>-        new OSRExitHandle(index, state.jitCode-&gt;osrExit.alloc(this)));
</del><ins>+        new OSRExitHandle(index, state.jitCode-&gt;osrExit.alloc(this, *exitDescriptorImpl)));
</ins><span class="cx">     for (unsigned i = offset; i &lt; params.reps.size(); ++i)
</span><span class="cx">         handle-&gt;exit.m_valueReps.append(params.reps[i]);
</span><span class="cx">     handle-&gt;exit.m_valueReps.shrinkToFit();
</span><span class="lines">@@ -109,19 +98,19 @@
</span><span class="cx"> #endif // FTL_USES_B3
</span><span class="cx"> 
</span><span class="cx"> OSRExit::OSRExit(
</span><del>-    OSRExitDescriptor* descriptor
</del><ins>+    OSRExitDescriptor* descriptor, OSRExitDescriptorImpl&amp; exitDescriptorImpl
</ins><span class="cx"> #if !FTL_USES_B3
</span><span class="cx">     , uint32_t stackmapRecordIndex
</span><span class="cx"> #endif // !FTL_USES_B3
</span><span class="cx">     )
</span><del>-    : OSRExitBase(descriptor-&gt;m_kind, descriptor-&gt;m_codeOrigin, descriptor-&gt;m_codeOriginForExitProfile)
</del><ins>+    : OSRExitBase(exitDescriptorImpl.m_kind, exitDescriptorImpl.m_codeOrigin, exitDescriptorImpl.m_codeOriginForExitProfile)
</ins><span class="cx">     , m_descriptor(descriptor)
</span><span class="cx"> #if !FTL_USES_B3
</span><span class="cx">     , m_stackmapRecordIndex(stackmapRecordIndex)
</span><span class="cx"> #endif // !FTL_USES_B3
</span><del>-    , m_exceptionType(descriptor-&gt;m_exceptionType)
</del><ins>+    , m_exceptionType(exitDescriptorImpl.m_exceptionType)
</ins><span class="cx"> {
</span><del>-    m_isExceptionHandler = descriptor-&gt;isExceptionHandler();
</del><ins>+    m_isExceptionHandler = exitDescriptorImpl.m_exceptionType != ExceptionType::None;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const
</span><span class="lines">@@ -140,7 +129,7 @@
</span><span class="cx"> #if !FTL_USES_B3
</span><span class="cx"> void OSRExit::gatherRegistersToSpillForCallIfException(StackMaps&amp; stackmaps, StackMaps::Record&amp; record)
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_descriptor-&gt;m_exceptionType == ExceptionType::JSCall);
</del><ins>+    RELEASE_ASSERT(m_exceptionType == ExceptionType::JSCall);
</ins><span class="cx"> 
</span><span class="cx">     RegisterSet volatileRegisters = RegisterSet::volatileRegistersForJSCall();
</span><span class="cx"> 
</span><span class="lines">@@ -226,9 +215,9 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool OSRExit::willArriveAtOSRExitFromGenericUnwind() const
</del><ins>+bool exceptionTypeWillArriveAtOSRExitFromGenericUnwind(ExceptionType exceptionType)
</ins><span class="cx"> {
</span><del>-    switch (m_exceptionType) {
</del><ins>+    switch (exceptionType) {
</ins><span class="cx">     case ExceptionType::JSCall:
</span><span class="cx">     case ExceptionType::GetById:
</span><span class="cx">     case ExceptionType::PutById:
</span><span class="lines">@@ -239,6 +228,11 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool OSRExit::willArriveAtOSRExitFromGenericUnwind() const
+{
+    return exceptionTypeWillArriveAtOSRExitFromGenericUnwind(m_exceptionType);
+}
+
</ins><span class="cx"> bool OSRExit::willArriveAtOSRExitFromCallOperation() const
</span><span class="cx"> {
</span><span class="cx">     switch (m_exceptionType) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExith"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExit.h        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -60,6 +60,7 @@
</span><span class="cx"> namespace FTL {
</span><span class="cx"> 
</span><span class="cx"> class State;
</span><ins>+struct OSRExitDescriptorImpl;
</ins><span class="cx"> 
</span><span class="cx"> enum class ExceptionType : uint8_t {
</span><span class="cx">     None,
</span><span class="lines">@@ -73,20 +74,13 @@
</span><span class="cx">     BinaryOpGenerator,
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+bool exceptionTypeWillArriveAtOSRExitFromGenericUnwind(ExceptionType);
+
</ins><span class="cx"> struct OSRExitDescriptor {
</span><span class="cx">     OSRExitDescriptor(
</span><del>-        ExitKind, ExceptionType, DataFormat profileDataFormat, MethodOfGettingAValueProfile,
-        CodeOrigin, CodeOrigin originForProfile,
</del><ins>+        DataFormat profileDataFormat, MethodOfGettingAValueProfile,
</ins><span class="cx">         unsigned numberOfArguments, unsigned numberOfLocals);
</span><span class="cx"> 
</span><del>-    bool isExceptionHandler() const;
-
-    ExitKind m_kind;
-    ExceptionType m_exceptionType;
-    CodeOrigin m_codeOrigin;
-    CodeOrigin m_codeOriginForExitProfile;
-    CodeOrigin m_semanticCodeOriginForCallFrameHeader;
-    
</del><span class="cx">     // The first argument to the exit call may be a value we wish to profile.
</span><span class="cx">     // If that's the case, the format will be not Invalid and we'll have a
</span><span class="cx">     // method of getting a value profile. Note that all of the ExitArgument's
</span><span class="lines">@@ -99,7 +93,6 @@
</span><span class="cx">     Bag&lt;ExitTimeObjectMaterialization&gt; m_materializations;
</span><span class="cx">     
</span><span class="cx">     uint32_t m_stackmapID;
</span><del>-    HandlerInfo m_baselineExceptionHandler;
</del><span class="cx">     bool m_isInvalidationPoint;
</span><span class="cx">     
</span><span class="cx">     void validateReferences(const TrackedReferences&amp;);
</span><span class="lines">@@ -112,7 +105,7 @@
</span><span class="cx">     // on the ground. It contains information that is mostly not useful if you use this API, since after
</span><span class="cx">     // this call, the OSRExit is simply ready to go.
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; emitOSRExit(
</span><del>-        State&amp;, CCallHelpers&amp;, const B3::StackmapGenerationParams&amp;, unsigned offset);
</del><ins>+        State&amp;, OSRExitDescriptorImpl*, CCallHelpers&amp;, const B3::StackmapGenerationParams&amp;, unsigned offset);
</ins><span class="cx"> 
</span><span class="cx">     // In some cases you want an OSRExit to come into existence, but you don't want to emit it right now.
</span><span class="cx">     // This will emit the OSR exit in a late path. You can't be sure exactly when that will happen, but
</span><span class="lines">@@ -123,19 +116,36 @@
</span><span class="cx">     // have a place to jump to for OSR exit. It doesn't care where that OSR exit is emitted so long as it
</span><span class="cx">     // eventually gets access to its label.
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; emitOSRExitLater(
</span><del>-        State&amp;, const B3::StackmapGenerationParams&amp;, unsigned offset);
</del><ins>+        State&amp;, OSRExitDescriptorImpl*, const B3::StackmapGenerationParams&amp;, unsigned offset);
</ins><span class="cx"> 
</span><span class="cx">     // This is the low-level interface. It will create a handle representing the desire to emit code for
</span><span class="cx">     // an OSR exit. You can call OSRExitHandle::emitExitThunk() once you have a place to emit it. Note
</span><span class="cx">     // that the above two APIs are written in terms of this and OSRExitHandle::emitExitThunk().
</span><span class="cx">     RefPtr&lt;OSRExitHandle&gt; prepareOSRExitHandle(
</span><del>-        State&amp;, const B3::StackmapGenerationParams&amp;, unsigned offset);
</del><ins>+        State&amp;, OSRExitDescriptorImpl*, const B3::StackmapGenerationParams&amp;, unsigned offset);
</ins><span class="cx"> #endif // FTL_USES_B3
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct OSRExitDescriptorImpl {
+    OSRExitDescriptorImpl(ExitKind kind, CodeOrigin exitOrigin, CodeOrigin forExitProfile, ExceptionType exceptionType)
+        : m_kind(kind)
+        , m_codeOrigin(exitOrigin)
+        , m_codeOriginForExitProfile(forExitProfile)
+        , m_exceptionType(exceptionType)
+    {
+    }
+
+    ExitKind m_kind;
+    CodeOrigin m_codeOrigin;
+    CodeOrigin m_codeOriginForExitProfile;
+    ExceptionType m_exceptionType;
+    CodeOrigin m_semanticCodeOriginForCallFrameHeader;
+    HandlerInfo m_baselineExceptionHandler;
+};
+
</ins><span class="cx"> struct OSRExit : public DFG::OSRExitBase {
</span><span class="cx">     OSRExit(
</span><del>-        OSRExitDescriptor*
</del><ins>+        OSRExitDescriptor*, OSRExitDescriptorImpl&amp;
</ins><span class="cx"> #if !FTL_USES_B3
</span><span class="cx">         , uint32_t stackmapRecordIndex
</span><span class="cx"> #endif // !FTL_USES_B3
</span><span class="lines">@@ -175,6 +185,7 @@
</span><span class="cx">     bool needsRegisterRecoveryOnGenericUnwindOSRExitPath() const;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -584,7 +584,7 @@
</span><span class="cx">         dataLog(&quot;    Current call site index: &quot;, exec-&gt;callSiteIndex().bits(), &quot;\n&quot;);
</span><span class="cx">         dataLog(&quot;    Exit is exception handler: &quot;, exit.m_isExceptionHandler,
</span><span class="cx">             &quot; will arrive at exit from genericUnwind(): &quot;, exit.willArriveAtOSRExitFromGenericUnwind(), 
</span><del>-            &quot; will arrive at exit from lazy slow path: &quot;, exit.m_descriptor-&gt;m_exceptionType == ExceptionType::LazySlowPath, &quot;\n&quot;);
</del><ins>+            &quot; will arrive at exit from lazy slow path: &quot;, exit.m_exceptionType == ExceptionType::LazySlowPath, &quot;\n&quot;);
</ins><span class="cx">         dataLog(&quot;    Exit values: &quot;, exit.m_descriptor-&gt;m_values, &quot;\n&quot;);
</span><span class="cx">         if (!exit.m_descriptor-&gt;m_materializations.isEmpty()) {
</span><span class="cx">             dataLog(&quot;    Materializations:\n&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLStateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLState.h (193370 => 193371)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLState.h        2015-12-03 20:57:55 UTC (rev 193370)
+++ trunk/Source/JavaScriptCore/ftl/FTLState.h        2015-12-03 21:09:41 UTC (rev 193371)
</span><span class="lines">@@ -101,6 +101,7 @@
</span><span class="cx">     Vector&lt;JSTailCall&gt; jsTailCalls;
</span><span class="cx">     Vector&lt;CString&gt; codeSectionNames;
</span><span class="cx">     Vector&lt;CString&gt; dataSectionNames;
</span><ins>+    SegmentedVector&lt;OSRExitDescriptorImpl&gt; osrExitDescriptorImpls;
</ins><span class="cx">     void* unwindDataSection;
</span><span class="cx">     size_t unwindDataSectionSize;
</span><span class="cx">     RefPtr&lt;DataSection&gt; stackmapsSection;
</span></span></pre>
</div>
</div>

</body>
</html>