ART: Refactor try/catch block info, store exception type
This patch replaces HBasicBlock fields storing try/catch info with a
single TryCatchInformation data structure, saving memory for the
majority of non-try/catch blocks. It also changes builder to store
the exception type for catch blocks.
Change-Id: Ib3e43f7db247e6915d67c267fc62410420e230c9
diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc
index 5406a0c..847d5a4 100644
--- a/compiler/optimizing/graph_checker.cc
+++ b/compiler/optimizing/graph_checker.cc
@@ -402,14 +402,14 @@
}
// Ensure try membership information is consistent.
- HTryBoundary* try_entry = block->GetTryEntry();
if (block->IsCatchBlock()) {
- if (try_entry != nullptr) {
+ if (block->IsTryBlock()) {
+ const HTryBoundary& try_entry = block->GetTryCatchInformation()->GetTryEntry();
AddError(StringPrintf("Catch blocks should not be try blocks but catch block %d "
"has try entry %s:%d.",
block->GetBlockId(),
- try_entry->DebugName(),
- try_entry->GetId()));
+ try_entry.DebugName(),
+ try_entry.GetId()));
}
if (block->IsLoopHeader()) {
@@ -419,29 +419,30 @@
} else {
for (size_t i = 0; i < block->GetPredecessors().Size(); ++i) {
HBasicBlock* predecessor = block->GetPredecessors().Get(i);
- HTryBoundary* incoming_try_entry = predecessor->ComputeTryEntryOfSuccessors();
- if (try_entry == nullptr) {
- if (incoming_try_entry != nullptr) {
- AddError(StringPrintf("Block %d has no try entry but try entry %s:%d follows "
+ const HTryBoundary* incoming_try_entry = predecessor->ComputeTryEntryOfSuccessors();
+ if (block->IsTryBlock()) {
+ const HTryBoundary& stored_try_entry = block->GetTryCatchInformation()->GetTryEntry();
+ if (incoming_try_entry == nullptr) {
+ AddError(StringPrintf("Block %d has try entry %s:%d but no try entry follows "
"from predecessor %d.",
block->GetBlockId(),
+ stored_try_entry.DebugName(),
+ stored_try_entry.GetId(),
+ predecessor->GetBlockId()));
+ } else if (!incoming_try_entry->HasSameExceptionHandlersAs(stored_try_entry)) {
+ AddError(StringPrintf("Block %d has try entry %s:%d which is not consistent "
+ "with %s:%d that follows from predecessor %d.",
+ block->GetBlockId(),
+ stored_try_entry.DebugName(),
+ stored_try_entry.GetId(),
incoming_try_entry->DebugName(),
incoming_try_entry->GetId(),
predecessor->GetBlockId()));
}
- } else if (incoming_try_entry == nullptr) {
- AddError(StringPrintf("Block %d has try entry %s:%d but no try entry follows "
+ } else if (incoming_try_entry != nullptr) {
+ AddError(StringPrintf("Block %d is not a try block but try entry %s:%d follows "
"from predecessor %d.",
block->GetBlockId(),
- try_entry->DebugName(),
- try_entry->GetId(),
- predecessor->GetBlockId()));
- } else if (!incoming_try_entry->HasSameExceptionHandlersAs(*try_entry)) {
- AddError(StringPrintf("Block %d has try entry %s:%d which is not consistent "
- "with %s:%d that follows from predecessor %d.",
- block->GetBlockId(),
- try_entry->DebugName(),
- try_entry->GetId(),
incoming_try_entry->DebugName(),
incoming_try_entry->GetId(),
predecessor->GetBlockId()));