ART: Stop creating a fallthrough block for Goto
Optimizing's Builder used to create a basic block after a Goto under
the assumption that control flow can fall through.
Bug: 19084197
Change-Id: Id85f31df98a4177466750d3cd0bc8bb74782ca2d
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index c497526..48ec497 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -378,15 +378,15 @@
dex_pc += instruction.SizeInCodeUnits();
code_ptr += instruction.SizeInCodeUnits();
- if (code_ptr >= code_end) {
- if (instruction.CanFlowThrough()) {
+ if (instruction.CanFlowThrough()) {
+ if (code_ptr >= code_end) {
// In the normal case we should never hit this but someone can artificially forge a dex
// file to fall-through out the method code. In this case we bail out compilation.
return false;
+ } else if (FindBlockStartingAt(dex_pc) == nullptr) {
+ block = new (arena_) HBasicBlock(graph_, dex_pc);
+ branch_targets_.Put(dex_pc, block);
}
- } else if (FindBlockStartingAt(dex_pc) == nullptr) {
- block = new (arena_) HBasicBlock(graph_, dex_pc);
- branch_targets_.Put(dex_pc, block);
}
} else if (instruction.IsSwitch()) {
SwitchTable table(instruction, dex_pc, instruction.Opcode() == Instruction::SPARSE_SWITCH);
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 01eb2d7..feb9afe 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -1035,9 +1035,8 @@
bool HBasicBlock::IsSingleGoto() const {
HLoopInformation* loop_info = GetLoopInformation();
- // TODO: Remove the null check b/19084197.
- return GetFirstInstruction() != nullptr
- && GetPhis().IsEmpty()
+ DCHECK(EndsWithControlFlowInstruction());
+ return GetPhis().IsEmpty()
&& GetFirstInstruction() == GetLastInstruction()
&& GetLastInstruction()->IsGoto()
// Back edges generate the suspend check.