Skip to content

Commit 41b80ee

Browse files
LeszekSwirskiCommit Bot
authored andcommitted
[compiler] Propagate liveness across suspends
Suspend points (inside generators and async functions) have slightly funky semantics when it comes to liveness, as they save and restore a chunk of the register file as-is. In particular, this means that granular liveness information is lost, as it is assumed that all registers in that chunk of the register file are live in a suspend. Rather than marking that entire chunk of register as live/dead in suspend/restore, we can instead pattern-match the set of bytecodes in a suspend point, and propagate liveness across them. This tightens liveness estimates, and could be used to optimize which values TurboFan actually saves when suspending. Bug: chromium:798137 Change-Id: I5840cdbfc2c6edb1d3a48cf025f52615b629cdfc Reviewed-on: https://chromium-review.googlesource.com/848895 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#50757}
1 parent e40a968 commit 41b80ee

1 file changed

Lines changed: 22 additions & 1 deletion

File tree

src/compiler/bytecode-analysis.cc

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,21 @@ void UpdateInLiveness(Bytecode bytecode, BytecodeLivenessState& in_liveness,
8080
int num_operands = Bytecodes::NumberOfOperands(bytecode);
8181
const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode);
8282

83+
// Special case Suspend and Resume to just pass through liveness.
84+
if (bytecode == Bytecode::kSuspendGenerator) {
85+
// The generator object has to be live.
86+
in_liveness.MarkRegisterLive(accessor.GetRegisterOperand(0).index());
87+
// Suspend additionally reads and returns the accumulator
88+
DCHECK(Bytecodes::ReadsAccumulator(bytecode));
89+
in_liveness.MarkAccumulatorDead();
90+
return;
91+
}
92+
if (bytecode == Bytecode::kResumeGenerator) {
93+
// The generator object has to be live.
94+
in_liveness.MarkRegisterLive(accessor.GetRegisterOperand(0).index());
95+
return;
96+
}
97+
8398
if (Bytecodes::WritesAccumulator(bytecode)) {
8499
in_liveness.MarkAccumulatorDead();
85100
}
@@ -175,6 +190,13 @@ void UpdateOutLiveness(Bytecode bytecode, BytecodeLivenessState& out_liveness,
175190
int current_offset = accessor.current_offset();
176191
const Handle<BytecodeArray>& bytecode_array = accessor.bytecode_array();
177192

193+
// Special case Suspend and Resume to just pass through liveness.
194+
if (bytecode == Bytecode::kSuspendGenerator ||
195+
bytecode == Bytecode::kResumeGenerator) {
196+
out_liveness.Union(*next_bytecode_in_liveness);
197+
return;
198+
}
199+
178200
// Update from jump target (if any). Skip loops, we update these manually in
179201
// the liveness iterations.
180202
if (Bytecodes::IsForwardJump(bytecode)) {
@@ -316,7 +338,6 @@ void BytecodeAnalysis::Analyze(BailoutId osr_bailout_id) {
316338
iterator, liveness_map_);
317339
liveness.in->CopyFrom(*liveness.out);
318340
UpdateInLiveness(bytecode, *liveness.in, iterator);
319-
320341
next_bytecode_in_liveness = liveness.in;
321342
}
322343
}

0 commit comments

Comments
 (0)