Skip to content

Commit

Permalink
Handle control flow edge case in JIT. Fixes rubinius#478.
Browse files Browse the repository at this point in the history
See the crash test committed. The bug as because if the instruction
after a git/gif was a loop header, we wouldn't set the exception handler
of the loop body block.
  • Loading branch information
Evan Phoenix committed Sep 21, 2010
1 parent 96a6d91 commit 82f2b57
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
13 changes: 11 additions & 2 deletions vm/llvm/cfg.hpp
Expand Up @@ -121,7 +121,16 @@ namespace jit {

CFGBlock* add_block(int ip, bool loop=false) {
CFGBlock* blk = find_block(ip);
if(blk) return blk;
if(blk) {
// If we hit a block that is the start of a loop header,
// be sure to set it's exception handler. These blocks are created
// during the first pass.
if(blk->loop_p()) {
// Inherit the current exception handler
blk->set_exception_handler(current_->exception_handler());
}
return blk;
}

blk = new CFGBlock(ip, loop);

Expand Down Expand Up @@ -185,7 +194,7 @@ namespace jit {
VMMethod::Iterator iter(stream_, stream_size_);
for(;;) {
if(CFGBlock* next_block = find_block(iter.position())) {
if(next_block->loop_p()) {
if(next_block->loop_p() && current_ != next_block) {
// The handler wasn't setup originally, so we have to set it now.
next_block->set_exception_handler(current_->exception_handler());

Expand Down
22 changes: 22 additions & 0 deletions vm/test/jit/crash_goto_loop_header.rb
@@ -0,0 +1,22 @@
# Test for a JIT bug where the while inside the if generated a goto
# of a loop header and skipped setup up the exception handler
# properly.
#
# If this doesn't crash, the bug is fixed.
def bad
i = 0
begin
if i < 10
while i < 20
i += 2
end
end
rescue => ex
raise "failure is an option"
end
i
end

1000000.times do
bad
end

0 comments on commit 82f2b57

Please sign in to comment.