| Index: src/crankshaft/lithium.cc
|
| diff --git a/src/crankshaft/lithium.cc b/src/crankshaft/lithium.cc
|
| index 3dff459a54a695676091d66cc161d76b48c6b650..d34b04f5da022ccaa582777c14db0fbb18f051cd 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,57 @@ 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.
|
| + // As for JS_GETTER/JS_SETTER/JS_CONSTRUCT nothing has to be done here,
|
| + // the deoptimizer ensures that the result of the callee is correctly
|
| + // propagated to result register during deoptimization.
|
| + 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;
|
|
|