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 {