diff options
author | 2015-09-15 17:00:52 +0100 | |
---|---|---|
committer | 2015-09-15 17:50:43 +0100 | |
commit | 72f7b880d5d0057b9fac3a51ef3a0f22909bc633 (patch) | |
tree | 5a5a92f0c52bd334f662ba2f51885540874973bb | |
parent | b505997b2176bd29a108cb6c33d06d4ef29ba001 (diff) |
ART: Fix 004-ReferenceMap run test
This patch adds a new option to ArtMethod::ToNativeQuickPc to select
the order of iteration over stack maps. The method is only used by
the runtime to find native_pc of catch blocks, but also by the
004-ReferenceMap test which uses it to find native_pc of a safepoint.
Change-Id: Idb2b34aabf1ac7249c30a00806af7d63d7e682dd
-rw-r--r-- | runtime/art_method.cc | 13 | ||||
-rw-r--r-- | runtime/art_method.h | 4 | ||||
-rw-r--r-- | runtime/exception_test.cc | 6 | ||||
-rw-r--r-- | runtime/quick_exception_handler.cc | 3 | ||||
-rw-r--r-- | test/004-ReferenceMap/stack_walk_refmap_jni.cc | 4 |
5 files changed, 21 insertions, 9 deletions
diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 65f41ccefa..26839ece11 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -223,7 +223,9 @@ uint32_t ArtMethod::ToDexPc(const uintptr_t pc, bool abort_on_failure) { return DexFile::kDexNoIndex; } -uintptr_t ArtMethod::ToNativeQuickPc(const uint32_t dex_pc, bool abort_on_failure) { +uintptr_t ArtMethod::ToNativeQuickPc(const uint32_t dex_pc, + bool is_catch_handler, + bool abort_on_failure) { const void* entry_point = GetQuickOatEntryPoint(sizeof(void*)); if (IsOptimized(sizeof(void*))) { // Optimized code does not have a mapping table. Search for the dex-to-pc @@ -231,9 +233,12 @@ uintptr_t ArtMethod::ToNativeQuickPc(const uint32_t dex_pc, bool abort_on_failur CodeInfo code_info = GetOptimizedCodeInfo(); StackMapEncoding encoding = code_info.ExtractEncoding(); - // Assume the caller needs the mapping for a catch handler. If there are - // multiple stack maps for this dex_pc, it will hit the catch stack map first. - StackMap stack_map = code_info.GetCatchStackMapForDexPc(dex_pc, encoding); + // All stack maps are stored in the same CodeItem section, safepoint stack + // maps first, then catch stack maps. We use `is_catch_dex_pc` to select the + // order of iteration. + StackMap stack_map = + LIKELY(is_catch_handler) ? code_info.GetCatchStackMapForDexPc(dex_pc, encoding) + : code_info.GetStackMapForDexPc(dex_pc, encoding); if (stack_map.IsValid()) { return reinterpret_cast<uintptr_t>(entry_point) + stack_map.GetNativePcOffset(encoding); } diff --git a/runtime/art_method.h b/runtime/art_method.h index 3f2161f4ee..6c3b13f0e0 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -442,7 +442,9 @@ class ArtMethod FINAL { SHARED_REQUIRES(Locks::mutator_lock_); // Converts a dex PC to a native PC. - uintptr_t ToNativeQuickPc(const uint32_t dex_pc, bool abort_on_failure = true) + uintptr_t ToNativeQuickPc(const uint32_t dex_pc, + bool is_catch_handler, + bool abort_on_failure = true) SHARED_REQUIRES(Locks::mutator_lock_); MethodReference ToMethodReference() SHARED_REQUIRES(Locks::mutator_lock_) { diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc index 33d756ea12..9f84bd2a39 100644 --- a/runtime/exception_test.cc +++ b/runtime/exception_test.cc @@ -186,13 +186,15 @@ TEST_F(ExceptionTest, StackTraceElement) { fake_stack.push_back(0); } - fake_stack.push_back(method_g_->ToNativeQuickPc(dex_pc)); // return pc + fake_stack.push_back( + method_g_->ToNativeQuickPc(dex_pc, /* is_catch_handler */ false)); // return pc // Create/push fake 16byte stack frame for method g fake_stack.push_back(reinterpret_cast<uintptr_t>(method_g_)); fake_stack.push_back(0); fake_stack.push_back(0); - fake_stack.push_back(method_f_->ToNativeQuickPc(dex_pc)); // return pc + fake_stack.push_back( + method_g_->ToNativeQuickPc(dex_pc, /* is_catch_handler */ false)); // return pc // Create/push fake 16byte stack frame for method f fake_stack.push_back(reinterpret_cast<uintptr_t>(method_f_)); diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index b9d76b491c..c905b63c6c 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -97,7 +97,8 @@ class CatchBlockStackVisitor FINAL : public StackVisitor { if (found_dex_pc != DexFile::kDexNoIndex) { exception_handler_->SetHandlerMethod(method); exception_handler_->SetHandlerDexPc(found_dex_pc); - exception_handler_->SetHandlerQuickFramePc(method->ToNativeQuickPc(found_dex_pc)); + exception_handler_->SetHandlerQuickFramePc( + method->ToNativeQuickPc(found_dex_pc, /* is_catch_handler */ true)); exception_handler_->SetHandlerQuickFrame(GetCurrentQuickFrame()); return false; // End stack walk. } diff --git a/test/004-ReferenceMap/stack_walk_refmap_jni.cc b/test/004-ReferenceMap/stack_walk_refmap_jni.cc index 767e1de68f..55a77ac2eb 100644 --- a/test/004-ReferenceMap/stack_walk_refmap_jni.cc +++ b/test/004-ReferenceMap/stack_walk_refmap_jni.cc @@ -22,7 +22,9 @@ namespace art { #define CHECK_REGS_CONTAIN_REFS(dex_pc, abort_if_not_found, ...) do { \ int t[] = {__VA_ARGS__}; \ int t_size = sizeof(t) / sizeof(*t); \ - uintptr_t native_quick_pc = m->ToNativeQuickPc(dex_pc, abort_if_not_found); \ + uintptr_t native_quick_pc = m->ToNativeQuickPc(dex_pc, \ + /* is_catch_handler */ false, \ + abort_if_not_found); \ if (native_quick_pc != UINTPTR_MAX) { \ CheckReferences(t, t_size, m->NativeQuickPcOffset(native_quick_pc)); \ } \ |