Factor out try item from catch handler finding.

Portable indexs try basic blocks using their try item index. Factor out this
computation from catch handler address computation so that the binary search
code can be shared (WIP for the sharing in
 https://googleplex-android-review.googlesource.com/#/c/281427/20).

Change-Id: Ifea63bf06c0184c6fa7a6aa3a6620711e390069a
diff --git a/src/dex_file.cc b/src/dex_file.cc
index 8b87ee7..11ddcd5 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -609,31 +609,39 @@
   return context.line_num_;
 }
 
-int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, int32_t tries_size,
-                                        uint32_t address) {
+int32_t DexFile::FindTryItem(const CodeItem &code_item, uint32_t address) {
   // Note: Signed type is important for max and min.
   int32_t min = 0;
-  int32_t max = tries_size - 1;
+  int32_t max = code_item.tries_size_ - 1;
 
-  while (max >= min) {
-    int32_t mid = (min + max) / 2;
-    const TryItem* try_item = DexFile::GetTryItems(code_item, mid);
-    uint32_t start = try_item->start_addr_;
+  while (min <= max) {
+    int32_t mid = min + ((max - min) / 2);
+
+    const art::DexFile::TryItem* ti = GetTryItems(code_item, mid);
+    uint32_t start = ti->start_addr_;
+    uint32_t end = start + ti->insn_count_;
+
     if (address < start) {
       max = mid - 1;
-    } else {
-      uint32_t end = start + try_item->insn_count_;
-      if (address >= end) {
-        min = mid + 1;
-      } else {  // We have a winner!
-        return (int32_t) try_item->handler_off_;
-      }
+    } else if (address >= end) {
+      min = mid + 1;
+    } else {  // We have a winner!
+      return mid;
     }
   }
   // No match.
   return -1;
 }
 
+int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address) {
+  int32_t try_item = FindTryItem(code_item, address);
+  if (try_item == -1) {
+    return -1;
+  } else {
+    return DexFile::GetTryItems(code_item, try_item)->handler_off_;
+  }
+}
+
 void DexFile::DecodeDebugInfo0(const CodeItem* code_item, bool is_static, uint32_t method_idx,
                                DexDebugNewPositionCb position_cb, DexDebugNewLocalCb local_cb,
                                void* context, const byte* stream, LocalInfo* local_in_reg) const {
@@ -1029,7 +1037,7 @@
       break;
     }
     default:
-      offset = DexFile::FindCatchHandlerOffset(code_item, code_item.tries_size_, address);
+      offset = DexFile::FindCatchHandlerOffset(code_item, address);
   }
   Init(code_item, offset);
 }
diff --git a/src/dex_file.h b/src/dex_file.h
index 002d79c..88dd5fc 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -690,11 +690,11 @@
     return handler_data + offset;
   }
 
-  // Find the handler associated with a given address, if any.
-  // Initializes the given iterator and returns true if a match is
-  // found. Returns end if there is no applicable handler.
-  static int32_t FindCatchHandlerOffset(const CodeItem &code_item, int32_t tries_size,
-                                        uint32_t address);
+  // Find which try region is associated with the given address (ie dex pc). Returns -1 if none.
+  static int32_t FindTryItem(const CodeItem &code_item, uint32_t address);
+
+  // Find the handler offset associated with the given address (ie dex pc). Returns -1 if none.
+  static int32_t FindCatchHandlerOffset(const CodeItem &code_item, uint32_t address);
 
   // Get the pointer to the start of the debugging data
   const byte* GetDebugInfoStream(const CodeItem* code_item) const {