Commit a6bf5bbd authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: [crankshaft] Fixing ES6 tail call elimination.

Port acbb968d
Port 66e22b79

Original commit messages:
    In case when F inlined normal call to G which tail calls H we should not write translation for G for the tail call site.
    Otherwise we will see G in a stack trace inside H.

    This CL also enables all existing tests related to ES6 tail call elimination and adds more combinations.

    Always generate lazy bailout points for tail calls because Debugger could still require them to inspect optimized frames.

R=ishell@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=chromium:596473, v8:4698
LOG=N

Review URL: https://codereview.chromium.org/1825513002

Cr-Commit-Position: refs/heads/master@{#34996}
parent 3521b37d
......@@ -559,11 +559,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);
}
......@@ -891,13 +887,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;
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(current_block_->last_environment());
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_);
}
......@@ -1075,6 +1094,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, r3), instr);
}
......@@ -1083,6 +1105,9 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), r4);
LInvokeFunction* result = new (zone()) LInvokeFunction(context, function);
if (instr->syntactic_tail_call_mode() == TailCallMode::kAllow) {
result->MarkAsSyntacticTailCall();
}
return MarkAsCall(DefineFixed(result, r3), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
......
......@@ -220,6 +220,13 @@ class LInstruction : public ZoneObject {
void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
bool IsCall() const { return IsCallBits::decode(bit_field_); }
void MarkAsSyntacticTailCall() {
bit_field_ = IsSyntacticTailCallBits::update(bit_field_, true);
}
bool IsSyntacticTailCall() const {
return IsSyntacticTailCallBits::decode(bit_field_);
}
// Interface to the register allocator and iterators.
bool ClobbersTemps() const { return IsCall(); }
bool ClobbersRegisters() const { return IsCall(); }
......@@ -254,6 +261,8 @@ class LInstruction : public ZoneObject {
virtual LOperand* TempAt(int i) = 0;
class IsCallBits : public BitField<bool, 0, 1> {};
class IsSyntacticTailCallBits : public BitField<bool, IsCallBits::kNext, 1> {
};
LEnvironment* environment_;
SetOncePointer<LPointerMap> pointer_map_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment