зеркало из 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 /
|
// 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, ©LoopTop);
|
masm.j(Assembler::NonZero, ©LoopTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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, ©LoopTop);
|
masm.j(Assembler::NonZero, ©LoopTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче