Title: [209846] trunk
Revision
209846
Author
[email protected]
Date
2016-12-14 17:25:16 -0800 (Wed, 14 Dec 2016)

Log Message

DirectTailCall implementation needs to tell the shuffler what to put into the ArgumentCount explicitly
https://bugs.webkit.org/show_bug.cgi?id=165882

Reviewed by Mark Lam.
JSTests:


* stress/direct-tail-call-arity-mismatch-count-args.js: Added.
(foo):
(bar):

Source/_javascript_Core:

        
The CallFrameShuffler was assuming that the ArgumentCount that it should store into the
callee frame is simply the size of the args vector.
        
That's not true for DirectTailCall, which will pad the args vector with undefined if we
are optimizing an arity mismatch. We need to pass the ArgumentCount explicitly in this
case.

* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::emitCall):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileDirectCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToB3::compileTailCall):
* jit/CallFrameShuffleData.h:
* jit/CallFrameShuffler.cpp:
(JSC::CallFrameShuffler::CallFrameShuffler):
(JSC::CallFrameShuffler::prepareAny):
* jit/CallFrameShuffler.h:
(JSC::CallFrameShuffler::snapshot):
* jit/JITCall.cpp:
(JSC::JIT::compileOpCall):

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (209845 => 209846)


--- trunk/JSTests/ChangeLog	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/JSTests/ChangeLog	2016-12-15 01:25:16 UTC (rev 209846)
@@ -1,3 +1,14 @@
+2016-12-14  Filip Pizlo  <[email protected]>
+
+        DirectTailCall implementation needs to tell the shuffler what to put into the ArgumentCount explicitly
+        https://bugs.webkit.org/show_bug.cgi?id=165882
+
+        Reviewed by Mark Lam.
+
+        * stress/direct-tail-call-arity-mismatch-count-args.js: Added.
+        (foo):
+        (bar):
+
 2016-12-14  Keith Miller  <[email protected]>
 
         WebAssembly JS API: implement Global

Added: trunk/JSTests/stress/direct-tail-call-arity-mismatch-count-args.js (0 => 209846)


--- trunk/JSTests/stress/direct-tail-call-arity-mismatch-count-args.js	                        (rev 0)
+++ trunk/JSTests/stress/direct-tail-call-arity-mismatch-count-args.js	2016-12-15 01:25:16 UTC (rev 209846)
@@ -0,0 +1,20 @@
+"use strict";
+
+function foo(a, b, c, d, e, f) {
+    return arguments.length;
+}
+
+noInline(foo);
+
+function bar() {
+    return foo(1, 2, 3);
+}
+
+noInline(bar);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = bar();
+    if (result != 3)
+        throw "Error: bad result: " + result;
+}
+

Modified: trunk/Source/_javascript_Core/ChangeLog (209845 => 209846)


--- trunk/Source/_javascript_Core/ChangeLog	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-12-15 01:25:16 UTC (rev 209846)
@@ -1,3 +1,33 @@
+2016-12-14  Filip Pizlo  <[email protected]>
+
+        DirectTailCall implementation needs to tell the shuffler what to put into the ArgumentCount explicitly
+        https://bugs.webkit.org/show_bug.cgi?id=165882
+
+        Reviewed by Mark Lam.
+        
+        The CallFrameShuffler was assuming that the ArgumentCount that it should store into the
+        callee frame is simply the size of the args vector.
+        
+        That's not true for DirectTailCall, which will pad the args vector with undefined if we
+        are optimizing an arity mismatch. We need to pass the ArgumentCount explicitly in this
+        case.
+
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileDirectCallOrConstruct):
+        (JSC::FTL::DFG::LowerDFGToB3::compileTailCall):
+        * jit/CallFrameShuffleData.h:
+        * jit/CallFrameShuffler.cpp:
+        (JSC::CallFrameShuffler::CallFrameShuffler):
+        (JSC::CallFrameShuffler::prepareAny):
+        * jit/CallFrameShuffler.h:
+        (JSC::CallFrameShuffler::snapshot):
+        * jit/JITCall.cpp:
+        (JSC::JIT::compileOpCall):
+
 2016-12-14  Keith Miller  <[email protected]>
 
         WebAssembly JS API: implement Global

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (209845 => 209846)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-12-15 01:25:16 UTC (rev 209846)
@@ -879,6 +879,7 @@
             shuffleData.numLocals = m_jit.graph().frameRegisterCount();
             shuffleData.callee = ValueRecovery::inPair(calleeTagGPR, calleePayloadGPR);
             shuffleData.args.resize(numAllocatedArgs);
+            shuffleData.numPassedArgs = numPassedArgs;
 
             for (unsigned i = 0; i < numPassedArgs; ++i) {
                 Edge argEdge = m_jit.graph().varArgChild(node, i + 1);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (209845 => 209846)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-12-15 01:25:16 UTC (rev 209846)
@@ -851,7 +851,8 @@
             shuffleData.numLocals = m_jit.graph().frameRegisterCount();
             shuffleData.callee = ValueRecovery::inGPR(calleeGPR, DataFormatJS);
             shuffleData.args.resize(numAllocatedArgs);
-
+            shuffleData.numPassedArgs = numPassedArgs;
+            
             for (unsigned i = 0; i < numPassedArgs; ++i) {
                 Edge argEdge = m_jit.graph().varArgChild(node, i + 1);
                 GenerationInfo& info = generationInfo(argEdge.node());

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (209845 => 209846)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-12-15 01:25:16 UTC (rev 209846)
@@ -5992,6 +5992,7 @@
                     }
                     for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i)
                         shuffleData.args.append(ValueRecovery::constant(jsUndefined()));
+                    shuffleData.numPassedArgs = numPassedArgs;
                     shuffleData.setupCalleeSaveRegisters(jit.codeBlock());
                     
                     CallLinkInfo* callLinkInfo = jit.codeBlock()->addCallLinkInfo();
@@ -6158,6 +6159,8 @@
                 for (unsigned i = 0; i < numArgs; ++i)
                     shuffleData.args.append(params[1 + i].recoveryForJSValue());
 
+                shuffleData.numPassedArgs = numArgs;
+                
                 shuffleData.setupCalleeSaveRegisters(jit.codeBlock());
 
                 CallLinkInfo* callLinkInfo = jit.codeBlock()->addCallLinkInfo();

Modified: trunk/Source/_javascript_Core/jit/CallFrameShuffleData.h (209845 => 209846)


--- trunk/Source/_javascript_Core/jit/CallFrameShuffleData.h	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/jit/CallFrameShuffleData.h	2016-12-15 01:25:16 UTC (rev 209846)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,9 +35,10 @@
 struct CallFrameShuffleData {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    unsigned numLocals;
+    unsigned numLocals { UINT_MAX };
     ValueRecovery callee;
     Vector<ValueRecovery> args;
+    unsigned numPassedArgs { UINT_MAX };
 #if USE(JSVALUE64)
     RegisterMap<ValueRecovery> registers;
     GPRReg tagTypeNumber { InvalidGPRReg };

Modified: trunk/Source/_javascript_Core/jit/CallFrameShuffler.cpp (209845 => 209846)


--- trunk/Source/_javascript_Core/jit/CallFrameShuffler.cpp	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/jit/CallFrameShuffler.cpp	2016-12-15 01:25:16 UTC (rev 209846)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -44,6 +44,7 @@
         + roundArgumentCountToAlignFrame(data.args.size()))
     , m_frameDelta(m_alignedNewFrameSize - m_alignedOldFrameSize)
     , m_lockedRegisters(RegisterSet::allRegisters())
+    , m_numPassedArgs(data.numPassedArgs)
 {
     // We are allowed all the usual registers...
     for (unsigned i = GPRInfo::numberOfRegisters; i--; )
@@ -746,7 +747,8 @@
         dataLog("   * Storing the argument count into ", VirtualRegister { CallFrameSlot::argumentCount }, "\n");
     m_jit.store32(MacroAssembler::TrustedImm32(0),
         addressForNew(VirtualRegister { CallFrameSlot::argumentCount }).withOffset(TagOffset));
-    m_jit.store32(MacroAssembler::TrustedImm32(argCount()),
+    RELEASE_ASSERT(m_numPassedArgs != UINT_MAX);
+    m_jit.store32(MacroAssembler::TrustedImm32(m_numPassedArgs),
         addressForNew(VirtualRegister { CallFrameSlot::argumentCount }).withOffset(PayloadOffset));
 
     if (!isSlowPath()) {

Modified: trunk/Source/_javascript_Core/jit/CallFrameShuffler.h (209845 => 209846)


--- trunk/Source/_javascript_Core/jit/CallFrameShuffler.h	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/jit/CallFrameShuffler.h	2016-12-15 01:25:16 UTC (rev 209846)
@@ -102,6 +102,7 @@
 
         CallFrameShuffleData data;
         data.numLocals = numLocals();
+        data.numPassedArgs = m_numPassedArgs;
         data.callee = getNew(VirtualRegister { CallFrameSlot::callee })->recovery();
         data.args.resize(argCount());
         for (size_t i = 0; i < argCount(); ++i)
@@ -794,6 +795,8 @@
     // It returns false if it was unable to perform some safe writes
     // due to high register pressure.
     bool performSafeWrites();
+    
+    unsigned m_numPassedArgs { UINT_MAX };
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/jit/JITCall.cpp (209845 => 209846)


--- trunk/Source/_javascript_Core/jit/JITCall.cpp	2016-12-15 01:06:21 UTC (rev 209845)
+++ trunk/Source/_javascript_Core/jit/JITCall.cpp	2016-12-15 01:25:16 UTC (rev 209846)
@@ -198,6 +198,7 @@
 
     if (opcodeID == op_tail_call) {
         CallFrameShuffleData shuffleData;
+        shuffleData.numPassedArgs = instruction[3].u.operand;
         shuffleData.tagTypeNumber = GPRInfo::tagTypeNumberRegister;
         shuffleData.numLocals =
             instruction[4].u.operand - sizeof(CallerFrameAndPC) / sizeof(Register);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to