[INFER] Use ebx as a general purpose register on x86, bug 638506.

This commit is contained in:
Brian Hackett 2011-04-13 12:09:31 -07:00
parent 8d6da2ebd6
commit 40a0021182
7 changed files with 54 additions and 16 deletions

View File

@ -634,6 +634,21 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
if (pinlined)
*pinlined = ptr;
}
restoreStackBase();
}
void restoreStackBase() {
#if defined(JS_CPU_X86)
/*
* We use the %ebp base stack pointer on x86 to store the JSStackFrame.
* Restore this before calling so that debuggers can construct a
* coherent stack if we crash outside of JIT code.
*/
JS_STATIC_ASSERT(JSFrameReg == JSC::X86Registers::ebp);
move(JSC::X86Registers::esp, JSFrameReg);
addPtr(Imm32(VMFrame::STACK_BASE_DIFFERENCE), JSFrameReg);
#endif
}
// An infallible VM call is a stub call (taking a VMFrame & and one
@ -652,11 +667,8 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
setupFallibleVMFrame(inlining, pc, pinlined, frameDepth);
Call call = wrapVMCall(ptr);
if (inlining) {
// Restore the frame pointer from the VM, in case it pushed/popped
// some frames or expanded any inline frames.
loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
}
// Restore the frame pointer from the VM.
loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
return call;
}

View File

@ -110,7 +110,9 @@ struct Registers {
#endif
// Register that homes the current JSStackFrame.
#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
#if defined(JS_CPU_X86)
static const RegisterID JSFrameReg = JSC::X86Registers::ebp;
#elif defined(JS_CPU_X64)
static const RegisterID JSFrameReg = JSC::X86Registers::ebx;
#elif defined(JS_CPU_ARM)
static const RegisterID JSFrameReg = JSC::ARMRegisters::r11;
@ -153,6 +155,9 @@ struct Registers {
#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
static const uint32 TempRegs =
(1 << JSC::X86Registers::eax)
# if defined(JS_CPU_X86)
| (1 << JSC::X86Registers::ebx)
# endif
| (1 << JSC::X86Registers::ecx)
| (1 << JSC::X86Registers::edx)
# if defined(JS_CPU_X64)

View File

@ -313,15 +313,18 @@ SYMBOL_STRING(JaegerTrampoline) ":" "\n"
"movl %esp, %ecx" "\n"
"call " SYMBOL_STRING_VMFRAME(PushActiveVMFrame) "\n"
"jmp *16(%ebp)" "\n"
"movl 28(%esp), %ebp" "\n" /* load fp for JIT code */
"jmp *72(%esp)" "\n"
);
asm volatile (
".text\n"
".globl " SYMBOL_STRING(JaegerTrampolineReturn) "\n"
SYMBOL_STRING(JaegerTrampolineReturn) ":" "\n"
"movl %edx, 0x18(%ebx)" "\n"
"movl %ecx, 0x1C(%ebx)" "\n"
"movl %edx, 0x18(%ebp)" "\n"
"movl %ecx, 0x1C(%ebp)" "\n"
"movl %esp, %ebp" "\n"
"addl $0x38, %ebp" "\n" /* Restore stack at STACK_BASE_DIFFERENCE */
"movl %esp, %ecx" "\n"
"call " SYMBOL_STRING_VMFRAME(PopActiveVMFrame) "\n"
@ -550,15 +553,18 @@ extern "C" {
mov ecx, esp;
call PushActiveVMFrame;
jmp dword ptr [ebp + 16];
mov ebp, [esp + 28]; /* load fp for JIT code */
jmp dword ptr [esp + 72];
}
}
__declspec(naked) void JaegerTrampolineReturn()
{
__asm {
mov [ebx + 0x18], edx;
mov [ebx + 0x1C], ecx;
mov [ebp + 0x18], edx;
mov [ebp + 0x1C], ecx;
mov ebp, esp;
add ebp, 0x38; /* Restore stack at STACK_BASE_DIFFERENCE */
mov ecx, esp;
call PopActiveVMFrame;

View File

@ -103,6 +103,10 @@ struct VMFrame
return reinterpret_cast<void**>(this) - 1;
}
# endif
/* The gap between ebp and esp in JaegerTrampoline frames on X86 platforms. */
static const uint32 STACK_BASE_DIFFERENCE = 0x38;
#elif defined(JS_CPU_X64)
void *savedRBX;
# ifdef _WIN64

View File

@ -872,7 +872,7 @@ class CallCompiler : public BaseCompiler
masm.storePtr(t0, FrameAddress(offsetof(VMFrame, regs.sp)));
}
/* Store fp. Note this doesn't need restoring afterwards, as we aren't inlining. */
/* Store fp. */
masm.storePtr(JSFrameReg, FrameAddress(offsetof(VMFrame, regs.fp)));
/* Grab cx. */
@ -928,6 +928,7 @@ class CallCompiler : public BaseCompiler
FrameAddress(offsetof(VMFrame, scratch)));
}
masm.restoreStackBase();
masm.setupABICall(Registers::NormalCall, 3);
masm.storeArg(2, vpReg);
if (ic.frameSize.isStatic())
@ -952,6 +953,9 @@ class CallCompiler : public BaseCompiler
if (cx->typeInferenceEnabled())
masm.storePtr(ImmPtr(NULL), FrameAddress(offsetof(VMFrame, scratch)));
/* Reload fp, which may have been clobbered by restoreStackBase(). */
masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
Jump hasException = masm.branchTest32(Assembler::Zero, Registers::ReturnReg,
Registers::ReturnReg);

View File

@ -116,6 +116,9 @@ TrampolineCompiler::compileTrampoline(Trampolines::TrampolinePtr *where,
bool
TrampolineCompiler::generateForceReturn(Assembler &masm)
{
/* The JSStackFrame register may have been clobbered while returning, reload it. */
masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
/* if (hasArgsObj() || hasCallObj()) stubs::PutActivationObjects() */
Jump noActObjs = masm.branchTest32(Assembler::Zero, FrameFlagsAddress(),
Imm32(JSFRAME_HAS_CALL_OBJ | JSFRAME_HAS_ARGS_OBJ));

View File

@ -65,15 +65,19 @@ JaegerTrampoline:
call SetVMFrameRegs
call PushActiveVMFrame
popl %edx
jmp *16(%ebp)
movl 28(%esp), %ebp
jmp *72(%esp)
.size JaegerTrampoline, . - JaegerTrampoline
/ void JaegerTrampolineReturn()
.global JaegerTrampolineReturn
.type JaegerTrampolineReturn, @function
JaegerTrampolineReturn:
movl %edx, 0x18(%ebx)
movl %ecx, 0x1C(%ebx)
movl %edx, 0x18(%ebp)
movl %ecx, 0x1C(%ebp)
movl %esp, %ebp
addl $0x38, %ebp
pushl %esp
call PopActiveVMFrame