[JAEGER] Split JSOP_CALL into more decisions, removed primitive-this check on returns.

This commit is contained in:
David Anderson
2010-06-16 15:21:39 -07:00
parent 683d126f2b
commit c6b76609ce
10 changed files with 255 additions and 128 deletions

View File

@@ -699,8 +699,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_APPLY)
{
JaegerSpew(JSpew_Insns, " --- SCRIPTED CALL --- \n");
frame.forgetEverything();
dispatchCall(stubs::Call, GET_ARGC(PC));
inlineCallHelper(GET_ARGC(PC), false);
JaegerSpew(JSpew_Insns, " --- END SCRIPTED CALL --- \n");
}
END_CASE(JSOP_CALL)
@@ -834,8 +833,7 @@ mjit::Compiler::generateMethod()
BEGIN_CASE(JSOP_NEW)
{
JaegerSpew(JSpew_Insns, " --- NEW OPERATOR --- \n");
frame.forgetEverything();
dispatchCall(stubs::New, GET_ARGC(PC));
inlineCallHelper(GET_ARGC(PC), true);
JaegerSpew(JSpew_Insns, " --- END NEW OPERATOR --- \n");
}
END_CASE(JSOP_NEW)
@@ -1453,15 +1451,6 @@ mjit::Compiler::emitReturn()
}
}
/* Fix rval - :TODO: lower into NEW */
masm.load32(Address(JSFrameReg, offsetof(JSStackFrame, flags)), t0);
masm.and32(Imm32(JSFRAME_CONSTRUCTING), t0);
Jump j = masm.branchTest32(Assembler::NonZero, t0, t0);
stubcc.linkExit(j);
stubcc.leave();
stubcc.call(stubs::CopyThisv);
stubcc.rejoin(0);
/*
* r = fp->down
* a1 = f.cx
@@ -1512,10 +1501,85 @@ mjit::Compiler::stubCall(void *ptr, Uses uses, Defs defs)
}
void
mjit::Compiler::dispatchCall(VoidPtrStubUInt32 stub, uint32 argc)
mjit::Compiler::inlineCallHelper(uint32 argc, bool callingNew)
{
FrameEntry *fe = frame.peek(-int(argc + 2));
bool typeKnown = fe->isTypeKnown();
if (typeKnown && fe->getTypeTag() != JSVAL_MASK32_FUNOBJ) {
VoidStubUInt32 stub = callingNew ? stubs::SlowNew : stubs::SlowCall;
masm.move(Imm32(argc), Registers::ArgReg1);
masm.stubCall(stub, PC, frame.stackDepth() + script->nfixed);
frame.popn(argc + 2);
frame.pushSynced();
return;
}
bool hasTypeReg;
RegisterID type = Registers::ReturnReg;
RegisterID data = frame.tempRegForData(fe);
frame.pinReg(data);
Address addr = frame.addressOf(fe);
if (!typeKnown) {
if (frame.shouldAvoidTypeRemat(fe)) {
hasTypeReg = false;
} else {
type = frame.tempRegForType(fe);
hasTypeReg = true;
frame.pinReg(type);
}
}
/*
* We rely on the fact that syncAndKill() is not allowed to touch the
* registers we've preserved.
*/
frame.forgetEverything();
Jump invokeCallDone;
if (!typeKnown) {
Jump j;
if (!hasTypeReg)
j = masm.testFunObj(Assembler::NotEqual, frame.addressOf(fe));
else
j = masm.testFunObj(Assembler::NotEqual, type);
stubcc.linkExit(j);
stubcc.leave();
stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
stubcc.call(callingNew ? stubs::SlowNew : stubs::SlowCall);
invokeCallDone = stubcc.masm.jump();
}
/* Get function private pointer. */
Address funPrivate(data, offsetof(JSObject, fslots) +
JSSLOT_PRIVATE * sizeof(Value));
masm.loadData32(funPrivate, data);
/* Test if it's interpreted. */
frame.takeReg(data);
RegisterID t0 = frame.allocReg();
RegisterID t1 = frame.allocReg();
masm.load16(Address(data, offsetof(JSFunction, flags)), t0);
masm.move(t0, t1);
masm.and32(Imm32(JSFUN_KINDMASK), t1);
Jump notInterp = masm.branch32(Assembler::Below, t1, Imm32(JSFUN_INTERPRETED));
stubcc.linkExit(notInterp);
frame.freeReg(t0);
frame.freeReg(t1);
frame.freeReg(data);
stubcc.leave();
stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
stubcc.call(callingNew ? stubs::SlowNew : stubs::NativeCall);
Jump slowCallDone = stubcc.masm.jump();
/* Scripted call. */
masm.move(Imm32(argc), Registers::ArgReg1);
masm.stubCall(stub, PC, frame.stackDepth() + script->nfixed);
masm.stubCall(callingNew ? stubs::New : stubs::Call,
PC, frame.stackDepth() + script->nfixed);
/*
* Stub call returns a pointer to JIT'd code, or NULL.
@@ -1531,11 +1595,6 @@ mjit::Compiler::dispatchCall(VoidPtrStubUInt32 stub, uint32 argc)
Jump j = masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg, Registers::ReturnReg);
stubcc.linkExit(j);
frame.popn(argc + 2);
frame.takeReg(JSReturnReg_Type);
frame.takeReg(JSReturnReg_Data);
frame.pushRegs(JSReturnReg_Type, JSReturnReg_Data);
#ifndef JS_CPU_ARM
/*
* Since ARM does not push return addresses on the stack, we rely on the
@@ -1552,7 +1611,30 @@ mjit::Compiler::dispatchCall(VoidPtrStubUInt32 stub, uint32 argc)
masm.push(Registers::ReturnReg);
#endif
if (callingNew) {
/* Deal with primitive |this| */
masm.move(JSReturnReg_Type, Registers::ReturnReg);
masm.and32(Imm32(JSVAL_MASK32_OBJECT), Registers::ReturnReg);
Jump primitive = masm.branch32(Assembler::BelowOrEqual, Registers::ReturnReg,
Imm32(JSVAL_MASK32_CLEAR));
stubcc.linkExit(primitive);
FrameEntry *fe = frame.peek(-int(argc + 1));
Address thisv(frame.addressOf(fe));
stubcc.masm.loadTypeTag(thisv, JSReturnReg_Type);
stubcc.masm.loadData32(thisv, JSReturnReg_Data);
Jump primFix = stubcc.masm.jump();
stubcc.crossJump(primFix, masm.label());
}
frame.popn(argc + 2);
frame.takeReg(JSReturnReg_Type);
frame.takeReg(JSReturnReg_Data);
frame.pushRegs(JSReturnReg_Type, JSReturnReg_Data);
stubcc.leave();
slowCallDone.linkTo(stubcc.masm.label(), &stubcc.masm);
if (!typeKnown)
invokeCallDone.linkTo(stubcc.masm.label(), &stubcc.masm);
stubcc.rejoin(0);
}