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
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 65f41cc..26839ec 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -223,7 +223,9 @@
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 @@
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 3f2161f..6c3b13f 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -442,7 +442,9 @@
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 33d756e..9f84bd2 100644
--- a/runtime/exception_test.cc
+++ b/runtime/exception_test.cc
@@ -186,13 +186,15 @@
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 b9d76b4..c905b63 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -97,7 +97,8 @@
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 767e1de..55a77ac 100644
--- a/test/004-ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/004-ReferenceMap/stack_walk_refmap_jni.cc
@@ -22,7 +22,9 @@
#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)); \
} \