Commit d8153656 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[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: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50403}
parent 1cd6efe7
......@@ -322,32 +322,32 @@ 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);
block->label_state.stack_base = __ cache_state()->stack_height();
}
void Loop(Decoder* decoder, Control* loop) {
TraceCacheState(decoder);
loop->label_state.stack_base = __ cache_state()->stack_height();
new_block->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();
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.
__ bind(loop->label.get());
// Loop labels bind at the beginning of the block, block labels at the
// end.
__ bind(new_block->label.get());
// Save the current cache state for the merge when jumping to this loop.
loop->label_state.Split(*__ cache_state());
new_block->label_state.Split(*__ cache_state());
}
// Execute a stack check in the loop header.
StackCheck(decoder->position());
}
void Loop(Decoder* decoder, Control* block) { Block(decoder, block); }
void Try(Decoder* decoder, Control* block) { unsupported(decoder, "try"); }
void If(Decoder* decoder, const Value& cond, Control* if_block) {
unsupported(decoder, "if");
......
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