Use try item offset to find catch block instead of Dex PC.

Change-Id: Icb8cd07a824be638c02a6204cfaf034a249d49b5
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 52807e3..f9a2833 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -3841,16 +3841,11 @@
   // Find catch block with matching type
   llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
 
-  // TODO: Maybe passing try item offset will be a better idea?  For now,
-  // we are passing dex_pc, so that we can use existing runtime support
-  // function directly.  However, in the runtime supporting function we
-  // have to search for try item with binary search which can be
-  // eliminated.
-  llvm::Value* dex_pc_value = irb_.getInt32(ti->start_addr_);
+  llvm::Value* ti_offset_value = irb_.getInt32(ti_offset);
 
   llvm::Value* catch_handler_index_value =
     irb_.CreateCall2(irb_.GetRuntime(FindCatchBlock),
-                     method_object_addr, dex_pc_value);
+                     method_object_addr, ti_offset_value);
 
   // Switch instruction (Go to unwind basic block by default)
   llvm::SwitchInst* sw =
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index 092c71b..bdfd222 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -159,14 +159,18 @@
   ThrowVerificationError(art_get_current_thread_from_code(), current_method, kind, ref);
 }
 
-int32_t art_find_catch_block_from_code(Method* current_method, int32_t dex_pc) {
+int32_t art_find_catch_block_from_code(Method* current_method,
+                                       uint32_t ti_offset) {
   Thread* thread = art_get_current_thread_from_code();
   Class* exception_type = thread->GetException()->GetClass();
   MethodHelper mh(current_method);
   const DexFile::CodeItem* code_item = mh.GetCodeItem();
+  DCHECK_LT(ti_offset, code_item->tries_size_);
+  const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item, ti_offset);
+
   int iter_index = 0;
   // Iterate over the catch handlers associated with dex_pc
-  for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
+  for (CatchHandlerIterator it(*code_item, *try_item); it.HasNext(); it.Next()) {
     uint16_t iter_type_idx = it.GetHandlerTypeIndex();
     // Catch all case
     if (iter_type_idx == DexFile::kDexNoIndex16) {
diff --git a/src/compiler_llvm/runtime_support_llvm.h b/src/compiler_llvm/runtime_support_llvm.h
index 6e3b81c..f8228c5 100644
--- a/src/compiler_llvm/runtime_support_llvm.h
+++ b/src/compiler_llvm/runtime_support_llvm.h
@@ -59,7 +59,8 @@
 
 void art_throw_exception_from_code(Object* exception);
 
-int32_t art_find_catch_block_from_code(Method* current_method, int32_t dex_pc);
+int32_t art_find_catch_block_from_code(Method* current_method,
+                                       uint32_t ti_offset);
 
 
 void art_test_suspend_from_code(Thread* thread);
diff --git a/src/dex_file.cc b/src/dex_file.cc
index 85dafee..eb2a157 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -1001,9 +1001,19 @@
     default:
       offset = DexFile::FindCatchHandlerOffset(code_item, code_item.tries_size_, address);
   }
+  Init(code_item, offset);
+}
+
+CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item,
+                                           const DexFile::TryItem& try_item) {
+  handler_.address_ = -1;
+  Init(code_item, try_item.handler_off_);
+}
+
+void CatchHandlerIterator::Init(const DexFile::CodeItem& code_item,
+                                int32_t offset) {
   if (offset >= 0) {
-    const byte* handler_data = DexFile::GetCatchHandlerData(code_item, offset);
-    Init(handler_data);
+    Init(DexFile::GetCatchHandlerData(code_item, offset));
   } else {
     // Not found, initialize as empty
     current_data_ = NULL;
diff --git a/src/dex_file.h b/src/dex_file.h
index 70c2059..aeb7e89 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -1128,6 +1128,10 @@
 class CatchHandlerIterator {
   public:
     CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address);
+
+    CatchHandlerIterator(const DexFile::CodeItem& code_item,
+                         const DexFile::TryItem& try_item);
+
     explicit CatchHandlerIterator(const byte* handler_data) {
       Init(handler_data);
     }
@@ -1148,6 +1152,7 @@
       return current_data_;
     }
   private:
+    void Init(const DexFile::CodeItem& code_item, int32_t offset);
     void Init(const byte* handler_data);
 
     struct CatchHandlerItem {