зеркало из https://github.com/mozilla/gecko-dev.git
Mark frame types correctly. (Bug 685099, r=dvander)
This commit is contained in:
Родитель
a5abae7879
Коммит
173796cc35
|
@ -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, ©LoopTop);
|
||||
}
|
||||
|
||||
// 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, ©LoopTop);
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче