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/nodes.cc b/compiler/optimizing/nodes.cc
index f2b63ae..64c680c 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -339,7 +339,10 @@
     // been visited already and had its try membership set.
     HBasicBlock* first_predecessor = block->GetPredecessors().Get(0);
     DCHECK(!block->IsLoopHeader() || !block->GetLoopInformation()->IsBackEdge(*first_predecessor));
-    block->SetTryEntry(first_predecessor->ComputeTryEntryOfSuccessors());
+    const HTryBoundary* try_entry = first_predecessor->ComputeTryEntryOfSuccessors();
+    if (try_entry != nullptr) {
+      block->SetTryCatchInformation(new (arena_) TryCatchInformation(*try_entry));
+    }
   }
 }
 
@@ -1164,19 +1167,21 @@
   return new_block;
 }
 
-HTryBoundary* HBasicBlock::ComputeTryEntryOfSuccessors() const {
+const HTryBoundary* HBasicBlock::ComputeTryEntryOfSuccessors() const {
   if (EndsWithTryBoundary()) {
     HTryBoundary* try_boundary = GetLastInstruction()->AsTryBoundary();
     if (try_boundary->IsEntry()) {
-      DCHECK(try_entry_ == nullptr);
+      DCHECK(!IsTryBlock());
       return try_boundary;
     } else {
-      DCHECK(try_entry_ != nullptr);
-      DCHECK(try_entry_->HasSameExceptionHandlersAs(*try_boundary));
+      DCHECK(IsTryBlock());
+      DCHECK(try_catch_information_->GetTryEntry().HasSameExceptionHandlersAs(*try_boundary));
       return nullptr;
     }
+  } else if (IsTryBlock()) {
+    return &try_catch_information_->GetTryEntry();
   } else {
-    return try_entry_;
+    return nullptr;
   }
 }