<!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>[161543] branches/jsCStack/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/161543">161543</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-01-08 20:11:59 -0800 (Wed, 08 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>FTL should not use the inputs of an add or sub as the live-at-exit values in an overflow check, if the values aren't live after
https://bugs.webkit.org/show_bug.cgi?id=126545

Not yet reviewed.
        
Introduces the notion of an ExitValue that is computed by doing some math on two
exit arguments. This gets used by LowerDFGToLLVM by tracking the
AvailableRecoveries - i.e. the set of ways we know how to recover the value of a
node by performing math on LValue's - and then trying to pick an AvailableRecovery
if we try to exit with an Availability pointing to a Node that isn't a constant.
The compileArithAddOrSub() code adds AvailableRecoveries for the ways you could
recovery the left or right operand by using the result.
        
Doing this uncovered a bug in stackmap constant parsing where we were casting a
32-bit value to 16-bit, thereby losing the top bits.

* JavaScriptCore.xcodeproj/project.pbxproj:
* ftl/FTLAvailableRecovery.cpp: Added.
(JSC::FTL::AvailableRecovery::dump):
* ftl/FTLAvailableRecovery.h: Added.
(JSC::FTL::AvailableRecovery::AvailableRecovery):
(JSC::FTL::AvailableRecovery::node):
(JSC::FTL::AvailableRecovery::format):
(JSC::FTL::AvailableRecovery::opcode):
(JSC::FTL::AvailableRecovery::left):
(JSC::FTL::AvailableRecovery::right):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::recovery):
(JSC::FTL::ExitValue::isRecovery):
(JSC::FTL::ExitValue::leftRecoveryArgument):
(JSC::FTL::ExitValue::rightRecoveryArgument):
(JSC::FTL::ExitValue::recoveryFormat):
(JSC::FTL::ExitValue::recoveryOpcode):
(JSC::FTL::ExitValue::valueFormat):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
(JSC::FTL::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
(JSC::FTL::LowerDFGToLLVM::doesKill):
(JSC::FTL::LowerDFGToLLVM::addAvailableRecovery):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* ftl/FTLRecoveryOpcode.cpp: Added.
(WTF::printInternal):
* ftl/FTLRecoveryOpcode.h: Added.
* ftl/FTLStackMaps.h:
* tests/stress/add-constant-overflow-recovery.js: Added.
(foo):
* tests/stress/add-int52-constant-overflow-recovery.js: Added.
(foo):
* tests/stress/add-int52-large-constant-overflow-recovery.js: Added.
(foo):
* tests/stress/add-overflow-recovery.js: Added.
(foo):
* tests/stress/add-small-constant-overflow-recovery.js: Added.
(foo):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreChangeLog">branches/jsCStack/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLExitValuecpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLExitValueh">branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLOSRExitCompilercpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLStackMapsh">branches/jsCStack/Source/JavaScriptCore/ftl/FTLStackMaps.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLAvailableRecoverycpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLAvailableRecoveryh">branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLRecoveryOpcodecpp">branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.cpp</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoreftlFTLRecoveryOpcodeh">branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.h</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressaddconstantoverflowrecoveryjs">branches/jsCStack/Source/JavaScriptCore/tests/stress/add-constant-overflow-recovery.js</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressaddint52constantoverflowrecoveryjs">branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-constant-overflow-recovery.js</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressaddint52largeconstantoverflowrecoveryjs">branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-large-constant-overflow-recovery.js</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressaddoverflowrecoveryjs">branches/jsCStack/Source/JavaScriptCore/tests/stress/add-overflow-recovery.js</a></li>
<li><a href="#branchesjsCStackSourceJavaScriptCoretestsstressaddsmallconstantoverflowrecoveryjs">branches/jsCStack/Source/JavaScriptCore/tests/stress/add-small-constant-overflow-recovery.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchesjsCStackSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ChangeLog (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/ChangeLog        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -1,3 +1,65 @@
</span><ins>+2014-01-08  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL should not use the inputs of an add or sub as the live-at-exit values in an overflow check, if the values aren't live after
+        https://bugs.webkit.org/show_bug.cgi?id=126545
+
+        Not yet reviewed.
+        
+        Introduces the notion of an ExitValue that is computed by doing some math on two
+        exit arguments. This gets used by LowerDFGToLLVM by tracking the
+        AvailableRecoveries - i.e. the set of ways we know how to recover the value of a
+        node by performing math on LValue's - and then trying to pick an AvailableRecovery
+        if we try to exit with an Availability pointing to a Node that isn't a constant.
+        The compileArithAddOrSub() code adds AvailableRecoveries for the ways you could
+        recovery the left or right operand by using the result.
+        
+        Doing this uncovered a bug in stackmap constant parsing where we were casting a
+        32-bit value to 16-bit, thereby losing the top bits.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * ftl/FTLAvailableRecovery.cpp: Added.
+        (JSC::FTL::AvailableRecovery::dump):
+        * ftl/FTLAvailableRecovery.h: Added.
+        (JSC::FTL::AvailableRecovery::AvailableRecovery):
+        (JSC::FTL::AvailableRecovery::node):
+        (JSC::FTL::AvailableRecovery::format):
+        (JSC::FTL::AvailableRecovery::opcode):
+        (JSC::FTL::AvailableRecovery::left):
+        (JSC::FTL::AvailableRecovery::right):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::recovery):
+        (JSC::FTL::ExitValue::isRecovery):
+        (JSC::FTL::ExitValue::leftRecoveryArgument):
+        (JSC::FTL::ExitValue::rightRecoveryArgument):
+        (JSC::FTL::ExitValue::recoveryFormat):
+        (JSC::FTL::ExitValue::recoveryOpcode):
+        (JSC::FTL::ExitValue::valueFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub):
+        (JSC::FTL::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode):
+        (JSC::FTL::LowerDFGToLLVM::doesKill):
+        (JSC::FTL::LowerDFGToLLVM::addAvailableRecovery):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * ftl/FTLRecoveryOpcode.cpp: Added.
+        (WTF::printInternal):
+        * ftl/FTLRecoveryOpcode.h: Added.
+        * ftl/FTLStackMaps.h:
+        * tests/stress/add-constant-overflow-recovery.js: Added.
+        (foo):
+        * tests/stress/add-int52-constant-overflow-recovery.js: Added.
+        (foo):
+        * tests/stress/add-int52-large-constant-overflow-recovery.js: Added.
+        (foo):
+        * tests/stress/add-overflow-recovery.js: Added.
+        (foo):
+        * tests/stress/add-small-constant-overflow-recovery.js: Added.
+        (foo):
+
</ins><span class="cx"> 2014-01-08  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CStack: stack frame gets unaligned before call to operationVMHandleException
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -236,6 +236,10 @@
</span><span class="cx">                 0F4680D514BBD24B00BFE272 /* HostCallReturnValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F485321187750560083B687 /* DFGArithMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F48531F187750560083B687 /* DFGArithMode.cpp */; };
</span><span class="cx">                 0F485322187750560083B687 /* DFGArithMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485320187750560083B687 /* DFGArithMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F485323187DFDEC0083B687 /* FTLAvailableRecovery.cpp */; };
+                0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */; };
+                0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; };
</span><span class="cx">                 0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */; };
</span><span class="lines">@@ -1566,6 +1570,10 @@
</span><span class="cx">                 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HostCallReturnValue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F48531F187750560083B687 /* DFGArithMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArithMode.cpp; path = dfg/DFGArithMode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F485320187750560083B687 /* DFGArithMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArithMode.h; path = dfg/DFGArithMode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                0F485323187DFDEC0083B687 /* FTLAvailableRecovery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLAvailableRecovery.cpp; path = ftl/FTLAvailableRecovery.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLAvailableRecovery.h; path = ftl/FTLAvailableRecovery.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLRecoveryOpcode.cpp; path = ftl/FTLRecoveryOpcode.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLRecoveryOpcode.h; path = ftl/FTLRecoveryOpcode.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 0F5541AF1613C1FB00CE3E25 /* SpecialPointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpecialPointer.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -2864,6 +2872,8 @@
</span><span class="cx">                                 0FEA0A181708B00700BB722C /* FTLAbstractHeap.h */,
</span><span class="cx">                                 0FEA0A191708B00700BB722C /* FTLAbstractHeapRepository.cpp */,
</span><span class="cx">                                 0FEA0A1A1708B00700BB722C /* FTLAbstractHeapRepository.h */,
</span><ins>+                                0F485323187DFDEC0083B687 /* FTLAvailableRecovery.cpp */,
+                                0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */,
</ins><span class="cx">                                 0FEA09FE170513DB00BB722C /* FTLCapabilities.cpp */,
</span><span class="cx">                                 0FEA09FF170513DB00BB722C /* FTLCapabilities.h */,
</span><span class="cx">                                 0FEA0A251709623B00BB722C /* FTLCommonValues.cpp */,
</span><span class="lines">@@ -2912,6 +2922,8 @@
</span><span class="cx">                                 0F235BCA17178E1C00690C7F /* FTLOSRExitCompiler.h */,
</span><span class="cx">                                 0FEA0A291709629600BB722C /* FTLOutput.cpp */,
</span><span class="cx">                                 0FEA0A06170513DB00BB722C /* FTLOutput.h */,
</span><ins>+                                0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */,
+                                0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */,
</ins><span class="cx">                                 0F6B1CBF1862C47800845D97 /* FTLRegisterAtOffset.cpp */,
</span><span class="cx">                                 0F6B1CC01862C47800845D97 /* FTLRegisterAtOffset.h */,
</span><span class="cx">                                 0FCEFAA91804C13E00472CE4 /* FTLSaveRestore.cpp */,
</span><span class="lines">@@ -4419,6 +4431,7 @@
</span><span class="cx">                                 0F8364B7164B0C110053329A /* DFGBranchDirection.h in Headers */,
</span><span class="cx">                                 A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */,
</span><span class="cx">                                 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */,
</span><ins>+                                0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */,
</ins><span class="cx">                                 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */,
</span><span class="cx">                                 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
</span><span class="cx">                                 0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
</span><span class="lines">@@ -4551,6 +4564,7 @@
</span><span class="cx">                                 0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
</span><span class="cx">                                 A59455931824744700CC3843 /* JSGlobalObjectDebuggable.h in Headers */,
</span><span class="cx">                                 0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */,
</span><ins>+                                0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */,
</ins><span class="cx">                                 0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */,
</span><span class="cx">                                 0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */,
</span><span class="cx">                                 0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */,
</span><span class="lines">@@ -5565,6 +5579,7 @@
</span><span class="cx">                                 0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */,
</span><span class="cx">                                 0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */,
</span><span class="cx">                                 0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */,
</span><ins>+                                0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */,
</ins><span class="cx">                                 0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */,
</span><span class="cx">                                 0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */,
</span><span class="cx">                                 0FBE0F7616C1DB0F0082C5E8 /* DFGUnificationPhase.cpp in Sources */,
</span><span class="lines">@@ -5697,6 +5712,7 @@
</span><span class="cx">                                 14280875107EC13E0013E7B2 /* JSLock.cpp in Sources */,
</span><span class="cx">                                 C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */,
</span><span class="cx">                                 A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */,
</span><ins>+                                0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */,
</ins><span class="cx">                                 14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */,
</span><span class="cx">                                 A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */,
</span><span class="cx">                                 147F39D4107EC37600427A48 /* JSObject.cpp in Sources */,
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLAvailableRecoverycpp"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.cpp (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.cpp                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.cpp        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FTLAvailableRecovery.h&quot;
+
+#if ENABLE(FTL_JIT)
+
+namespace JSC { namespace FTL {
+
+void AvailableRecovery::dump(PrintStream&amp; out) const
+{
+    out.print(node(), &quot; =&gt; &quot;, opcode(), &quot;, &quot;, RawPointer(m_left), &quot;, &quot;, RawPointer(m_right), &quot;, &quot;, m_format);
+}
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLAvailableRecoveryh"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.h (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.h                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLAvailableRecovery.h        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLAvailableRecovery_h
+#define FTLAvailableRecovery_h
+
+#if ENABLE(FTL_JIT)
+
+#include &quot;DFGNode.h&quot;
+#include &quot;FTLAbbreviatedTypes.h&quot;
+#include &quot;FTLRecoveryOpcode.h&quot;
+#include &quot;FTLValueFormat.h&quot;
+
+namespace JSC { namespace FTL {
+
+class AvailableRecovery {
+public:
+    AvailableRecovery()
+        : m_node(0)
+        , m_format(InvalidValueFormat)
+        , m_opcode(AddRecovery)
+        , m_left(0)
+        , m_right(0)
+    {
+    }
+    
+    AvailableRecovery(DFG::Node* node, RecoveryOpcode opcode, LValue left, LValue right, ValueFormat format)
+        : m_node(node)
+        , m_format(format)
+        , m_opcode(opcode)
+        , m_left(left)
+        , m_right(right)
+    {
+    }
+    
+    DFG::Node* node() const { return m_node; }
+    ValueFormat format() const { return m_format; }
+    RecoveryOpcode opcode() const { return m_opcode; }
+    LValue left() const { return m_left; }
+    LValue right() const { return m_right; }
+    
+    void dump(PrintStream&amp;) const;
+    
+private:
+    DFG::Node* m_node;
+    ValueFormat m_format;
+    RecoveryOpcode m_opcode;
+    LValue m_left;
+    LValue m_right;
+};
+
+} } // namespace JSC::FTL
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLAvailableRecovery_h
+
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLExitValuecpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.cpp (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.cpp        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.cpp        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -59,6 +59,9 @@
</span><span class="cx">     case ExitValueInJSStackAsDouble:
</span><span class="cx">         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
</span><span class="cx">         return;
</span><ins>+    case ExitValueRecovery:
+        out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
+        return;
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLExitValueh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.h (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.h        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.h        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FTLExitArgument.h&quot;
</span><ins>+#include &quot;FTLRecoveryOpcode.h&quot;
</ins><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;VirtualRegister.h&quot;
</span><span class="cx"> #include &lt;wtf/PrintStream.h&gt;
</span><span class="lines">@@ -51,7 +52,8 @@
</span><span class="cx">     ExitValueInJSStack,
</span><span class="cx">     ExitValueInJSStackAsInt32,
</span><span class="cx">     ExitValueInJSStackAsInt52,
</span><del>-    ExitValueInJSStackAsDouble
</del><ins>+    ExitValueInJSStackAsDouble,
+    ExitValueRecovery
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class ExitValue {
</span><span class="lines">@@ -118,6 +120,17 @@
</span><span class="cx">         return result;
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
+    {
+        ExitValue result;
+        result.m_kind = ExitValueRecovery;
+        result.u.recovery.opcode = opcode;
+        result.u.recovery.leftArgument = leftArgument;
+        result.u.recovery.rightArgument = rightArgument;
+        result.u.recovery.format = format;
+        return result;
+    }
+    
</ins><span class="cx">     ExitValueKind kind() const { return m_kind; }
</span><span class="cx">     
</span><span class="cx">     bool isDead() const { return kind() == ExitValueDead; }
</span><span class="lines">@@ -135,6 +148,7 @@
</span><span class="cx">     }
</span><span class="cx">     bool isConstant() const { return kind() == ExitValueConstant; }
</span><span class="cx">     bool isArgument() const { return kind() == ExitValueArgument; }
</span><ins>+    bool isRecovery() const { return kind() == ExitValueRecovery; }
</ins><span class="cx">     
</span><span class="cx">     ExitArgument exitArgument() const
</span><span class="cx">     {
</span><span class="lines">@@ -142,6 +156,30 @@
</span><span class="cx">         return ExitArgument(u.argument);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    unsigned leftRecoveryArgument() const
+    {
+        ASSERT(isRecovery());
+        return u.recovery.leftArgument;
+    }
+    
+    unsigned rightRecoveryArgument() const
+    {
+        ASSERT(isRecovery());
+        return u.recovery.rightArgument;
+    }
+    
+    ValueFormat recoveryFormat() const
+    {
+        ASSERT(isRecovery());
+        return static_cast&lt;ValueFormat&gt;(u.recovery.format);
+    }
+    
+    RecoveryOpcode recoveryOpcode() const
+    {
+        ASSERT(isRecovery());
+        return static_cast&lt;RecoveryOpcode&gt;(u.recovery.opcode);
+    }
+    
</ins><span class="cx">     JSValue constant() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(isConstant());
</span><span class="lines">@@ -190,6 +228,9 @@
</span><span class="cx">             
</span><span class="cx">         case ExitValueInJSStackAsDouble:
</span><span class="cx">             return ValueFormatDouble;
</span><ins>+            
+        case ExitValueRecovery:
+            return recoveryFormat();
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -205,6 +246,12 @@
</span><span class="cx">         ExitArgumentRepresentation argument;
</span><span class="cx">         EncodedJSValue constant;
</span><span class="cx">         int virtualRegister;
</span><ins>+        struct {
+            uint16_t leftArgument;
+            uint16_t rightArgument;
+            uint16_t opcode;
+            uint16_t format;
+        } recovery;
</ins><span class="cx">     } u;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DFGAbstractInterpreterInlines.h&quot;
</span><span class="cx"> #include &quot;DFGInPlaceAbstractState.h&quot;
</span><span class="cx"> #include &quot;FTLAbstractHeapRepository.h&quot;
</span><ins>+#include &quot;FTLAvailableRecovery.h&quot;
</ins><span class="cx"> #include &quot;FTLForOSREntryJITCode.h&quot;
</span><span class="cx"> #include &quot;FTLFormattedValue.h&quot;
</span><span class="cx"> #include &quot;FTLInlineCacheSize.h&quot;
</span><span class="lines">@@ -256,6 +257,8 @@
</span><span class="cx">         if (verboseCompilationEnabled())
</span><span class="cx">             dataLog(&quot;Lowering &quot;, m_node, &quot;\n&quot;);
</span><span class="cx">         
</span><ins>+        m_availableRecoveries.resize(0);
+        
</ins><span class="cx">         bool shouldExecuteEffects = m_interpreter.startExecuting(m_node);
</span><span class="cx">         
</span><span class="cx">         switch (m_node-&gt;op()) {
</span><span class="lines">@@ -295,10 +298,8 @@
</span><span class="cx">             compileValueAdd();
</span><span class="cx">             break;
</span><span class="cx">         case ArithAdd:
</span><del>-            compileAddSub();
-            break;
</del><span class="cx">         case ArithSub:
</span><del>-            compileAddSub();
</del><ins>+            compileArithAddOrSub();
</ins><span class="cx">             break;
</span><span class="cx">         case ArithMul:
</span><span class="cx">             compileArithMul();
</span><span class="lines">@@ -808,7 +809,7 @@
</span><span class="cx">             lowJSValue(m_node-&gt;child1()), lowJSValue(m_node-&gt;child2())));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    void compileAddSub()
</del><ins>+    void compileArithAddOrSub()
</ins><span class="cx">     {
</span><span class="cx">         bool isSub =  m_node-&gt;op() == ArithSub;
</span><span class="cx">         switch (m_node-&gt;binaryUseKind()) {
</span><span class="lines">@@ -821,7 +822,37 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            LValue result = isSub ? m_out.subWithOverflow32(left, right) : m_out.addWithOverflow32(left, right);
</del><ins>+            LValue result;
+            if (!isSub) {
+                result = m_out.addWithOverflow32(left, right);
+                
+                if (doesKill(m_node-&gt;child2())) {
+                    addAvailableRecovery(
+                        m_node-&gt;child2(), SubRecovery,
+                        m_out.extractValue(result, 0), left, ValueFormatInt32);
+                } else if (doesKill(m_node-&gt;child1())) {
+                    addAvailableRecovery(
+                        m_node-&gt;child1(), SubRecovery,
+                        m_out.extractValue(result, 0), right, ValueFormatInt32);
+                }
+            } else {
+                result = m_out.subWithOverflow32(left, right);
+                
+                if (doesKill(m_node-&gt;child2())) {
+                    // result = left - right
+                    // result - left = -right
+                    // right = left - result
+                    addAvailableRecovery(
+                        m_node-&gt;child2(), SubRecovery,
+                        left, m_out.extractValue(result, 0), ValueFormatInt32);
+                } else if (doesKill(m_node-&gt;child1())) {
+                    // result = left - right
+                    // result + right = left
+                    addAvailableRecovery(
+                        m_node-&gt;child1(), AddRecovery,
+                        m_out.extractValue(result, 0), right, ValueFormatInt32);
+                }
+            }
</ins><span class="cx"> 
</span><span class="cx">             speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1));
</span><span class="cx">             setInt32(m_out.extractValue(result, 0));
</span><span class="lines">@@ -841,7 +872,38 @@
</span><span class="cx">             LValue left = lowInt52(m_node-&gt;child1());
</span><span class="cx">             LValue right = lowInt52(m_node-&gt;child2());
</span><span class="cx"> 
</span><del>-            LValue result = isSub ? m_out.subWithOverflow64(left, right) : m_out.addWithOverflow64(left, right);
</del><ins>+            LValue result;
+            if (!isSub) {
+                result = m_out.addWithOverflow64(left, right);
+                
+                if (doesKill(m_node-&gt;child2())) {
+                    addAvailableRecovery(
+                        m_node-&gt;child2(), SubRecovery,
+                        m_out.extractValue(result, 0), left, ValueFormatInt52);
+                } else if (doesKill(m_node-&gt;child1())) {
+                    addAvailableRecovery(
+                        m_node-&gt;child1(), SubRecovery,
+                        m_out.extractValue(result, 0), right, ValueFormatInt52);
+                }
+            } else {
+                result = m_out.subWithOverflow64(left, right);
+                
+                if (doesKill(m_node-&gt;child2())) {
+                    // result = left - right
+                    // result - left = -right
+                    // right = left - result
+                    addAvailableRecovery(
+                        m_node-&gt;child2(), SubRecovery,
+                        left, m_out.extractValue(result, 0), ValueFormatInt52);
+                } else if (doesKill(m_node-&gt;child1())) {
+                    // result = left - right
+                    // result + right = left
+                    addAvailableRecovery(
+                        m_node-&gt;child1(), AddRecovery,
+                        m_out.extractValue(result, 0), right, ValueFormatInt52);
+                }
+            }
+
</ins><span class="cx">             speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1));
</span><span class="cx">             setInt52(m_out.extractValue(result, 0));
</span><span class="cx">             break;
</span><span class="lines">@@ -4065,8 +4127,11 @@
</span><span class="cx">     void appendOSRExit(
</span><span class="cx">         ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
</span><span class="cx">     {
</span><del>-        if (verboseCompilationEnabled())
</del><ins>+        if (verboseCompilationEnabled()) {
</ins><span class="cx">             dataLog(&quot;    OSR exit #&quot;, m_ftlState.jitCode-&gt;osrExit.size(), &quot; with availability: &quot;, m_availability, &quot;\n&quot;);
</span><ins>+            if (!m_availableRecoveries.isEmpty())
+                dataLog(&quot;        Available recoveries: &quot;, listDump(m_availableRecoveries), &quot;\n&quot;);
+        }
</ins><span class="cx"> 
</span><span class="cx">         ASSERT(m_ftlState.jitCode-&gt;osrExit.size() == m_ftlState.finalizer-&gt;osrExit.size());
</span><span class="cx">         
</span><span class="lines">@@ -4191,6 +4256,19 @@
</span><span class="cx">         if (tryToSetConstantExitArgument(exit, index, node))
</span><span class="cx">             return;
</span><span class="cx">         
</span><ins>+        for (unsigned i = 0; i &lt; m_availableRecoveries.size(); ++i) {
+            AvailableRecovery recovery = m_availableRecoveries[i];
+            if (recovery.node() != node)
+                continue;
+            
+            exit.m_values[index] = ExitValue::recovery(
+                recovery.opcode(), arguments.size(), arguments.size() + 1,
+                recovery.format());
+            arguments.append(recovery.left());
+            arguments.append(recovery.right());
+            return;
+        }
+        
</ins><span class="cx">         LoweredNodeValue value = m_int32Values.get(node);
</span><span class="cx">         if (isValid(value)) {
</span><span class="cx">             addExitArgument(exit, arguments, index, ValueFormatInt32, value.value());
</span><span class="lines">@@ -4260,6 +4338,29 @@
</span><span class="cx">         arguments.append(value);
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    bool doesKill(Edge edge)
+    {
+        if (edge.doesNotKill())
+            return false;
+        
+        if (edge-&gt;hasConstant())
+            return false;
+        
+        return true;
+    }
+    
+    void addAvailableRecovery(
+        Node* node, RecoveryOpcode opcode, LValue left, LValue right, ValueFormat format)
+    {
+        m_availableRecoveries.append(AvailableRecovery(node, opcode, left, right, format));
+    }
+    
+    void addAvailableRecovery(
+        Edge edge, RecoveryOpcode opcode, LValue left, LValue right, ValueFormat format)
+    {
+        addAvailableRecovery(edge.node(), opcode, left, right, format);
+    }
+    
</ins><span class="cx">     void setInt32(Node* node, LValue value)
</span><span class="cx">     {
</span><span class="cx">         m_int32Values.set(node, LoweredNodeValue(value, m_highBlock));
</span><span class="lines">@@ -4423,6 +4524,8 @@
</span><span class="cx">     
</span><span class="cx">     Operands&lt;Availability&gt; m_availability;
</span><span class="cx">     
</span><ins>+    Vector&lt;AvailableRecovery, 3&gt; m_availableRecoveries;
+    
</ins><span class="cx">     InPlaceAbstractState m_state;
</span><span class="cx">     AbstractInterpreter&lt;InPlaceAbstractState&gt; m_interpreter;
</span><span class="cx">     BasicBlock* m_highBlock;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLOSRExitCompilercpp"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -134,6 +134,44 @@
</span><span class="cx">             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
</span><span class="cx">             break;
</span><span class="cx">             
</span><ins>+        case ExitValueRecovery:
+            record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
+                jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
+            record-&gt;locations[value.leftRecoveryArgument()].restoreInto(
+                jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT0);
+            switch (value.recoveryOpcode()) {
+            case AddRecovery:
+                switch (value.recoveryFormat()) {
+                case ValueFormatInt32:
+                    jit.add32(GPRInfo::regT1, GPRInfo::regT0);
+                    break;
+                case ValueFormatInt52:
+                    jit.add64(GPRInfo::regT1, GPRInfo::regT0);
+                    break;
+                default:
+                    RELEASE_ASSERT_NOT_REACHED();
+                    break;
+                }
+                break;
+            case SubRecovery:
+                switch (value.recoveryFormat()) {
+                case ValueFormatInt32:
+                    jit.sub32(GPRInfo::regT1, GPRInfo::regT0);
+                    break;
+                case ValueFormatInt52:
+                    jit.sub64(GPRInfo::regT1, GPRInfo::regT0);
+                    break;
+                default:
+                    RELEASE_ASSERT_NOT_REACHED();
+                    break;
+                }
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+                break;
+            }
+            break;
+            
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLRecoveryOpcodecpp"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.cpp (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.cpp                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.cpp        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FTLRecoveryOpcode.h&quot;
+
+#if ENABLE(FTL_JIT)
+
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace WTF {
+
+void printInternal(PrintStream&amp; out, JSC::FTL::RecoveryOpcode opcode)
+{
+    switch (opcode) {
+    case JSC::FTL::AddRecovery:
+        out.print(&quot;Add&quot;);
+        return;
+    case JSC::FTL::SubRecovery:
+        out.print(&quot;Sub&quot;);
+        return;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
+#endif // ENABLE(FTL_JIT)
+
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLRecoveryOpcodeh"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.h (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.h                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLRecoveryOpcode.h        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef FTLRecoveryOpcode_h
+#define FTLRecoveryOpcode_h
+
+#if ENABLE(FTL_JIT)
+
+namespace JSC { namespace FTL {
+
+enum RecoveryOpcode {
+    AddRecovery,
+    SubRecovery
+};
+
+} } // namespace JSC::FTL
+
+namespace WTF {
+
+class PrintStream;
+void printInternal(PrintStream&amp;, JSC::FTL::RecoveryOpcode);
+
+} // namespace WTF
+
+#endif // ENABLE(FTL_JIT)
+
+#endif // FTLRecoveryOpcode_h
+
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoreftlFTLStackMapsh"></a>
<div class="modfile"><h4>Modified: branches/jsCStack/Source/JavaScriptCore/ftl/FTLStackMaps.h (161542 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/ftl/FTLStackMaps.h        2014-01-09 04:01:48 UTC (rev 161542)
+++ branches/jsCStack/Source/JavaScriptCore/ftl/FTLStackMaps.h        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">         uint16_t dwarfRegNum; // Represented as a 12-bit int in the section.
</span><span class="cx">         int8_t size;
</span><span class="cx">         Kind kind;
</span><del>-        int16_t offset;
</del><ins>+        int32_t offset;
</ins><span class="cx">         
</span><span class="cx">         void parse(DataView*, unsigned&amp; offset);
</span><span class="cx">         void dump(PrintStream&amp; out) const;
</span></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressaddconstantoverflowrecoveryjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/add-constant-overflow-recovery.js (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/add-constant-overflow-recovery.js                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/add-constant-overflow-recovery.js        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a) {
+    return a.f + 2000000000;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo({f:1});
+    if (result != 2000000001)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo({f:2000000000});
+if (result != 4000000000)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressaddint52constantoverflowrecoveryjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-constant-overflow-recovery.js (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-constant-overflow-recovery.js                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-constant-overflow-recovery.js        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a) {
+    return a * 2097144 + 1073745920;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo(1073736383);
+    if (result != 2251780886936072)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo(1073745919);
+if (result != 2251800885301256)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressaddint52largeconstantoverflowrecoveryjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-large-constant-overflow-recovery.js (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-large-constant-overflow-recovery.js                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/add-int52-large-constant-overflow-recovery.js        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a) {
+    return a * 2097144 + 10000000000;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo(1073741151);
+    if (result != 2251799812372744)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo(1073741152);
+if (result != 2251799814469888)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressaddoverflowrecoveryjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/add-overflow-recovery.js (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/add-overflow-recovery.js                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/add-overflow-recovery.js        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a, b) {
+    return a.f + b.f;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo({f:1}, {f:2});
+    if (result != 3)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo({f:2000000000}, {f:2000000000});
+if (result != 4000000000)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre></div>
<a id="branchesjsCStackSourceJavaScriptCoretestsstressaddsmallconstantoverflowrecoveryjs"></a>
<div class="addfile"><h4>Added: branches/jsCStack/Source/JavaScriptCore/tests/stress/add-small-constant-overflow-recovery.js (0 => 161543)</h4>
<pre class="diff"><span>
<span class="info">--- branches/jsCStack/Source/JavaScriptCore/tests/stress/add-small-constant-overflow-recovery.js                                (rev 0)
+++ branches/jsCStack/Source/JavaScriptCore/tests/stress/add-small-constant-overflow-recovery.js        2014-01-09 04:11:59 UTC (rev 161543)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+function foo(a) {
+    return a.f + 1000;
+}
+
+noInline(foo);
+
+for (var i = 0; i &lt; 100000; ++i) {
+    var result = foo({f:1});
+    if (result != 1001)
+        throw &quot;Error: bad result: &quot; + result;
+}
+
+var result = foo({f:2147483148});
+if (result != 2147484148)
+    throw &quot;Error: bad result: &quot; + result;
</ins></span></pre>
</div>
</div>

</body>
</html>