Don't restore FP twice when exiting a fragment (513787, r=rreitmai).

This commit is contained in:
Andreas Gal 2009-08-31 16:35:50 -07:00
parent a33078ac37
commit 292f7e316d
7 changed files with 48 additions and 36 deletions

View File

@ -105,6 +105,7 @@ namespace nanojit
verbose_only( _logc = logc; )
verbose_only( _outputCache = 0; )
verbose_only( outlineEOL[0] = '\0'; )
verbose_only( outputAddr = false; )
reset();
}
@ -538,7 +539,6 @@ namespace nanojit
swapptrs();
_inExit = true;
//verbose_only( verbose_outputf(" LIR_xend swapptrs, _nIns is now %08X(%08X), _nExitIns is now %08X(%08X)",_nIns, *_nIns,_nExitIns,*_nExitIns) );
debug_only( _sv_fpuStkDepth = _fpuStkDepth; _fpuStkDepth = 0; )
nFragExit(guard);
@ -612,11 +612,10 @@ namespace nanojit
_stats.codeExitStart = _nExitIns-1;
#endif /* PERFM */
_epilogue = genEpilogue();
_branchStateMap = branchStateMap;
_epilogue = NULL;
verbose_only( outputAddr=true; )
verbose_only( asm_output("[epilogue]"); )
nBeginAssembly();
}
void Assembler::assemble(Fragment* frag)

View File

@ -301,6 +301,7 @@ namespace nanojit
// platform specific implementation (see NativeXXX.cpp file)
void nInit(AvmCore *);
void nBeginAssembly();
Register nRegisterAllocFromSet(RegisterMask set);
void nRegisterResetAll(RegAlloc& a);
static void nPatchBranch(NIns* branch, NIns* location);

View File

@ -505,7 +505,10 @@ Assembler::nFragExit(LInsp guard)
// The target doesn't exit yet, so emit a jump to the epilogue. If the
// target is created later on, the jump will be patched.
GuardRecord * gr = guard->record();
GuardRecord *gr = guard->record();
if (!_epilogue)
_epilogue = genEpilogue();
// Jump to the epilogue. This may get patched later, but JMP_far always
// emits two instructions even when only one is required, so patching
@ -549,13 +552,6 @@ Assembler::genEpilogue()
POP_mask(savingMask); // regs
// Pop the stack frame.
// As far as I can tell, the generated code doesn't use the stack between
// popping the stack frame in nFragExit and getting here and so this MOV
// should be redundant. However, removing this seems to break some regular
// expression stuff.
MOV(SP,FP);
// nFragExit loads the guard record pointer into R2, but we need it in R0
// so it must be moved here.
MOV(R0,R2); // return GuardRecord*
@ -2360,9 +2356,11 @@ Assembler::asm_int(LInsp ins)
void
Assembler::asm_ret(LIns *ins)
{
if (_nIns != _epilogue) {
B(_epilogue);
}
genEpilogue();
// Pop the stack frame.
MOV(SP,FP);
assignSavedRegs();
LIns *value = ins->oprnd1();
if (ins->isop(LIR_ret)) {

View File

@ -118,7 +118,6 @@ namespace nanojit
}
NIns* Assembler::genEpilogue() {
max_param_size = 0;
BLR();
MTLR(R0);
LP(R0, lr_offset, SP);
@ -563,9 +562,7 @@ namespace nanojit
}
void Assembler::asm_ret(LIns *ins) {
UNLESS_PEDANTIC( if (_nIns != _epilogue) ) {
br(_epilogue, 0);
}
genEpilogue();
assignSavedParams();
LIns *value = ins->oprnd1();
Register r = ins->isop(LIR_ret) ? R3 : F1;
@ -1179,6 +1176,10 @@ namespace nanojit
void Assembler::nInit(AvmCore*) {
}
void Assembler::nBeginAssembly() {
max_param_size = 0;
}
void Assembler::nativePageSetup() {
if (!_nIns) {
codeAlloc();

View File

@ -76,6 +76,9 @@ namespace nanojit
has_cmov = true;
}
void Assembler::nBeginAssembly() {
}
NIns* Assembler::genPrologue()
{
/**
@ -126,7 +129,9 @@ namespace nanojit
}
else
{
// target doesn't exit yet. emit jump to epilog, and set up to patch later.
// Target doesn't exit yet. Emit jump to epilog, and set up to patch later.
if (!_epilogue)
_epilogue = genEpilogue();
lr = guard->record();
JMP_long((intptr_t)_epilogue);
lr->jmp = _nIns;
@ -1042,9 +1047,7 @@ namespace nanojit
void Assembler::asm_ret(LInsp ins)
{
if (_nIns != _epilogue) {
JMP(_epilogue);
}
genEpilogue();
assignSavedRegs();
LIns *val = ins->oprnd1();
if (ins->isop(LIR_ret)) {

View File

@ -898,7 +898,7 @@ namespace nanojit
}
void Assembler::asm_ret(LIns *ins) {
JMP(_epilogue);
genEpilogue();
assignSavedRegs();
LIns *value = ins->oprnd1();
Register r = ins->isop(LIR_ret) ? RAX : XMM0;
@ -1169,7 +1169,6 @@ namespace nanojit
// mov rsp, rbp
// pop rbp
// ret
max_stk_used = 0;
emit(X64_ret);
emitr(X64_popr, RBP);
MR(RSP, RBP);
@ -1234,8 +1233,12 @@ namespace nanojit
TODO(nFragExit);
}
void Assembler::nInit(AvmCore*)
{}
void Assembler::nInit(AvmCore*) {
}
void Assembler::nBeginAssembly() {
max_stk_used = 0;
}
void Assembler::underrunProtect(ptrdiff_t bytes) {
NanoAssertMsg(bytes<=LARGEST_UNDERRUN_PROT, "constant LARGEST_UNDERRUN_PROT is too small");

View File

@ -83,6 +83,9 @@ namespace nanojit
OSDep::getDate();
}
void Assembler::nBeginAssembly() {
}
NIns* Assembler::genPrologue()
{
/**
@ -119,12 +122,15 @@ namespace nanojit
Fragment *frag = exit->target;
GuardRecord *lr = 0;
bool destKnown = (frag && frag->fragEntry);
// Generate jump to epilog and initialize lr.
// If the guard is LIR_xtbl, use a jump table with epilog in every entry
if (guard->isop(LIR_xtbl)) {
lr = guard->record();
Register r = EDX;
SwitchInfo* si = guard->record()->exit->switchInfo;
if (!_epilogue)
_epilogue = genEpilogue();
emitJumpTable(si, _epilogue);
JMP_indirect(r);
LEAmi4(r, si->table, r);
@ -133,14 +139,16 @@ namespace nanojit
if (destKnown && !trees) {
JMP(frag->fragEntry);
lr = 0;
} else { // target doesn't exist. Use 0 jump offset and patch later
} else { // Target doesn't exist. Jump to an epilogue for now. This can be patched later.
if (!_epilogue)
_epilogue = genEpilogue();
lr = guard->record();
JMP_long(_epilogue);
lr->jmp = _nIns;
}
}
// first restore ESP from EBP, undoing SUBi(SP,amt) from genPrologue
// Restore ESP from EBP, undoing SUBi(SP,amt) in the prologue
MR(SP,FP);
// return value is GuardRecord*
@ -150,9 +158,8 @@ namespace nanojit
NIns *Assembler::genEpilogue()
{
RET();
POPr(FP); // Restore caller's FP.
MR(SP,FP); // pop the stack frame
return _nIns;
}
@ -1670,9 +1677,11 @@ namespace nanojit
void Assembler::asm_ret(LInsp ins)
{
if (_nIns != _epilogue) {
JMP(_epilogue);
}
genEpilogue();
// Restore ESP from EBP, undoing SUBi(SP,amt) in the prologue
MR(SP,FP);
assignSavedRegs();
LIns *val = ins->oprnd1();
if (ins->isop(LIR_ret)) {
@ -1688,7 +1697,5 @@ namespace nanojit
TODO(asm_promote);
}
#endif /* FEATURE_NANOJIT */
}