| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index c95742588d5778206e03b3936ce596f595dbba1b..cb6db29ef5eda3295f3b4b1cba34d76bd72de8ff 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -297,10 +297,10 @@ void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) {
|
|
|
|
|
| bool LCodeGen::GenerateJumpTable() {
|
| + if (jump_table_.length() == 0) return !is_aborted();
|
| +
|
| Label needs_frame;
|
| - if (jump_table_.length() > 0) {
|
| - Comment(";;; -------------------- Jump table --------------------");
|
| - }
|
| + Comment(";;; -------------------- Jump table --------------------");
|
| for (int i = 0; i < jump_table_.length(); i++) {
|
| Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i];
|
| __ bind(&table_entry->label);
|
| @@ -309,23 +309,7 @@ bool LCodeGen::GenerateJumpTable() {
|
| if (table_entry->needs_frame) {
|
| DCHECK(!info()->saves_caller_doubles());
|
| __ Move(kScratchRegister, ExternalReference::ForDeoptEntry(entry));
|
| - if (needs_frame.is_bound()) {
|
| - __ jmp(&needs_frame);
|
| - } else {
|
| - __ bind(&needs_frame);
|
| - __ movp(rsi, MemOperand(rbp, StandardFrameConstants::kContextOffset));
|
| - __ pushq(rbp);
|
| - __ movp(rbp, rsp);
|
| - __ Push(rsi);
|
| - // This variant of deopt can only be used with stubs. Since we don't
|
| - // have a function pointer to install in the stack frame that we're
|
| - // building, install a special marker there instead.
|
| - DCHECK(info()->IsStub());
|
| - __ Move(rsi, Smi::FromInt(StackFrame::STUB));
|
| - __ Push(rsi);
|
| - __ movp(rsi, MemOperand(rsp, kPointerSize));
|
| - __ call(kScratchRegister);
|
| - }
|
| + __ call(&needs_frame);
|
| } else {
|
| if (info()->saves_caller_doubles()) {
|
| DCHECK(info()->IsStub());
|
| @@ -334,6 +318,55 @@ bool LCodeGen::GenerateJumpTable() {
|
| __ call(entry, RelocInfo::RUNTIME_ENTRY);
|
| }
|
| }
|
| +
|
| + if (needs_frame.is_linked()) {
|
| + __ bind(&needs_frame);
|
| + /* stack layout
|
| + 4: return address <-- rsp
|
| + 3: garbage
|
| + 2: garbage
|
| + 1: garbage
|
| + 0: garbage
|
| + */
|
| + // Reserve space for context and stub marker.
|
| + __ subp(rsp, Immediate(2 * kPointerSize));
|
| + __ Push(MemOperand(rsp, 2 * kPointerSize)); // Copy return address.
|
| + __ Push(kScratchRegister); // Save entry address for ret(0)
|
| +
|
| + /* stack layout
|
| + 4: return address
|
| + 3: garbage
|
| + 2: garbage
|
| + 1: return address
|
| + 0: entry address <-- rsp
|
| + */
|
| +
|
| + // Remember context pointer.
|
| + __ movp(kScratchRegister,
|
| + MemOperand(rbp, StandardFrameConstants::kContextOffset));
|
| + // Save context pointer into the stack frame.
|
| + __ movp(MemOperand(rsp, 3 * kPointerSize), kScratchRegister);
|
| +
|
| + // Create a stack frame.
|
| + __ movp(MemOperand(rsp, 4 * kPointerSize), rbp);
|
| + __ leap(rbp, MemOperand(rsp, 4 * kPointerSize));
|
| +
|
| + // This variant of deopt can only be used with stubs. Since we don't
|
| + // have a function pointer to install in the stack frame that we're
|
| + // building, install a special marker there instead.
|
| + DCHECK(info()->IsStub());
|
| + __ Move(MemOperand(rsp, 2 * kPointerSize), Smi::FromInt(StackFrame::STUB));
|
| +
|
| + /* stack layout
|
| + 4: old ebp
|
| + 3: context pointer
|
| + 2: stub marker
|
| + 1: return address
|
| + 0: entry address <-- rsp
|
| + */
|
| + __ ret(0);
|
| + }
|
| +
|
| return !is_aborted();
|
| }
|
|
|
|
|