| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 979c5029bec18c07b3026f92ba5db35ced34e0bf..da0301e24f2d2b603bfa4ef40f717305807131bb 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -377,10 +377,11 @@ void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { }
|
|
|
|
|
| bool LCodeGen::GenerateJumpTable() {
|
| + if (!jump_table_.length()) 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);
|
| @@ -389,35 +390,54 @@ bool LCodeGen::GenerateJumpTable() {
|
| if (table_entry->needs_frame) {
|
| DCHECK(!info()->saves_caller_doubles());
|
| __ push(Immediate(ExternalReference::ForDeoptEntry(entry)));
|
| - if (needs_frame.is_bound()) {
|
| - __ jmp(&needs_frame);
|
| - } else {
|
| - __ bind(&needs_frame);
|
| - __ push(MemOperand(ebp, StandardFrameConstants::kContextOffset));
|
| - // 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());
|
| - __ push(Immediate(Smi::FromInt(StackFrame::STUB)));
|
| - // Push a PC inside the function so that the deopt code can find where
|
| - // the deopt comes from. It doesn't have to be the precise return
|
| - // address of a "calling" LAZY deopt, it only has to be somewhere
|
| - // inside the code body.
|
| - Label push_approx_pc;
|
| - __ call(&push_approx_pc);
|
| - __ bind(&push_approx_pc);
|
| - // Push the continuation which was stashed were the ebp should
|
| - // be. Replace it with the saved ebp.
|
| - __ push(MemOperand(esp, 3 * kPointerSize));
|
| - __ mov(MemOperand(esp, 4 * kPointerSize), ebp);
|
| - __ lea(ebp, MemOperand(esp, 4 * kPointerSize));
|
| - __ ret(0); // Call the continuation without clobbering registers.
|
| - }
|
| + __ call(&needs_frame);
|
| } else {
|
| if (info()->saves_caller_doubles()) RestoreCallerDoubles();
|
| __ call(entry, RelocInfo::RUNTIME_ENTRY);
|
| }
|
| }
|
| + if (needs_frame.is_linked()) {
|
| + __ bind(&needs_frame);
|
| + /* stack layout
|
| + 4: entry address
|
| + 3: return address <-- esp
|
| + 2: garbage
|
| + 1: garbage
|
| + 0: garbage
|
| + */
|
| + __ sub(esp, Immediate(kPointerSize)); // Reserve space for stub marker.
|
| + __ push(MemOperand(esp, kPointerSize)); // Copy return address.
|
| + __ push(MemOperand(esp, 3 * kPointerSize)); // Copy entry address.
|
| +
|
| + /* stack layout
|
| + 4: entry address
|
| + 3: return address
|
| + 2: garbage
|
| + 1: return address
|
| + 0: entry address <-- esp
|
| + */
|
| + __ mov(MemOperand(esp, 4 * kPointerSize), ebp); // Save ebp.
|
| + // Copy context.
|
| + __ mov(ebp, MemOperand(ebp, StandardFrameConstants::kContextOffset));
|
| + __ mov(MemOperand(esp, 3 * kPointerSize), ebp);
|
| + // Fill ebp with the right stack frame address.
|
| + __ lea(ebp, MemOperand(esp, 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());
|
| + __ mov(MemOperand(esp, 2 * kPointerSize),
|
| + Immediate(Smi::FromInt(StackFrame::STUB)));
|
| +
|
| + /* stack layout
|
| + 4: old ebp
|
| + 3: context pointer
|
| + 2: stub marker
|
| + 1: return address
|
| + 0: entry address <-- esp
|
| + */
|
| + __ ret(0); // Call the continuation without clobbering registers.
|
| + }
|
| return !is_aborted();
|
| }
|
|
|
|
|