2011-09-25 Filip Pizlo <fpizlo@apple.com>
+ DFG JIT Construct opcode takes a this argument even though it's
+ not passed
+ https://bugs.webkit.org/show_bug.cgi?id=68782
+
+ Reviewed by Oliver Hunt.
+
+ This is performance-neutral, mostly. It's a slight speed-up on
+ v8-splay.
+
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addCall):
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::emitCall):
+
+2011-09-25 Filip Pizlo <fpizlo@apple.com>
+
DFG tracking of the value in cachedResultRegister does not handle
op_mov correctly
https://bugs.webkit.org/show_bug.cgi?id=68781
int argCount = currentInstruction[2].u.operand;
int registerOffset = currentInstruction[3].u.operand;
int firstArg = registerOffset - argCount - RegisterFile::CallFrameHeaderSize;
- for (int argIdx = firstArg; argIdx < firstArg + argCount; argIdx++)
+ for (int argIdx = firstArg + (op == Construct ? 1 : 0); argIdx < firstArg + argCount; argIdx++)
addVarArgChild(get(argIdx));
NodeIndex call = addToGraph(Node::VarArg, op, OpInfo(0), OpInfo(prediction));
if (interpreter->getOpcodeID(putInstruction->u.opcode) == op_call_put_result)
// 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 += numArgs;
+ callDataSize += numPassedArgs;
// and then there is the call frame header
callDataSize += RegisterFile::CallFrameHeaderSize;
- m_jit.storePtr(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(numArgs))), addressOfCallData(RegisterFile::ArgumentCount));
+ m_jit.storePtr(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(numPassedArgs))), addressOfCallData(RegisterFile::ArgumentCount));
m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame));
- if (node.op == Construct)
- use(m_jit.graph().m_varArgChildren[node.firstChild() + 1]);
-
- for (int argIdx = (node.op == Call ? 0 : 1); argIdx < numArgs; argIdx++) {
+ for (int argIdx = 0; argIdx < numArgs; argIdx++) {
NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx];
JSValueOperand arg(this, argNodeIndex);
GPRReg argGPR = arg.gpr();
use(argNodeIndex);
- m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx));
+ m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx + (isCall ? 0 : 1)));
}
m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
JITCompiler::Call slowCall = m_jit.appendCallWithFastExceptionCheck(slowCallFunction, m_jit.graph()[m_compileIndex].codeOrigin);
- m_jit.move(Imm32(numArgs), GPRInfo::regT1);
+ 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);