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