Index: src/crankshaft/s390/lithium-s390.cc |
diff --git a/src/crankshaft/s390/lithium-s390.cc b/src/crankshaft/s390/lithium-s390.cc |
index 9095a2782f2fa83e3d8fa7c504aa3812bf077641..5b278d828d065289fad4a867b2b5e3015cb97eb5 100644 |
--- a/src/crankshaft/s390/lithium-s390.cc |
+++ b/src/crankshaft/s390/lithium-s390.cc |
@@ -499,11 +499,7 @@ LInstruction* LChunkBuilder::DefineFixedDouble( |
LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { |
HEnvironment* hydrogen_env = current_block_->last_environment(); |
- int argument_index_accumulator = 0; |
- ZoneList<HValue*> objects_to_materialize(0, zone()); |
- instr->set_environment(CreateEnvironment( |
- hydrogen_env, &argument_index_accumulator, &objects_to_materialize)); |
- return instr; |
+ return LChunkBuilderBase::AssignEnvironment(instr, hydrogen_env); |
} |
LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, |
@@ -815,13 +811,36 @@ void LChunkBuilder::AddInstruction(LInstruction* instr, |
chunk_->AddInstruction(instr, current_block_); |
if (instr->IsCall()) { |
+ HEnvironment* hydrogen_env = current_block_->last_environment(); |
HValue* hydrogen_value_for_lazy_bailout = hydrogen_val; |
- if (hydrogen_val->HasObservableSideEffects()) { |
- HSimulate* sim = HSimulate::cast(hydrogen_val->next()); |
- sim->ReplayEnvironment(current_block_->last_environment()); |
- hydrogen_value_for_lazy_bailout = sim; |
+ DCHECK_NOT_NULL(hydrogen_env); |
+ if (instr->IsSyntacticTailCall()) { |
+ // If it was a syntactic tail call we need to drop the current frame and |
+ // an arguments adaptor frame on top of it (if the latter is present). |
+ hydrogen_env = hydrogen_env->outer(); |
+ if (hydrogen_env != nullptr && |
+ hydrogen_env->frame_type() == ARGUMENTS_ADAPTOR) { |
+ hydrogen_env = hydrogen_env->outer(); |
+ } |
+ if (hydrogen_env != nullptr) { |
+ // Push return value on top of outer environment. |
+ 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 = AssignEnvironment(new (zone()) LLazyBailout()); |
+ LInstruction* bailout = LChunkBuilderBase::AssignEnvironment( |
+ new (zone()) LLazyBailout(), hydrogen_env); |
bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout); |
chunk_->AddInstruction(bailout, current_block_); |
} |
@@ -981,6 +1000,9 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) { |
LCallWithDescriptor* result = |
new (zone()) LCallWithDescriptor(descriptor, ops, zone()); |
+ if (instr->syntactic_tail_call_mode() == TailCallMode::kAllow) { |
+ result->MarkAsSyntacticTailCall(); |
+ } |
return MarkAsCall(DefineFixed(result, r2), instr); |
} |
@@ -988,6 +1010,9 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { |
LOperand* context = UseFixed(instr->context(), cp); |
LOperand* function = UseFixed(instr->function(), r3); |
LInvokeFunction* result = new (zone()) LInvokeFunction(context, function); |
+ if (instr->syntactic_tail_call_mode() == TailCallMode::kAllow) { |
+ result->MarkAsSyntacticTailCall(); |
+ } |
return MarkAsCall(DefineFixed(result, r2), instr, CANNOT_DEOPTIMIZE_EAGERLY); |
} |