[Liftoff] Add loop-header stack checks
This is needed to ensure that code can be interrupted. It will be covered by a test once we support if-constructs in Liftoff. Drive-by: Separate handling of blocks and loops, as there is only one line in common. R=ahaas@chromium.org Bug: v8:6600 Change-Id: Ic22ca5e65c8d03a5d504289ec2a9e30cb97dc220 Reviewed-on: https://chromium-review.googlesource.com/853858 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Andreas Haas <ahaas@chromium.org> Cr-Commit-Position: refs/heads/master@{#50403}
This commit is contained in:
parent
1cd6efe7bb
commit
d81536564d
@ -322,31 +322,31 @@ class LiftoffCompiler {
|
||||
BindUnboundLabels(decoder);
|
||||
}
|
||||
|
||||
void Block(Decoder* decoder, Control* new_block) {
|
||||
// Note: This is called for blocks and loops.
|
||||
DCHECK_EQ(new_block, decoder->control_at(0));
|
||||
|
||||
void Block(Decoder* decoder, Control* block) {
|
||||
TraceCacheState(decoder);
|
||||
|
||||
new_block->label_state.stack_base = __ cache_state()->stack_height();
|
||||
|
||||
if (new_block->is_loop()) {
|
||||
// Before entering a loop, spill all locals to the stack, in order to free
|
||||
// the cache registers, and to avoid unnecessarily reloading stack values
|
||||
// into registers at branches.
|
||||
// TODO(clemensh): Come up with a better strategy here, involving
|
||||
// pre-analysis of the function.
|
||||
__ SpillLocals();
|
||||
|
||||
// Loop labels bind at the beginning of the block, block labels at the
|
||||
// end.
|
||||
__ bind(new_block->label.get());
|
||||
|
||||
new_block->label_state.Split(*__ cache_state());
|
||||
}
|
||||
block->label_state.stack_base = __ cache_state()->stack_height();
|
||||
}
|
||||
|
||||
void Loop(Decoder* decoder, Control* block) { Block(decoder, block); }
|
||||
void Loop(Decoder* decoder, Control* loop) {
|
||||
TraceCacheState(decoder);
|
||||
loop->label_state.stack_base = __ cache_state()->stack_height();
|
||||
|
||||
// Before entering a loop, spill all locals to the stack, in order to free
|
||||
// the cache registers, and to avoid unnecessarily reloading stack values
|
||||
// into registers at branches.
|
||||
// TODO(clemensh): Come up with a better strategy here, involving
|
||||
// pre-analysis of the function.
|
||||
__ SpillLocals();
|
||||
|
||||
// Loop labels bind at the beginning of the block.
|
||||
__ bind(loop->label.get());
|
||||
|
||||
// Save the current cache state for the merge when jumping to this loop.
|
||||
loop->label_state.Split(*__ cache_state());
|
||||
|
||||
// Execute a stack check in the loop header.
|
||||
StackCheck(decoder->position());
|
||||
}
|
||||
|
||||
void Try(Decoder* decoder, Control* block) { unsupported(decoder, "try"); }
|
||||
void If(Decoder* decoder, const Value& cond, Control* if_block) {
|
||||
|
Loading…
Reference in New Issue
Block a user