Title: [191394] trunk/Source/_javascript_Core
Revision
191394
Author
[email protected]
Date
2015-10-21 11:44:44 -0700 (Wed, 21 Oct 2015)

Log Message

The FTL should place the CallSiteIndex on the call frame for JS calls when it fills in the patchpoint
https://bugs.webkit.org/show_bug.cgi?id=150104

Reviewed by Filip Pizlo.

We lower JS Calls to patchpoints in LLVM. LLVM may decide to duplicate
these patchpoints (or remove them). We eagerly store the CallSiteIndex on the 
call frame when lowering DFG to LLVM. But, because the patchpoint we lower to may
be duplicated, we really don't know the unique CallSiteIndex until we've
actually seen the resulting patchpoints after LLVM has completed its transformations.
To solve this, we now store the unique CallSiteIndex on the call frame header 
when generating code to fill into the patchpoint.

* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLJSCall.cpp:
(JSC::FTL::JSCall::JSCall):
(JSC::FTL::JSCall::emit):
* ftl/FTLJSCall.h:
(JSC::FTL::JSCall::stackmapID):
* ftl/FTLJSCallBase.cpp:
(JSC::FTL::JSCallBase::JSCallBase):
(JSC::FTL::JSCallBase::emit):
(JSC::FTL::JSCallBase::link):
* ftl/FTLJSCallBase.h:
* ftl/FTLJSCallVarargs.cpp:
(JSC::FTL::JSCallVarargs::JSCallVarargs):
(JSC::FTL::JSCallVarargs::numSpillSlotsNeeded):
(JSC::FTL::JSCallVarargs::emit):
* ftl/FTLJSCallVarargs.h:
(JSC::FTL::JSCallVarargs::node):
(JSC::FTL::JSCallVarargs::stackmapID):
* ftl/FTLJSTailCall.cpp:
(JSC::FTL::JSTailCall::JSTailCall):
(JSC::FTL::m_instructionOffset):
(JSC::FTL::JSTailCall::emit):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstructVarargs):
(JSC::FTL::DFG::LowerDFGToLLVM::callPreflight):
(JSC::FTL::DFG::LowerDFGToLLVM::codeOriginDescriptionOfCallSite):
(JSC::FTL::DFG::LowerDFGToLLVM::callCheck):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (191393 => 191394)


--- trunk/Source/_javascript_Core/ChangeLog	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ChangeLog	2015-10-21 18:44:44 UTC (rev 191394)
@@ -1,3 +1,48 @@
+2015-10-21  Saam barati  <[email protected]>
+
+        The FTL should place the CallSiteIndex on the call frame for JS calls when it fills in the patchpoint
+        https://bugs.webkit.org/show_bug.cgi?id=150104
+
+        Reviewed by Filip Pizlo.
+
+        We lower JS Calls to patchpoints in LLVM. LLVM may decide to duplicate
+        these patchpoints (or remove them). We eagerly store the CallSiteIndex on the 
+        call frame when lowering DFG to LLVM. But, because the patchpoint we lower to may
+        be duplicated, we really don't know the unique CallSiteIndex until we've
+        actually seen the resulting patchpoints after LLVM has completed its transformations.
+        To solve this, we now store the unique CallSiteIndex on the call frame header 
+        when generating code to fill into the patchpoint.
+
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLJSCall.cpp:
+        (JSC::FTL::JSCall::JSCall):
+        (JSC::FTL::JSCall::emit):
+        * ftl/FTLJSCall.h:
+        (JSC::FTL::JSCall::stackmapID):
+        * ftl/FTLJSCallBase.cpp:
+        (JSC::FTL::JSCallBase::JSCallBase):
+        (JSC::FTL::JSCallBase::emit):
+        (JSC::FTL::JSCallBase::link):
+        * ftl/FTLJSCallBase.h:
+        * ftl/FTLJSCallVarargs.cpp:
+        (JSC::FTL::JSCallVarargs::JSCallVarargs):
+        (JSC::FTL::JSCallVarargs::numSpillSlotsNeeded):
+        (JSC::FTL::JSCallVarargs::emit):
+        * ftl/FTLJSCallVarargs.h:
+        (JSC::FTL::JSCallVarargs::node):
+        (JSC::FTL::JSCallVarargs::stackmapID):
+        * ftl/FTLJSTailCall.cpp:
+        (JSC::FTL::JSTailCall::JSTailCall):
+        (JSC::FTL::m_instructionOffset):
+        (JSC::FTL::JSTailCall::emit):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstruct):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileCallOrConstructVarargs):
+        (JSC::FTL::DFG::LowerDFGToLLVM::callPreflight):
+        (JSC::FTL::DFG::LowerDFGToLLVM::codeOriginDescriptionOfCallSite):
+        (JSC::FTL::DFG::LowerDFGToLLVM::callCheck):
+
 2015-10-21  Geoffrey Garen  <[email protected]>
 
         Date creation should share a little code

Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2015-10-21 18:44:44 UTC (rev 191394)
@@ -657,7 +657,7 @@
         JSCall& call = state.jsCalls[i];
 
         CCallHelpers fastPathJIT(&vm, codeBlock);
-        call.emit(fastPathJIT, state.jitCode->stackmaps.stackSizeForLocals());
+        call.emit(fastPathJIT, state);
 
         char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset;
 
@@ -672,7 +672,7 @@
         JSCallVarargs& call = state.jsCallVarargses[i];
         
         CCallHelpers fastPathJIT(&vm, codeBlock);
-        call.emit(fastPathJIT, varargsSpillSlotsOffset);
+        call.emit(fastPathJIT, state, varargsSpillSlotsOffset);
 
         char* startOfIC = bitwise_cast<char*>(generatedFunction) + call.m_instructionOffset;
         size_t sizeOfIC = sizeOfICFor(call.node());

Modified: trunk/Source/_javascript_Core/ftl/FTLJSCall.cpp (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSCall.cpp	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSCall.cpp	2015-10-21 18:44:44 UTC (rev 191394)
@@ -29,6 +29,7 @@
 #if ENABLE(FTL_JIT)
 
 #include "DFGNode.h"
+#include "FTLState.h"
 #include "LinkBuffer.h"
 
 namespace JSC { namespace FTL {
@@ -41,21 +42,19 @@
 {
 }
 
-JSCall::JSCall(unsigned stackmapID, Node* node)
-    : JSCallBase(
-        node->op() == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call,
-        node->origin.semantic)
+JSCall::JSCall(unsigned stackmapID, Node* node, CodeOrigin callSiteDescriptionOrigin)
+    : JSCallBase(node->op() == Construct ? CallLinkInfo::Construct : CallLinkInfo::Call, node->origin.semantic, callSiteDescriptionOrigin)
     , m_stackmapID(stackmapID)
     , m_instructionOffset(0)
 {
     ASSERT(node->op() == Call || node->op() == Construct || node->op() == TailCallInlinedCaller);
 }
 
-void JSCall::emit(CCallHelpers& jit, unsigned stackSizeForLocals)
+void JSCall::emit(CCallHelpers& jit, State& state)
 {
-    JSCallBase::emit(jit);
+    JSCallBase::emit(jit, state);
 
-    jit.addPtr(CCallHelpers::TrustedImm32(- static_cast<int64_t>(stackSizeForLocals)), CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
+    jit.addPtr(CCallHelpers::TrustedImm32(- static_cast<int64_t>(state.jitCode->stackmaps.stackSizeForLocals())), CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister);
 }
 
 } } // namespace JSC::FTL

Modified: trunk/Source/_javascript_Core/ftl/FTLJSCall.h (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSCall.h	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSCall.h	2015-10-21 18:44:44 UTC (rev 191394)
@@ -41,9 +41,9 @@
 class JSCall : public JSCallBase {
 public:
     JSCall();
-    JSCall(unsigned stackmapID, DFG::Node*);
+    JSCall(unsigned stackmapID, DFG::Node*, CodeOrigin callSiteDescriptionOrigin);
 
-    void emit(CCallHelpers&, unsigned stackSizeForLocals);
+    void emit(CCallHelpers&, State&);
     
     unsigned stackmapID() const { return m_stackmapID; }
     

Modified: trunk/Source/_javascript_Core/ftl/FTLJSCallBase.cpp (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSCallBase.cpp	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSCallBase.cpp	2015-10-21 18:44:44 UTC (rev 191394)
@@ -29,6 +29,7 @@
 #if ENABLE(FTL_JIT)
 
 #include "DFGNode.h"
+#include "FTLState.h"
 #include "LinkBuffer.h"
 
 namespace JSC { namespace FTL {
@@ -41,15 +42,19 @@
 {
 }
 
-JSCallBase::JSCallBase(CallLinkInfo::CallType type, CodeOrigin origin)
+JSCallBase::JSCallBase(CallLinkInfo::CallType type, CodeOrigin semantic, CodeOrigin callSiteDescription)
     : m_type(type)
-    , m_origin(origin)
+    , m_semanticeOrigin(semantic)
+    , m_callSiteDescriptionOrigin(callSiteDescription)
     , m_callLinkInfo(nullptr)
 {
 }
 
-void JSCallBase::emit(CCallHelpers& jit)
+void JSCallBase::emit(CCallHelpers& jit, State& state)
 {
+    CallSiteIndex callSiteIndex = state.jitCode->common.addUniqueCallSiteIndex(m_callSiteDescriptionOrigin);
+    jit.store32(CCallHelpers::TrustedImm32(callSiteIndex.bits()), CCallHelpers::tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount)));
+
     m_callLinkInfo = jit.codeBlock()->addCallLinkInfo();
     
     if (CallLinkInfo::callModeFor(m_type) == CallMode::Tail)
@@ -79,7 +84,7 @@
     else
         done.link(&jit);
 
-    m_callLinkInfo->setUpCall(m_type, m_origin, GPRInfo::regT0);
+    m_callLinkInfo->setUpCall(m_type, m_semanticeOrigin, GPRInfo::regT0);
 }
 
 void JSCallBase::link(VM& vm, LinkBuffer& linkBuffer)

Modified: trunk/Source/_javascript_Core/ftl/FTLJSCallBase.h (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSCallBase.h	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSCallBase.h	2015-10-21 18:44:44 UTC (rev 191394)
@@ -42,17 +42,20 @@
 
 namespace FTL {
 
+class State;
+
 class JSCallBase {
 public:
     JSCallBase();
-    JSCallBase(CallLinkInfo::CallType, CodeOrigin);
+    JSCallBase(CallLinkInfo::CallType, CodeOrigin semantic, CodeOrigin callSiteDescription);
     
-    void emit(CCallHelpers&);
+    void emit(CCallHelpers&, State&);
     void link(VM&, LinkBuffer&);
     
 protected:
     CallLinkInfo::CallType m_type;
-    CodeOrigin m_origin;
+    CodeOrigin m_semanticeOrigin;
+    CodeOrigin m_callSiteDescriptionOrigin; // These two code origins may be different with tail calls under some circumstances of inlining. See relevant comment in LowerDFGToLLVM.
     CCallHelpers::DataLabelPtr m_targetToCheck;
     CCallHelpers::Call m_fastCall;
     CCallHelpers::Call m_slowCall;

Modified: trunk/Source/_javascript_Core/ftl/FTLJSCallVarargs.cpp (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSCallVarargs.cpp	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSCallVarargs.cpp	2015-10-21 18:44:44 UTC (rev 191394)
@@ -30,6 +30,7 @@
 
 #include "DFGNode.h"
 #include "DFGOperations.h"
+#include "FTLState.h"
 #include "JSCInlines.h"
 #include "LinkBuffer.h"
 #include "ScratchRegisterAllocator.h"
@@ -46,14 +47,14 @@
 {
 }
 
-JSCallVarargs::JSCallVarargs(unsigned stackmapID, Node* node)
+JSCallVarargs::JSCallVarargs(unsigned stackmapID, Node* node, CodeOrigin callSiteDescriptionOrigin)
     : m_stackmapID(stackmapID)
     , m_node(node)
     , m_callBase(
         (node->op() == ConstructVarargs || node->op() == ConstructForwardVarargs)
         ? CallLinkInfo::ConstructVarargs : (node->op() == TailCallVarargs || node->op() == TailCallForwardVarargs)
         ? CallLinkInfo::TailCallVarargs : CallLinkInfo::CallVarargs,
-        node->origin.semantic)
+        node->origin.semantic, callSiteDescriptionOrigin)
     , m_instructionOffset(0)
 {
     ASSERT(
@@ -68,7 +69,7 @@
     return 4;
 }
 
-void JSCallVarargs::emit(CCallHelpers& jit, int32_t spillSlotsOffset)
+void JSCallVarargs::emit(CCallHelpers& jit, State& state, int32_t spillSlotsOffset)
 {
     // We are passed three pieces of information:
     // - The callee.
@@ -204,7 +205,7 @@
     // stack frame to already be set up, which it is.
     jit.store64(GPRInfo::regT0, CCallHelpers::calleeFrameSlot(JSStack::Callee));
 
-    m_callBase.emit(jit);
+    m_callBase.emit(jit, state);
     
     // Undo the damage we've done.
     if (isARM64()) {

Modified: trunk/Source/_javascript_Core/ftl/FTLJSCallVarargs.h (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSCallVarargs.h	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSCallVarargs.h	2015-10-21 18:44:44 UTC (rev 191394)
@@ -43,13 +43,13 @@
 class JSCallVarargs {
 public:
     JSCallVarargs();
-    JSCallVarargs(unsigned stackmapID, DFG::Node*);
+    JSCallVarargs(unsigned stackmapID, DFG::Node*, CodeOrigin callSiteDescriptionOrigin);
     
     DFG::Node* node() const { return m_node; }
     
     static unsigned numSpillSlotsNeeded();
     
-    void emit(CCallHelpers&, int32_t spillSlotsOffset);
+    void emit(CCallHelpers&, State&, int32_t spillSlotsOffset);
     void link(VM&, LinkBuffer&, CodeLocationLabel exceptionHandler);
     
     unsigned stackmapID() const { return m_stackmapID; }

Modified: trunk/Source/_javascript_Core/ftl/FTLJSTailCall.cpp (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLJSTailCall.cpp	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLJSTailCall.cpp	2015-10-21 18:44:44 UTC (rev 191394)
@@ -179,7 +179,7 @@
 } // anonymous namespace
 
 JSTailCall::JSTailCall(unsigned stackmapID, Node* node, Vector<ExitValue> arguments)
-    : JSCallBase(CallLinkInfo::TailCall, node->origin.semantic)
+    : JSCallBase(CallLinkInfo::TailCall, node->origin.semantic, node->origin.semantic)
     , m_stackmapID(stackmapID)
     , m_arguments { WTF::move(arguments) }
     , m_instructionOffset(0)
@@ -318,7 +318,7 @@
 
     jit.abortWithReason(JITDidReturnFromTailCall);
 
-    m_callLinkInfo->setUpCall(m_type, m_origin, calleeGPR);
+    m_callLinkInfo->setUpCall(m_type, m_semanticeOrigin, calleeGPR);
 }
 
 } } // namespace JSC::FTL

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (191393 => 191394)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2015-10-21 18:42:06 UTC (rev 191393)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2015-10-21 18:44:44 UTC (rev 191394)
@@ -4462,12 +4462,10 @@
         for (unsigned i = 0; i < padding; ++i)
             arguments.append(getUndef(m_out.int64));
         
-        callPreflight();
-        
         LValue call = m_out.call(m_out.patchpointInt64Intrinsic(), arguments);
         setInstructionCallingConvention(call, LLVMWebKitJSCallConv);
         
-        m_ftlState.jsCalls.append(JSCall(stackmapID, m_node));
+        m_ftlState.jsCalls.append(JSCall(stackmapID, m_node, codeOriginDescriptionOfCallSite()));
         
         setJSValue(call);
     }
@@ -4544,12 +4542,10 @@
         ASSERT(thisArg);
         arguments.append(thisArg);
         
-        callPreflight();
-        
         LValue call = m_out.call(m_out.patchpointInt64Intrinsic(), arguments);
         setInstructionCallingConvention(call, LLVMCCallConv);
         
-        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, m_node));
+        m_ftlState.jsCallVarargses.append(JSCallVarargs(stackmapID, m_node, codeOriginDescriptionOfCallSite()));
 
         switch (m_node->op()) {
         case TailCallVarargs:
@@ -8665,16 +8661,27 @@
                 m_ftlState.jitCode->common.addCodeOrigin(codeOrigin).bits()),
             tagFor(JSStack::ArgumentCount));
     }
+
     void callPreflight()
     {
+        callPreflight(codeOriginDescriptionOfCallSite());
+    }
+
+    CodeOrigin codeOriginDescriptionOfCallSite() const
+    {
         CodeOrigin codeOrigin = m_node->origin.semantic;
-
         if (m_node->op() == TailCallInlinedCaller
             || m_node->op() == TailCallVarargsInlinedCaller
-            || m_node->op() == TailCallForwardVarargsInlinedCaller)
+            || m_node->op() == TailCallForwardVarargsInlinedCaller) {
+            // This case arises when you have a situation like this:
+            // foo makes a call to bar, bar is inlined in foo. bar makes a call
+            // to baz and baz is inlined in bar. And then baz makes a tail-call to jaz,
+            // and jaz is inlined in baz. We want the callframe for jaz to appear to 
+            // have caller be bar.
             codeOrigin = *codeOrigin.inlineCallFrame->getCallerSkippingDeadFrames();
+        }
 
-        callPreflight(codeOrigin);
+        return codeOrigin;
     }
     
     void callCheck()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to