Chromium Code Reviews| Index: src/arm64/lithium-codegen-arm64.cc |
| diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc |
| index 29c13ac5833e2bf59dbb713c5f7f8529176b867d..f49b511e6b7d3454b05d6cc3d071802f0483f270 100644 |
| --- a/src/arm64/lithium-codegen-arm64.cc |
| +++ b/src/arm64/lithium-codegen-arm64.cc |
| @@ -387,6 +387,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code, |
| LInstruction* instr, |
| SafepointMode safepoint_mode) { |
| ASSERT(instr != NULL); |
| + ASSERT(instr->IsMarkedAsCall()); |
| Assembler::BlockPoolsScope scope(masm_); |
| __ Call(code, mode); |
| @@ -839,7 +840,9 @@ bool LCodeGen::GenerateDeoptJumpTable() { |
| Address base = deopt_jump_table_[0]->address; |
| UseScratchRegisterScope temps(masm()); |
| - Register entry_offset = temps.AcquireX(); |
| + // This is reused as the caller address later, and the second-level deopt |
| + // table expects this in ip1. |
| + Register entry_offset = temps.Acquire(ip1); |
|
ulan
2014/06/23 11:17:11
Nit: maybe introduce a descriptive alias for ip1 t
jbramley
2014/06/23 17:22:05
Done.
|
| int length = deopt_jump_table_.length(); |
| for (int i = 0; i < length; i++) { |
| @@ -907,7 +910,11 @@ bool LCodeGen::GenerateDeoptJumpTable() { |
| __ Mov(deopt_entry, Operand(reinterpret_cast<uint64_t>(base), |
| RelocInfo::RUNTIME_ENTRY)); |
| __ Add(deopt_entry, deopt_entry, entry_offset); |
| - __ Call(deopt_entry); |
| + |
| + const Register& caller_address = entry_offset; |
| + ASSERT(caller_address.Is(ip1)); |
| + __ adr(caller_address, 0); |
| + __ Br(deopt_entry); |
| } |
| // Force constant pool emission at the end of the deopt jump table to make |
| @@ -1036,7 +1043,19 @@ void LCodeGen::DeoptimizeBranch( |
| __ Str(w1, MemOperand(x0)); |
| __ Pop(x2, x1, x0); |
| ASSERT(frame_is_built_); |
| - __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| + |
| + { |
| + UseScratchRegisterScope temps(masm()); |
| + // The second-level deopt table expects the caller address in ip1. |
| + Register caller_address = temps.Acquire(ip1); |
| + Register entry_address = temps.AcquireX(); |
| + |
| + __ Mov(entry_address, Operand(reinterpret_cast<uintptr_t>(entry), |
| + RelocInfo::RUNTIME_ENTRY)); |
| + __ adr(caller_address, 0); |
| + __ Br(entry_address); |
| + } |
| + |
| __ Unreachable(); |
| __ Bind(¬_zero); |
| @@ -1053,11 +1072,25 @@ void LCodeGen::DeoptimizeBranch( |
| } |
| ASSERT(info()->IsStub() || frame_is_built_); |
| - // Go through jump table if we need to build frame, or restore caller doubles. |
| if (branch_type == always && |
| frame_is_built_ && !info()->saves_caller_doubles()) { |
| - __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| + // For unconditional deopts that don't require special handling (such as |
| + // constructing a frame), branch directly to the second-level table. |
| + |
| + UseScratchRegisterScope temps(masm()); |
| + // The second-level deopt table expects the caller address in ip1. |
| + Register caller_address = temps.Acquire(ip1); |
| + Register entry_address = temps.AcquireX(); |
| + |
| + __ Mov(entry_address, Operand(reinterpret_cast<uintptr_t>(entry), |
| + RelocInfo::RUNTIME_ENTRY)); |
| + __ adr(caller_address, 0); |
| + __ Br(entry_address); |
| } else { |
| + // For conditional deopts, try to generate as little fast-path code as |
| + // possible. Defer all special handling to the first-level deopt table and |
| + // emit a simple conditional branch here. |
| + |
| // We often have several deopts to the same entry, reuse the last |
| // jump entry if this is the case. |
| if (deopt_jump_table_.is_empty() || |