<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>113986</bug_id>
          
          <creation_ts>2013-04-04 18:44:37 -0700</creation_ts>
          <short_desc>FTL should support PhantomArguments</short_desc>
          <delta_ts>2014-11-18 13:40:30 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          <dependson>126218</dependson>
          <blocked>112840</blocked>
          <everconfirmed>1</everconfirmed>
          <reporter name="Filip Pizlo">fpizlo</reporter>
          <assigned_to name="Filip Pizlo">fpizlo</assigned_to>
          <cc>barraclough</cc>
    
    <cc>commit-queue</cc>
    
    <cc>ggaren</cc>
    
    <cc>mark.lam</cc>
    
    <cc>mhahnenberg</cc>
    
    <cc>msaboff</cc>
    
    <cc>oliver</cc>
    
    <cc>sam</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>869505</commentid>
    <comment_count>0</comment_count>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2013-04-04 18:44:37 -0700</bug_when>
    <thetext>I&apos;ll do this after I do OSR.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>985733</commentid>
    <comment_count>1</comment_count>
      <attachid>225494</attachid>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2014-02-28 15:13:56 -0800</bug_when>
    <thetext>Created attachment 225494
work in progress</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>985739</commentid>
    <comment_count>2</comment_count>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2014-02-28 15:21:24 -0800</bug_when>
    <thetext>(In reply to comment #1)
&gt; Created an attachment (id=225494) [details]
&gt; work in progress

Shockingly, this appears to actually just work.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>985743</commentid>
    <comment_count>3</comment_count>
      <attachid>225498</attachid>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2014-02-28 15:23:36 -0800</bug_when>
    <thetext>Created attachment 225498
the patch</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>985750</commentid>
    <comment_count>4</comment_count>
    <who name="WebKit Commit Bot">commit-queue</who>
    <bug_when>2014-02-28 15:26:57 -0800</bug_when>
    <thetext>Attachment 225498 did not pass style-queue:


ERROR: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp:229:  Weird number of spaces at line-start.  Are you using a 4-space indent?  [whitespace/indent] [3]
ERROR: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp:230:  Weird number of spaces at line-start.  Are you using a 4-space indent?  [whitespace/indent] [3]
Total errors found: 2 in 10 files


If any of these errors are false positives, please file a bug against check-webkit-style.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>985952</commentid>
    <comment_count>5</comment_count>
    <who name="Filip Pizlo">fpizlo</who>
    <bug_when>2014-03-01 11:52:25 -0800</bug_when>
    <thetext>Landed in http://trac.webkit.org/changeset/164923</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1044148</commentid>
    <comment_count>6</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-10-25 19:19:52 -0700</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1044149</commentid>
    <comment_count>7</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-10-25 19:19:56 -0700</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1044150</commentid>
    <comment_count>8</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-10-25 19:20:00 -0700</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1047074</commentid>
    <comment_count>9</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-11-07 07:47:46 -0800</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1047075</commentid>
    <comment_count>10</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-11-07 07:47:50 -0800</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1047076</commentid>
    <comment_count>11</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-11-07 07:47:54 -0800</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1049576</commentid>
    <comment_count>12</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-11-18 13:40:21 -0800</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1049577</commentid>
    <comment_count>13</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-11-18 13:40:25 -0800</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1049578</commentid>
    <comment_count>14</comment_count>
      <attachid>225498</attachid>
    <who name="Whitehat Security">sentinel-4</who>
    <bug_when>2014-11-18 13:40:30 -0800</bug_when>
    <thetext>Comment on attachment 225498
the patch

&gt;Index: Source/JavaScriptCore/ChangeLog
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ChangeLog	(revision 164889)
&gt;+++ Source/JavaScriptCore/ChangeLog	(working copy)
&gt;@@ -1,3 +1,38 @@
&gt;+2014-02-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
&gt;+
&gt;+        FTL should support PhantomArguments
&gt;+        https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;+
&gt;+        Reviewed by NOBODY (OOPS!).
&gt;+        
&gt;+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
&gt;+        object into the FTL&apos;s OSR exit compiler.
&gt;+
&gt;+        * dfg/DFGOSRExitCompiler32_64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompiler64.cpp:
&gt;+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
&gt;+        * dfg/DFGOSRExitCompilerCommon.cpp:
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
&gt;+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
&gt;+        * dfg/DFGOSRExitCompilerCommon.h:
&gt;+        * ftl/FTLCapabilities.cpp:
&gt;+        (JSC::FTL::canCompile):
&gt;+        * ftl/FTLExitValue.cpp:
&gt;+        (JSC::FTL::ExitValue::dumpInContext):
&gt;+        * ftl/FTLExitValue.h:
&gt;+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
&gt;+        (JSC::FTL::ExitValue::valueFormat):
&gt;+        * ftl/FTLLowerDFGToLLVM.cpp:
&gt;+        (JSC::FTL::LowerDFGToLLVM::compileNode):
&gt;+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
&gt;+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
&gt;+        * ftl/FTLOSRExitCompiler.cpp:
&gt;+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
&gt;+
&gt; 2014-02-28  Oliver Hunt  &lt;oliver@apple.com&gt;
&gt; 
&gt;         REGRESSION(r164835): It broke 10 JSC stress test on 32 bit platforms
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -393,66 +393,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.setupArgumentsWithExecState(
&gt;-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                } else {
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                    m_jit.move(
&gt;-                        AssemblyHelpers::TrustedImmPtr(
&gt;-                            bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                        GPRInfo::nonArgGPR0);
&gt;-                }
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(argumentsRegister));
&gt;-                m_jit.store32(
&gt;-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.store32(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store32(
&gt;-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;-                AssemblyHelpers::tagFor(operand));
&gt;-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -365,50 +365,14 @@ void OSRExitCompiler::compileExit(const 
&gt;     //     registers.
&gt;     
&gt;     if (haveArguments) {
&gt;-        HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;-            NullableHashTraits&lt;InlineCallFrame*&gt;&gt; didCreateArgumentsObject;
&gt;+        ArgumentsRecoveryGenerator argumentsRecovery;
&gt; 
&gt;         for (size_t index = 0; index &lt; operands.size(); ++index) {
&gt;             const ValueRecovery&amp; recovery = operands[index];
&gt;             if (recovery.technique() != ArgumentsThatWereNotCreated)
&gt;                 continue;
&gt;-            int operand = operands.operandForIndex(index);
&gt;-            // Find the right inline call frame.
&gt;-            InlineCallFrame* inlineCallFrame = 0;
&gt;-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
&gt;-                 current;
&gt;-                 current = current-&gt;caller.inlineCallFrame) {
&gt;-                if (current-&gt;stackOffset &gt;= operand) {
&gt;-                    inlineCallFrame = current;
&gt;-                    break;
&gt;-                }
&gt;-            }
&gt;-
&gt;-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;-                continue;
&gt;-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;-                // We know this call frame optimized out an arguments object that
&gt;-                // the baseline JIT would have created. Do that creation now.
&gt;-                if (inlineCallFrame) {
&gt;-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;-                    m_jit.setupArguments(GPRInfo::regT0);
&gt;-                } else
&gt;-                    m_jit.setupArgumentsExecState();
&gt;-                m_jit.move(
&gt;-                    AssemblyHelpers::TrustedImmPtr(
&gt;-                        bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;-                    GPRInfo::nonArgGPR0);
&gt;-                m_jit.call(GPRInfo::nonArgGPR0);
&gt;-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;-                m_jit.store64(
&gt;-                    GPRInfo::returnValueGPR,
&gt;-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;-            }
&gt;-
&gt;-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+            argumentsRecovery.generateFor(
&gt;+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
&gt;         }
&gt;     }
&gt; 
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp	(working copy)
&gt;@@ -1,5 +1,5 @@
&gt; /*
&gt;- * Copyright (C) 2013 Apple Inc. All rights reserved.
&gt;+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
&gt;  *
&gt;  * Redistribution and use in source and binary forms, with or without
&gt;  * modification, are permitted provided that the following conditions
&gt;@@ -217,6 +217,89 @@ void adjustAndJumpToTarget(CCallHelpers&amp;
&gt;     jit.jump(GPRInfo::regT2);
&gt; }
&gt; 
&gt;+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
&gt;+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
&gt;+
&gt;+void ArgumentsRecoveryGenerator::generateFor(
&gt;+    int operand, CodeOrigin codeOrigin, CCallHelpers&amp; jit)
&gt;+{
&gt;+    // Find the right inline call frame.
&gt;+    InlineCallFrame* inlineCallFrame = 0;
&gt;+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
&gt;+         current;
&gt;+         current = current-&gt;caller.inlineCallFrame) {
&gt;+        if (current-&gt;stackOffset &gt;= operand) {
&gt;+            inlineCallFrame = current;
&gt;+            break;
&gt;+        }
&gt;+    }
&gt;+
&gt;+    if (!jit.baselineCodeBlockFor(inlineCallFrame)-&gt;usesArguments())
&gt;+        return;
&gt;+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
&gt;+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
&gt;+        // We know this call frame optimized out an arguments object that
&gt;+        // the baseline JIT would have created. Do that creation now.
&gt;+#if USE(JSVALUE64)
&gt;+        if (inlineCallFrame) {
&gt;+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame-&gt;stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
&gt;+            jit.setupArguments(GPRInfo::regT0);
&gt;+        } else
&gt;+            jit.setupArgumentsExecState();
&gt;+        jit.move(
&gt;+            AssemblyHelpers::TrustedImmPtr(
&gt;+                bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+            GPRInfo::nonArgGPR0);
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
&gt;+        jit.store64(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+        if (inlineCallFrame) {
&gt;+            jit.setupArgumentsWithExecState(
&gt;+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateInlinedArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        } else {
&gt;+            jit.setupArgumentsExecState();
&gt;+            jit.move(
&gt;+                AssemblyHelpers::TrustedImmPtr(
&gt;+                    bitwise_cast&lt;void*&gt;(operationCreateArguments)),
&gt;+                GPRInfo::nonArgGPR0);
&gt;+        }
&gt;+        jit.call(GPRInfo::nonArgGPR0);
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(argumentsRegister));
&gt;+        jit.store32(
&gt;+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.store32(
&gt;+            GPRInfo::returnValueGPR,
&gt;+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
&gt;+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
&gt;+#endif // USE(JSVALUE64)
&gt;+    }
&gt;+
&gt;+#if USE(JSVALUE64)
&gt;+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
&gt;+#else // USE(JSVALUE64) -&gt; so the 32_64 part
&gt;+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
&gt;+    jit.store32(
&gt;+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
&gt;+        AssemblyHelpers::tagFor(operand));
&gt;+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
&gt;+#endif // USE(JSVALUE64)
&gt;+}
&gt;+    
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.h	(working copy)
&gt;@@ -37,6 +37,18 @@ void handleExitCounts(CCallHelpers&amp;, con
&gt; void reifyInlinedCallFrames(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; void adjustAndJumpToTarget(CCallHelpers&amp;, const OSRExitBase&amp;);
&gt; 
&gt;+class ArgumentsRecoveryGenerator {
&gt;+public:
&gt;+    ArgumentsRecoveryGenerator();
&gt;+    ~ArgumentsRecoveryGenerator();
&gt;+    
&gt;+    void generateFor(int operand, CodeOrigin, CCallHelpers&amp;);
&gt;+    
&gt;+private:
&gt;+    HashSet&lt;InlineCallFrame*, DefaultHash&lt;InlineCallFrame*&gt;::Hash,
&gt;+        NullableHashTraits&lt;InlineCallFrame*&gt;&gt; m_didCreateArgumentsObject;
&gt;+};
&gt;+
&gt; } } // namespace JSC::DFG
&gt; 
&gt; #endif // ENABLE(DFG_JIT)
&gt;Index: Source/JavaScriptCore/ftl/FTLCapabilities.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLCapabilities.cpp	(working copy)
&gt;@@ -140,6 +140,7 @@ inline CapabilityLevel canCompile(Node* 
&gt;     case MultiGetByOffset:
&gt;     case MultiPutByOffset:
&gt;     case ToPrimitive:
&gt;+    case PhantomArguments:
&gt;         // These are OK.
&gt;         break;
&gt;     case PutByIdDirect:
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.cpp	(working copy)
&gt;@@ -59,6 +59,9 @@ void ExitValue::dumpInContext(PrintStrea
&gt;     case ExitValueInJSStackAsDouble:
&gt;         out.print(&quot;InJSStackAsDouble:r&quot;, virtualRegister());
&gt;         return;
&gt;+    case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+        out.print(&quot;ArgumentsObjectThatWasNotCreated&quot;);
&gt;+        return;
&gt;     case ExitValueRecovery:
&gt;         out.print(&quot;Recovery(&quot;, recoveryOpcode(), &quot;, arg&quot;, leftRecoveryArgument(), &quot;, arg&quot;, rightRecoveryArgument(), &quot;, &quot;, recoveryFormat(), &quot;)&quot;);
&gt;         return;
&gt;Index: Source/JavaScriptCore/ftl/FTLExitValue.h
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLExitValue.h	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLExitValue.h	(working copy)
&gt;@@ -51,6 +51,7 @@ enum ExitValueKind {
&gt;     ExitValueInJSStackAsInt32,
&gt;     ExitValueInJSStackAsInt52,
&gt;     ExitValueInJSStackAsDouble,
&gt;+    ExitValueArgumentsObjectThatWasNotCreated,
&gt;     ExitValueRecovery
&gt; };
&gt; 
&gt;@@ -118,6 +119,13 @@ public:
&gt;         return result;
&gt;     }
&gt;     
&gt;+    static ExitValue argumentsObjectThatWasNotCreated()
&gt;+    {
&gt;+        ExitValue result;
&gt;+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
&gt;+        return result;
&gt;+    }
&gt;+    
&gt;     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
&gt;     {
&gt;         ExitValue result;
&gt;@@ -146,6 +154,7 @@ public:
&gt;     }
&gt;     bool isConstant() const { return kind() == ExitValueConstant; }
&gt;     bool isArgument() const { return kind() == ExitValueArgument; }
&gt;+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
&gt;     bool isRecovery() const { return kind() == ExitValueRecovery; }
&gt;     
&gt;     ExitArgument exitArgument() const
&gt;@@ -213,6 +222,7 @@ public:
&gt;         case ExitValueDead:
&gt;         case ExitValueConstant:
&gt;         case ExitValueInJSStack:
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;             return ValueFormatJSValue;
&gt;             
&gt;         case ExitValueArgument:
&gt;Index: Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp	(working copy)
&gt;@@ -282,6 +282,9 @@ private:
&gt;         case WeakJSConstant:
&gt;             compileWeakJSConstant();
&gt;             break;
&gt;+        case PhantomArguments:
&gt;+            compilePhantomArguments();
&gt;+            break;
&gt;         case GetArgument:
&gt;             compileGetArgument();
&gt;             break;
&gt;@@ -781,6 +784,11 @@ private:
&gt;             break;
&gt;         }
&gt;     }
&gt;+
&gt;+    void compilePhantomArguments()
&gt;+    {
&gt;+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
&gt;+    }
&gt;     
&gt;     void compileWeakJSConstant()
&gt;     {
&gt;@@ -5519,9 +5527,7 @@ private:
&gt;                 break;
&gt;                 
&gt;             case FlushedArguments:
&gt;-                // FIXME: implement PhantomArguments.
&gt;-                // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-                RELEASE_ASSERT_NOT_REACHED();
&gt;+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;                 break;
&gt;             }
&gt;         }
&gt;@@ -5613,9 +5619,7 @@ private:
&gt;             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
&gt;             return true;
&gt;         case PhantomArguments:
&gt;-            // FIXME: implement PhantomArguments.
&gt;-            // https://bugs.webkit.org/show_bug.cgi?id=113986
&gt;-            RELEASE_ASSERT_NOT_REACHED();
&gt;+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
&gt;             return true;
&gt;         default:
&gt;             return false;
&gt;Index: Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
&gt;===================================================================
&gt;--- Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(revision 164883)
&gt;+++ Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp	(working copy)
&gt;@@ -146,6 +146,12 @@ static void compileStub(
&gt;             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
&gt;             break;
&gt;             
&gt;+        case ExitValueArgumentsObjectThatWasNotCreated:
&gt;+            // We can&apos;t actually recover this yet, but we can make the stack look sane. This is
&gt;+            // a prerequisite to running the actual arguments recovery.
&gt;+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
&gt;+            break;
&gt;+            
&gt;         case ExitValueRecovery:
&gt;             record-&gt;locations[value.rightRecoveryArgument()].restoreInto(
&gt;                 jit, jitCode-&gt;stackmaps, registerScratch, GPRInfo::regT1);
&gt;@@ -337,6 +343,15 @@ static void compileStub(
&gt;     
&gt;     handleExitCounts(jit, exit);
&gt;     reifyInlinedCallFrames(jit, exit);
&gt;+    
&gt;+    ArgumentsRecoveryGenerator argumentsRecovery;
&gt;+    for (unsigned index = exit.m_values.size(); index--;) {
&gt;+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
&gt;+            continue;
&gt;+        int operand = exit.m_values.operandForIndex(index);
&gt;+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
&gt;+    }
&gt;+    
&gt;     adjustAndJumpToTarget(jit, exit);
&gt;     
&gt;     LinkBuffer patchBuffer(*vm, &amp;jit, codeBlock);</thetext>
  </long_desc>
      
          <attachment
              isobsolete="1"
              ispatch="1"
              isprivate="0"
          >
            <attachid>225494</attachid>
            <date>2014-02-28 15:13:56 -0800</date>
            <delta_ts>2014-02-28 15:23:36 -0800</delta_ts>
            <desc>work in progress</desc>
            <filename>blah.patch</filename>
            <type>text/plain</type>
            <size>20630</size>
            <attacher name="Filip Pizlo">fpizlo</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9DaGFuZ2VMb2cKPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291
cmNlL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkocmV2aXNpb24gMTY0ODg5KQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDM3IEBA
CisyMDE0LTAyLTI4ICBGaWxpcCBQaXpsbyAgPGZwaXpsb0BhcHBsZS5jb20+CisKKyAgICAgICAg
RlRMIHNob3VsZCBzdXBwb3J0IFBoYW50b21Bcmd1bWVudHMKKyAgICAgICAgaHR0cHM6Ly9idWdz
LndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTExMzk4NgorCisgICAgICAgIFJldmlld2VkIGJ5
IE5PQk9EWSAoT09QUyEpLgorICAgICAgICAKKyAgICAgICAgV29yayBpbiBwcm9ncmVzcy4KKwor
ICAgICAgICAqIGRmZy9ERkdPU1JFeGl0Q29tcGlsZXIzMl82NC5jcHA6CisgICAgICAgIChKU0M6
OkRGRzo6T1NSRXhpdENvbXBpbGVyOjpjb21waWxlRXhpdCk6CisgICAgICAgICogZGZnL0RGR09T
UkV4aXRDb21waWxlcjY0LmNwcDoKKyAgICAgICAgKEpTQzo6REZHOjpPU1JFeGl0Q29tcGlsZXI6
OmNvbXBpbGVFeGl0KToKKyAgICAgICAgKiBkZmcvREZHT1NSRXhpdENvbXBpbGVyQ29tbW9uLmNw
cDoKKyAgICAgICAgKEpTQzo6REZHOjpBcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcjo6QXJndW1l
bnRzUmVjb3ZlcnlHZW5lcmF0b3IpOgorICAgICAgICAoSlNDOjpERkc6OkFyZ3VtZW50c1JlY292
ZXJ5R2VuZXJhdG9yOjp+QXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3IpOgorICAgICAgICAoSlND
OjpERkc6OkFyZ3VtZW50c1JlY292ZXJ5R2VuZXJhdG9yOjpnZW5lcmF0ZUZvcik6CisgICAgICAg
ICogZGZnL0RGR09TUkV4aXRDb21waWxlckNvbW1vbi5oOgorICAgICAgICAqIGZ0bC9GVExDYXBh
YmlsaXRpZXMuY3BwOgorICAgICAgICAoSlNDOjpGVEw6OmNhbkNvbXBpbGUpOgorICAgICAgICAq
IGZ0bC9GVExFeGl0VmFsdWUuY3BwOgorICAgICAgICAoSlNDOjpGVEw6OkV4aXRWYWx1ZTo6ZHVt
cEluQ29udGV4dCk6CisgICAgICAgICogZnRsL0ZUTEV4aXRWYWx1ZS5oOgorICAgICAgICAoSlND
OjpGVEw6OkV4aXRWYWx1ZTo6YXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQpOgorICAg
ICAgICAoSlNDOjpGVEw6OkV4aXRWYWx1ZTo6aXNBcmd1bWVudHNPYmplY3RUaGF0V2FzTm90Q3Jl
YXRlZCk6CisgICAgICAgIChKU0M6OkZUTDo6RXhpdFZhbHVlOjp2YWx1ZUZvcm1hdCk6CisgICAg
ICAgICogZnRsL0ZUTExvd2VyREZHVG9MTFZNLmNwcDoKKyAgICAgICAgKEpTQzo6RlRMOjpMb3dl
ckRGR1RvTExWTTo6Y29tcGlsZU5vZGUpOgorICAgICAgICAoSlNDOjpGVEw6Okxvd2VyREZHVG9M
TFZNOjpjb21waWxlUGhhbnRvbUFyZ3VtZW50cyk6CisgICAgICAgIChKU0M6OkZUTDo6TG93ZXJE
RkdUb0xMVk06OmJ1aWxkRXhpdEFyZ3VtZW50cyk6CisgICAgICAgIChKU0M6OkZUTDo6TG93ZXJE
RkdUb0xMVk06OnRyeVRvU2V0Q29uc3RhbnRFeGl0QXJndW1lbnQpOgorICAgICAgICAqIGZ0bC9G
VExPU1JFeGl0Q29tcGlsZXIuY3BwOgorICAgICAgICAoSlNDOjpGVEw6OmNvbXBpbGVTdHViKToK
KwogMjAxNC0wMi0yOCAgT2xpdmVyIEh1bnQgIDxvbGl2ZXJAYXBwbGUuY29tPgogCiAgICAgICAg
IFJFR1JFU1NJT04ocjE2NDgzNSk6IEl0IGJyb2tlIDEwIEpTQyBzdHJlc3MgdGVzdCBvbiAzMiBi
aXQgcGxhdGZvcm1zCkluZGV4OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRD
b21waWxlcjMyXzY0LmNwcAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZn
L0RGR09TUkV4aXRDb21waWxlcjMyXzY0LmNwcAkocmV2aXNpb24gMTY0ODgzKQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL2RmZy9ERkdPU1JFeGl0Q29tcGlsZXIzMl82NC5jcHAJKHdvcmtpbmcg
Y29weSkKQEAgLTEsNSArMSw1IEBACiAvKgotICogQ29weXJpZ2h0IChDKSAyMDExLCAyMDEzIEFw
cGxlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIENvcHlyaWdodCAoQykgMjAxMSwgMjAx
MywgMjAxNCBBcHBsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAgKgogICogUmVkaXN0cmli
dXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0
CiAgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93
aW5nIGNvbmRpdGlvbnMKQEAgLTM5Myw2NiArMzkzLDE0IEBAIHZvaWQgT1NSRXhpdENvbXBpbGVy
Ojpjb21waWxlRXhpdChjb25zdCAKICAgICAvLyAgICAgcmVnaXN0ZXJzLgogICAgIAogICAgIGlm
IChoYXZlQXJndW1lbnRzKSB7Ci0gICAgICAgIEhhc2hTZXQ8SW5saW5lQ2FsbEZyYW1lKiwgRGVm
YXVsdEhhc2g8SW5saW5lQ2FsbEZyYW1lKj46Okhhc2gsCi0gICAgICAgICAgICBOdWxsYWJsZUhh
c2hUcmFpdHM8SW5saW5lQ2FsbEZyYW1lKj4+IGRpZENyZWF0ZUFyZ3VtZW50c09iamVjdDsKKyAg
ICAgICAgQXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3IgYXJndW1lbnRzUmVjb3Zlcnk7CiAKICAg
ICAgICAgZm9yIChzaXplX3QgaW5kZXggPSAwOyBpbmRleCA8IG9wZXJhbmRzLnNpemUoKTsgKytp
bmRleCkgewogICAgICAgICAgICAgY29uc3QgVmFsdWVSZWNvdmVyeSYgcmVjb3ZlcnkgPSBvcGVy
YW5kc1tpbmRleF07CiAgICAgICAgICAgICBpZiAocmVjb3ZlcnkudGVjaG5pcXVlKCkgIT0gQXJn
dW1lbnRzVGhhdFdlcmVOb3RDcmVhdGVkKQogICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAg
ICAgICAgICAgaW50IG9wZXJhbmQgPSBvcGVyYW5kcy5vcGVyYW5kRm9ySW5kZXgoaW5kZXgpOwot
ICAgICAgICAgICAgLy8gRmluZCB0aGUgcmlnaHQgaW5saW5lIGNhbGwgZnJhbWUuCi0gICAgICAg
ICAgICBJbmxpbmVDYWxsRnJhbWUqIGlubGluZUNhbGxGcmFtZSA9IDA7Ci0gICAgICAgICAgICBm
b3IgKElubGluZUNhbGxGcmFtZSogY3VycmVudCA9IGV4aXQubV9jb2RlT3JpZ2luLmlubGluZUNh
bGxGcmFtZTsKLSAgICAgICAgICAgICAgICAgY3VycmVudDsKLSAgICAgICAgICAgICAgICAgY3Vy
cmVudCA9IGN1cnJlbnQtPmNhbGxlci5pbmxpbmVDYWxsRnJhbWUpIHsKLSAgICAgICAgICAgICAg
ICBpZiAoY3VycmVudC0+c3RhY2tPZmZzZXQgPj0gb3BlcmFuZCkgewotICAgICAgICAgICAgICAg
ICAgICBpbmxpbmVDYWxsRnJhbWUgPSBjdXJyZW50OwotICAgICAgICAgICAgICAgICAgICBicmVh
azsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICgh
bV9qaXQuYmFzZWxpbmVDb2RlQmxvY2tGb3IoaW5saW5lQ2FsbEZyYW1lKS0+dXNlc0FyZ3VtZW50
cygpKQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgVmlydHVhbFJlZ2lz
dGVyIGFyZ3VtZW50c1JlZ2lzdGVyID0gbV9qaXQuYmFzZWxpbmVBcmd1bWVudHNSZWdpc3RlckZv
cihpbmxpbmVDYWxsRnJhbWUpOwotICAgICAgICAgICAgaWYgKGRpZENyZWF0ZUFyZ3VtZW50c09i
amVjdC5hZGQoaW5saW5lQ2FsbEZyYW1lKS5pc05ld0VudHJ5KSB7Ci0gICAgICAgICAgICAgICAg
Ly8gV2Uga25vdyB0aGlzIGNhbGwgZnJhbWUgb3B0aW1pemVkIG91dCBhbiBhcmd1bWVudHMgb2Jq
ZWN0IHRoYXQKLSAgICAgICAgICAgICAgICAvLyB0aGUgYmFzZWxpbmUgSklUIHdvdWxkIGhhdmUg
Y3JlYXRlZC4gRG8gdGhhdCBjcmVhdGlvbiBub3cuCi0gICAgICAgICAgICAgICAgaWYgKGlubGlu
ZUNhbGxGcmFtZSkgewotICAgICAgICAgICAgICAgICAgICBtX2ppdC5zZXR1cEFyZ3VtZW50c1dp
dGhFeGVjU3RhdGUoCi0gICAgICAgICAgICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRy
dXN0ZWRJbW1QdHIoaW5saW5lQ2FsbEZyYW1lKSk7Ci0gICAgICAgICAgICAgICAgICAgIG1faml0
Lm1vdmUoCi0gICAgICAgICAgICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJ
bW1QdHIoCi0gICAgICAgICAgICAgICAgICAgICAgICAgICAgYml0d2lzZV9jYXN0PHZvaWQqPihv
cGVyYXRpb25DcmVhdGVJbmxpbmVkQXJndW1lbnRzKSksCi0gICAgICAgICAgICAgICAgICAgICAg
ICBHUFJJbmZvOjpub25BcmdHUFIwKTsKLSAgICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAg
ICAgICAgICAgICAgICBtX2ppdC5zZXR1cEFyZ3VtZW50c0V4ZWNTdGF0ZSgpOwotICAgICAgICAg
ICAgICAgICAgICBtX2ppdC5tb3ZlKAotICAgICAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlI
ZWxwZXJzOjpUcnVzdGVkSW1tUHRyKAotICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpdHdp
c2VfY2FzdDx2b2lkKj4ob3BlcmF0aW9uQ3JlYXRlQXJndW1lbnRzKSksCi0gICAgICAgICAgICAg
ICAgICAgICAgICBHUFJJbmZvOjpub25BcmdHUFIwKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAg
ICAgICAgICAgICAgbV9qaXQuY2FsbChHUFJJbmZvOjpub25BcmdHUFIwKTsKLSAgICAgICAgICAg
ICAgICBtX2ppdC5zdG9yZTMyKAotICAgICAgICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6
OlRydXN0ZWRJbW0zMihKU1ZhbHVlOjpDZWxsVGFnKSwKLSAgICAgICAgICAgICAgICAgICAgQXNz
ZW1ibHlIZWxwZXJzOjp0YWdGb3IoYXJndW1lbnRzUmVnaXN0ZXIpKTsKLSAgICAgICAgICAgICAg
ICBtX2ppdC5zdG9yZTMyKAotICAgICAgICAgICAgICAgICAgICBHUFJJbmZvOjpyZXR1cm5WYWx1
ZUdQUiwKLSAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpwYXlsb2FkRm9yKGFy
Z3VtZW50c1JlZ2lzdGVyKSk7Ci0gICAgICAgICAgICAgICAgbV9qaXQuc3RvcmUzMigKLSAgICAg
ICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tMzIoSlNWYWx1ZTo6Q2Vs
bFRhZyksCi0gICAgICAgICAgICAgICAgICAgIEFzc2VtYmx5SGVscGVyczo6dGFnRm9yKHVubW9k
aWZpZWRBcmd1bWVudHNSZWdpc3Rlcihhcmd1bWVudHNSZWdpc3RlcikpKTsKLSAgICAgICAgICAg
ICAgICBtX2ppdC5zdG9yZTMyKAotICAgICAgICAgICAgICAgICAgICBHUFJJbmZvOjpyZXR1cm5W
YWx1ZUdQUiwKLSAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpwYXlsb2FkRm9y
KHVubW9kaWZpZWRBcmd1bWVudHNSZWdpc3Rlcihhcmd1bWVudHNSZWdpc3RlcikpKTsKLSAgICAg
ICAgICAgICAgICBtX2ppdC5tb3ZlKEdQUkluZm86OnJldHVyblZhbHVlR1BSLCBHUFJJbmZvOjpy
ZWdUMCk7IC8vIG5vLW9wIG1vdmUgb24gYWxtb3N0IGFsbCBwbGF0Zm9ybXMuCi0gICAgICAgICAg
ICB9Ci0KLSAgICAgICAgICAgIG1faml0LmxvYWQzMihBc3NlbWJseUhlbHBlcnM6OnBheWxvYWRG
b3IoYXJndW1lbnRzUmVnaXN0ZXIpLCBHUFJJbmZvOjpyZWdUMCk7Ci0gICAgICAgICAgICBtX2pp
dC5zdG9yZTMyKAotICAgICAgICAgICAgICAgIEFzc2VtYmx5SGVscGVyczo6VHJ1c3RlZEltbTMy
KEpTVmFsdWU6OkNlbGxUYWcpLAotICAgICAgICAgICAgICAgIEFzc2VtYmx5SGVscGVyczo6dGFn
Rm9yKG9wZXJhbmQpKTsKLSAgICAgICAgICAgIG1faml0LnN0b3JlMzIoR1BSSW5mbzo6cmVnVDAs
IEFzc2VtYmx5SGVscGVyczo6cGF5bG9hZEZvcihvcGVyYW5kKSk7CisgICAgICAgICAgICBhcmd1
bWVudHNSZWNvdmVyeS5nZW5lcmF0ZUZvcigKKyAgICAgICAgICAgICAgICBvcGVyYW5kcy5vcGVy
YW5kRm9ySW5kZXgoaW5kZXgpLCBleGl0Lm1fY29kZU9yaWdpbiwgbV9qaXQpOwogICAgICAgICB9
CiAgICAgfQogCkluZGV4OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21w
aWxlcjY0LmNwcAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09T
UkV4aXRDb21waWxlcjY0LmNwcAkocmV2aXNpb24gMTY0ODgzKQorKysgU291cmNlL0phdmFTY3Jp
cHRDb3JlL2RmZy9ERkdPU1JFeGl0Q29tcGlsZXI2NC5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTEs
NSArMSw1IEBACiAvKgotICogQ29weXJpZ2h0IChDKSAyMDExLCAyMDEzIEFwcGxlIEluYy4gQWxs
IHJpZ2h0cyByZXNlcnZlZC4KKyAqIENvcHlyaWdodCAoQykgMjAxMSwgMjAxMywgMjAxNCBBcHBs
ZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAgKgogICogUmVkaXN0cmlidXRpb24gYW5kIHVz
ZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAgKiBtb2RpZmlj
YXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlv
bnMKQEAgLTM2NSw1MCArMzY1LDE0IEBAIHZvaWQgT1NSRXhpdENvbXBpbGVyOjpjb21waWxlRXhp
dChjb25zdCAKICAgICAvLyAgICAgcmVnaXN0ZXJzLgogICAgIAogICAgIGlmIChoYXZlQXJndW1l
bnRzKSB7Ci0gICAgICAgIEhhc2hTZXQ8SW5saW5lQ2FsbEZyYW1lKiwgRGVmYXVsdEhhc2g8SW5s
aW5lQ2FsbEZyYW1lKj46Okhhc2gsCi0gICAgICAgICAgICBOdWxsYWJsZUhhc2hUcmFpdHM8SW5s
aW5lQ2FsbEZyYW1lKj4+IGRpZENyZWF0ZUFyZ3VtZW50c09iamVjdDsKKyAgICAgICAgQXJndW1l
bnRzUmVjb3ZlcnlHZW5lcmF0b3IgYXJndW1lbnRzUmVjb3Zlcnk7CiAKICAgICAgICAgZm9yIChz
aXplX3QgaW5kZXggPSAwOyBpbmRleCA8IG9wZXJhbmRzLnNpemUoKTsgKytpbmRleCkgewogICAg
ICAgICAgICAgY29uc3QgVmFsdWVSZWNvdmVyeSYgcmVjb3ZlcnkgPSBvcGVyYW5kc1tpbmRleF07
CiAgICAgICAgICAgICBpZiAocmVjb3ZlcnkudGVjaG5pcXVlKCkgIT0gQXJndW1lbnRzVGhhdFdl
cmVOb3RDcmVhdGVkKQogICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgaW50
IG9wZXJhbmQgPSBvcGVyYW5kcy5vcGVyYW5kRm9ySW5kZXgoaW5kZXgpOwotICAgICAgICAgICAg
Ly8gRmluZCB0aGUgcmlnaHQgaW5saW5lIGNhbGwgZnJhbWUuCi0gICAgICAgICAgICBJbmxpbmVD
YWxsRnJhbWUqIGlubGluZUNhbGxGcmFtZSA9IDA7Ci0gICAgICAgICAgICBmb3IgKElubGluZUNh
bGxGcmFtZSogY3VycmVudCA9IGV4aXQubV9jb2RlT3JpZ2luLmlubGluZUNhbGxGcmFtZTsKLSAg
ICAgICAgICAgICAgICAgY3VycmVudDsKLSAgICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJl
bnQtPmNhbGxlci5pbmxpbmVDYWxsRnJhbWUpIHsKLSAgICAgICAgICAgICAgICBpZiAoY3VycmVu
dC0+c3RhY2tPZmZzZXQgPj0gb3BlcmFuZCkgewotICAgICAgICAgICAgICAgICAgICBpbmxpbmVD
YWxsRnJhbWUgPSBjdXJyZW50OwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAg
ICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghbV9qaXQuYmFzZWxp
bmVDb2RlQmxvY2tGb3IoaW5saW5lQ2FsbEZyYW1lKS0+dXNlc0FyZ3VtZW50cygpKQotICAgICAg
ICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgVmlydHVhbFJlZ2lzdGVyIGFyZ3VtZW50
c1JlZ2lzdGVyID0gbV9qaXQuYmFzZWxpbmVBcmd1bWVudHNSZWdpc3RlckZvcihpbmxpbmVDYWxs
RnJhbWUpOwotICAgICAgICAgICAgaWYgKGRpZENyZWF0ZUFyZ3VtZW50c09iamVjdC5hZGQoaW5s
aW5lQ2FsbEZyYW1lKS5pc05ld0VudHJ5KSB7Ci0gICAgICAgICAgICAgICAgLy8gV2Uga25vdyB0
aGlzIGNhbGwgZnJhbWUgb3B0aW1pemVkIG91dCBhbiBhcmd1bWVudHMgb2JqZWN0IHRoYXQKLSAg
ICAgICAgICAgICAgICAvLyB0aGUgYmFzZWxpbmUgSklUIHdvdWxkIGhhdmUgY3JlYXRlZC4gRG8g
dGhhdCBjcmVhdGlvbiBub3cuCi0gICAgICAgICAgICAgICAgaWYgKGlubGluZUNhbGxGcmFtZSkg
ewotICAgICAgICAgICAgICAgICAgICBtX2ppdC5hZGRQdHIoQXNzZW1ibHlIZWxwZXJzOjpUcnVz
dGVkSW1tMzIoaW5saW5lQ2FsbEZyYW1lLT5zdGFja09mZnNldCAqIHNpemVvZihFbmNvZGVkSlNW
YWx1ZSkpLCBHUFJJbmZvOjpjYWxsRnJhbWVSZWdpc3RlciwgR1BSSW5mbzo6cmVnVDApOwotICAg
ICAgICAgICAgICAgICAgICBtX2ppdC5zZXR1cEFyZ3VtZW50cyhHUFJJbmZvOjpyZWdUMCk7Ci0g
ICAgICAgICAgICAgICAgfSBlbHNlCi0gICAgICAgICAgICAgICAgICAgIG1faml0LnNldHVwQXJn
dW1lbnRzRXhlY1N0YXRlKCk7Ci0gICAgICAgICAgICAgICAgbV9qaXQubW92ZSgKLSAgICAgICAg
ICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tUHRyKAotICAgICAgICAgICAg
ICAgICAgICAgICAgYml0d2lzZV9jYXN0PHZvaWQqPihvcGVyYXRpb25DcmVhdGVBcmd1bWVudHMp
KSwKLSAgICAgICAgICAgICAgICAgICAgR1BSSW5mbzo6bm9uQXJnR1BSMCk7Ci0gICAgICAgICAg
ICAgICAgbV9qaXQuY2FsbChHUFJJbmZvOjpub25BcmdHUFIwKTsKLSAgICAgICAgICAgICAgICBt
X2ppdC5zdG9yZTY0KEdQUkluZm86OnJldHVyblZhbHVlR1BSLCBBc3NlbWJseUhlbHBlcnM6OmFk
ZHJlc3NGb3IoYXJndW1lbnRzUmVnaXN0ZXIpKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5zdG9y
ZTY0KAotICAgICAgICAgICAgICAgICAgICBHUFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwKLSAgICAg
ICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjphZGRyZXNzRm9yKHVubW9kaWZpZWRBcmd1
bWVudHNSZWdpc3Rlcihhcmd1bWVudHNSZWdpc3RlcikpKTsKLSAgICAgICAgICAgICAgICBtX2pp
dC5tb3ZlKEdQUkluZm86OnJldHVyblZhbHVlR1BSLCBHUFJJbmZvOjpyZWdUMCk7IC8vIG5vLW9w
IG1vdmUgb24gYWxtb3N0IGFsbCBwbGF0Zm9ybXMuCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAg
ICAgIG1faml0LmxvYWQ2NChBc3NlbWJseUhlbHBlcnM6OmFkZHJlc3NGb3IoYXJndW1lbnRzUmVn
aXN0ZXIpLCBHUFJJbmZvOjpyZWdUMCk7Ci0gICAgICAgICAgICBtX2ppdC5zdG9yZTY0KEdQUklu
Zm86OnJlZ1QwLCBBc3NlbWJseUhlbHBlcnM6OmFkZHJlc3NGb3Iob3BlcmFuZCkpOworICAgICAg
ICAgICAgYXJndW1lbnRzUmVjb3ZlcnkuZ2VuZXJhdGVGb3IoCisgICAgICAgICAgICAgICAgb3Bl
cmFuZHMub3BlcmFuZEZvckluZGV4KGluZGV4KSwgZXhpdC5tX2NvZGVPcmlnaW4sIG1faml0KTsK
ICAgICAgICAgfQogICAgIH0KIApJbmRleDogU291cmNlL0phdmFTY3JpcHRDb3JlL2RmZy9ERkdP
U1JFeGl0Q29tcGlsZXJDb21tb24uY3BwCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFNvdXJjZS9KYXZhU2NyaXB0
Q29yZS9kZmcvREZHT1NSRXhpdENvbXBpbGVyQ29tbW9uLmNwcAkocmV2aXNpb24gMTY0ODgzKQor
KysgU291cmNlL0phdmFTY3JpcHRDb3JlL2RmZy9ERkdPU1JFeGl0Q29tcGlsZXJDb21tb24uY3Bw
CSh3b3JraW5nIGNvcHkpCkBAIC0xLDUgKzEsNSBAQAogLyoKLSAqIENvcHlyaWdodCAoQykgMjAx
MyBBcHBsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCisgKiBDb3B5cmlnaHQgKEMpIDIwMTMs
IDIwMTQgQXBwbGUgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogICoKICAqIFJlZGlzdHJpYnV0
aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAog
ICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2lu
ZyBjb25kaXRpb25zCkBAIC0yMTcsNiArMjE3LDg5IEBAIHZvaWQgYWRqdXN0QW5kSnVtcFRvVGFy
Z2V0KENDYWxsSGVscGVycyYKICAgICBqaXQuanVtcChHUFJJbmZvOjpyZWdUMik7CiB9CiAKK0Fy
Z3VtZW50c1JlY292ZXJ5R2VuZXJhdG9yOjpBcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcigpIHsg
fQorQXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3I6On5Bcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRv
cigpIHsgfQorCit2b2lkIEFyZ3VtZW50c1JlY292ZXJ5R2VuZXJhdG9yOjpnZW5lcmF0ZUZvcigK
KyAgICBpbnQgb3BlcmFuZCwgQ29kZU9yaWdpbiBjb2RlT3JpZ2luLCBDQ2FsbEhlbHBlcnMmIGpp
dCkKK3sKKyAgICAvLyBGaW5kIHRoZSByaWdodCBpbmxpbmUgY2FsbCBmcmFtZS4KKyAgICBJbmxp
bmVDYWxsRnJhbWUqIGlubGluZUNhbGxGcmFtZSA9IDA7CisgICAgZm9yIChJbmxpbmVDYWxsRnJh
bWUqIGN1cnJlbnQgPSBjb2RlT3JpZ2luLmlubGluZUNhbGxGcmFtZTsKKyAgICAgICAgIGN1cnJl
bnQ7CisgICAgICAgICBjdXJyZW50ID0gY3VycmVudC0+Y2FsbGVyLmlubGluZUNhbGxGcmFtZSkg
eworICAgICAgICBpZiAoY3VycmVudC0+c3RhY2tPZmZzZXQgPj0gb3BlcmFuZCkgeworICAgICAg
ICAgICAgaW5saW5lQ2FsbEZyYW1lID0gY3VycmVudDsKKyAgICAgICAgICAgIGJyZWFrOworICAg
ICAgICB9CisgICAgfQorCisgICAgaWYgKCFqaXQuYmFzZWxpbmVDb2RlQmxvY2tGb3IoaW5saW5l
Q2FsbEZyYW1lKS0+dXNlc0FyZ3VtZW50cygpKQorICAgICAgICByZXR1cm47CisgICAgVmlydHVh
bFJlZ2lzdGVyIGFyZ3VtZW50c1JlZ2lzdGVyID0gaml0LmJhc2VsaW5lQXJndW1lbnRzUmVnaXN0
ZXJGb3IoaW5saW5lQ2FsbEZyYW1lKTsKKyAgICBpZiAobV9kaWRDcmVhdGVBcmd1bWVudHNPYmpl
Y3QuYWRkKGlubGluZUNhbGxGcmFtZSkuaXNOZXdFbnRyeSkgeworICAgICAgICAvLyBXZSBrbm93
IHRoaXMgY2FsbCBmcmFtZSBvcHRpbWl6ZWQgb3V0IGFuIGFyZ3VtZW50cyBvYmplY3QgdGhhdAor
ICAgICAgICAvLyB0aGUgYmFzZWxpbmUgSklUIHdvdWxkIGhhdmUgY3JlYXRlZC4gRG8gdGhhdCBj
cmVhdGlvbiBub3cuCisjaWYgVVNFKEpTVkFMVUU2NCkKKyAgICAgICAgaWYgKGlubGluZUNhbGxG
cmFtZSkgeworICAgICAgICAgICAgaml0LmFkZFB0cihBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJ
bW0zMihpbmxpbmVDYWxsRnJhbWUtPnN0YWNrT2Zmc2V0ICogc2l6ZW9mKEVuY29kZWRKU1ZhbHVl
KSksIEdQUkluZm86OmNhbGxGcmFtZVJlZ2lzdGVyLCBHUFJJbmZvOjpyZWdUMCk7CisgICAgICAg
ICAgICBqaXQuc2V0dXBBcmd1bWVudHMoR1BSSW5mbzo6cmVnVDApOworICAgICAgICB9IGVsc2UK
KyAgICAgICAgICAgIGppdC5zZXR1cEFyZ3VtZW50c0V4ZWNTdGF0ZSgpOworICAgICAgICBqaXQu
bW92ZSgKKyAgICAgICAgICAgIEFzc2VtYmx5SGVscGVyczo6VHJ1c3RlZEltbVB0cigKKyAgICAg
ICAgICAgICAgICBiaXR3aXNlX2Nhc3Q8dm9pZCo+KG9wZXJhdGlvbkNyZWF0ZUFyZ3VtZW50cykp
LAorICAgICAgICAgICAgR1BSSW5mbzo6bm9uQXJnR1BSMCk7CisgICAgICAgIGppdC5jYWxsKEdQ
UkluZm86Om5vbkFyZ0dQUjApOworICAgICAgICBqaXQuc3RvcmU2NChHUFJJbmZvOjpyZXR1cm5W
YWx1ZUdQUiwgQXNzZW1ibHlIZWxwZXJzOjphZGRyZXNzRm9yKGFyZ3VtZW50c1JlZ2lzdGVyKSk7
CisgICAgICAgIGppdC5zdG9yZTY0KAorICAgICAgICAgICAgR1BSSW5mbzo6cmV0dXJuVmFsdWVH
UFIsCisgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OmFkZHJlc3NGb3IodW5tb2RpZmllZEFy
Z3VtZW50c1JlZ2lzdGVyKGFyZ3VtZW50c1JlZ2lzdGVyKSkpOworICAgICAgICBqaXQubW92ZShH
UFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwgR1BSSW5mbzo6cmVnVDApOyAvLyBuby1vcCBtb3ZlIG9u
IGFsbW9zdCBhbGwgcGxhdGZvcm1zLgorI2Vsc2UgLy8gVVNFKEpTVkFMVUU2NCkgLT4gc28gdGhl
IDMyXzY0IHBhcnQKKyAgICAgICAgaWYgKGlubGluZUNhbGxGcmFtZSkgeworICAgICAgICAgICAg
aml0LnNldHVwQXJndW1lbnRzV2l0aEV4ZWNTdGF0ZSgKKyAgICAgICAgICAgICAgICBBc3NlbWJs
eUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIoaW5saW5lQ2FsbEZyYW1lKSk7CisgICAgICAgICAgICBq
aXQubW92ZSgKKyAgICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIo
CisgICAgICAgICAgICAgICAgICAgIGJpdHdpc2VfY2FzdDx2b2lkKj4ob3BlcmF0aW9uQ3JlYXRl
SW5saW5lZEFyZ3VtZW50cykpLAorICAgICAgICAgICAgICAgIEdQUkluZm86Om5vbkFyZ0dQUjAp
OworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaml0LnNldHVwQXJndW1lbnRzRXhlY1N0
YXRlKCk7CisgICAgICAgICAgICBqaXQubW92ZSgKKyAgICAgICAgICAgICAgICBBc3NlbWJseUhl
bHBlcnM6OlRydXN0ZWRJbW1QdHIoCisgICAgICAgICAgICAgICAgICAgIGJpdHdpc2VfY2FzdDx2
b2lkKj4ob3BlcmF0aW9uQ3JlYXRlQXJndW1lbnRzKSksCisgICAgICAgICAgICAgICAgR1BSSW5m
bzo6bm9uQXJnR1BSMCk7CisgICAgICAgIH0KKyAgICAgICAgaml0LmNhbGwoR1BSSW5mbzo6bm9u
QXJnR1BSMCk7CisgICAgICAgIGppdC5zdG9yZTMyKAorICAgICAgICAgICAgQXNzZW1ibHlIZWxw
ZXJzOjpUcnVzdGVkSW1tMzIoSlNWYWx1ZTo6Q2VsbFRhZyksCisgICAgICAgICAgICBBc3NlbWJs
eUhlbHBlcnM6OnRhZ0Zvcihhcmd1bWVudHNSZWdpc3RlcikpOworICAgICAgICBqaXQuc3RvcmUz
MigKKyAgICAgICAgICAgIEdQUkluZm86OnJldHVyblZhbHVlR1BSLAorICAgICAgICAgICAgQXNz
ZW1ibHlIZWxwZXJzOjpwYXlsb2FkRm9yKGFyZ3VtZW50c1JlZ2lzdGVyKSk7CisgICAgICAgIGpp
dC5zdG9yZTMyKAorICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tMzIoSlNW
YWx1ZTo6Q2VsbFRhZyksCisgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OnRhZ0Zvcih1bm1v
ZGlmaWVkQXJndW1lbnRzUmVnaXN0ZXIoYXJndW1lbnRzUmVnaXN0ZXIpKSk7CisgICAgICAgIGpp
dC5zdG9yZTMyKAorICAgICAgICAgICAgR1BSSW5mbzo6cmV0dXJuVmFsdWVHUFIsCisgICAgICAg
ICAgICBBc3NlbWJseUhlbHBlcnM6OnBheWxvYWRGb3IodW5tb2RpZmllZEFyZ3VtZW50c1JlZ2lz
dGVyKGFyZ3VtZW50c1JlZ2lzdGVyKSkpOworICAgICAgICBqaXQubW92ZShHUFJJbmZvOjpyZXR1
cm5WYWx1ZUdQUiwgR1BSSW5mbzo6cmVnVDApOyAvLyBuby1vcCBtb3ZlIG9uIGFsbW9zdCBhbGwg
cGxhdGZvcm1zLgorI2VuZGlmIC8vIFVTRShKU1ZBTFVFNjQpCisgICAgfQorCisjaWYgVVNFKEpT
VkFMVUU2NCkKKyAgICBqaXQubG9hZDY0KEFzc2VtYmx5SGVscGVyczo6YWRkcmVzc0Zvcihhcmd1
bWVudHNSZWdpc3RlciksIEdQUkluZm86OnJlZ1QwKTsKKyAgICBqaXQuc3RvcmU2NChHUFJJbmZv
OjpyZWdUMCwgQXNzZW1ibHlIZWxwZXJzOjphZGRyZXNzRm9yKG9wZXJhbmQpKTsKKyNlbHNlIC8v
IFVTRShKU1ZBTFVFNjQpIC0+IHNvIHRoZSAzMl82NCBwYXJ0CisgICAgaml0LmxvYWQzMihBc3Nl
bWJseUhlbHBlcnM6OnBheWxvYWRGb3IoYXJndW1lbnRzUmVnaXN0ZXIpLCBHUFJJbmZvOjpyZWdU
MCk7CisgICAgaml0LnN0b3JlMzIoCisgICAgICAgIEFzc2VtYmx5SGVscGVyczo6VHJ1c3RlZElt
bTMyKEpTVmFsdWU6OkNlbGxUYWcpLAorICAgICAgICBBc3NlbWJseUhlbHBlcnM6OnRhZ0Zvcihv
cGVyYW5kKSk7CisgICAgaml0LnN0b3JlMzIoR1BSSW5mbzo6cmVnVDAsIEFzc2VtYmx5SGVscGVy
czo6cGF5bG9hZEZvcihvcGVyYW5kKSk7CisjZW5kaWYgLy8gVVNFKEpTVkFMVUU2NCkKK30KKyAg
ICAKIH0gfSAvLyBuYW1lc3BhY2UgSlNDOjpERkcKIAogI2VuZGlmIC8vIEVOQUJMRShERkdfSklU
KQpJbmRleDogU291cmNlL0phdmFTY3JpcHRDb3JlL2RmZy9ERkdPU1JFeGl0Q29tcGlsZXJDb21t
b24uaAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRD
b21waWxlckNvbW1vbi5oCShyZXZpc2lvbiAxNjQ4ODMpCisrKyBTb3VyY2UvSmF2YVNjcmlwdENv
cmUvZGZnL0RGR09TUkV4aXRDb21waWxlckNvbW1vbi5oCSh3b3JraW5nIGNvcHkpCkBAIC0zNyw2
ICszNywxOCBAQCB2b2lkIGhhbmRsZUV4aXRDb3VudHMoQ0NhbGxIZWxwZXJzJiwgY29uCiB2b2lk
IHJlaWZ5SW5saW5lZENhbGxGcmFtZXMoQ0NhbGxIZWxwZXJzJiwgY29uc3QgT1NSRXhpdEJhc2Um
KTsKIHZvaWQgYWRqdXN0QW5kSnVtcFRvVGFyZ2V0KENDYWxsSGVscGVycyYsIGNvbnN0IE9TUkV4
aXRCYXNlJik7CiAKK2NsYXNzIEFyZ3VtZW50c1JlY292ZXJ5R2VuZXJhdG9yIHsKK3B1YmxpYzoK
KyAgICBBcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcigpOworICAgIH5Bcmd1bWVudHNSZWNvdmVy
eUdlbmVyYXRvcigpOworICAgIAorICAgIHZvaWQgZ2VuZXJhdGVGb3IoaW50IG9wZXJhbmQsIENv
ZGVPcmlnaW4sIENDYWxsSGVscGVycyYpOworICAgIAorcHJpdmF0ZToKKyAgICBIYXNoU2V0PElu
bGluZUNhbGxGcmFtZSosIERlZmF1bHRIYXNoPElubGluZUNhbGxGcmFtZSo+OjpIYXNoLAorICAg
ICAgICBOdWxsYWJsZUhhc2hUcmFpdHM8SW5saW5lQ2FsbEZyYW1lKj4+IG1fZGlkQ3JlYXRlQXJn
dW1lbnRzT2JqZWN0OworfTsKKwogfSB9IC8vIG5hbWVzcGFjZSBKU0M6OkRGRwogCiAjZW5kaWYg
Ly8gRU5BQkxFKERGR19KSVQpCkluZGV4OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZnRsL0ZUTENh
cGFiaWxpdGllcy5jcHAKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9G
VExDYXBhYmlsaXRpZXMuY3BwCShyZXZpc2lvbiAxNjQ4ODMpCisrKyBTb3VyY2UvSmF2YVNjcmlw
dENvcmUvZnRsL0ZUTENhcGFiaWxpdGllcy5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTE0MCw2ICsx
NDAsNyBAQCBpbmxpbmUgQ2FwYWJpbGl0eUxldmVsIGNhbkNvbXBpbGUoTm9kZSogCiAgICAgY2Fz
ZSBNdWx0aUdldEJ5T2Zmc2V0OgogICAgIGNhc2UgTXVsdGlQdXRCeU9mZnNldDoKICAgICBjYXNl
IFRvUHJpbWl0aXZlOgorICAgIGNhc2UgUGhhbnRvbUFyZ3VtZW50czoKICAgICAgICAgLy8gVGhl
c2UgYXJlIE9LLgogICAgICAgICBicmVhazsKICAgICBjYXNlIFB1dEJ5SWREaXJlY3Q6CkluZGV4
OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZnRsL0ZUTEV4aXRWYWx1ZS5jcHAKPT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQot
LS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExFeGl0VmFsdWUuY3BwCShyZXZpc2lvbiAx
NjQ4ODMpCisrKyBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZnRsL0ZUTEV4aXRWYWx1ZS5jcHAJKHdv
cmtpbmcgY29weSkKQEAgLTU5LDYgKzU5LDkgQEAgdm9pZCBFeGl0VmFsdWU6OmR1bXBJbkNvbnRl
eHQoUHJpbnRTdHJlYQogICAgIGNhc2UgRXhpdFZhbHVlSW5KU1N0YWNrQXNEb3VibGU6CiAgICAg
ICAgIG91dC5wcmludCgiSW5KU1N0YWNrQXNEb3VibGU6ciIsIHZpcnR1YWxSZWdpc3RlcigpKTsK
ICAgICAgICAgcmV0dXJuOworICAgIGNhc2UgRXhpdFZhbHVlQXJndW1lbnRzT2JqZWN0VGhhdFdh
c05vdENyZWF0ZWQ6CisgICAgICAgIG91dC5wcmludCgiQXJndW1lbnRzT2JqZWN0VGhhdFdhc05v
dENyZWF0ZWQiKTsKKyAgICAgICAgcmV0dXJuOwogICAgIGNhc2UgRXhpdFZhbHVlUmVjb3Zlcnk6
CiAgICAgICAgIG91dC5wcmludCgiUmVjb3ZlcnkoIiwgcmVjb3ZlcnlPcGNvZGUoKSwgIiwgYXJn
IiwgbGVmdFJlY292ZXJ5QXJndW1lbnQoKSwgIiwgYXJnIiwgcmlnaHRSZWNvdmVyeUFyZ3VtZW50
KCksICIsICIsIHJlY292ZXJ5Rm9ybWF0KCksICIpIik7CiAgICAgICAgIHJldHVybjsKSW5kZXg6
IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9mdGwvRlRMRXhpdFZhbHVlLmgKPT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0g
U291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExFeGl0VmFsdWUuaAkocmV2aXNpb24gMTY0ODgz
KQorKysgU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExFeGl0VmFsdWUuaAkod29ya2luZyBj
b3B5KQpAQCAtNTEsNiArNTEsNyBAQCBlbnVtIEV4aXRWYWx1ZUtpbmQgewogICAgIEV4aXRWYWx1
ZUluSlNTdGFja0FzSW50MzIsCiAgICAgRXhpdFZhbHVlSW5KU1N0YWNrQXNJbnQ1MiwKICAgICBF
eGl0VmFsdWVJbkpTU3RhY2tBc0RvdWJsZSwKKyAgICBFeGl0VmFsdWVBcmd1bWVudHNPYmplY3RU
aGF0V2FzTm90Q3JlYXRlZCwKICAgICBFeGl0VmFsdWVSZWNvdmVyeQogfTsKIApAQCAtMTE4LDYg
KzExOSwxMyBAQCBwdWJsaWM6CiAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgfQogICAgIAor
ICAgIHN0YXRpYyBFeGl0VmFsdWUgYXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQoKQor
ICAgIHsKKyAgICAgICAgRXhpdFZhbHVlIHJlc3VsdDsKKyAgICAgICAgcmVzdWx0Lm1fa2luZCA9
IEV4aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkOworICAgICAgICByZXR1
cm4gcmVzdWx0OworICAgIH0KKyAgICAKICAgICBzdGF0aWMgRXhpdFZhbHVlIHJlY292ZXJ5KFJl
Y292ZXJ5T3Bjb2RlIG9wY29kZSwgdW5zaWduZWQgbGVmdEFyZ3VtZW50LCB1bnNpZ25lZCByaWdo
dEFyZ3VtZW50LCBWYWx1ZUZvcm1hdCBmb3JtYXQpCiAgICAgewogICAgICAgICBFeGl0VmFsdWUg
cmVzdWx0OwpAQCAtMTQ2LDYgKzE1NCw3IEBAIHB1YmxpYzoKICAgICB9CiAgICAgYm9vbCBpc0Nv
bnN0YW50KCkgY29uc3QgeyByZXR1cm4ga2luZCgpID09IEV4aXRWYWx1ZUNvbnN0YW50OyB9CiAg
ICAgYm9vbCBpc0FyZ3VtZW50KCkgY29uc3QgeyByZXR1cm4ga2luZCgpID09IEV4aXRWYWx1ZUFy
Z3VtZW50OyB9CisgICAgYm9vbCBpc0FyZ3VtZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkKCkg
Y29uc3QgeyByZXR1cm4ga2luZCgpID09IEV4aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRoYXRXYXNO
b3RDcmVhdGVkOyB9CiAgICAgYm9vbCBpc1JlY292ZXJ5KCkgY29uc3QgeyByZXR1cm4ga2luZCgp
ID09IEV4aXRWYWx1ZVJlY292ZXJ5OyB9CiAgICAgCiAgICAgRXhpdEFyZ3VtZW50IGV4aXRBcmd1
bWVudCgpIGNvbnN0CkBAIC0yMTMsNiArMjIyLDcgQEAgcHVibGljOgogICAgICAgICBjYXNlIEV4
aXRWYWx1ZURlYWQ6CiAgICAgICAgIGNhc2UgRXhpdFZhbHVlQ29uc3RhbnQ6CiAgICAgICAgIGNh
c2UgRXhpdFZhbHVlSW5KU1N0YWNrOgorICAgICAgICBjYXNlIEV4aXRWYWx1ZUFyZ3VtZW50c09i
amVjdFRoYXRXYXNOb3RDcmVhdGVkOgogICAgICAgICAgICAgcmV0dXJuIFZhbHVlRm9ybWF0SlNW
YWx1ZTsKICAgICAgICAgICAgIAogICAgICAgICBjYXNlIEV4aXRWYWx1ZUFyZ3VtZW50OgpJbmRl
eDogU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExMb3dlckRGR1RvTExWTS5jcHAKPT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PQotLS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExMb3dlckRGR1RvTExWTS5jcHAJ
KHJldmlzaW9uIDE2NDg4MykKKysrIFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9mdGwvRlRMTG93ZXJE
RkdUb0xMVk0uY3BwCSh3b3JraW5nIGNvcHkpCkBAIC0yODIsNiArMjgyLDkgQEAgcHJpdmF0ZToK
ICAgICAgICAgY2FzZSBXZWFrSlNDb25zdGFudDoKICAgICAgICAgICAgIGNvbXBpbGVXZWFrSlND
b25zdGFudCgpOwogICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUGhhbnRvbUFyZ3Vt
ZW50czoKKyAgICAgICAgICAgIGNvbXBpbGVQaGFudG9tQXJndW1lbnRzKCk7CisgICAgICAgICAg
ICBicmVhazsKICAgICAgICAgY2FzZSBHZXRBcmd1bWVudDoKICAgICAgICAgICAgIGNvbXBpbGVH
ZXRBcmd1bWVudCgpOwogICAgICAgICAgICAgYnJlYWs7CkBAIC03ODEsNiArNzg0LDExIEBAIHBy
aXZhdGU6CiAgICAgICAgICAgICBicmVhazsKICAgICAgICAgfQogICAgIH0KKworICAgIHZvaWQg
Y29tcGlsZVBoYW50b21Bcmd1bWVudHMoKQorICAgIHsKKyAgICAgICAgc2V0SlNWYWx1ZShtX291
dC5jb25zdEludDY0KEpTVmFsdWU6OmVuY29kZShKU1ZhbHVlKCkpKSk7CisgICAgfQogICAgIAog
ICAgIHZvaWQgY29tcGlsZVdlYWtKU0NvbnN0YW50KCkKICAgICB7CkBAIC01NTE5LDkgKzU1Mjcs
NyBAQCBwcml2YXRlOgogICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIAog
ICAgICAgICAgICAgY2FzZSBGbHVzaGVkQXJndW1lbnRzOgotICAgICAgICAgICAgICAgIC8vIEZJ
WE1FOiBpbXBsZW1lbnQgUGhhbnRvbUFyZ3VtZW50cy4KLSAgICAgICAgICAgICAgICAvLyBodHRw
czovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTEzOTg2Ci0gICAgICAgICAgICAg
ICAgUkVMRUFTRV9BU1NFUlRfTk9UX1JFQUNIRUQoKTsKKyAgICAgICAgICAgICAgICBleGl0Lm1f
dmFsdWVzW2ldID0gRXhpdFZhbHVlOjphcmd1bWVudHNPYmplY3RUaGF0V2FzTm90Q3JlYXRlZCgp
OwogICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgfQogICAgICAgICB9CkBAIC01
NjEzLDkgKzU2MTksNyBAQCBwcml2YXRlOgogICAgICAgICAgICAgZXhpdC5tX3ZhbHVlc1tpbmRl
eF0gPSBFeGl0VmFsdWU6OmNvbnN0YW50KG1fZ3JhcGgudmFsdWVPZkpTQ29uc3RhbnQobm9kZSkp
OwogICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgIGNhc2UgUGhhbnRvbUFyZ3VtZW50
czoKLSAgICAgICAgICAgIC8vIEZJWE1FOiBpbXBsZW1lbnQgUGhhbnRvbUFyZ3VtZW50cy4KLSAg
ICAgICAgICAgIC8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMTM5
ODYKLSAgICAgICAgICAgIFJFTEVBU0VfQVNTRVJUX05PVF9SRUFDSEVEKCk7CisgICAgICAgICAg
ICBleGl0Lm1fdmFsdWVzW2luZGV4XSA9IEV4aXRWYWx1ZTo6YXJndW1lbnRzT2JqZWN0VGhhdFdh
c05vdENyZWF0ZWQoKTsKICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICBkZWZhdWx0
OgogICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwpJbmRleDogU291cmNlL0phdmFTY3JpcHRDb3Jl
L2Z0bC9GVExPU1JFeGl0Q29tcGlsZXIuY3BwCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIFNvdXJjZS9KYXZhU2Ny
aXB0Q29yZS9mdGwvRlRMT1NSRXhpdENvbXBpbGVyLmNwcAkocmV2aXNpb24gMTY0ODgzKQorKysg
U291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExPU1JFeGl0Q29tcGlsZXIuY3BwCSh3b3JraW5n
IGNvcHkpCkBAIC0xNDYsNiArMTQ2LDEyIEBAIHN0YXRpYyB2b2lkIGNvbXBpbGVTdHViKAogICAg
ICAgICAgICAgaml0LmxvYWQ2NChBc3NlbWJseUhlbHBlcnM6OmFkZHJlc3NGb3IodmFsdWUudmly
dHVhbFJlZ2lzdGVyKCkpLCBHUFJJbmZvOjpyZWdUMCk7CiAgICAgICAgICAgICBicmVhazsKICAg
ICAgICAgICAgIAorICAgICAgICBjYXNlIEV4aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRoYXRXYXNO
b3RDcmVhdGVkOgorICAgICAgICAgICAgLy8gV2UgY2FuJ3QgYWN0dWFsbHkgcmVjb3ZlciB0aGlz
IHlldCwgYnV0IHdlIGNhbiBtYWtlIHRoZSBzdGFjayBsb29rIHNhbmUuIFRoaXMgaXMKKyAgICAg
ICAgICAgIC8vIGEgcHJlcmVxdWlzaXRlIHRvIHJ1bm5pbmcgdGhlIGFjdHVhbCBhcmd1bWVudHMg
cmVjb3ZlcnkuCisgICAgICAgICAgICBqaXQubW92ZShNYWNyb0Fzc2VtYmxlcjo6VHJ1c3RlZElt
bTY0KEpTVmFsdWU6OmVuY29kZShKU1ZhbHVlKCkpKSwgR1BSSW5mbzo6cmVnVDApOworICAgICAg
ICAgICAgYnJlYWs7CisgICAgICAgICAgICAKICAgICAgICAgY2FzZSBFeGl0VmFsdWVSZWNvdmVy
eToKICAgICAgICAgICAgIHJlY29yZC0+bG9jYXRpb25zW3ZhbHVlLnJpZ2h0UmVjb3ZlcnlBcmd1
bWVudCgpXS5yZXN0b3JlSW50bygKICAgICAgICAgICAgICAgICBqaXQsIGppdENvZGUtPnN0YWNr
bWFwcywgcmVnaXN0ZXJTY3JhdGNoLCBHUFJJbmZvOjpyZWdUMSk7CkBAIC0zMzcsNiArMzQzLDE1
IEBAIHN0YXRpYyB2b2lkIGNvbXBpbGVTdHViKAogICAgIAogICAgIGhhbmRsZUV4aXRDb3VudHMo
aml0LCBleGl0KTsKICAgICByZWlmeUlubGluZWRDYWxsRnJhbWVzKGppdCwgZXhpdCk7CisgICAg
CisgICAgQXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3IgYXJndW1lbnRzUmVjb3Zlcnk7CisgICAg
Zm9yICh1bnNpZ25lZCBpbmRleCA9IGV4aXQubV92YWx1ZXMuc2l6ZSgpOyBpbmRleC0tOykgewor
ICAgICAgICBpZiAoIWV4aXQubV92YWx1ZXNbaW5kZXhdLmlzQXJndW1lbnRzT2JqZWN0VGhhdFdh
c05vdENyZWF0ZWQoKSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBpbnQgb3BlcmFu
ZCA9IGV4aXQubV92YWx1ZXMub3BlcmFuZEZvckluZGV4KGluZGV4KTsKKyAgICAgICAgYXJndW1l
bnRzUmVjb3ZlcnkuZ2VuZXJhdGVGb3Iob3BlcmFuZCwgZXhpdC5tX2NvZGVPcmlnaW4sIGppdCk7
CisgICAgfQorICAgIAogICAgIGFkanVzdEFuZEp1bXBUb1RhcmdldChqaXQsIGV4aXQpOwogICAg
IAogICAgIExpbmtCdWZmZXIgcGF0Y2hCdWZmZXIoKnZtLCAmaml0LCBjb2RlQmxvY2spOwo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>225498</attachid>
            <date>2014-02-28 15:23:36 -0800</date>
            <delta_ts>2014-03-01 10:06:49 -0800</delta_ts>
            <desc>the patch</desc>
            <filename>blah.patch</filename>
            <type>text/plain</type>
            <size>20945</size>
            <attacher name="Filip Pizlo">fpizlo</attacher>
            
              <data encoding="base64">SW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9DaGFuZ2VMb2cKPT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291
cmNlL0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkocmV2aXNpb24gMTY0ODg5KQorKysgU291cmNl
L0phdmFTY3JpcHRDb3JlL0NoYW5nZUxvZwkod29ya2luZyBjb3B5KQpAQCAtMSwzICsxLDM4IEBA
CisyMDE0LTAyLTI4ICBGaWxpcCBQaXpsbyAgPGZwaXpsb0BhcHBsZS5jb20+CisKKyAgICAgICAg
RlRMIHNob3VsZCBzdXBwb3J0IFBoYW50b21Bcmd1bWVudHMKKyAgICAgICAgaHR0cHM6Ly9idWdz
LndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTExMzk4NgorCisgICAgICAgIFJldmlld2VkIGJ5
IE5PQk9EWSAoT09QUyEpLgorICAgICAgICAKKyAgICAgICAgQWRkaW5nIFBoYW50b21Bcmd1bWVu
dHMgdG8gdGhlIEZUTCBtb3N0bHkgbWVhbnMgd2lyaW5nIHRoZSByZWNvdmVyeSBvZiB0aGUgQXJn
dW1lbnRzCisgICAgICAgIG9iamVjdCBpbnRvIHRoZSBGVEwncyBPU1IgZXhpdCBjb21waWxlci4K
KworICAgICAgICAqIGRmZy9ERkdPU1JFeGl0Q29tcGlsZXIzMl82NC5jcHA6CisgICAgICAgIChK
U0M6OkRGRzo6T1NSRXhpdENvbXBpbGVyOjpjb21waWxlRXhpdCk6IG1vdmUgdGhlIHJlY292ZXJ5
IGNvZGUgdG8gREZHT1NSRXhpdENvbXBpbGVyQ29tbW9uLmNwcAorICAgICAgICAqIGRmZy9ERkdP
U1JFeGl0Q29tcGlsZXI2NC5jcHA6CisgICAgICAgIChKU0M6OkRGRzo6T1NSRXhpdENvbXBpbGVy
Ojpjb21waWxlRXhpdCk6IG1vdmUgdGhlIHJlY292ZXJ5IGNvZGUgdG8gREZHT1NSRXhpdENvbXBp
bGVyQ29tbW9uLmNwcAorICAgICAgICAqIGRmZy9ERkdPU1JFeGl0Q29tcGlsZXJDb21tb24uY3Bw
OgorICAgICAgICAoSlNDOjpERkc6OkFyZ3VtZW50c1JlY292ZXJ5R2VuZXJhdG9yOjpBcmd1bWVu
dHNSZWNvdmVyeUdlbmVyYXRvcik6CisgICAgICAgIChKU0M6OkRGRzo6QXJndW1lbnRzUmVjb3Zl
cnlHZW5lcmF0b3I6On5Bcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcik6CisgICAgICAgIChKU0M6
OkRGRzo6QXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3I6OmdlbmVyYXRlRm9yKTogdGhpcyBpcyB0
aGUgY29tbW9uIHBsYWNlIGZvciB0aGUgcmVjb3ZlcnkgY29kZQorICAgICAgICAqIGRmZy9ERkdP
U1JFeGl0Q29tcGlsZXJDb21tb24uaDoKKyAgICAgICAgKiBmdGwvRlRMQ2FwYWJpbGl0aWVzLmNw
cDoKKyAgICAgICAgKEpTQzo6RlRMOjpjYW5Db21waWxlKToKKyAgICAgICAgKiBmdGwvRlRMRXhp
dFZhbHVlLmNwcDoKKyAgICAgICAgKEpTQzo6RlRMOjpFeGl0VmFsdWU6OmR1bXBJbkNvbnRleHQp
OgorICAgICAgICAqIGZ0bC9GVExFeGl0VmFsdWUuaDoKKyAgICAgICAgKEpTQzo6RlRMOjpFeGl0
VmFsdWU6OmFyZ3VtZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkKToKKyAgICAgICAgKEpTQzo6
RlRMOjpFeGl0VmFsdWU6OmlzQXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQpOgorICAg
ICAgICAoSlNDOjpGVEw6OkV4aXRWYWx1ZTo6dmFsdWVGb3JtYXQpOgorICAgICAgICAqIGZ0bC9G
VExMb3dlckRGR1RvTExWTS5jcHA6CisgICAgICAgIChKU0M6OkZUTDo6TG93ZXJERkdUb0xMVk06
OmNvbXBpbGVOb2RlKToKKyAgICAgICAgKEpTQzo6RlRMOjpMb3dlckRGR1RvTExWTTo6Y29tcGls
ZVBoYW50b21Bcmd1bWVudHMpOgorICAgICAgICAoSlNDOjpGVEw6Okxvd2VyREZHVG9MTFZNOjpi
dWlsZEV4aXRBcmd1bWVudHMpOgorICAgICAgICAoSlNDOjpGVEw6Okxvd2VyREZHVG9MTFZNOjp0
cnlUb1NldENvbnN0YW50RXhpdEFyZ3VtZW50KToKKyAgICAgICAgKiBmdGwvRlRMT1NSRXhpdENv
bXBpbGVyLmNwcDoKKyAgICAgICAgKEpTQzo6RlRMOjpjb21waWxlU3R1Yik6IENhbGwgaW50byB0
aGUgQXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3IKKwogMjAxNC0wMi0yOCAgT2xpdmVyIEh1bnQg
IDxvbGl2ZXJAYXBwbGUuY29tPgogCiAgICAgICAgIFJFR1JFU1NJT04ocjE2NDgzNSk6IEl0IGJy
b2tlIDEwIEpTQyBzdHJlc3MgdGVzdCBvbiAzMiBiaXQgcGxhdGZvcm1zCkluZGV4OiBTb3VyY2Uv
SmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21waWxlcjMyXzY0LmNwcAo9PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
Ci0tLSBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21waWxlcjMyXzY0LmNw
cAkocmV2aXNpb24gMTY0ODgzKQorKysgU291cmNlL0phdmFTY3JpcHRDb3JlL2RmZy9ERkdPU1JF
eGl0Q29tcGlsZXIzMl82NC5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTEsNSArMSw1IEBACiAvKgot
ICogQ29weXJpZ2h0IChDKSAyMDExLCAyMDEzIEFwcGxlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZl
ZC4KKyAqIENvcHlyaWdodCAoQykgMjAxMSwgMjAxMywgMjAxNCBBcHBsZSBJbmMuIEFsbCByaWdo
dHMgcmVzZXJ2ZWQuCiAgKgogICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5k
IGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJt
aXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKQEAgLTM5Myw2NiAr
MzkzLDE0IEBAIHZvaWQgT1NSRXhpdENvbXBpbGVyOjpjb21waWxlRXhpdChjb25zdCAKICAgICAv
LyAgICAgcmVnaXN0ZXJzLgogICAgIAogICAgIGlmIChoYXZlQXJndW1lbnRzKSB7Ci0gICAgICAg
IEhhc2hTZXQ8SW5saW5lQ2FsbEZyYW1lKiwgRGVmYXVsdEhhc2g8SW5saW5lQ2FsbEZyYW1lKj46
Okhhc2gsCi0gICAgICAgICAgICBOdWxsYWJsZUhhc2hUcmFpdHM8SW5saW5lQ2FsbEZyYW1lKj4+
IGRpZENyZWF0ZUFyZ3VtZW50c09iamVjdDsKKyAgICAgICAgQXJndW1lbnRzUmVjb3ZlcnlHZW5l
cmF0b3IgYXJndW1lbnRzUmVjb3Zlcnk7CiAKICAgICAgICAgZm9yIChzaXplX3QgaW5kZXggPSAw
OyBpbmRleCA8IG9wZXJhbmRzLnNpemUoKTsgKytpbmRleCkgewogICAgICAgICAgICAgY29uc3Qg
VmFsdWVSZWNvdmVyeSYgcmVjb3ZlcnkgPSBvcGVyYW5kc1tpbmRleF07CiAgICAgICAgICAgICBp
ZiAocmVjb3ZlcnkudGVjaG5pcXVlKCkgIT0gQXJndW1lbnRzVGhhdFdlcmVOb3RDcmVhdGVkKQog
ICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgaW50IG9wZXJhbmQgPSBvcGVy
YW5kcy5vcGVyYW5kRm9ySW5kZXgoaW5kZXgpOwotICAgICAgICAgICAgLy8gRmluZCB0aGUgcmln
aHQgaW5saW5lIGNhbGwgZnJhbWUuCi0gICAgICAgICAgICBJbmxpbmVDYWxsRnJhbWUqIGlubGlu
ZUNhbGxGcmFtZSA9IDA7Ci0gICAgICAgICAgICBmb3IgKElubGluZUNhbGxGcmFtZSogY3VycmVu
dCA9IGV4aXQubV9jb2RlT3JpZ2luLmlubGluZUNhbGxGcmFtZTsKLSAgICAgICAgICAgICAgICAg
Y3VycmVudDsKLSAgICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQtPmNhbGxlci5pbmxp
bmVDYWxsRnJhbWUpIHsKLSAgICAgICAgICAgICAgICBpZiAoY3VycmVudC0+c3RhY2tPZmZzZXQg
Pj0gb3BlcmFuZCkgewotICAgICAgICAgICAgICAgICAgICBpbmxpbmVDYWxsRnJhbWUgPSBjdXJy
ZW50OwotICAgICAgICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAg
ICAgICAgICB9Ci0KLSAgICAgICAgICAgIGlmICghbV9qaXQuYmFzZWxpbmVDb2RlQmxvY2tGb3Io
aW5saW5lQ2FsbEZyYW1lKS0+dXNlc0FyZ3VtZW50cygpKQotICAgICAgICAgICAgICAgIGNvbnRp
bnVlOwotICAgICAgICAgICAgVmlydHVhbFJlZ2lzdGVyIGFyZ3VtZW50c1JlZ2lzdGVyID0gbV9q
aXQuYmFzZWxpbmVBcmd1bWVudHNSZWdpc3RlckZvcihpbmxpbmVDYWxsRnJhbWUpOwotICAgICAg
ICAgICAgaWYgKGRpZENyZWF0ZUFyZ3VtZW50c09iamVjdC5hZGQoaW5saW5lQ2FsbEZyYW1lKS5p
c05ld0VudHJ5KSB7Ci0gICAgICAgICAgICAgICAgLy8gV2Uga25vdyB0aGlzIGNhbGwgZnJhbWUg
b3B0aW1pemVkIG91dCBhbiBhcmd1bWVudHMgb2JqZWN0IHRoYXQKLSAgICAgICAgICAgICAgICAv
LyB0aGUgYmFzZWxpbmUgSklUIHdvdWxkIGhhdmUgY3JlYXRlZC4gRG8gdGhhdCBjcmVhdGlvbiBu
b3cuCi0gICAgICAgICAgICAgICAgaWYgKGlubGluZUNhbGxGcmFtZSkgewotICAgICAgICAgICAg
ICAgICAgICBtX2ppdC5zZXR1cEFyZ3VtZW50c1dpdGhFeGVjU3RhdGUoCi0gICAgICAgICAgICAg
ICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIoaW5saW5lQ2FsbEZyYW1l
KSk7Ci0gICAgICAgICAgICAgICAgICAgIG1faml0Lm1vdmUoCi0gICAgICAgICAgICAgICAgICAg
ICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIoCi0gICAgICAgICAgICAgICAgICAg
ICAgICAgICAgYml0d2lzZV9jYXN0PHZvaWQqPihvcGVyYXRpb25DcmVhdGVJbmxpbmVkQXJndW1l
bnRzKSksCi0gICAgICAgICAgICAgICAgICAgICAgICBHUFJJbmZvOjpub25BcmdHUFIwKTsKLSAg
ICAgICAgICAgICAgICB9IGVsc2UgewotICAgICAgICAgICAgICAgICAgICBtX2ppdC5zZXR1cEFy
Z3VtZW50c0V4ZWNTdGF0ZSgpOwotICAgICAgICAgICAgICAgICAgICBtX2ppdC5tb3ZlKAotICAg
ICAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tUHRyKAotICAg
ICAgICAgICAgICAgICAgICAgICAgICAgIGJpdHdpc2VfY2FzdDx2b2lkKj4ob3BlcmF0aW9uQ3Jl
YXRlQXJndW1lbnRzKSksCi0gICAgICAgICAgICAgICAgICAgICAgICBHUFJJbmZvOjpub25BcmdH
UFIwKTsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICAgICAgbV9qaXQuY2FsbChHUFJJ
bmZvOjpub25BcmdHUFIwKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5zdG9yZTMyKAotICAgICAg
ICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW0zMihKU1ZhbHVlOjpDZWxs
VGFnKSwKLSAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjp0YWdGb3IoYXJndW1l
bnRzUmVnaXN0ZXIpKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5zdG9yZTMyKAotICAgICAgICAg
ICAgICAgICAgICBHUFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwKLSAgICAgICAgICAgICAgICAgICAg
QXNzZW1ibHlIZWxwZXJzOjpwYXlsb2FkRm9yKGFyZ3VtZW50c1JlZ2lzdGVyKSk7Ci0gICAgICAg
ICAgICAgICAgbV9qaXQuc3RvcmUzMigKLSAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxw
ZXJzOjpUcnVzdGVkSW1tMzIoSlNWYWx1ZTo6Q2VsbFRhZyksCi0gICAgICAgICAgICAgICAgICAg
IEFzc2VtYmx5SGVscGVyczo6dGFnRm9yKHVubW9kaWZpZWRBcmd1bWVudHNSZWdpc3Rlcihhcmd1
bWVudHNSZWdpc3RlcikpKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5zdG9yZTMyKAotICAgICAg
ICAgICAgICAgICAgICBHUFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwKLSAgICAgICAgICAgICAgICAg
ICAgQXNzZW1ibHlIZWxwZXJzOjpwYXlsb2FkRm9yKHVubW9kaWZpZWRBcmd1bWVudHNSZWdpc3Rl
cihhcmd1bWVudHNSZWdpc3RlcikpKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5tb3ZlKEdQUklu
Zm86OnJldHVyblZhbHVlR1BSLCBHUFJJbmZvOjpyZWdUMCk7IC8vIG5vLW9wIG1vdmUgb24gYWxt
b3N0IGFsbCBwbGF0Zm9ybXMuCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG1faml0Lmxv
YWQzMihBc3NlbWJseUhlbHBlcnM6OnBheWxvYWRGb3IoYXJndW1lbnRzUmVnaXN0ZXIpLCBHUFJJ
bmZvOjpyZWdUMCk7Ci0gICAgICAgICAgICBtX2ppdC5zdG9yZTMyKAotICAgICAgICAgICAgICAg
IEFzc2VtYmx5SGVscGVyczo6VHJ1c3RlZEltbTMyKEpTVmFsdWU6OkNlbGxUYWcpLAotICAgICAg
ICAgICAgICAgIEFzc2VtYmx5SGVscGVyczo6dGFnRm9yKG9wZXJhbmQpKTsKLSAgICAgICAgICAg
IG1faml0LnN0b3JlMzIoR1BSSW5mbzo6cmVnVDAsIEFzc2VtYmx5SGVscGVyczo6cGF5bG9hZEZv
cihvcGVyYW5kKSk7CisgICAgICAgICAgICBhcmd1bWVudHNSZWNvdmVyeS5nZW5lcmF0ZUZvcigK
KyAgICAgICAgICAgICAgICBvcGVyYW5kcy5vcGVyYW5kRm9ySW5kZXgoaW5kZXgpLCBleGl0Lm1f
Y29kZU9yaWdpbiwgbV9qaXQpOwogICAgICAgICB9CiAgICAgfQogCkluZGV4OiBTb3VyY2UvSmF2
YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21waWxlcjY0LmNwcAo9PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBT
b3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21waWxlcjY0LmNwcAkocmV2aXNp
b24gMTY0ODgzKQorKysgU291cmNlL0phdmFTY3JpcHRDb3JlL2RmZy9ERkdPU1JFeGl0Q29tcGls
ZXI2NC5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTEsNSArMSw1IEBACiAvKgotICogQ29weXJpZ2h0
IChDKSAyMDExLCAyMDEzIEFwcGxlIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyAqIENvcHly
aWdodCAoQykgMjAxMSwgMjAxMywgMjAxNCBBcHBsZSBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQu
CiAgKgogICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jt
cywgd2l0aCBvciB3aXRob3V0CiAgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlk
ZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKQEAgLTM2NSw1MCArMzY1LDE0IEBAIHZv
aWQgT1NSRXhpdENvbXBpbGVyOjpjb21waWxlRXhpdChjb25zdCAKICAgICAvLyAgICAgcmVnaXN0
ZXJzLgogICAgIAogICAgIGlmIChoYXZlQXJndW1lbnRzKSB7Ci0gICAgICAgIEhhc2hTZXQ8SW5s
aW5lQ2FsbEZyYW1lKiwgRGVmYXVsdEhhc2g8SW5saW5lQ2FsbEZyYW1lKj46Okhhc2gsCi0gICAg
ICAgICAgICBOdWxsYWJsZUhhc2hUcmFpdHM8SW5saW5lQ2FsbEZyYW1lKj4+IGRpZENyZWF0ZUFy
Z3VtZW50c09iamVjdDsKKyAgICAgICAgQXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0b3IgYXJndW1l
bnRzUmVjb3Zlcnk7CiAKICAgICAgICAgZm9yIChzaXplX3QgaW5kZXggPSAwOyBpbmRleCA8IG9w
ZXJhbmRzLnNpemUoKTsgKytpbmRleCkgewogICAgICAgICAgICAgY29uc3QgVmFsdWVSZWNvdmVy
eSYgcmVjb3ZlcnkgPSBvcGVyYW5kc1tpbmRleF07CiAgICAgICAgICAgICBpZiAocmVjb3Zlcnku
dGVjaG5pcXVlKCkgIT0gQXJndW1lbnRzVGhhdFdlcmVOb3RDcmVhdGVkKQogICAgICAgICAgICAg
ICAgIGNvbnRpbnVlOwotICAgICAgICAgICAgaW50IG9wZXJhbmQgPSBvcGVyYW5kcy5vcGVyYW5k
Rm9ySW5kZXgoaW5kZXgpOwotICAgICAgICAgICAgLy8gRmluZCB0aGUgcmlnaHQgaW5saW5lIGNh
bGwgZnJhbWUuCi0gICAgICAgICAgICBJbmxpbmVDYWxsRnJhbWUqIGlubGluZUNhbGxGcmFtZSA9
IDA7Ci0gICAgICAgICAgICBmb3IgKElubGluZUNhbGxGcmFtZSogY3VycmVudCA9IGV4aXQubV9j
b2RlT3JpZ2luLmlubGluZUNhbGxGcmFtZTsKLSAgICAgICAgICAgICAgICAgY3VycmVudDsKLSAg
ICAgICAgICAgICAgICAgY3VycmVudCA9IGN1cnJlbnQtPmNhbGxlci5pbmxpbmVDYWxsRnJhbWUp
IHsKLSAgICAgICAgICAgICAgICBpZiAoY3VycmVudC0+c3RhY2tPZmZzZXQgPj0gb3BlcmFuZCkg
ewotICAgICAgICAgICAgICAgICAgICBpbmxpbmVDYWxsRnJhbWUgPSBjdXJyZW50OwotICAgICAg
ICAgICAgICAgICAgICBicmVhazsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAgICB9Ci0K
LSAgICAgICAgICAgIGlmICghbV9qaXQuYmFzZWxpbmVDb2RlQmxvY2tGb3IoaW5saW5lQ2FsbEZy
YW1lKS0+dXNlc0FyZ3VtZW50cygpKQotICAgICAgICAgICAgICAgIGNvbnRpbnVlOwotICAgICAg
ICAgICAgVmlydHVhbFJlZ2lzdGVyIGFyZ3VtZW50c1JlZ2lzdGVyID0gbV9qaXQuYmFzZWxpbmVB
cmd1bWVudHNSZWdpc3RlckZvcihpbmxpbmVDYWxsRnJhbWUpOwotICAgICAgICAgICAgaWYgKGRp
ZENyZWF0ZUFyZ3VtZW50c09iamVjdC5hZGQoaW5saW5lQ2FsbEZyYW1lKS5pc05ld0VudHJ5KSB7
Ci0gICAgICAgICAgICAgICAgLy8gV2Uga25vdyB0aGlzIGNhbGwgZnJhbWUgb3B0aW1pemVkIG91
dCBhbiBhcmd1bWVudHMgb2JqZWN0IHRoYXQKLSAgICAgICAgICAgICAgICAvLyB0aGUgYmFzZWxp
bmUgSklUIHdvdWxkIGhhdmUgY3JlYXRlZC4gRG8gdGhhdCBjcmVhdGlvbiBub3cuCi0gICAgICAg
ICAgICAgICAgaWYgKGlubGluZUNhbGxGcmFtZSkgewotICAgICAgICAgICAgICAgICAgICBtX2pp
dC5hZGRQdHIoQXNzZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tMzIoaW5saW5lQ2FsbEZyYW1lLT5z
dGFja09mZnNldCAqIHNpemVvZihFbmNvZGVkSlNWYWx1ZSkpLCBHUFJJbmZvOjpjYWxsRnJhbWVS
ZWdpc3RlciwgR1BSSW5mbzo6cmVnVDApOwotICAgICAgICAgICAgICAgICAgICBtX2ppdC5zZXR1
cEFyZ3VtZW50cyhHUFJJbmZvOjpyZWdUMCk7Ci0gICAgICAgICAgICAgICAgfSBlbHNlCi0gICAg
ICAgICAgICAgICAgICAgIG1faml0LnNldHVwQXJndW1lbnRzRXhlY1N0YXRlKCk7Ci0gICAgICAg
ICAgICAgICAgbV9qaXQubW92ZSgKLSAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJz
OjpUcnVzdGVkSW1tUHRyKAotICAgICAgICAgICAgICAgICAgICAgICAgYml0d2lzZV9jYXN0PHZv
aWQqPihvcGVyYXRpb25DcmVhdGVBcmd1bWVudHMpKSwKLSAgICAgICAgICAgICAgICAgICAgR1BS
SW5mbzo6bm9uQXJnR1BSMCk7Ci0gICAgICAgICAgICAgICAgbV9qaXQuY2FsbChHUFJJbmZvOjpu
b25BcmdHUFIwKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5zdG9yZTY0KEdQUkluZm86OnJldHVy
blZhbHVlR1BSLCBBc3NlbWJseUhlbHBlcnM6OmFkZHJlc3NGb3IoYXJndW1lbnRzUmVnaXN0ZXIp
KTsKLSAgICAgICAgICAgICAgICBtX2ppdC5zdG9yZTY0KAotICAgICAgICAgICAgICAgICAgICBH
UFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwKLSAgICAgICAgICAgICAgICAgICAgQXNzZW1ibHlIZWxw
ZXJzOjphZGRyZXNzRm9yKHVubW9kaWZpZWRBcmd1bWVudHNSZWdpc3Rlcihhcmd1bWVudHNSZWdp
c3RlcikpKTsKLSAgICAgICAgICAgICAgICBtX2ppdC5tb3ZlKEdQUkluZm86OnJldHVyblZhbHVl
R1BSLCBHUFJJbmZvOjpyZWdUMCk7IC8vIG5vLW9wIG1vdmUgb24gYWxtb3N0IGFsbCBwbGF0Zm9y
bXMuCi0gICAgICAgICAgICB9Ci0KLSAgICAgICAgICAgIG1faml0LmxvYWQ2NChBc3NlbWJseUhl
bHBlcnM6OmFkZHJlc3NGb3IoYXJndW1lbnRzUmVnaXN0ZXIpLCBHUFJJbmZvOjpyZWdUMCk7Ci0g
ICAgICAgICAgICBtX2ppdC5zdG9yZTY0KEdQUkluZm86OnJlZ1QwLCBBc3NlbWJseUhlbHBlcnM6
OmFkZHJlc3NGb3Iob3BlcmFuZCkpOworICAgICAgICAgICAgYXJndW1lbnRzUmVjb3ZlcnkuZ2Vu
ZXJhdGVGb3IoCisgICAgICAgICAgICAgICAgb3BlcmFuZHMub3BlcmFuZEZvckluZGV4KGluZGV4
KSwgZXhpdC5tX2NvZGVPcmlnaW4sIG1faml0KTsKICAgICAgICAgfQogICAgIH0KIApJbmRleDog
U291cmNlL0phdmFTY3JpcHRDb3JlL2RmZy9ERkdPU1JFeGl0Q29tcGlsZXJDb21tb24uY3BwCj09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT0KLS0tIFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9kZmcvREZHT1NSRXhpdENvbXBpbGVy
Q29tbW9uLmNwcAkocmV2aXNpb24gMTY0ODgzKQorKysgU291cmNlL0phdmFTY3JpcHRDb3JlL2Rm
Zy9ERkdPU1JFeGl0Q29tcGlsZXJDb21tb24uY3BwCSh3b3JraW5nIGNvcHkpCkBAIC0xLDUgKzEs
NSBAQAogLyoKLSAqIENvcHlyaWdodCAoQykgMjAxMyBBcHBsZSBJbmMuIEFsbCByaWdodHMgcmVz
ZXJ2ZWQuCisgKiBDb3B5cmlnaHQgKEMpIDIwMTMsIDIwMTQgQXBwbGUgSW5jLiBBbGwgcmlnaHRz
IHJlc2VydmVkLgogICoKICAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBi
aW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0
dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCkBAIC0yMTcsNiArMjE3
LDg5IEBAIHZvaWQgYWRqdXN0QW5kSnVtcFRvVGFyZ2V0KENDYWxsSGVscGVycyYKICAgICBqaXQu
anVtcChHUFJJbmZvOjpyZWdUMik7CiB9CiAKK0FyZ3VtZW50c1JlY292ZXJ5R2VuZXJhdG9yOjpB
cmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcigpIHsgfQorQXJndW1lbnRzUmVjb3ZlcnlHZW5lcmF0
b3I6On5Bcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcigpIHsgfQorCit2b2lkIEFyZ3VtZW50c1Jl
Y292ZXJ5R2VuZXJhdG9yOjpnZW5lcmF0ZUZvcigKKyAgICBpbnQgb3BlcmFuZCwgQ29kZU9yaWdp
biBjb2RlT3JpZ2luLCBDQ2FsbEhlbHBlcnMmIGppdCkKK3sKKyAgICAvLyBGaW5kIHRoZSByaWdo
dCBpbmxpbmUgY2FsbCBmcmFtZS4KKyAgICBJbmxpbmVDYWxsRnJhbWUqIGlubGluZUNhbGxGcmFt
ZSA9IDA7CisgICAgZm9yIChJbmxpbmVDYWxsRnJhbWUqIGN1cnJlbnQgPSBjb2RlT3JpZ2luLmlu
bGluZUNhbGxGcmFtZTsKKyAgICAgICAgIGN1cnJlbnQ7CisgICAgICAgICBjdXJyZW50ID0gY3Vy
cmVudC0+Y2FsbGVyLmlubGluZUNhbGxGcmFtZSkgeworICAgICAgICBpZiAoY3VycmVudC0+c3Rh
Y2tPZmZzZXQgPj0gb3BlcmFuZCkgeworICAgICAgICAgICAgaW5saW5lQ2FsbEZyYW1lID0gY3Vy
cmVudDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCFq
aXQuYmFzZWxpbmVDb2RlQmxvY2tGb3IoaW5saW5lQ2FsbEZyYW1lKS0+dXNlc0FyZ3VtZW50cygp
KQorICAgICAgICByZXR1cm47CisgICAgVmlydHVhbFJlZ2lzdGVyIGFyZ3VtZW50c1JlZ2lzdGVy
ID0gaml0LmJhc2VsaW5lQXJndW1lbnRzUmVnaXN0ZXJGb3IoaW5saW5lQ2FsbEZyYW1lKTsKKyAg
ICBpZiAobV9kaWRDcmVhdGVBcmd1bWVudHNPYmplY3QuYWRkKGlubGluZUNhbGxGcmFtZSkuaXNO
ZXdFbnRyeSkgeworICAgICAgICAvLyBXZSBrbm93IHRoaXMgY2FsbCBmcmFtZSBvcHRpbWl6ZWQg
b3V0IGFuIGFyZ3VtZW50cyBvYmplY3QgdGhhdAorICAgICAgICAvLyB0aGUgYmFzZWxpbmUgSklU
IHdvdWxkIGhhdmUgY3JlYXRlZC4gRG8gdGhhdCBjcmVhdGlvbiBub3cuCisjaWYgVVNFKEpTVkFM
VUU2NCkKKyAgICAgICAgaWYgKGlubGluZUNhbGxGcmFtZSkgeworICAgICAgICAgICAgaml0LmFk
ZFB0cihBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW0zMihpbmxpbmVDYWxsRnJhbWUtPnN0YWNr
T2Zmc2V0ICogc2l6ZW9mKEVuY29kZWRKU1ZhbHVlKSksIEdQUkluZm86OmNhbGxGcmFtZVJlZ2lz
dGVyLCBHUFJJbmZvOjpyZWdUMCk7CisgICAgICAgICAgICBqaXQuc2V0dXBBcmd1bWVudHMoR1BS
SW5mbzo6cmVnVDApOworICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgIGppdC5zZXR1cEFyZ3Vt
ZW50c0V4ZWNTdGF0ZSgpOworICAgICAgICBqaXQubW92ZSgKKyAgICAgICAgICAgIEFzc2VtYmx5
SGVscGVyczo6VHJ1c3RlZEltbVB0cigKKyAgICAgICAgICAgICAgICBiaXR3aXNlX2Nhc3Q8dm9p
ZCo+KG9wZXJhdGlvbkNyZWF0ZUFyZ3VtZW50cykpLAorICAgICAgICAgICAgR1BSSW5mbzo6bm9u
QXJnR1BSMCk7CisgICAgICAgIGppdC5jYWxsKEdQUkluZm86Om5vbkFyZ0dQUjApOworICAgICAg
ICBqaXQuc3RvcmU2NChHUFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwgQXNzZW1ibHlIZWxwZXJzOjph
ZGRyZXNzRm9yKGFyZ3VtZW50c1JlZ2lzdGVyKSk7CisgICAgICAgIGppdC5zdG9yZTY0KAorICAg
ICAgICAgICAgR1BSSW5mbzo6cmV0dXJuVmFsdWVHUFIsCisgICAgICAgICAgICBBc3NlbWJseUhl
bHBlcnM6OmFkZHJlc3NGb3IodW5tb2RpZmllZEFyZ3VtZW50c1JlZ2lzdGVyKGFyZ3VtZW50c1Jl
Z2lzdGVyKSkpOworICAgICAgICBqaXQubW92ZShHUFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwgR1BS
SW5mbzo6cmVnVDApOyAvLyBuby1vcCBtb3ZlIG9uIGFsbW9zdCBhbGwgcGxhdGZvcm1zLgorI2Vs
c2UgLy8gVVNFKEpTVkFMVUU2NCkgLT4gc28gdGhlIDMyXzY0IHBhcnQKKyAgICAgICAgaWYgKGlu
bGluZUNhbGxGcmFtZSkgeworICAgICAgICAgICAgaml0LnNldHVwQXJndW1lbnRzV2l0aEV4ZWNT
dGF0ZSgKKyAgICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIoaW5s
aW5lQ2FsbEZyYW1lKSk7CisgICAgICAgICAgICBqaXQubW92ZSgKKyAgICAgICAgICAgICAgICBB
c3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIoCisgICAgICAgICAgICAgICAgICAgIGJpdHdp
c2VfY2FzdDx2b2lkKj4ob3BlcmF0aW9uQ3JlYXRlSW5saW5lZEFyZ3VtZW50cykpLAorICAgICAg
ICAgICAgICAgIEdQUkluZm86Om5vbkFyZ0dQUjApOworICAgICAgICB9IGVsc2UgeworICAgICAg
ICAgICAgaml0LnNldHVwQXJndW1lbnRzRXhlY1N0YXRlKCk7CisgICAgICAgICAgICBqaXQubW92
ZSgKKyAgICAgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OlRydXN0ZWRJbW1QdHIoCisgICAg
ICAgICAgICAgICAgICAgIGJpdHdpc2VfY2FzdDx2b2lkKj4ob3BlcmF0aW9uQ3JlYXRlQXJndW1l
bnRzKSksCisgICAgICAgICAgICAgICAgR1BSSW5mbzo6bm9uQXJnR1BSMCk7CisgICAgICAgIH0K
KyAgICAgICAgaml0LmNhbGwoR1BSSW5mbzo6bm9uQXJnR1BSMCk7CisgICAgICAgIGppdC5zdG9y
ZTMyKAorICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tMzIoSlNWYWx1ZTo6
Q2VsbFRhZyksCisgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OnRhZ0Zvcihhcmd1bWVudHNS
ZWdpc3RlcikpOworICAgICAgICBqaXQuc3RvcmUzMigKKyAgICAgICAgICAgIEdQUkluZm86OnJl
dHVyblZhbHVlR1BSLAorICAgICAgICAgICAgQXNzZW1ibHlIZWxwZXJzOjpwYXlsb2FkRm9yKGFy
Z3VtZW50c1JlZ2lzdGVyKSk7CisgICAgICAgIGppdC5zdG9yZTMyKAorICAgICAgICAgICAgQXNz
ZW1ibHlIZWxwZXJzOjpUcnVzdGVkSW1tMzIoSlNWYWx1ZTo6Q2VsbFRhZyksCisgICAgICAgICAg
ICBBc3NlbWJseUhlbHBlcnM6OnRhZ0Zvcih1bm1vZGlmaWVkQXJndW1lbnRzUmVnaXN0ZXIoYXJn
dW1lbnRzUmVnaXN0ZXIpKSk7CisgICAgICAgIGppdC5zdG9yZTMyKAorICAgICAgICAgICAgR1BS
SW5mbzo6cmV0dXJuVmFsdWVHUFIsCisgICAgICAgICAgICBBc3NlbWJseUhlbHBlcnM6OnBheWxv
YWRGb3IodW5tb2RpZmllZEFyZ3VtZW50c1JlZ2lzdGVyKGFyZ3VtZW50c1JlZ2lzdGVyKSkpOwor
ICAgICAgICBqaXQubW92ZShHUFJJbmZvOjpyZXR1cm5WYWx1ZUdQUiwgR1BSSW5mbzo6cmVnVDAp
OyAvLyBuby1vcCBtb3ZlIG9uIGFsbW9zdCBhbGwgcGxhdGZvcm1zLgorI2VuZGlmIC8vIFVTRShK
U1ZBTFVFNjQpCisgICAgfQorCisjaWYgVVNFKEpTVkFMVUU2NCkKKyAgICBqaXQubG9hZDY0KEFz
c2VtYmx5SGVscGVyczo6YWRkcmVzc0Zvcihhcmd1bWVudHNSZWdpc3RlciksIEdQUkluZm86OnJl
Z1QwKTsKKyAgICBqaXQuc3RvcmU2NChHUFJJbmZvOjpyZWdUMCwgQXNzZW1ibHlIZWxwZXJzOjph
ZGRyZXNzRm9yKG9wZXJhbmQpKTsKKyNlbHNlIC8vIFVTRShKU1ZBTFVFNjQpIC0+IHNvIHRoZSAz
Ml82NCBwYXJ0CisgICAgaml0LmxvYWQzMihBc3NlbWJseUhlbHBlcnM6OnBheWxvYWRGb3IoYXJn
dW1lbnRzUmVnaXN0ZXIpLCBHUFJJbmZvOjpyZWdUMCk7CisgICAgaml0LnN0b3JlMzIoCisgICAg
ICAgIEFzc2VtYmx5SGVscGVyczo6VHJ1c3RlZEltbTMyKEpTVmFsdWU6OkNlbGxUYWcpLAorICAg
ICAgICBBc3NlbWJseUhlbHBlcnM6OnRhZ0ZvcihvcGVyYW5kKSk7CisgICAgaml0LnN0b3JlMzIo
R1BSSW5mbzo6cmVnVDAsIEFzc2VtYmx5SGVscGVyczo6cGF5bG9hZEZvcihvcGVyYW5kKSk7Cisj
ZW5kaWYgLy8gVVNFKEpTVkFMVUU2NCkKK30KKyAgICAKIH0gfSAvLyBuYW1lc3BhY2UgSlNDOjpE
RkcKIAogI2VuZGlmIC8vIEVOQUJMRShERkdfSklUKQpJbmRleDogU291cmNlL0phdmFTY3JpcHRD
b3JlL2RmZy9ERkdPU1JFeGl0Q29tcGlsZXJDb21tb24uaAo9PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0tLSBTb3VyY2Uv
SmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21waWxlckNvbW1vbi5oCShyZXZpc2lvbiAx
NjQ4ODMpCisrKyBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZGZnL0RGR09TUkV4aXRDb21waWxlckNv
bW1vbi5oCSh3b3JraW5nIGNvcHkpCkBAIC0zNyw2ICszNywxOCBAQCB2b2lkIGhhbmRsZUV4aXRD
b3VudHMoQ0NhbGxIZWxwZXJzJiwgY29uCiB2b2lkIHJlaWZ5SW5saW5lZENhbGxGcmFtZXMoQ0Nh
bGxIZWxwZXJzJiwgY29uc3QgT1NSRXhpdEJhc2UmKTsKIHZvaWQgYWRqdXN0QW5kSnVtcFRvVGFy
Z2V0KENDYWxsSGVscGVycyYsIGNvbnN0IE9TUkV4aXRCYXNlJik7CiAKK2NsYXNzIEFyZ3VtZW50
c1JlY292ZXJ5R2VuZXJhdG9yIHsKK3B1YmxpYzoKKyAgICBBcmd1bWVudHNSZWNvdmVyeUdlbmVy
YXRvcigpOworICAgIH5Bcmd1bWVudHNSZWNvdmVyeUdlbmVyYXRvcigpOworICAgIAorICAgIHZv
aWQgZ2VuZXJhdGVGb3IoaW50IG9wZXJhbmQsIENvZGVPcmlnaW4sIENDYWxsSGVscGVycyYpOwor
ICAgIAorcHJpdmF0ZToKKyAgICBIYXNoU2V0PElubGluZUNhbGxGcmFtZSosIERlZmF1bHRIYXNo
PElubGluZUNhbGxGcmFtZSo+OjpIYXNoLAorICAgICAgICBOdWxsYWJsZUhhc2hUcmFpdHM8SW5s
aW5lQ2FsbEZyYW1lKj4+IG1fZGlkQ3JlYXRlQXJndW1lbnRzT2JqZWN0OworfTsKKwogfSB9IC8v
IG5hbWVzcGFjZSBKU0M6OkRGRwogCiAjZW5kaWYgLy8gRU5BQkxFKERGR19KSVQpCkluZGV4OiBT
b3VyY2UvSmF2YVNjcmlwdENvcmUvZnRsL0ZUTENhcGFiaWxpdGllcy5jcHAKPT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQot
LS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExDYXBhYmlsaXRpZXMuY3BwCShyZXZpc2lv
biAxNjQ4ODMpCisrKyBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZnRsL0ZUTENhcGFiaWxpdGllcy5j
cHAJKHdvcmtpbmcgY29weSkKQEAgLTE0MCw2ICsxNDAsNyBAQCBpbmxpbmUgQ2FwYWJpbGl0eUxl
dmVsIGNhbkNvbXBpbGUoTm9kZSogCiAgICAgY2FzZSBNdWx0aUdldEJ5T2Zmc2V0OgogICAgIGNh
c2UgTXVsdGlQdXRCeU9mZnNldDoKICAgICBjYXNlIFRvUHJpbWl0aXZlOgorICAgIGNhc2UgUGhh
bnRvbUFyZ3VtZW50czoKICAgICAgICAgLy8gVGhlc2UgYXJlIE9LLgogICAgICAgICBicmVhazsK
ICAgICBjYXNlIFB1dEJ5SWREaXJlY3Q6CkluZGV4OiBTb3VyY2UvSmF2YVNjcmlwdENvcmUvZnRs
L0ZUTEV4aXRWYWx1ZS5jcHAKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0
bC9GVExFeGl0VmFsdWUuY3BwCShyZXZpc2lvbiAxNjQ4ODMpCisrKyBTb3VyY2UvSmF2YVNjcmlw
dENvcmUvZnRsL0ZUTEV4aXRWYWx1ZS5jcHAJKHdvcmtpbmcgY29weSkKQEAgLTU5LDYgKzU5LDkg
QEAgdm9pZCBFeGl0VmFsdWU6OmR1bXBJbkNvbnRleHQoUHJpbnRTdHJlYQogICAgIGNhc2UgRXhp
dFZhbHVlSW5KU1N0YWNrQXNEb3VibGU6CiAgICAgICAgIG91dC5wcmludCgiSW5KU1N0YWNrQXNE
b3VibGU6ciIsIHZpcnR1YWxSZWdpc3RlcigpKTsKICAgICAgICAgcmV0dXJuOworICAgIGNhc2Ug
RXhpdFZhbHVlQXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQ6CisgICAgICAgIG91dC5w
cmludCgiQXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQiKTsKKyAgICAgICAgcmV0dXJu
OwogICAgIGNhc2UgRXhpdFZhbHVlUmVjb3Zlcnk6CiAgICAgICAgIG91dC5wcmludCgiUmVjb3Zl
cnkoIiwgcmVjb3ZlcnlPcGNvZGUoKSwgIiwgYXJnIiwgbGVmdFJlY292ZXJ5QXJndW1lbnQoKSwg
IiwgYXJnIiwgcmlnaHRSZWNvdmVyeUFyZ3VtZW50KCksICIsICIsIHJlY292ZXJ5Rm9ybWF0KCks
ICIpIik7CiAgICAgICAgIHJldHVybjsKSW5kZXg6IFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9mdGwv
RlRMRXhpdFZhbHVlLmgKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9G
VExFeGl0VmFsdWUuaAkocmV2aXNpb24gMTY0ODgzKQorKysgU291cmNlL0phdmFTY3JpcHRDb3Jl
L2Z0bC9GVExFeGl0VmFsdWUuaAkod29ya2luZyBjb3B5KQpAQCAtNTEsNiArNTEsNyBAQCBlbnVt
IEV4aXRWYWx1ZUtpbmQgewogICAgIEV4aXRWYWx1ZUluSlNTdGFja0FzSW50MzIsCiAgICAgRXhp
dFZhbHVlSW5KU1N0YWNrQXNJbnQ1MiwKICAgICBFeGl0VmFsdWVJbkpTU3RhY2tBc0RvdWJsZSwK
KyAgICBFeGl0VmFsdWVBcmd1bWVudHNPYmplY3RUaGF0V2FzTm90Q3JlYXRlZCwKICAgICBFeGl0
VmFsdWVSZWNvdmVyeQogfTsKIApAQCAtMTE4LDYgKzExOSwxMyBAQCBwdWJsaWM6CiAgICAgICAg
IHJldHVybiByZXN1bHQ7CiAgICAgfQogICAgIAorICAgIHN0YXRpYyBFeGl0VmFsdWUgYXJndW1l
bnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQoKQorICAgIHsKKyAgICAgICAgRXhpdFZhbHVlIHJl
c3VsdDsKKyAgICAgICAgcmVzdWx0Lm1fa2luZCA9IEV4aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRo
YXRXYXNOb3RDcmVhdGVkOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICAKICAg
ICBzdGF0aWMgRXhpdFZhbHVlIHJlY292ZXJ5KFJlY292ZXJ5T3Bjb2RlIG9wY29kZSwgdW5zaWdu
ZWQgbGVmdEFyZ3VtZW50LCB1bnNpZ25lZCByaWdodEFyZ3VtZW50LCBWYWx1ZUZvcm1hdCBmb3Jt
YXQpCiAgICAgewogICAgICAgICBFeGl0VmFsdWUgcmVzdWx0OwpAQCAtMTQ2LDYgKzE1NCw3IEBA
IHB1YmxpYzoKICAgICB9CiAgICAgYm9vbCBpc0NvbnN0YW50KCkgY29uc3QgeyByZXR1cm4ga2lu
ZCgpID09IEV4aXRWYWx1ZUNvbnN0YW50OyB9CiAgICAgYm9vbCBpc0FyZ3VtZW50KCkgY29uc3Qg
eyByZXR1cm4ga2luZCgpID09IEV4aXRWYWx1ZUFyZ3VtZW50OyB9CisgICAgYm9vbCBpc0FyZ3Vt
ZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkKCkgY29uc3QgeyByZXR1cm4ga2luZCgpID09IEV4
aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkOyB9CiAgICAgYm9vbCBpc1Jl
Y292ZXJ5KCkgY29uc3QgeyByZXR1cm4ga2luZCgpID09IEV4aXRWYWx1ZVJlY292ZXJ5OyB9CiAg
ICAgCiAgICAgRXhpdEFyZ3VtZW50IGV4aXRBcmd1bWVudCgpIGNvbnN0CkBAIC0yMTMsNiArMjIy
LDcgQEAgcHVibGljOgogICAgICAgICBjYXNlIEV4aXRWYWx1ZURlYWQ6CiAgICAgICAgIGNhc2Ug
RXhpdFZhbHVlQ29uc3RhbnQ6CiAgICAgICAgIGNhc2UgRXhpdFZhbHVlSW5KU1N0YWNrOgorICAg
ICAgICBjYXNlIEV4aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkOgogICAg
ICAgICAgICAgcmV0dXJuIFZhbHVlRm9ybWF0SlNWYWx1ZTsKICAgICAgICAgICAgIAogICAgICAg
ICBjYXNlIEV4aXRWYWx1ZUFyZ3VtZW50OgpJbmRleDogU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0
bC9GVExMb3dlckRGR1RvTExWTS5jcHAKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gU291cmNlL0phdmFTY3JpcHRD
b3JlL2Z0bC9GVExMb3dlckRGR1RvTExWTS5jcHAJKHJldmlzaW9uIDE2NDg4MykKKysrIFNvdXJj
ZS9KYXZhU2NyaXB0Q29yZS9mdGwvRlRMTG93ZXJERkdUb0xMVk0uY3BwCSh3b3JraW5nIGNvcHkp
CkBAIC0yODIsNiArMjgyLDkgQEAgcHJpdmF0ZToKICAgICAgICAgY2FzZSBXZWFrSlNDb25zdGFu
dDoKICAgICAgICAgICAgIGNvbXBpbGVXZWFrSlNDb25zdGFudCgpOwogICAgICAgICAgICAgYnJl
YWs7CisgICAgICAgIGNhc2UgUGhhbnRvbUFyZ3VtZW50czoKKyAgICAgICAgICAgIGNvbXBpbGVQ
aGFudG9tQXJndW1lbnRzKCk7CisgICAgICAgICAgICBicmVhazsKICAgICAgICAgY2FzZSBHZXRB
cmd1bWVudDoKICAgICAgICAgICAgIGNvbXBpbGVHZXRBcmd1bWVudCgpOwogICAgICAgICAgICAg
YnJlYWs7CkBAIC03ODEsNiArNzg0LDExIEBAIHByaXZhdGU6CiAgICAgICAgICAgICBicmVhazsK
ICAgICAgICAgfQogICAgIH0KKworICAgIHZvaWQgY29tcGlsZVBoYW50b21Bcmd1bWVudHMoKQor
ICAgIHsKKyAgICAgICAgc2V0SlNWYWx1ZShtX291dC5jb25zdEludDY0KEpTVmFsdWU6OmVuY29k
ZShKU1ZhbHVlKCkpKSk7CisgICAgfQogICAgIAogICAgIHZvaWQgY29tcGlsZVdlYWtKU0NvbnN0
YW50KCkKICAgICB7CkBAIC01NTE5LDkgKzU1MjcsNyBAQCBwcml2YXRlOgogICAgICAgICAgICAg
ICAgIGJyZWFrOwogICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgY2FzZSBGbHVzaGVkQXJn
dW1lbnRzOgotICAgICAgICAgICAgICAgIC8vIEZJWE1FOiBpbXBsZW1lbnQgUGhhbnRvbUFyZ3Vt
ZW50cy4KLSAgICAgICAgICAgICAgICAvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1
Zy5jZ2k/aWQ9MTEzOTg2Ci0gICAgICAgICAgICAgICAgUkVMRUFTRV9BU1NFUlRfTk9UX1JFQUNI
RUQoKTsKKyAgICAgICAgICAgICAgICBleGl0Lm1fdmFsdWVzW2ldID0gRXhpdFZhbHVlOjphcmd1
bWVudHNPYmplY3RUaGF0V2FzTm90Q3JlYXRlZCgpOwogICAgICAgICAgICAgICAgIGJyZWFrOwog
ICAgICAgICAgICAgfQogICAgICAgICB9CkBAIC01NjEzLDkgKzU2MTksNyBAQCBwcml2YXRlOgog
ICAgICAgICAgICAgZXhpdC5tX3ZhbHVlc1tpbmRleF0gPSBFeGl0VmFsdWU6OmNvbnN0YW50KG1f
Z3JhcGgudmFsdWVPZkpTQ29uc3RhbnQobm9kZSkpOwogICAgICAgICAgICAgcmV0dXJuIHRydWU7
CiAgICAgICAgIGNhc2UgUGhhbnRvbUFyZ3VtZW50czoKLSAgICAgICAgICAgIC8vIEZJWE1FOiBp
bXBsZW1lbnQgUGhhbnRvbUFyZ3VtZW50cy4KLSAgICAgICAgICAgIC8vIGh0dHBzOi8vYnVncy53
ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMTM5ODYKLSAgICAgICAgICAgIFJFTEVBU0VfQVNT
RVJUX05PVF9SRUFDSEVEKCk7CisgICAgICAgICAgICBleGl0Lm1fdmFsdWVzW2luZGV4XSA9IEV4
aXRWYWx1ZTo6YXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQoKTsKICAgICAgICAgICAg
IHJldHVybiB0cnVlOwogICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgcmV0dXJuIGZhbHNl
OwpJbmRleDogU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9GVExPU1JFeGl0Q29tcGlsZXIuY3Bw
Cj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
PT09PT09PT09PT0KLS0tIFNvdXJjZS9KYXZhU2NyaXB0Q29yZS9mdGwvRlRMT1NSRXhpdENvbXBp
bGVyLmNwcAkocmV2aXNpb24gMTY0ODgzKQorKysgU291cmNlL0phdmFTY3JpcHRDb3JlL2Z0bC9G
VExPU1JFeGl0Q29tcGlsZXIuY3BwCSh3b3JraW5nIGNvcHkpCkBAIC0xNDYsNiArMTQ2LDEyIEBA
IHN0YXRpYyB2b2lkIGNvbXBpbGVTdHViKAogICAgICAgICAgICAgaml0LmxvYWQ2NChBc3NlbWJs
eUhlbHBlcnM6OmFkZHJlc3NGb3IodmFsdWUudmlydHVhbFJlZ2lzdGVyKCkpLCBHUFJJbmZvOjpy
ZWdUMCk7CiAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgIAorICAgICAgICBjYXNlIEV4
aXRWYWx1ZUFyZ3VtZW50c09iamVjdFRoYXRXYXNOb3RDcmVhdGVkOgorICAgICAgICAgICAgLy8g
V2UgY2FuJ3QgYWN0dWFsbHkgcmVjb3ZlciB0aGlzIHlldCwgYnV0IHdlIGNhbiBtYWtlIHRoZSBz
dGFjayBsb29rIHNhbmUuIFRoaXMgaXMKKyAgICAgICAgICAgIC8vIGEgcHJlcmVxdWlzaXRlIHRv
IHJ1bm5pbmcgdGhlIGFjdHVhbCBhcmd1bWVudHMgcmVjb3ZlcnkuCisgICAgICAgICAgICBqaXQu
bW92ZShNYWNyb0Fzc2VtYmxlcjo6VHJ1c3RlZEltbTY0KEpTVmFsdWU6OmVuY29kZShKU1ZhbHVl
KCkpKSwgR1BSSW5mbzo6cmVnVDApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAK
ICAgICAgICAgY2FzZSBFeGl0VmFsdWVSZWNvdmVyeToKICAgICAgICAgICAgIHJlY29yZC0+bG9j
YXRpb25zW3ZhbHVlLnJpZ2h0UmVjb3ZlcnlBcmd1bWVudCgpXS5yZXN0b3JlSW50bygKICAgICAg
ICAgICAgICAgICBqaXQsIGppdENvZGUtPnN0YWNrbWFwcywgcmVnaXN0ZXJTY3JhdGNoLCBHUFJJ
bmZvOjpyZWdUMSk7CkBAIC0zMzcsNiArMzQzLDE1IEBAIHN0YXRpYyB2b2lkIGNvbXBpbGVTdHVi
KAogICAgIAogICAgIGhhbmRsZUV4aXRDb3VudHMoaml0LCBleGl0KTsKICAgICByZWlmeUlubGlu
ZWRDYWxsRnJhbWVzKGppdCwgZXhpdCk7CisgICAgCisgICAgQXJndW1lbnRzUmVjb3ZlcnlHZW5l
cmF0b3IgYXJndW1lbnRzUmVjb3Zlcnk7CisgICAgZm9yICh1bnNpZ25lZCBpbmRleCA9IGV4aXQu
bV92YWx1ZXMuc2l6ZSgpOyBpbmRleC0tOykgeworICAgICAgICBpZiAoIWV4aXQubV92YWx1ZXNb
aW5kZXhdLmlzQXJndW1lbnRzT2JqZWN0VGhhdFdhc05vdENyZWF0ZWQoKSkKKyAgICAgICAgICAg
IGNvbnRpbnVlOworICAgICAgICBpbnQgb3BlcmFuZCA9IGV4aXQubV92YWx1ZXMub3BlcmFuZEZv
ckluZGV4KGluZGV4KTsKKyAgICAgICAgYXJndW1lbnRzUmVjb3ZlcnkuZ2VuZXJhdGVGb3Iob3Bl
cmFuZCwgZXhpdC5tX2NvZGVPcmlnaW4sIGppdCk7CisgICAgfQorICAgIAogICAgIGFkanVzdEFu
ZEp1bXBUb1RhcmdldChqaXQsIGV4aXQpOwogICAgIAogICAgIExpbmtCdWZmZXIgcGF0Y2hCdWZm
ZXIoKnZtLCAmaml0LCBjb2RlQmxvY2spOwo=
</data>
<flag name="review"
          id="249644"
          type_id="1"
          status="+"
          setter="oliver"
    />
          </attachment>
      

    </bug>

</bugzilla>