Mark frame types correctly. (Bug 685099, r=dvander)

This commit is contained in:
Sean Stangl 2011-09-14 11:13:50 -07:00
Родитель a5abae7879
Коммит 173796cc35
4 изменённых файлов: 46 добавлений и 28 удалений

Просмотреть файл

@ -57,7 +57,7 @@ namespace ion {
// arg0 /
// this _/
// calleeToken - Encodes script or JSFunction
// descriptor - Size of the parent frame
// sizeDescriptor - Size of the parent frame, with lower bits for FrameType.
// returnAddr - Return address, entering into the next call.
// .. locals ..
@ -72,15 +72,26 @@ struct IonFrameData
class IonFramePrefix : protected IonFrameData
{
public:
enum FrameType {
JSFrame,
EntryFrame,
RectifierFrame
};
// The FrameType is packed into the sizeDescriptor by left-shifting the
// sizeDescriptor by FrameTypeBits, then ORing in the FrameType.
static const unsigned FrameTypeBits = 2;
public:
// True if this is the frame passed into EnterIonCode.
bool isEntryFrame() const {
return !(sizeDescriptor_ & 1);
return !!(sizeDescriptor_ & EntryFrame);
}
// The depth of the parent frame.
size_t prevFrameDepth() const {
JS_ASSERT(!isEntryFrame());
return sizeDescriptor_ >> 1;
return sizeDescriptor_ >> FrameTypeBits;
}
IonFramePrefix *prev() const {
JS_ASSERT(!isEntryFrame());

Просмотреть файл

@ -727,9 +727,9 @@ CodeGeneratorX86Shared::visitCallGeneric(LCallGeneric *call)
return false;
// Remember the size of the frame above this point, in case of bailout.
JS_STATIC_ASSERT(IonFramePrefix::JSFrame == 0x0);
uint32 stack_size = masm.framePushed() - unused_stack;
// Mark !IonFramePrefix::isEntryFrame().
uint32 size_descriptor = stack_size << 1;
uint32 size_descriptor = stack_size << IonFramePrefix::FrameTypeBits;
// Nestle %esp up to the argument vector.
if (unused_stack)

Просмотреть файл

@ -154,14 +154,17 @@ IonCompartment::generateEnterJIT(JSContext *cx)
Push the number of bytes we've pushed so far on the stack and call
*****************************************************************/
masm.subq(rsp, r14);
// Safe to not shift sizeDescriptor: no other consumers.
masm.orl(Imm32(0x1), r14); // Mark EntryFrame.
masm.push(r14);
// Call function.
masm.call(reg_code);
// Pop arguments and padding from stack.
masm.pop(r14);
masm.addq(r14, rsp);
masm.pop(r14); // sizeDescriptor.
masm.xorl(Imm32(0x1), r14); // Unmark EntryFrame.
masm.addq(r14, rsp); // Remove arguments.
/*****************************************************************
Place return value where it belongs, pop all saved registers
@ -180,13 +183,10 @@ IonCompartment::generateReturnError(JSContext *cx)
{
MacroAssembler masm(cx);
// Pop arguments off the stack.
// eax <- 8*argc (size of all arguments we pushed on the stack)
masm.pop(r14);
masm.addq(r14, rsp);
// Discard pushed vp.
masm.pop(r11);
masm.pop(r14); // sizeDescriptor.
masm.xorl(Imm32(0x1), r14); // Unmark EntryFrame.
masm.addq(r14, rsp); // Remove arguments.
masm.pop(r11); // Discard |vp|: returning from error.
GenerateReturn(masm, JS_FALSE);
@ -250,8 +250,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
masm.j(Assembler::NonZero, &copyLoopTop);
}
// Construct sizeDescriptor.
masm.subq(rsp, rbp);
masm.shll(Imm32(1), rbp); // construct sizeDescriptor.
masm.shll(Imm32(IonFramePrefix::FrameTypeBits), rbp);
masm.orl(Imm32(IonFramePrefix::RectifierFrame), rbp);
// Construct IonFrameData.
masm.push(rax); // calleeToken.
@ -266,10 +268,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
masm.call(rax);
// Remove the rectifier frame.
masm.pop(rbx); // rbx <- sizeDescriptor_
masm.shrl(Imm32(1), rbx); // rbx <- size of pushed arguments
masm.pop(r11); // Discard calleeToken_
masm.addq(rbx, rsp); // Discard pushed arguments.
masm.pop(rbp); // rbp <- sizeDescriptor with FrameType.
masm.shrl(Imm32(IonFramePrefix::FrameTypeBits), rbp); // rbp <- size of pushed arguments.
masm.pop(r11); // Discard calleeToken.
masm.addq(rbp, rsp); // Discard pushed arguments.
masm.ret();

Просмотреть файл

@ -141,6 +141,9 @@ IonCompartment::generateEnterJIT(JSContext *cx)
masm.shll(Imm32(3), eax);
masm.addl(eax, ecx);
masm.addl(Imm32(4), ecx);
// Safe to take lowest bit without shifting: aligned, and no other consumers.
masm.orl(Imm32(0x1), ecx); // Mark EntryFrame.
masm.push(ecx);
/***************************************************************
@ -153,6 +156,7 @@ IonCompartment::generateEnterJIT(JSContext *cx)
// Pop arguments off the stack.
// eax <- 8*argc (size of all arugments we pushed on the stack)
masm.pop(eax);
masm.xorl(Imm32(0x1), eax); // Unmark EntryFrame.
masm.addl(eax, esp);
// |ebp| could have been clobbered by the inner function. For now, re-grab
@ -185,10 +189,9 @@ IonCompartment::generateReturnError(JSContext *cx)
{
MacroAssembler masm(cx);
// Pop arguments off the stack.
// eax <- 8*argc (size of all arugments we pushed on the stack)
masm.pop(eax);
masm.addl(eax, esp);
masm.pop(eax); // sizeDescriptor.
masm.xorl(Imm32(0x1), eax); // Unmark EntryFrame.
masm.addl(eax, esp); // Remove arguments.
GenerateReturn(masm, JS_FALSE);
@ -255,8 +258,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
masm.j(Assembler::NonZero, &copyLoopTop);
}
// Construct sizeDescriptor.
masm.subl(esp, ebp);
masm.shll(Imm32(1), ebp); // construct sizeDescriptor.
masm.shll(Imm32(IonFramePrefix::FrameTypeBits), ebp);
masm.orl(Imm32(IonFramePrefix::RectifierFrame), ebp);
// Construct IonFrameData.
masm.push(eax); // calleeToken
@ -271,10 +276,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
masm.call(eax);
// Remove the rectifier frame.
masm.pop(ebx); // ebx <- sizeDescriptor
masm.shrl(Imm32(1), ebx); // ebx <- size of pushed arguments
masm.pop(edi); // Discard calleeToken
masm.addl(ebx, esp); // Discard pushed arguments.
masm.pop(ebp); // ebp <- sizeDescriptor with FrameType.
masm.shrl(Imm32(IonFramePrefix::FrameTypeBits), ebp); // ebp <- sizeDescriptor.
masm.pop(edi); // Discard calleeToken.
masm.addl(ebp, esp); // Discard pushed arguments.
masm.ret();