Title: [164923] trunk/Source/_javascript_Core
Revision
164923
Author
[email protected]
Date
2014-03-01 11:57:40 -0800 (Sat, 01 Mar 2014)

Log Message

FTL should support PhantomArguments
https://bugs.webkit.org/show_bug.cgi?id=113986

Reviewed by Oliver Hunt.
        
Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
object into the FTL's OSR exit compiler.
        
This isn't a speed-up yet, since there is still more to be done to fully support
all of the arguments craziness that our varargs benchmarks do.

* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
(JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
(JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
* dfg/DFGOSRExitCompilerCommon.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLExitValue.cpp:
(JSC::FTL::ExitValue::dumpInContext):
* ftl/FTLExitValue.h:
(JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
(JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
(JSC::FTL::ExitValue::valueFormat):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
(JSC::FTL::LowerDFGToLLVM::buildExitArguments):
(JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
* tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js: Added.
* tests/stress/trivially-foldable-reflective-arguments-access.js: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (164922 => 164923)


--- trunk/Source/_javascript_Core/ChangeLog	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-03-01 19:57:40 UTC (rev 164923)
@@ -1,5 +1,45 @@
 2014-02-28  Filip Pizlo  <[email protected]>
 
+        FTL should support PhantomArguments
+        https://bugs.webkit.org/show_bug.cgi?id=113986
+
+        Reviewed by Oliver Hunt.
+        
+        Adding PhantomArguments to the FTL mostly means wiring the recovery of the Arguments
+        object into the FTL's OSR exit compiler.
+        
+        This isn't a speed-up yet, since there is still more to be done to fully support
+        all of the arguments craziness that our varargs benchmarks do.
+
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit): move the recovery code to DFGOSRExitCompilerCommon.cpp
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator):
+        (JSC::DFG::ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator):
+        (JSC::DFG::ArgumentsRecoveryGenerator::generateFor): this is the common place for the recovery code
+        * dfg/DFGOSRExitCompilerCommon.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLExitValue.cpp:
+        (JSC::FTL::ExitValue::dumpInContext):
+        * ftl/FTLExitValue.h:
+        (JSC::FTL::ExitValue::argumentsObjectThatWasNotCreated):
+        (JSC::FTL::ExitValue::isArgumentsObjectThatWasNotCreated):
+        (JSC::FTL::ExitValue::valueFormat):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::LowerDFGToLLVM::compilePhantomArguments):
+        (JSC::FTL::LowerDFGToLLVM::buildExitArguments):
+        (JSC::FTL::LowerDFGToLLVM::tryToSetConstantExitArgument):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub): Call into the ArgumentsRecoveryGenerator
+        * tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js: Added.
+        * tests/stress/trivially-foldable-reflective-arguments-access.js: Added.
+
+2014-02-28  Filip Pizlo  <[email protected]>
+
         Unreviewed, uncomment some code. It wasn't meant to be commented in the first place.
 
         * dfg/DFGCSEPhase.cpp:

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -393,66 +393,14 @@
     //     registers.
     
     if (haveArguments) {
-        HashSet<InlineCallFrame*, DefaultHash<InlineCallFrame*>::Hash,
-            NullableHashTraits<InlineCallFrame*>> didCreateArgumentsObject;
+        ArgumentsRecoveryGenerator argumentsRecovery;
 
         for (size_t index = 0; index < operands.size(); ++index) {
             const ValueRecovery& recovery = operands[index];
             if (recovery.technique() != ArgumentsThatWereNotCreated)
                 continue;
-            int operand = operands.operandForIndex(index);
-            // Find the right inline call frame.
-            InlineCallFrame* inlineCallFrame = 0;
-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
-                 current;
-                 current = current->caller.inlineCallFrame) {
-                if (current->stackOffset >= operand) {
-                    inlineCallFrame = current;
-                    break;
-                }
-            }
-
-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)->usesArguments())
-                continue;
-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
-                // We know this call frame optimized out an arguments object that
-                // the baseline JIT would have created. Do that creation now.
-                if (inlineCallFrame) {
-                    m_jit.setupArgumentsWithExecState(
-                        AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
-                    m_jit.move(
-                        AssemblyHelpers::TrustedImmPtr(
-                            bitwise_cast<void*>(operationCreateInlinedArguments)),
-                        GPRInfo::nonArgGPR0);
-                } else {
-                    m_jit.setupArgumentsExecState();
-                    m_jit.move(
-                        AssemblyHelpers::TrustedImmPtr(
-                            bitwise_cast<void*>(operationCreateArguments)),
-                        GPRInfo::nonArgGPR0);
-                }
-                m_jit.call(GPRInfo::nonArgGPR0);
-                m_jit.store32(
-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-                    AssemblyHelpers::tagFor(argumentsRegister));
-                m_jit.store32(
-                    GPRInfo::returnValueGPR,
-                    AssemblyHelpers::payloadFor(argumentsRegister));
-                m_jit.store32(
-                    AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-                    AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
-                m_jit.store32(
-                    GPRInfo::returnValueGPR,
-                    AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
-            }
-
-            m_jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
-            m_jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-                AssemblyHelpers::tagFor(operand));
-            m_jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
+            argumentsRecovery.generateFor(
+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
         }
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -365,50 +365,14 @@
     //     registers.
     
     if (haveArguments) {
-        HashSet<InlineCallFrame*, DefaultHash<InlineCallFrame*>::Hash,
-            NullableHashTraits<InlineCallFrame*>> didCreateArgumentsObject;
+        ArgumentsRecoveryGenerator argumentsRecovery;
 
         for (size_t index = 0; index < operands.size(); ++index) {
             const ValueRecovery& recovery = operands[index];
             if (recovery.technique() != ArgumentsThatWereNotCreated)
                 continue;
-            int operand = operands.operandForIndex(index);
-            // Find the right inline call frame.
-            InlineCallFrame* inlineCallFrame = 0;
-            for (InlineCallFrame* current = exit.m_codeOrigin.inlineCallFrame;
-                 current;
-                 current = current->caller.inlineCallFrame) {
-                if (current->stackOffset >= operand) {
-                    inlineCallFrame = current;
-                    break;
-                }
-            }
-
-            if (!m_jit.baselineCodeBlockFor(inlineCallFrame)->usesArguments())
-                continue;
-            VirtualRegister argumentsRegister = m_jit.baselineArgumentsRegisterFor(inlineCallFrame);
-            if (didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
-                // We know this call frame optimized out an arguments object that
-                // the baseline JIT would have created. Do that creation now.
-                if (inlineCallFrame) {
-                    m_jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
-                    m_jit.setupArguments(GPRInfo::regT0);
-                } else
-                    m_jit.setupArgumentsExecState();
-                m_jit.move(
-                    AssemblyHelpers::TrustedImmPtr(
-                        bitwise_cast<void*>(operationCreateArguments)),
-                    GPRInfo::nonArgGPR0);
-                m_jit.call(GPRInfo::nonArgGPR0);
-                m_jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
-                m_jit.store64(
-                    GPRInfo::returnValueGPR,
-                    AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
-                m_jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
-            }
-
-            m_jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
-            m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+            argumentsRecovery.generateFor(
+                operands.operandForIndex(index), exit.m_codeOrigin, m_jit);
         }
     }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -217,6 +217,89 @@
     jit.jump(GPRInfo::regT2);
 }
 
+ArgumentsRecoveryGenerator::ArgumentsRecoveryGenerator() { }
+ArgumentsRecoveryGenerator::~ArgumentsRecoveryGenerator() { }
+
+void ArgumentsRecoveryGenerator::generateFor(
+    int operand, CodeOrigin codeOrigin, CCallHelpers& jit)
+{
+    // Find the right inline call frame.
+    InlineCallFrame* inlineCallFrame = 0;
+    for (InlineCallFrame* current = codeOrigin.inlineCallFrame;
+         current;
+         current = current->caller.inlineCallFrame) {
+        if (current->stackOffset >= operand) {
+            inlineCallFrame = current;
+            break;
+        }
+    }
+
+    if (!jit.baselineCodeBlockFor(inlineCallFrame)->usesArguments())
+        return;
+    VirtualRegister argumentsRegister = jit.baselineArgumentsRegisterFor(inlineCallFrame);
+    if (m_didCreateArgumentsObject.add(inlineCallFrame).isNewEntry) {
+        // We know this call frame optimized out an arguments object that
+        // the baseline JIT would have created. Do that creation now.
+#if USE(JSVALUE64)
+        if (inlineCallFrame) {
+            jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->stackOffset * sizeof(EncodedJSValue)), GPRInfo::callFrameRegister, GPRInfo::regT0);
+            jit.setupArguments(GPRInfo::regT0);
+        } else
+            jit.setupArgumentsExecState();
+        jit.move(
+            AssemblyHelpers::TrustedImmPtr(
+                bitwise_cast<void*>(operationCreateArguments)),
+            GPRInfo::nonArgGPR0);
+        jit.call(GPRInfo::nonArgGPR0);
+        jit.store64(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(argumentsRegister));
+        jit.store64(
+            GPRInfo::returnValueGPR,
+            AssemblyHelpers::addressFor(unmodifiedArgumentsRegister(argumentsRegister)));
+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
+#else // USE(JSVALUE64) -> so the 32_64 part
+        if (inlineCallFrame) {
+            jit.setupArgumentsWithExecState(
+                AssemblyHelpers::TrustedImmPtr(inlineCallFrame));
+            jit.move(
+                AssemblyHelpers::TrustedImmPtr(
+                    bitwise_cast<void*>(operationCreateInlinedArguments)),
+                GPRInfo::nonArgGPR0);
+        } else {
+            jit.setupArgumentsExecState();
+            jit.move(
+                AssemblyHelpers::TrustedImmPtr(
+                    bitwise_cast<void*>(operationCreateArguments)),
+                GPRInfo::nonArgGPR0);
+        }
+        jit.call(GPRInfo::nonArgGPR0);
+        jit.store32(
+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
+            AssemblyHelpers::tagFor(argumentsRegister));
+        jit.store32(
+            GPRInfo::returnValueGPR,
+            AssemblyHelpers::payloadFor(argumentsRegister));
+        jit.store32(
+            AssemblyHelpers::TrustedImm32(JSValue::CellTag),
+            AssemblyHelpers::tagFor(unmodifiedArgumentsRegister(argumentsRegister)));
+        jit.store32(
+            GPRInfo::returnValueGPR,
+            AssemblyHelpers::payloadFor(unmodifiedArgumentsRegister(argumentsRegister)));
+        jit.move(GPRInfo::returnValueGPR, GPRInfo::regT0); // no-op move on almost all platforms.
+#endif // USE(JSVALUE64)
+    }
+
+#if USE(JSVALUE64)
+    jit.load64(AssemblyHelpers::addressFor(argumentsRegister), GPRInfo::regT0);
+    jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));
+#else // USE(JSVALUE64) -> so the 32_64 part
+    jit.load32(AssemblyHelpers::payloadFor(argumentsRegister), GPRInfo::regT0);
+    jit.store32(
+        AssemblyHelpers::TrustedImm32(JSValue::CellTag),
+        AssemblyHelpers::tagFor(operand));
+    jit.store32(GPRInfo::regT0, AssemblyHelpers::payloadFor(operand));
+#endif // USE(JSVALUE64)
+}
+    
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h (164922 => 164923)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h	2014-03-01 19:57:40 UTC (rev 164923)
@@ -37,6 +37,18 @@
 void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
 void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
 
+class ArgumentsRecoveryGenerator {
+public:
+    ArgumentsRecoveryGenerator();
+    ~ArgumentsRecoveryGenerator();
+    
+    void generateFor(int operand, CodeOrigin, CCallHelpers&);
+    
+private:
+    HashSet<InlineCallFrame*, DefaultHash<InlineCallFrame*>::Hash,
+        NullableHashTraits<InlineCallFrame*>> m_didCreateArgumentsObject;
+};
+
 } } // namespace JSC::DFG
 
 #endif // ENABLE(DFG_JIT)

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -140,6 +140,7 @@
     case MultiGetByOffset:
     case MultiPutByOffset:
     case ToPrimitive:
+    case PhantomArguments:
         // These are OK.
         break;
     case PutByIdDirect:

Modified: trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/ftl/FTLExitValue.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -59,6 +59,9 @@
     case ExitValueInJSStackAsDouble:
         out.print("InJSStackAsDouble:r", virtualRegister());
         return;
+    case ExitValueArgumentsObjectThatWasNotCreated:
+        out.print("ArgumentsObjectThatWasNotCreated");
+        return;
     case ExitValueRecovery:
         out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")");
         return;

Modified: trunk/Source/_javascript_Core/ftl/FTLExitValue.h (164922 => 164923)


--- trunk/Source/_javascript_Core/ftl/FTLExitValue.h	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/ftl/FTLExitValue.h	2014-03-01 19:57:40 UTC (rev 164923)
@@ -51,6 +51,7 @@
     ExitValueInJSStackAsInt32,
     ExitValueInJSStackAsInt52,
     ExitValueInJSStackAsDouble,
+    ExitValueArgumentsObjectThatWasNotCreated,
     ExitValueRecovery
 };
 
@@ -118,6 +119,13 @@
         return result;
     }
     
+    static ExitValue argumentsObjectThatWasNotCreated()
+    {
+        ExitValue result;
+        result.m_kind = ExitValueArgumentsObjectThatWasNotCreated;
+        return result;
+    }
+    
     static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format)
     {
         ExitValue result;
@@ -146,6 +154,7 @@
     }
     bool isConstant() const { return kind() == ExitValueConstant; }
     bool isArgument() const { return kind() == ExitValueArgument; }
+    bool isArgumentsObjectThatWasNotCreated() const { return kind() == ExitValueArgumentsObjectThatWasNotCreated; }
     bool isRecovery() const { return kind() == ExitValueRecovery; }
     
     ExitArgument exitArgument() const
@@ -213,6 +222,7 @@
         case ExitValueDead:
         case ExitValueConstant:
         case ExitValueInJSStack:
+        case ExitValueArgumentsObjectThatWasNotCreated:
             return ValueFormatJSValue;
             
         case ExitValueArgument:

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -282,6 +282,9 @@
         case WeakJSConstant:
             compileWeakJSConstant();
             break;
+        case PhantomArguments:
+            compilePhantomArguments();
+            break;
         case GetArgument:
             compileGetArgument();
             break;
@@ -781,6 +784,11 @@
             break;
         }
     }
+
+    void compilePhantomArguments()
+    {
+        setJSValue(m_out.constInt64(JSValue::encode(JSValue())));
+    }
     
     void compileWeakJSConstant()
     {
@@ -5519,9 +5527,7 @@
                 break;
                 
             case FlushedArguments:
-                // FIXME: implement PhantomArguments.
-                // https://bugs.webkit.org/show_bug.cgi?id=113986
-                RELEASE_ASSERT_NOT_REACHED();
+                exit.m_values[i] = ExitValue::argumentsObjectThatWasNotCreated();
                 break;
             }
         }
@@ -5613,9 +5619,7 @@
             exit.m_values[index] = ExitValue::constant(m_graph.valueOfJSConstant(node));
             return true;
         case PhantomArguments:
-            // FIXME: implement PhantomArguments.
-            // https://bugs.webkit.org/show_bug.cgi?id=113986
-            RELEASE_ASSERT_NOT_REACHED();
+            exit.m_values[index] = ExitValue::argumentsObjectThatWasNotCreated();
             return true;
         default:
             return false;

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (164922 => 164923)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2014-03-01 19:42:14 UTC (rev 164922)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2014-03-01 19:57:40 UTC (rev 164923)
@@ -146,6 +146,12 @@
             jit.load64(AssemblyHelpers::addressFor(value.virtualRegister()), GPRInfo::regT0);
             break;
             
+        case ExitValueArgumentsObjectThatWasNotCreated:
+            // We can't actually recover this yet, but we can make the stack look sane. This is
+            // a prerequisite to running the actual arguments recovery.
+            jit.move(MacroAssembler::TrustedImm64(JSValue::encode(JSValue())), GPRInfo::regT0);
+            break;
+            
         case ExitValueRecovery:
             record->locations[value.rightRecoveryArgument()].restoreInto(
                 jit, jitCode->stackmaps, registerScratch, GPRInfo::regT1);
@@ -337,6 +343,15 @@
     
     handleExitCounts(jit, exit);
     reifyInlinedCallFrames(jit, exit);
+    
+    ArgumentsRecoveryGenerator argumentsRecovery;
+    for (unsigned index = exit.m_values.size(); index--;) {
+        if (!exit.m_values[index].isArgumentsObjectThatWasNotCreated())
+            continue;
+        int operand = exit.m_values.operandForIndex(index);
+        argumentsRecovery.generateFor(operand, exit.m_codeOrigin, jit);
+    }
+    
     adjustAndJumpToTarget(jit, exit);
     
     LinkBuffer patchBuffer(*vm, &jit, codeBlock);

Added: trunk/Source/_javascript_Core/tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js (0 => 164923)


--- trunk/Source/_javascript_Core/tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/slightly-more-difficult-to-fold-reflective-arguments-access.js	2014-03-01 19:57:40 UTC (rev 164923)
@@ -0,0 +1,16 @@
+function foo() {
+    var a = arguments;
+    return a[0];
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = bar(42);
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}

Added: trunk/Source/_javascript_Core/tests/stress/trivially-foldable-reflective-arguments-access.js (0 => 164923)


--- trunk/Source/_javascript_Core/tests/stress/trivially-foldable-reflective-arguments-access.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/trivially-foldable-reflective-arguments-access.js	2014-03-01 19:57:40 UTC (rev 164923)
@@ -0,0 +1,15 @@
+function foo() {
+    return arguments[0];
+}
+
+function bar(x) {
+    return foo(x);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = bar(42);
+    if (result != 42)
+        throw "Error: bad result: " + result;
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to