Chromium Code Reviews| Index: src/crankshaft/lithium.cc |
| diff --git a/src/crankshaft/lithium.cc b/src/crankshaft/lithium.cc |
| index 3dff459a54a695676091d66cc161d76b48c6b650..8ba491dfaf9ff5ae1dac3dabd643a9d893bc5b77 100644 |
| --- a/src/crankshaft/lithium.cc |
| +++ b/src/crankshaft/lithium.cc |
| @@ -338,7 +338,6 @@ void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { |
| } |
| } |
| - |
| LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { |
| return LConstantOperand::Create(constant->id(), zone()); |
| } |
| @@ -508,6 +507,54 @@ void LChunkBuilderBase::Retry(BailoutReason reason) { |
| status_ = ABORTED; |
| } |
| +void LChunkBuilderBase::CreateLazyBailoutForCall(HBasicBlock* current_block, |
| + LInstruction* instr, |
| + HInstruction* hydrogen_val) { |
| + if (!instr->IsCall()) return; |
| + |
| + HEnvironment* hydrogen_env = current_block->last_environment(); |
| + HValue* hydrogen_value_for_lazy_bailout = hydrogen_val; |
| + DCHECK_NOT_NULL(hydrogen_env); |
| + if (instr->IsSyntacticTailCall()) { |
| + // If it was a syntactic tail call we need to drop the current frame and |
| + // all the frames on top of it that are either an arguments adaptor frame |
| + // or a tail caller frame. |
| + hydrogen_env = hydrogen_env->outer(); |
| + while (hydrogen_env != nullptr && |
| + (hydrogen_env->frame_type() == ARGUMENTS_ADAPTOR || |
| + hydrogen_env->frame_type() == TAIL_CALLER_FUNCTION)) { |
| + hydrogen_env = hydrogen_env->outer(); |
| + } |
| + if (hydrogen_env != nullptr) { |
| + if (hydrogen_env->frame_type() == JS_FUNCTION) { |
| + // In case an outer frame is a function frame we have to replay |
| + // environment manually because |
| + // 1) it does not contain a result of inlined function yet, |
| + // 2) we can't find the proper simulate that corresponds to the point |
| + // after inlined call to do a ReplayEnvironment() on. |
| + // So we push return value on top of outer environment. |
|
Jarin
2016/05/06 10:40:17
Could you also mention that pushing magic for the
Igor Sheludko
2016/05/06 11:56:05
Done.
|
| + hydrogen_env = hydrogen_env->Copy(); |
| + hydrogen_env->Push(hydrogen_val); |
| + } |
| + } else { |
| + // Although we don't need this lazy bailout for normal execution |
| + // (because when we tail call from the outermost function we should pop |
| + // its frame) we still need it when debugger is on. |
| + hydrogen_env = current_block->last_environment(); |
| + } |
| + } else { |
| + if (hydrogen_val->HasObservableSideEffects()) { |
| + HSimulate* sim = HSimulate::cast(hydrogen_val->next()); |
| + sim->ReplayEnvironment(hydrogen_env); |
| + hydrogen_value_for_lazy_bailout = sim; |
| + } |
| + } |
| + LInstruction* bailout = LChunkBuilderBase::AssignEnvironment( |
| + new (zone()) LLazyBailout(), hydrogen_env); |
| + bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout); |
| + chunk_->AddInstruction(bailout, current_block); |
| +} |
| + |
| LInstruction* LChunkBuilderBase::AssignEnvironment(LInstruction* instr, |
| HEnvironment* hydrogen_env) { |
| int argument_index_accumulator = 0; |