| Index: src/x64/lithium-codegen-x64.cc
 | 
| ===================================================================
 | 
| --- src/x64/lithium-codegen-x64.cc	(revision 9984)
 | 
| +++ src/x64/lithium-codegen-x64.cc	(working copy)
 | 
| @@ -43,35 +43,22 @@
 | 
|   public:
 | 
|    SafepointGenerator(LCodeGen* codegen,
 | 
|                       LPointerMap* pointers,
 | 
| -                     int deoptimization_index)
 | 
| +                     Safepoint::DeoptMode mode)
 | 
|        : codegen_(codegen),
 | 
|          pointers_(pointers),
 | 
| -        deoptimization_index_(deoptimization_index) { }
 | 
| +        deopt_mode_(mode) { }
 | 
|    virtual ~SafepointGenerator() { }
 | 
|  
 | 
| -  virtual void BeforeCall(int call_size) const {
 | 
| -    ASSERT(call_size >= 0);
 | 
| -    // Ensure that we have enough space after the previous safepoint position
 | 
| -    // for the jump generated there.
 | 
| -    int call_end = codegen_->masm()->pc_offset() + call_size;
 | 
| -    int prev_jump_end = codegen_->LastSafepointEnd() + kMinSafepointSize;
 | 
| -    if (call_end < prev_jump_end) {
 | 
| -      int padding_size = prev_jump_end - call_end;
 | 
| -      STATIC_ASSERT(kMinSafepointSize <= 9);  // One multibyte nop is enough.
 | 
| -      codegen_->masm()->nop(padding_size);
 | 
| -    }
 | 
| -  }
 | 
| +  virtual void BeforeCall(int call_size) const { }
 | 
|  
 | 
|    virtual void AfterCall() const {
 | 
| -    codegen_->RecordSafepoint(pointers_, deoptimization_index_);
 | 
| +    codegen_->RecordSafepoint(pointers_, deopt_mode_);
 | 
|    }
 | 
|  
 | 
|   private:
 | 
| -  static const int kMinSafepointSize =
 | 
| -      MacroAssembler::kShortCallInstructionLength;
 | 
|    LCodeGen* codegen_;
 | 
|    LPointerMap* pointers_;
 | 
| -  int deoptimization_index_;
 | 
| +  Safepoint::DeoptMode deopt_mode_;
 | 
|  };
 | 
|  
 | 
|  
 | 
| @@ -100,7 +87,6 @@
 | 
|    code->set_stack_slots(GetStackSlotCount());
 | 
|    code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
 | 
|    PopulateDeoptimizationData(code);
 | 
| -  Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -206,7 +192,7 @@
 | 
|      } else {
 | 
|        __ CallRuntime(Runtime::kNewFunctionContext, 1);
 | 
|      }
 | 
| -    RecordSafepoint(Safepoint::kNoDeoptimizationIndex);
 | 
| +    RecordSafepoint(Safepoint::kNoLazyDeopt);
 | 
|      // Context is returned in both rax and rsi.  It replaces the context
 | 
|      // passed to us.  It's saved in the stack and kept live in rsi.
 | 
|      __ movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
 | 
| @@ -255,19 +241,11 @@
 | 
|        instr->CompileToNative(this);
 | 
|      }
 | 
|    }
 | 
| +  EnsureSpaceForLazyDeopt();
 | 
|    return !is_aborted();
 | 
|  }
 | 
|  
 | 
|  
 | 
| -LInstruction* LCodeGen::GetNextInstruction() {
 | 
| -  if (current_instruction_ < instructions_->length() - 1) {
 | 
| -    return instructions_->at(current_instruction_ + 1);
 | 
| -  } else {
 | 
| -    return NULL;
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
|  bool LCodeGen::GenerateJumpTable() {
 | 
|    for (int i = 0; i < jump_table_.length(); i++) {
 | 
|      __ bind(&jump_table_[i].label);
 | 
| @@ -289,18 +267,6 @@
 | 
|        code->Generate();
 | 
|        __ jmp(code->exit());
 | 
|      }
 | 
| -
 | 
| -    // Pad code to ensure that the last piece of deferred code have
 | 
| -    // room for lazy bailout.
 | 
| -    while ((masm()->pc_offset() - LastSafepointEnd())
 | 
| -           < Deoptimizer::patch_size()) {
 | 
| -      int padding = masm()->pc_offset() - LastSafepointEnd();
 | 
| -      if (padding > 9) {
 | 
| -        __ nop(9);
 | 
| -      } else {
 | 
| -        __ nop(padding);
 | 
| -      }
 | 
| -    }
 | 
|    }
 | 
|  
 | 
|    // Deferred code is the last part of the instruction sequence. Mark
 | 
| @@ -312,20 +278,6 @@
 | 
|  
 | 
|  bool LCodeGen::GenerateSafepointTable() {
 | 
|    ASSERT(is_done());
 | 
| -  // Ensure that there is space at the end of the code to write a number
 | 
| -  // of jump instructions, as well as to afford writing a call near the end
 | 
| -  // of the code.
 | 
| -  // The jumps are used when there isn't room in the code stream to write
 | 
| -  // a long call instruction. Instead it writes a shorter call to a
 | 
| -  // jump instruction in the same code object.
 | 
| -  // The calls are used when lazy deoptimizing a function and calls to a
 | 
| -  // deoptimization function.
 | 
| -  int short_deopts = safepoints_.CountShortDeoptimizationIntervals(
 | 
| -      static_cast<unsigned>(MacroAssembler::kJumpInstructionLength));
 | 
| -  int byte_count = (short_deopts) * MacroAssembler::kJumpInstructionLength;
 | 
| -  while (byte_count-- > 0) {
 | 
| -    __ int3();
 | 
| -  }
 | 
|    safepoints_.Emit(masm(), GetStackSlotCount());
 | 
|    return !is_aborted();
 | 
|  }
 | 
| @@ -491,7 +443,7 @@
 | 
|    LPointerMap* pointers = instr->pointer_map();
 | 
|    RecordPosition(pointers->position());
 | 
|    __ call(code, mode);
 | 
| -  RegisterLazyDeoptimization(instr, safepoint_mode, argc);
 | 
| +  RecordSafepointWithLazyDeopt(instr, safepoint_mode, argc);
 | 
|  
 | 
|    // Signal that we don't inline smi code before these stubs in the
 | 
|    // optimizing code generator.
 | 
| @@ -518,7 +470,7 @@
 | 
|    RecordPosition(pointers->position());
 | 
|  
 | 
|    __ CallRuntime(function, num_arguments);
 | 
| -  RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0);
 | 
| +  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -528,39 +480,12 @@
 | 
|    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
 | 
|    __ CallRuntimeSaveDoubles(id);
 | 
|    RecordSafepointWithRegisters(
 | 
| -      instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex);
 | 
| +      instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr,
 | 
| -                                          SafepointMode safepoint_mode,
 | 
| -                                          int argc) {
 | 
| -  // Create the environment to bailout to. If the call has side effects
 | 
| -  // execution has to continue after the call otherwise execution can continue
 | 
| -  // from a previous bailout point repeating the call.
 | 
| -  LEnvironment* deoptimization_environment;
 | 
| -  if (instr->HasDeoptimizationEnvironment()) {
 | 
| -    deoptimization_environment = instr->deoptimization_environment();
 | 
| -  } else {
 | 
| -    deoptimization_environment = instr->environment();
 | 
| -  }
 | 
| -
 | 
| -  RegisterEnvironmentForDeoptimization(deoptimization_environment);
 | 
| -  if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
 | 
| -    ASSERT(argc == 0);
 | 
| -    RecordSafepoint(instr->pointer_map(),
 | 
| -                    deoptimization_environment->deoptimization_index());
 | 
| -  } else {
 | 
| -    ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS);
 | 
| -    RecordSafepointWithRegisters(
 | 
| -        instr->pointer_map(),
 | 
| -        argc,
 | 
| -        deoptimization_environment->deoptimization_index());
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
 | 
| +void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
 | 
| +                                                    Safepoint::DeoptMode mode) {
 | 
|    if (!environment->HasBeenRegistered()) {
 | 
|      // Physical stack frame layout:
 | 
|      // -x ............. -4  0 ..................................... y
 | 
| @@ -582,14 +507,17 @@
 | 
|      Translation translation(&translations_, frame_count);
 | 
|      WriteTranslation(environment, &translation);
 | 
|      int deoptimization_index = deoptimizations_.length();
 | 
| -    environment->Register(deoptimization_index, translation.index());
 | 
| +    int pc_offset = masm()->pc_offset();
 | 
| +    environment->Register(deoptimization_index,
 | 
| +                          translation.index(),
 | 
| +                          (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
 | 
|      deoptimizations_.Add(environment);
 | 
|    }
 | 
|  }
 | 
|  
 | 
|  
 | 
|  void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
 | 
| -  RegisterEnvironmentForDeoptimization(environment);
 | 
| +  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
 | 
|    ASSERT(environment->HasBeenRegistered());
 | 
|    int id = environment->deoptimization_index();
 | 
|    Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER);
 | 
| @@ -641,6 +569,7 @@
 | 
|      data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
 | 
|      data->SetArgumentsStackHeight(i,
 | 
|                                    Smi::FromInt(env->arguments_stack_height()));
 | 
| +    data->SetPc(i, Smi::FromInt(env->pc_offset()));
 | 
|    }
 | 
|    code->set_deoptimization_data(*data);
 | 
|  }
 | 
| @@ -672,17 +601,29 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void LCodeGen::RecordSafepointWithLazyDeopt(
 | 
| +    LInstruction* instr, SafepointMode safepoint_mode, int argc) {
 | 
| +  if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
 | 
| +    RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
 | 
| +  } else {
 | 
| +    ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS);
 | 
| +    RecordSafepointWithRegisters(
 | 
| +        instr->pointer_map(), argc, Safepoint::kLazyDeopt);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void LCodeGen::RecordSafepoint(
 | 
|      LPointerMap* pointers,
 | 
|      Safepoint::Kind kind,
 | 
|      int arguments,
 | 
| -    int deoptimization_index) {
 | 
| +    Safepoint::DeoptMode deopt_mode) {
 | 
|    ASSERT(kind == expected_safepoint_kind_);
 | 
|  
 | 
|    const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands();
 | 
|  
 | 
|    Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
 | 
| -      kind, arguments, deoptimization_index);
 | 
| +      kind, arguments, deopt_mode);
 | 
|    for (int i = 0; i < operands->length(); i++) {
 | 
|      LOperand* pointer = operands->at(i);
 | 
|      if (pointer->IsStackSlot()) {
 | 
| @@ -699,22 +640,21 @@
 | 
|  
 | 
|  
 | 
|  void LCodeGen::RecordSafepoint(LPointerMap* pointers,
 | 
| -                               int deoptimization_index) {
 | 
| -  RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index);
 | 
| +                               Safepoint::DeoptMode deopt_mode) {
 | 
| +  RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void LCodeGen::RecordSafepoint(int deoptimization_index) {
 | 
| +void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
 | 
|    LPointerMap empty_pointers(RelocInfo::kNoPosition);
 | 
| -  RecordSafepoint(&empty_pointers, deoptimization_index);
 | 
| +  RecordSafepoint(&empty_pointers, deopt_mode);
 | 
|  }
 | 
|  
 | 
|  
 | 
|  void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
 | 
|                                              int arguments,
 | 
| -                                            int deoptimization_index) {
 | 
| -  RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments,
 | 
| -      deoptimization_index);
 | 
| +                                            Safepoint::DeoptMode deopt_mode) {
 | 
| +  RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -749,12 +689,6 @@
 | 
|      LParallelMove* move = gap->GetParallelMove(inner_pos);
 | 
|      if (move != NULL) DoParallelMove(move);
 | 
|    }
 | 
| -
 | 
| -  LInstruction* next = GetNextInstruction();
 | 
| -  if (next != NULL && next->IsLazyBailout()) {
 | 
| -    int pc = masm()->pc_offset();
 | 
| -    safepoints_.SetPcAfterGap(pc);
 | 
| -  }
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -1889,7 +1823,7 @@
 | 
|                                    LInstanceOfKnownGlobal* instr)
 | 
|          : LDeferredCode(codegen), instr_(instr) { }
 | 
|      virtual void Generate() {
 | 
| -      codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_);
 | 
| +      codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
 | 
|      }
 | 
|      virtual LInstruction* instr() { return instr_; }
 | 
|      Label* map_check() { return &map_check_; }
 | 
| @@ -1947,8 +1881,8 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
 | 
| -                                                Label* map_check) {
 | 
| +void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
 | 
| +                                               Label* map_check) {
 | 
|    {
 | 
|      PushSafepointRegistersScope scope(this);
 | 
|      InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
 | 
| @@ -1974,6 +1908,9 @@
 | 
|                      RECORD_SAFEPOINT_WITH_REGISTERS,
 | 
|                      2);
 | 
|      ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check));
 | 
| +    ASSERT(instr->HasDeoptimizationEnvironment());
 | 
| +    LEnvironment* env = instr->deoptimization_environment();
 | 
| +    safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
 | 
|      // Move result to a register that survives the end of the
 | 
|      // PushSafepointRegisterScope.
 | 
|      __ movq(kScratchRegister, rax);
 | 
| @@ -2569,12 +2506,9 @@
 | 
|    __ bind(&invoke);
 | 
|    ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
 | 
|    LPointerMap* pointers = instr->pointer_map();
 | 
| -  LEnvironment* env = instr->deoptimization_environment();
 | 
|    RecordPosition(pointers->position());
 | 
| -  RegisterEnvironmentForDeoptimization(env);
 | 
| -  SafepointGenerator safepoint_generator(this,
 | 
| -                                         pointers,
 | 
| -                                         env->deoptimization_index());
 | 
| +  SafepointGenerator safepoint_generator(
 | 
| +      this, pointers, Safepoint::kLazyDeopt);
 | 
|    v8::internal::ParameterCount actual(rax);
 | 
|    __ InvokeFunction(function, actual, CALL_FUNCTION,
 | 
|                      safepoint_generator, CALL_AS_METHOD);
 | 
| @@ -2652,7 +2586,7 @@
 | 
|    }
 | 
|  
 | 
|    // Setup deoptimization.
 | 
| -  RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT, 0);
 | 
| +  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0);
 | 
|  
 | 
|    // Restore context.
 | 
|    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
 | 
| @@ -3000,10 +2934,8 @@
 | 
|    ASSERT(instr->HasPointerMap());
 | 
|    ASSERT(instr->HasDeoptimizationEnvironment());
 | 
|    LPointerMap* pointers = instr->pointer_map();
 | 
| -  LEnvironment* env = instr->deoptimization_environment();
 | 
|    RecordPosition(pointers->position());
 | 
| -  RegisterEnvironmentForDeoptimization(env);
 | 
| -  SafepointGenerator generator(this, pointers, env->deoptimization_index());
 | 
| +  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
 | 
|    ParameterCount count(instr->arity());
 | 
|    __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
 | 
|    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
 | 
| @@ -4184,9 +4116,29 @@
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void LCodeGen::EnsureSpaceForLazyDeopt() {
 | 
| +  // Ensure that we have enough space after the previous lazy-bailout
 | 
| +  // instruction for patching the code here.
 | 
| +  int current_pc = masm()->pc_offset();
 | 
| +  int patch_size = Deoptimizer::patch_size();
 | 
| +  if (current_pc < last_lazy_deopt_pc_ + patch_size) {
 | 
| +    int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
 | 
| +    while (padding_size > 0) {
 | 
| +      int nop_size = padding_size > 9 ? 9 : padding_size;
 | 
| +      __ nop(nop_size);
 | 
| +      padding_size -= nop_size;
 | 
| +    }
 | 
| +  }
 | 
| +  last_lazy_deopt_pc_ = current_pc;
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
 | 
| -  // No code for lazy bailout instruction. Used to capture environment after a
 | 
| -  // call for populating the safepoint data with deoptimization data.
 | 
| +  EnsureSpaceForLazyDeopt();
 | 
| +  ASSERT(instr->HasEnvironment());
 | 
| +  LEnvironment* env = instr->environment();
 | 
| +  RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
 | 
| +  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -4202,15 +4154,12 @@
 | 
|    EmitPushTaggedOperand(key);
 | 
|    ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
 | 
|    LPointerMap* pointers = instr->pointer_map();
 | 
| -  LEnvironment* env = instr->deoptimization_environment();
 | 
|    RecordPosition(pointers->position());
 | 
| -  RegisterEnvironmentForDeoptimization(env);
 | 
|    // Create safepoint generator that will also ensure enough space in the
 | 
|    // reloc info for patching in deoptimization (since this is invoking a
 | 
|    // builtin)
 | 
| -  SafepointGenerator safepoint_generator(this,
 | 
| -                                         pointers,
 | 
| -                                         env->deoptimization_index());
 | 
| +  SafepointGenerator safepoint_generator(
 | 
| +      this, pointers, Safepoint::kLazyDeopt);
 | 
|    __ Push(Smi::FromInt(strict_mode_flag()));
 | 
|    __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
 | 
|  }
 | 
| @@ -4223,30 +4172,21 @@
 | 
|    EmitPushTaggedOperand(obj);
 | 
|    ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
 | 
|    LPointerMap* pointers = instr->pointer_map();
 | 
| -  LEnvironment* env = instr->deoptimization_environment();
 | 
|    RecordPosition(pointers->position());
 | 
| -  RegisterEnvironmentForDeoptimization(env);
 | 
| -  // Create safepoint generator that will also ensure enough space in the
 | 
| -  // reloc info for patching in deoptimization (since this is invoking a
 | 
| -  // builtin)
 | 
| -  SafepointGenerator safepoint_generator(this,
 | 
| -                                         pointers,
 | 
| -                                         env->deoptimization_index());
 | 
| +  SafepointGenerator safepoint_generator(
 | 
| +      this, pointers, Safepoint::kLazyDeopt);
 | 
|    __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
 | 
|  }
 | 
|  
 | 
|  
 | 
|  void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
 | 
| -  {
 | 
| -    PushSafepointRegistersScope scope(this);
 | 
| -    __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
 | 
| -    __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
 | 
| -    RegisterLazyDeoptimization(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
 | 
| -  }
 | 
| -
 | 
| -  // The gap code includes the restoring of the safepoint registers.
 | 
| -  int pc = masm()->pc_offset();
 | 
| -  safepoints_.SetPcAfterGap(pc);
 | 
| +  PushSafepointRegistersScope scope(this);
 | 
| +  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
 | 
| +  __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
 | 
| +  RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
 | 
| +  ASSERT(instr->HasEnvironment());
 | 
| +  LEnvironment* env = instr->environment();
 | 
| +  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -4261,6 +4201,10 @@
 | 
|      LStackCheck* instr_;
 | 
|    };
 | 
|  
 | 
| +  ASSERT(instr->HasEnvironment());
 | 
| +  LEnvironment* env = instr->environment();
 | 
| +  // There is no LLazyBailout instruction for stack-checks. We have to
 | 
| +  // prepare for lazy deoptimization explicitly here.
 | 
|    if (instr->hydrogen()->is_function_entry()) {
 | 
|      // Perform stack overflow check.
 | 
|      Label done;
 | 
| @@ -4268,7 +4212,10 @@
 | 
|      __ j(above_equal, &done, Label::kNear);
 | 
|      StackCheckStub stub;
 | 
|      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
 | 
| +    EnsureSpaceForLazyDeopt();
 | 
|      __ bind(&done);
 | 
| +    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
 | 
| +    safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
 | 
|    } else {
 | 
|      ASSERT(instr->hydrogen()->is_backwards_branch());
 | 
|      // Perform stack overflow check if this goto needs it before jumping.
 | 
| @@ -4276,8 +4223,13 @@
 | 
|          new DeferredStackCheck(this, instr);
 | 
|      __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
 | 
|      __ j(below, deferred_stack_check->entry());
 | 
| +    EnsureSpaceForLazyDeopt();
 | 
|      __ bind(instr->done_label());
 | 
|      deferred_stack_check->SetExit(instr->done_label());
 | 
| +    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
 | 
| +    // Don't record a deoptimization index for the safepoint here.
 | 
| +    // This will be done explicitly when emitting call and the safepoint in
 | 
| +    // the deferred code.
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -4293,7 +4245,7 @@
 | 
|    // If the environment were already registered, we would have no way of
 | 
|    // backpatching it with the spill slot operands.
 | 
|    ASSERT(!environment->HasBeenRegistered());
 | 
| -  RegisterEnvironmentForDeoptimization(environment);
 | 
| +  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
 | 
|    ASSERT(osr_pc_offset_ == -1);
 | 
|    osr_pc_offset_ = masm()->pc_offset();
 | 
|  }
 | 
| 
 |