diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc index bc735df6b7..a27c61cb2d 100644 --- a/src/mips/deoptimizer-mips.cc +++ b/src/mips/deoptimizer-mips.cc @@ -45,12 +45,6 @@ int Deoptimizer::patch_size() { } -void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle code) { - // Nothing to do. No new relocation information is written for lazy - // deoptimization on MIPS. -} - - void Deoptimizer::DeoptimizeFunction(JSFunction* function) { HandleScope scope; AssertNoAllocation no_allocation; @@ -59,58 +53,38 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) { // Get the optimized code. Code* code = function->code(); + Address code_start_address = code->instruction_start(); // Invalidate the relocation information, as it will become invalid by the // code patching below, and is not needed any more. code->InvalidateRelocation(); - // For each return after a safepoint insert an absolute call to the - // corresponding deoptimization entry. - unsigned last_pc_offset = 0; - SafepointTable table(function->code()); - for (unsigned i = 0; i < table.length(); i++) { - unsigned pc_offset = table.GetPcOffset(i); - SafepointEntry safepoint_entry = table.GetEntry(i); - int deoptimization_index = safepoint_entry.deoptimization_index(); - int gap_code_size = safepoint_entry.gap_code_size(); - // Check that we did not shoot past next safepoint. - CHECK(pc_offset >= last_pc_offset); + // For each LLazyBailout instruction insert a call to the corresponding + // deoptimization entry. + DeoptimizationInputData* deopt_data = + DeoptimizationInputData::cast(code->deoptimization_data()); #ifdef DEBUG - // Destroy the code which is not supposed to be run again. - int instructions = (pc_offset - last_pc_offset) / Assembler::kInstrSize; - CodePatcher destroyer(code->instruction_start() + last_pc_offset, - instructions); - for (int x = 0; x < instructions; x++) { - destroyer.masm()->break_(0); - } + Address prev_call_address = NULL; #endif - last_pc_offset = pc_offset; - if (deoptimization_index != Safepoint::kNoDeoptimizationIndex) { - Address deoptimization_entry = Deoptimizer::GetDeoptimizationEntry( - deoptimization_index, Deoptimizer::LAZY); - last_pc_offset += gap_code_size; - int call_size_in_bytes = MacroAssembler::CallSize(deoptimization_entry, - RelocInfo::NONE); - int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; - ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); - ASSERT(call_size_in_bytes <= patch_size()); - CodePatcher patcher(code->instruction_start() + last_pc_offset, - call_size_in_words); - patcher.masm()->Call(deoptimization_entry, RelocInfo::NONE); - last_pc_offset += call_size_in_bytes; - } - } + for (int i = 0; i < deopt_data->DeoptCount(); i++) { + if (deopt_data->Pc(i)->value() == -1) continue; + Address call_address = code_start_address + deopt_data->Pc(i)->value(); + Address deopt_entry = GetDeoptimizationEntry(i, LAZY); + int call_size_in_bytes = MacroAssembler::CallSize(deopt_entry, + RelocInfo::NONE); + int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize; + ASSERT(call_size_in_bytes % Assembler::kInstrSize == 0); + ASSERT(call_size_in_bytes <= patch_size()); + CodePatcher patcher(call_address, call_size_in_words); + patcher.masm()->Call(deopt_entry, RelocInfo::NONE); + ASSERT(prev_call_address == NULL || + call_address >= prev_call_address + patch_size()); + ASSERT(call_address + patch_size() <= code->instruction_end()); #ifdef DEBUG - // Destroy the code which is not supposed to be run again. - int instructions = - (code->safepoint_table_offset() - last_pc_offset) / Assembler::kInstrSize; - CodePatcher destroyer(code->instruction_start() + last_pc_offset, - instructions); - for (int x = 0; x < instructions; x++) { - destroyer.masm()->break_(0); - } + prev_call_address = call_address; #endif + } Isolate* isolate = code->GetIsolate(); diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 5f423aab00..afe8056dc7 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -40,37 +40,22 @@ class SafepointGenerator : public CallWrapper { 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 generated code there. - int call_end = codegen_->masm()->pc_offset() + call_size; - int prev_jump_end = - codegen_->LastSafepointEnd() + Deoptimizer::patch_size(); - if (call_end < prev_jump_end) { - int padding_size = prev_jump_end - call_end; - ASSERT_EQ(0, padding_size % Assembler::kInstrSize); - while (padding_size > 0) { - codegen_->masm()->nop(); - padding_size -= Assembler::kInstrSize; - } - } - } + virtual void BeforeCall(int call_size) const { } virtual void AfterCall() const { - codegen_->RecordSafepoint(pointers_, deoptimization_index_); + codegen_->RecordSafepoint(pointers_, deopt_mode_); } private: LCodeGen* codegen_; LPointerMap* pointers_; - int deoptimization_index_; + Safepoint::DeoptMode deopt_mode_; }; @@ -101,7 +86,6 @@ void LCodeGen::FinishCode(Handle code) { code->set_stack_slots(GetStackSlotCount()); code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); PopulateDeoptimizationData(code); - Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(code); } @@ -198,7 +182,7 @@ bool LCodeGen::GeneratePrologue() { } else { __ CallRuntime(Runtime::kNewFunctionContext, 1); } - RecordSafepoint(Safepoint::kNoDeoptimizationIndex); + RecordSafepoint(Safepoint::kNoLazyDeopt); // Context is returned in both v0 and cp. It replaces the context // passed to us. It's saved in the stack and kept live in cp. __ sw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); @@ -226,6 +210,7 @@ bool LCodeGen::GeneratePrologue() { if (FLAG_trace) { __ CallRuntime(Runtime::kTraceEnter, 0); } + EnsureSpaceForLazyDeopt(); return !is_aborted(); } @@ -251,15 +236,6 @@ bool LCodeGen::GenerateBody() { } -LInstruction* LCodeGen::GetNextInstruction() { - if (current_instruction_ < instructions_->length() - 1) { - return instructions_->at(current_instruction_ + 1); - } else { - return NULL; - } -} - - bool LCodeGen::GenerateDeferredCode() { ASSERT(is_generating()); if (deferred_.length() > 0) { @@ -272,13 +248,6 @@ bool LCodeGen::GenerateDeferredCode() { 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()) { - __ nop(); - } } // Deferred code is the last part of the instruction sequence. Mark // the generated code as done unless we bailed out. @@ -534,7 +503,7 @@ void LCodeGen::CallCodeGeneric(Handle code, LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); __ Call(code, mode); - RegisterLazyDeoptimization(instr, safepoint_mode); + RecordSafepointWithLazyDeopt(instr, safepoint_mode); } @@ -547,7 +516,7 @@ void LCodeGen::CallRuntime(const Runtime::Function* function, RecordPosition(pointers->position()); __ CallRuntime(function, num_arguments); - RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); + RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); } @@ -556,37 +525,12 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, LInstruction* instr) { __ CallRuntimeSaveDoubles(id); RecordSafepointWithRegisters( - instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); + instr->pointer_map(), argc, Safepoint::kNoLazyDeopt); } -void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr, - SafepointMode safepoint_mode) { - // 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) { - RecordSafepoint(instr->pointer_map(), - deoptimization_environment->deoptimization_index()); - } else { - ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - RecordSafepointWithRegisters( - instr->pointer_map(), - 0, - 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 @@ -608,7 +552,10 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) { 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); } } @@ -618,7 +565,7 @@ void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment, Register src1, const Operand& src2) { - RegisterEnvironmentForDeoptimization(environment); + RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); ASSERT(environment->HasBeenRegistered()); int id = environment->deoptimization_index(); Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER); @@ -683,6 +630,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle code) { 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); } @@ -714,16 +662,28 @@ void LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { } +void LCodeGen::RecordSafepointWithLazyDeopt( + LInstruction* instr, SafepointMode safepoint_mode) { + if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { + RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); + } else { + ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); + RecordSafepointWithRegisters( + instr->pointer_map(), 0, Safepoint::kLazyDeopt); + } +} + + void LCodeGen::RecordSafepoint( LPointerMap* pointers, Safepoint::Kind kind, int arguments, - int deoptimization_index) { + Safepoint::DeoptMode deopt_mode) { ASSERT(expected_safepoint_kind_ == kind); const ZoneList* 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()) { @@ -740,31 +700,31 @@ void LCodeGen::RecordSafepoint( 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); } void LCodeGen::RecordSafepointWithRegistersAndDoubles( LPointerMap* pointers, int arguments, - int deoptimization_index) { - RecordSafepoint(pointers, Safepoint::kWithRegistersAndDoubles, arguments, - deoptimization_index); + Safepoint::DeoptMode deopt_mode) { + RecordSafepoint( + pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); } @@ -799,12 +759,6 @@ void LCodeGen::DoGap(LGap* gap) { 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); - } } @@ -1936,7 +1890,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 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_; } @@ -2004,8 +1958,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { } -void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, - Label* map_check) { +void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, + Label* map_check) { Register result = ToRegister(instr->result()); ASSERT(result.is(v0)); @@ -2039,6 +1993,9 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, RelocInfo::CODE_TARGET, instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); + ASSERT(instr->HasDeoptimizationEnvironment()); + LEnvironment* env = instr->deoptimization_environment(); + safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); // Put the result value into the result register slot and // restore all registers. __ StoreToSafepointRegisterSlot(result, result); @@ -2665,12 +2622,9 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { __ 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); // The number of arguments is stored in receiver which is a0, as expected // by InvokeFunction. v8::internal::ParameterCount actual(receiver); @@ -2753,7 +2707,7 @@ void LCodeGen::CallKnownFunction(Handle function, __ Call(at); // Setup deoptimization. - RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); + RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); // Restore context. __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); @@ -3130,10 +3084,8 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 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(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); @@ -4513,9 +4465,29 @@ void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { } +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; + ASSERT_EQ(0, padding_size % Assembler::kInstrSize); + while (padding_size > 0) { + __ nop(); + padding_size -= Assembler::kInstrSize; + } + } + 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()); } @@ -4532,12 +4504,9 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { __ Push(object, key, strict); 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); __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); } @@ -4548,27 +4517,20 @@ void LCodeGen::DoIn(LIn* instr) { __ Push(key, obj); 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); __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); } void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { - { - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); - __ CallRuntimeSaveDoubles(Runtime::kStackGuard); - RegisterLazyDeoptimization( - instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - } - - // The gap code includes the restoring of the safepoint registers. - int pc = masm()->pc_offset(); - safepoints_.SetPcAfterGap(pc); + PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + __ CallRuntimeSaveDoubles(Runtime::kStackGuard); + RecordSafepointWithLazyDeopt( + instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); + ASSERT(instr->HasEnvironment()); + LEnvironment* env = instr->environment(); + safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); } @@ -4583,6 +4545,10 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { 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; @@ -4590,7 +4556,10 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { __ Branch(&done, hs, sp, Operand(at)); 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. @@ -4598,8 +4567,13 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { new DeferredStackCheck(this, instr); __ LoadRoot(at, Heap::kStackLimitRootIndex); __ Branch(deferred_stack_check->entry(), lo, sp, Operand(at)); + 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. } } @@ -4615,7 +4589,7 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) { // 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(); } diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index 939404b986..5d4a057feb 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -58,6 +58,7 @@ class LCodeGen BASE_EMBEDDED { status_(UNUSED), deferred_(8), osr_pc_offset_(-1), + last_lazy_deopt_pc_(0), resolver_(this), expected_safepoint_kind_(Safepoint::kSimple) { PopulateDeoptimizationLiteralsWithInlinedFunctions(); @@ -108,8 +109,8 @@ class LCodeGen BASE_EMBEDDED { void DoDeferredStackCheck(LStackCheck* instr); void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); void DoDeferredStringCharFromCode(LStringCharFromCode* instr); - void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, - Label* map_check); + void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, + Label* map_check); // Parallel move support. void DoParallelMove(LParallelMove* move); @@ -212,10 +213,11 @@ class LCodeGen BASE_EMBEDDED { void LoadHeapObject(Register result, Handle object); - void RegisterLazyDeoptimization(LInstruction* instr, - SafepointMode safepoint_mode); + void RecordSafepointWithLazyDeopt(LInstruction* instr, + SafepointMode safepoint_mode); - void RegisterEnvironmentForDeoptimization(LEnvironment* environment); + void RegisterEnvironmentForDeoptimization(LEnvironment* environment, + Safepoint::DeoptMode mode); void DeoptimizeIf(Condition cc, LEnvironment* environment, Register src1, @@ -247,19 +249,16 @@ class LCodeGen BASE_EMBEDDED { void RecordSafepoint(LPointerMap* pointers, Safepoint::Kind kind, int arguments, - int deoptimization_index); - void RecordSafepoint(LPointerMap* pointers, int deoptimization_index); - void RecordSafepoint(int deoptimization_index); + Safepoint::DeoptMode mode); + void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); + void RecordSafepoint(Safepoint::DeoptMode mode); void RecordSafepointWithRegisters(LPointerMap* pointers, int arguments, - int deoptimization_index); + Safepoint::DeoptMode mode); void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers, int arguments, - int deoptimization_index); + Safepoint::DeoptMode mode); void RecordPosition(int position); - int LastSafepointEnd() { - return static_cast(safepoints_.GetPcAfterGap()); - } static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); @@ -317,6 +316,8 @@ class LCodeGen BASE_EMBEDDED { Address address; }; + void EnsureSpaceForLazyDeopt(); + LChunk* const chunk_; MacroAssembler* const masm_; CompilationInfo* const info_; @@ -333,6 +334,7 @@ class LCodeGen BASE_EMBEDDED { TranslationBuffer translations_; ZoneList deferred_; int osr_pc_offset_; + int last_lazy_deopt_pc_; // Builder that keeps track of safepoints in the code. The table // itself is emitted at the end of the generated code.