| Index: src/compiler/frame-elider.cc
 | 
| diff --git a/src/compiler/frame-elider.cc b/src/compiler/frame-elider.cc
 | 
| index bb35643f5dc965c612bc0d9a73f5982a4b9b0aff..5ad4aad41eb35c2bdf30e047aae1756b56792f5b 100644
 | 
| --- a/src/compiler/frame-elider.cc
 | 
| +++ b/src/compiler/frame-elider.cc
 | 
| @@ -22,8 +22,9 @@ void FrameElider::MarkBlocks() {
 | 
|    for (InstructionBlock* block : instruction_blocks()) {
 | 
|      if (block->needs_frame()) continue;
 | 
|      for (int i = block->code_start(); i < block->code_end(); ++i) {
 | 
| -      if (InstructionAt(i)->IsCall() ||
 | 
| -          InstructionAt(i)->opcode() == ArchOpcode::kArchDeoptimize) {
 | 
| +      const Instruction* instr = InstructionAt(i);
 | 
| +      if (instr->IsCall() || instr->IsDeoptimizeCall() ||
 | 
| +          instr->arch_opcode() == ArchOpcode::kArchStackPointer) {
 | 
|          block->mark_needs_frame();
 | 
|          break;
 | 
|        }
 | 
| @@ -50,6 +51,16 @@ void FrameElider::MarkDeConstruction() {
 | 
|        for (RpoNumber& succ : block->successors()) {
 | 
|          if (!InstructionBlockAt(succ)->needs_frame()) {
 | 
|            DCHECK_EQ(1U, block->SuccessorCount());
 | 
| +          const Instruction* last =
 | 
| +              InstructionAt(block->last_instruction_index());
 | 
| +          if (last->IsThrow() || last->IsTailCall() ||
 | 
| +              last->IsDeoptimizeCall()) {
 | 
| +            // We need to keep the frame if we exit the block through any
 | 
| +            // of these.
 | 
| +            continue;
 | 
| +          }
 | 
| +          // The only cases when we need to deconstruct are ret and jump.
 | 
| +          DCHECK(last->IsRet() || last->IsJump());
 | 
|            block->mark_must_deconstruct_frame();
 | 
|          }
 | 
|        }
 | 
| 
 |