summaryrefslogtreecommitdiff
path: root/runtime/thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/thread.cc')
-rw-r--r--runtime/thread.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/runtime/thread.cc b/runtime/thread.cc
index a4bc8ee5f8..6e57ec6695 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -89,6 +89,7 @@
#include "native_stack_dump.h"
#include "nativehelper/scoped_local_ref.h"
#include "nativehelper/scoped_utf_chars.h"
+#include "nterp_helpers.h"
#include "nth_caller_visitor.h"
#include "oat_quick_method_header.h"
#include "obj_ptr-inl.h"
@@ -3713,6 +3714,8 @@ class ReferenceMapVisitor : public StackVisitor {
ShadowFrame* shadow_frame = GetCurrentShadowFrame();
if (shadow_frame != nullptr) {
VisitShadowFrame(shadow_frame);
+ } else if (GetCurrentOatQuickMethodHeader()->IsNterpMethodHeader()) {
+ VisitNterpFrame();
} else {
VisitQuickFrame();
}
@@ -3781,6 +3784,32 @@ class ReferenceMapVisitor : public StackVisitor {
}
}
+ void VisitNterpFrame() REQUIRES_SHARED(Locks::mutator_lock_) {
+ ArtMethod** cur_quick_frame = GetCurrentQuickFrame();
+ StackReference<mirror::Object>* vreg_ref_base =
+ reinterpret_cast<StackReference<mirror::Object>*>(NterpGetReferenceArray(cur_quick_frame));
+ StackReference<mirror::Object>* vreg_int_base =
+ reinterpret_cast<StackReference<mirror::Object>*>(NterpGetRegistersArray(cur_quick_frame));
+ CodeItemDataAccessor accessor((*cur_quick_frame)->DexInstructionData());
+ const uint16_t num_regs = accessor.RegistersSize();
+ // An nterp frame has two arrays: a dex register array and a reference array
+ // that shadows the dex register array but only containing references
+ // (non-reference dex registers have nulls). See nterp_helpers.cc.
+ for (size_t reg = 0; reg < num_regs; ++reg) {
+ StackReference<mirror::Object>* ref_addr = vreg_ref_base + reg;
+ mirror::Object* ref = ref_addr->AsMirrorPtr();
+ if (ref != nullptr) {
+ mirror::Object* new_ref = ref;
+ visitor_(&new_ref, reg, this);
+ if (new_ref != ref) {
+ ref_addr->Assign(new_ref);
+ StackReference<mirror::Object>* int_addr = vreg_int_base + reg;
+ int_addr->Assign(new_ref);
+ }
+ }
+ }
+ }
+
template <typename T>
ALWAYS_INLINE
inline void VisitQuickFrameWithVregCallback() REQUIRES_SHARED(Locks::mutator_lock_) {