ART: Changes to try-catch in GraphBuilder
This patch adds an additional case into the insertion algorithm for
HTryBoundary inside HGraphBuilder in order to better handle catch
blocks covered by a TryItem.
Building SSA form also required to stop combining HTryBoundaries for
neighbouring TryItems because it was not clear which exception
handlers belong to which try block.
Change-Id: Ic68bd6ef98fee784609fa593cb08dca1f00a15e0
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 95ea966..5c10245 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -729,9 +729,10 @@
bool IsExceptionalSuccessor(size_t idx) const;
// Split the block into two blocks just before `cursor`. Returns the newly
- // created, latter block. Note that this method will create a Goto at the end
- // of the former block and will create an edge between them. It will not,
- // however, update the graph, reverse post order or loop information.
+ // created, latter block. Note that this method will add the block to the
+ // graph, create a Goto at the end of the former block and will create an edge
+ // between the blocks. It will not, however, update the reverse post order or
+ // loop information.
HBasicBlock* SplitBefore(HInstruction* cursor);
// Split the block into two blocks just after `cursor`. Returns the newly
@@ -1946,11 +1947,18 @@
// higher indices in no particular order.
class HTryBoundary : public HTemplateInstruction<0> {
public:
- HTryBoundary(bool is_entry, bool is_exit)
- : HTemplateInstruction(SideEffects::None()), is_entry_(is_entry), is_exit_(is_exit) {}
+ enum BoundaryKind {
+ kEntry,
+ kExit,
+ };
+
+ explicit HTryBoundary(BoundaryKind kind)
+ : HTemplateInstruction(SideEffects::None()), kind_(kind) {}
bool IsControlFlow() const OVERRIDE { return true; }
+ bool CanThrow() const OVERRIDE { return true; }
+
// Returns the block's non-exceptional successor (index zero).
HBasicBlock* GetNormalFlowSuccessor() const { return GetBlock()->GetSuccessors().Get(0); }
@@ -1977,21 +1985,12 @@
}
}
- bool IsTryEntry() const { return is_entry_; }
- bool IsTryExit() const { return is_exit_; }
+ bool IsEntry() const { return kind_ == BoundaryKind::kEntry; }
DECLARE_INSTRUCTION(TryBoundary);
private:
- // Only for debugging purposes.
- bool is_entry_;
- bool is_exit_;
-
- // Only set by HGraphBuilder.
- void SetIsTryEntry() { is_entry_ = true; }
- void SetIsTryExit() { is_exit_ = true; }
-
- friend HGraphBuilder;
+ const BoundaryKind kind_;
DISALLOW_COPY_AND_ASSIGN(HTryBoundary);
};