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(); |
} |