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 / // arg0 /
// this _/ // this _/
// calleeToken - Encodes script or JSFunction // 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. // returnAddr - Return address, entering into the next call.
// .. locals .. // .. locals ..
@ -72,15 +72,26 @@ struct IonFrameData
class IonFramePrefix : protected 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: public:
// True if this is the frame passed into EnterIonCode. // True if this is the frame passed into EnterIonCode.
bool isEntryFrame() const { bool isEntryFrame() const {
return !(sizeDescriptor_ & 1); return !!(sizeDescriptor_ & EntryFrame);
} }
// The depth of the parent frame. // The depth of the parent frame.
size_t prevFrameDepth() const { size_t prevFrameDepth() const {
JS_ASSERT(!isEntryFrame()); JS_ASSERT(!isEntryFrame());
return sizeDescriptor_ >> 1; return sizeDescriptor_ >> FrameTypeBits;
} }
IonFramePrefix *prev() const { IonFramePrefix *prev() const {
JS_ASSERT(!isEntryFrame()); JS_ASSERT(!isEntryFrame());

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

@ -727,9 +727,9 @@ CodeGeneratorX86Shared::visitCallGeneric(LCallGeneric *call)
return false; return false;
// Remember the size of the frame above this point, in case of bailout. // 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; uint32 stack_size = masm.framePushed() - unused_stack;
// Mark !IonFramePrefix::isEntryFrame(). uint32 size_descriptor = stack_size << IonFramePrefix::FrameTypeBits;
uint32 size_descriptor = stack_size << 1;
// Nestle %esp up to the argument vector. // Nestle %esp up to the argument vector.
if (unused_stack) 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 Push the number of bytes we've pushed so far on the stack and call
*****************************************************************/ *****************************************************************/
masm.subq(rsp, r14); masm.subq(rsp, r14);
// Safe to not shift sizeDescriptor: no other consumers.
masm.orl(Imm32(0x1), r14); // Mark EntryFrame.
masm.push(r14); masm.push(r14);
// Call function. // Call function.
masm.call(reg_code); masm.call(reg_code);
// Pop arguments and padding from stack. // Pop arguments and padding from stack.
masm.pop(r14); masm.pop(r14); // sizeDescriptor.
masm.addq(r14, rsp); masm.xorl(Imm32(0x1), r14); // Unmark EntryFrame.
masm.addq(r14, rsp); // Remove arguments.
/***************************************************************** /*****************************************************************
Place return value where it belongs, pop all saved registers Place return value where it belongs, pop all saved registers
@ -180,13 +183,10 @@ IonCompartment::generateReturnError(JSContext *cx)
{ {
MacroAssembler masm(cx); MacroAssembler masm(cx);
// Pop arguments off the stack. masm.pop(r14); // sizeDescriptor.
// eax <- 8*argc (size of all arguments we pushed on the stack) masm.xorl(Imm32(0x1), r14); // Unmark EntryFrame.
masm.pop(r14); masm.addq(r14, rsp); // Remove arguments.
masm.addq(r14, rsp); masm.pop(r11); // Discard |vp|: returning from error.
// Discard pushed vp.
masm.pop(r11);
GenerateReturn(masm, JS_FALSE); GenerateReturn(masm, JS_FALSE);
@ -250,8 +250,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
masm.j(Assembler::NonZero, &copyLoopTop); masm.j(Assembler::NonZero, &copyLoopTop);
} }
// Construct sizeDescriptor.
masm.subq(rsp, rbp); 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. // Construct IonFrameData.
masm.push(rax); // calleeToken. masm.push(rax); // calleeToken.
@ -266,10 +268,10 @@ IonCompartment::generateArgumentsRectifier(JSContext *cx)
masm.call(rax); masm.call(rax);
// Remove the rectifier frame. // Remove the rectifier frame.
masm.pop(rbx); // rbx <- sizeDescriptor_ masm.pop(rbp); // rbp <- sizeDescriptor with FrameType.
masm.shrl(Imm32(1), rbx); // rbx <- size of pushed arguments masm.shrl(Imm32(IonFramePrefix::FrameTypeBits), rbp); // rbp <- size of pushed arguments.
masm.pop(r11); // Discard calleeToken_ masm.pop(r11); // Discard calleeToken.
masm.addq(rbx, rsp); // Discard pushed arguments. masm.addq(rbp, rsp); // Discard pushed arguments.
masm.ret(); masm.ret();

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

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