Title: [96391] trunk/Source/_javascript_Core
Revision
96391
Author
[email protected]
Date
2011-09-29 23:17:13 -0700 (Thu, 29 Sep 2011)

Log Message

Add op_call/op_constructor support to JSVALUE32_64 DFG JIT
https://bugs.webkit.org/show_bug.cgi?id=69120

Patch by Yuqiang Xian <[email protected]> on 2011-09-29
Reviewed by Gavin Barraclough.

Improve the coverage of JSVALUE32_64 DFG JIT.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.h:
(JSC::DFG::canCompileOpcode):
* dfg/DFGJITCodeGenerator.h:
(JSC::DFG::tagOfCallData):
(JSC::DFG::payloadOfCallData):
* dfg/DFGJITCodeGenerator32_64.cpp:
(JSC::DFG::JITCodeGenerator::emitCall):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (96390 => 96391)


--- trunk/Source/_javascript_Core/ChangeLog	2011-09-30 05:22:55 UTC (rev 96390)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-09-30 06:17:13 UTC (rev 96391)
@@ -1,5 +1,24 @@
 2011-09-29  Yuqiang Xian  <[email protected]>
 
+        Add op_call/op_constructor support to JSVALUE32_64 DFG JIT
+        https://bugs.webkit.org/show_bug.cgi?id=69120
+
+        Reviewed by Gavin Barraclough.
+
+        Improve the coverage of JSVALUE32_64 DFG JIT.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.h:
+        (JSC::DFG::canCompileOpcode):
+        * dfg/DFGJITCodeGenerator.h:
+        (JSC::DFG::tagOfCallData):
+        (JSC::DFG::payloadOfCallData):
+        * dfg/DFGJITCodeGenerator32_64.cpp:
+        (JSC::DFG::JITCodeGenerator::emitCall):
+
+2011-09-29  Yuqiang Xian  <[email protected]>
+
         DFG JIT - register not unlocked after usage in ArithDiv
         https://bugs.webkit.org/show_bug.cgi?id=69122
 

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (96390 => 96391)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-09-30 05:22:55 UTC (rev 96390)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-09-30 06:17:13 UTC (rev 96391)
@@ -1382,7 +1382,6 @@
             addToGraph(ThrowReferenceError);
             LAST_OPCODE(op_throw_reference_error);
             
-#if USE(JSVALUE64)
         case op_call: {
             NodeIndex callTarget = get(currentInstruction[1].u.operand);
             if (m_graph.isFunctionConstant(m_codeBlock, callTarget)) {
@@ -1416,7 +1415,6 @@
             addCall(interpreter, currentInstruction, Construct);
             NEXT_OPCODE(op_construct);
         }
-#endif
             
         case op_call_put_result:
             NEXT_OPCODE(op_call_put_result);

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.h (96390 => 96391)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.h	2011-09-30 05:22:55 UTC (rev 96390)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.h	2011-09-30 06:17:13 UTC (rev 96391)
@@ -113,10 +113,8 @@
     case op_loop_if_greatereq:
     case op_ret:
     case op_end:
-#if USE(JSVALUE64)
     case op_call:
     case op_construct:
-#endif
     case op_call_put_result:
     case op_resolve:
     case op_resolve_base:

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (96390 => 96391)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-09-30 05:22:55 UTC (rev 96390)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h	2011-09-30 06:17:13 UTC (rev 96391)
@@ -785,7 +785,19 @@
     {
         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)));
     }
-    
+
+#if USE(JSVALUE32_64)    
+    MacroAssembler::Address tagOfCallData(int idx)
+    {
+        return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
+    }
+
+    MacroAssembler::Address payloadOfCallData(int idx)
+    {
+        return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + idx) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
+    }
+#endif
+
     void emitCall(Node&);
     
     void speculationCheck(MacroAssembler::Jump jumpToFail);

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp (96390 => 96391)


--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-09-30 05:22:55 UTC (rev 96390)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator32_64.cpp	2011-09-30 06:17:13 UTC (rev 96391)
@@ -1586,11 +1586,101 @@
     jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
 }
 
-void NO_RETURN JITCodeGenerator::emitCall(Node& node)
+void JITCodeGenerator::emitCall(Node& node)
 {
-    // FIXME: It's not supported yet!
-    ASSERT_NOT_REACHED();
-    UNUSED_PARAM(node);
+    P_DFGOperation_E slowCallFunction;
+    bool isCall;
+
+    if (node.op == Call) {
+        slowCallFunction = operationLinkCall;
+        isCall = true;
+    } else {
+        ASSERT(node.op == Construct);
+        slowCallFunction = operationLinkConstruct;
+        isCall = false;
+    }
+
+    NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
+    JSValueOperand callee(this, calleeNodeIndex);
+    GPRReg calleeTagGPR = callee.tagGPR();
+    GPRReg calleePayloadGPR = callee.payloadGPR();
+    use(calleeNodeIndex);
+
+    // the call instruction's first child is either the function (normal call) or the
+    // receiver (method call). subsequent children are the arguments.
+    int numArgs = node.numChildren() - 1;
+
+    // For constructors, the this argument is not passed but we have to make space
+    // for it.
+    int numPassedArgs = numArgs + (isCall ? 0 : 1);
+
+    // amount of stuff (in units of sizeof(Register)) that we need to place at the
+    // top of the JS stack.
+    int callDataSize = 0;
+
+    // first there are the arguments
+    callDataSize += numPassedArgs;
+
+    // and then there is the call frame header
+    callDataSize += RegisterFile::CallFrameHeaderSize;
+
+    m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), payloadOfCallData(RegisterFile::ArgumentCount));
+    m_jit.store32(MacroAssembler::TrustedImm32(JSValue::Int32Tag), tagOfCallData(RegisterFile::ArgumentCount));
+    m_jit.storePtr(GPRInfo::callFrameRegister, payloadOfCallData(RegisterFile::CallerFrame));
+    m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), tagOfCallData(RegisterFile::CallerFrame));
+
+    for (int argIdx = 0; argIdx < numArgs; argIdx++) {
+        NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx];
+        JSValueOperand arg(this, argNodeIndex);
+        GPRReg argTagGPR = arg.tagGPR();
+        GPRReg argPayloadGPR = arg.payloadGPR();
+        use(argNodeIndex);
+
+        m_jit.store32(argTagGPR, tagOfCallData(-callDataSize + argIdx + (isCall ? 0 : 1)));
+        m_jit.store32(argPayloadGPR, payloadOfCallData(-callDataSize + argIdx + (isCall ? 0 : 1)));
+    }
+
+    m_jit.store32(calleeTagGPR, tagOfCallData(RegisterFile::Callee));
+    m_jit.store32(calleePayloadGPR, payloadOfCallData(RegisterFile::Callee));
+
+    flushRegisters();
+
+    GPRResult resultPayload(this);
+    GPRResult2 resultTag(this);
+    GPRReg resultPayloadGPR = resultPayload.gpr();
+    GPRReg resultTagGPR = resultTag.gpr();
+
+    JITCompiler::DataLabelPtr targetToCheck;
+    JITCompiler::Jump slowPath;
+
+    slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleePayloadGPR, targetToCheck);
+    m_jit.loadPtr(MacroAssembler::Address(calleePayloadGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultPayloadGPR);
+    m_jit.storePtr(resultPayloadGPR, payloadOfCallData(RegisterFile::ScopeChain));
+    m_jit.store32(MacroAssembler::TrustedImm32(JSValue::CellTag), tagOfCallData(RegisterFile::ScopeChain));
+
+    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
+
+    JITCompiler::Call fastCall = m_jit.nearCall();
+    m_jit.notifyCall(fastCall, m_jit.graph()[m_compileIndex].codeOrigin);
+
+    JITCompiler::Jump done = m_jit.jump();
+
+    slowPath.link(&m_jit);
+
+    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    m_jit.push(GPRInfo::argumentGPR0);
+    JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, m_jit.graph()[m_compileIndex].codeOrigin);
+    m_jit.move(Imm32(numPassedArgs), GPRInfo::regT1);
+    m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
+    m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), m_jit.graph()[m_compileIndex].codeOrigin);
+
+    done.link(&m_jit);
+
+    setupResults(resultTagGPR, resultPayloadGPR);
+
+    jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
+
+    m_jit.addJSCall(fastCall, slowCall, targetToCheck, isCall, m_jit.graph()[m_compileIndex].codeOrigin);
 }
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to