summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2019-05-08 03:33:04 -0700
committer android-build-merger <android-build-merger@google.com> 2019-05-08 03:33:04 -0700
commitca87b0c0d6ae3546b74016f3700c42db856ee90e (patch)
tree35e251f5b41e54fc684d9f922bf5b72a648bd9c2
parentbd2a4db4c62da2796e2695206596f1a03aef83cb (diff)
parent439d12691964780784a67f178384c0175780f665 (diff)
Add StackVisitor::SetVRegReference().
am: 439d126919 Change-Id: I0abade5f4ef9c787b405d2887bd04979cb47558c
-rw-r--r--openjdkjvmti/ti_method.cc10
-rw-r--r--runtime/debugger.cc3
-rw-r--r--runtime/stack.cc51
-rw-r--r--runtime/stack.h9
4 files changed, 40 insertions, 33 deletions
diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc
index a4b579b96e..408ce6901f 100644
--- a/openjdkjvmti/ti_method.cc
+++ b/openjdkjvmti/ti_method.cc
@@ -814,13 +814,9 @@ class SetLocalVariableClosure : public CommonLocalVariableClosure {
override REQUIRES_SHARED(art::Locks::mutator_lock_) {
switch (type_) {
case art::Primitive::kPrimNot: {
- uint32_t ptr_val;
- art::ObjPtr<art::mirror::Object> obj(caller_->DecodeJObject(val_.l));
- ptr_val = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(obj.Ptr()));
- if (!visitor.SetVReg(method,
- static_cast<uint16_t>(slot_),
- ptr_val,
- art::kReferenceVReg)) {
+ if (!visitor.SetVRegReference(method,
+ static_cast<uint16_t>(slot_),
+ caller_->DecodeJObject(val_.l))) {
return ERR(OPAQUE_FRAME);
}
break;
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 8a1dbdda0f..c042d19b71 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -2848,8 +2848,7 @@ JDWP::JdwpError Dbg::SetLocalValue(Thread* thread, StackVisitor& visitor, int sl
VLOG(jdwp) << tag << " object " << o << " is an invalid object";
return JDWP::ERR_INVALID_OBJECT;
}
- if (!visitor.SetVReg(m, vreg, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(o.Ptr())),
- kReferenceVReg)) {
+ if (!visitor.SetVRegReference(m, vreg, o)) {
return FailSetLocalValue(visitor, vreg, tag, reinterpret_cast<uintptr_t>(o.Ptr()));
}
break;
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 80a563b57f..2ea39491c2 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -38,6 +38,7 @@
#include "mirror/object-inl.h"
#include "mirror/object_array-inl.h"
#include "oat_quick_method_header.h"
+#include "obj_ptr-inl.h"
#include "quick/quick_method_frame_info.h"
#include "runtime.h"
#include "thread.h"
@@ -372,13 +373,10 @@ bool StackVisitor::GetRegisterPairIfAccessible(uint32_t reg_lo, uint32_t reg_hi,
return true;
}
-bool StackVisitor::SetVReg(ArtMethod* m,
- uint16_t vreg,
- uint32_t new_value,
- VRegKind kind) {
+ShadowFrame* StackVisitor::PrepareSetVReg(ArtMethod* m, uint16_t vreg, bool wide) {
CodeItemDataAccessor accessor(m->DexInstructionData());
if (!accessor.HasCodeItem()) {
- return false;
+ return nullptr;
}
ShadowFrame* shadow_frame = GetCurrentShadowFrame();
if (shadow_frame == nullptr) {
@@ -388,15 +386,32 @@ bool StackVisitor::SetVReg(ArtMethod* m,
const uint16_t num_regs = accessor.RegistersSize();
shadow_frame = thread_->FindOrCreateDebuggerShadowFrame(frame_id, num_regs, m, GetDexPc());
CHECK(shadow_frame != nullptr);
- // Remember the vreg has been set for debugging and must not be overwritten by the
+ // Remember the vreg(s) has been set for debugging and must not be overwritten by the
// original value during deoptimization of the stack.
thread_->GetUpdatedVRegFlags(frame_id)[vreg] = true;
+ if (wide) {
+ thread_->GetUpdatedVRegFlags(frame_id)[vreg + 1] = true;
+ }
}
- if (kind == kReferenceVReg) {
- shadow_frame->SetVRegReference(vreg, reinterpret_cast<mirror::Object*>(new_value));
- } else {
- shadow_frame->SetVReg(vreg, new_value);
+ return shadow_frame;
+}
+
+bool StackVisitor::SetVReg(ArtMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind) {
+ DCHECK(kind == kIntVReg || kind == kFloatVReg);
+ ShadowFrame* shadow_frame = PrepareSetVReg(m, vreg, /* wide= */ false);
+ if (shadow_frame == nullptr) {
+ return false;
+ }
+ shadow_frame->SetVReg(vreg, new_value);
+ return true;
+}
+
+bool StackVisitor::SetVRegReference(ArtMethod* m, uint16_t vreg, ObjPtr<mirror::Object> new_value) {
+ ShadowFrame* shadow_frame = PrepareSetVReg(m, vreg, /* wide= */ false);
+ if (shadow_frame == nullptr) {
+ return false;
}
+ shadow_frame->SetVRegReference(vreg, new_value);
return true;
}
@@ -413,21 +428,9 @@ bool StackVisitor::SetVRegPair(ArtMethod* m,
LOG(FATAL) << "Expected long or double: kind_lo=" << kind_lo << ", kind_hi=" << kind_hi;
UNREACHABLE();
}
- CodeItemDataAccessor accessor(m->DexInstructionData());
- if (!accessor.HasCodeItem()) {
- return false;
- }
- ShadowFrame* shadow_frame = GetCurrentShadowFrame();
+ ShadowFrame* shadow_frame = PrepareSetVReg(m, vreg, /* wide= */ true);
if (shadow_frame == nullptr) {
- // This is a compiled frame: we must prepare for deoptimization (see SetVRegFromDebugger).
- const size_t frame_id = GetFrameId();
- const uint16_t num_regs = accessor.RegistersSize();
- shadow_frame = thread_->FindOrCreateDebuggerShadowFrame(frame_id, num_regs, m, GetDexPc());
- CHECK(shadow_frame != nullptr);
- // Remember the vreg pair has been set for debugging and must not be overwritten by the
- // original value during deoptimization of the stack.
- thread_->GetUpdatedVRegFlags(frame_id)[vreg] = true;
- thread_->GetUpdatedVRegFlags(frame_id)[vreg + 1] = true;
+ return false;
}
shadow_frame->SetVRegLong(vreg, new_value);
return true;
diff --git a/runtime/stack.h b/runtime/stack.h
index 1f305d2625..4bc0fc85d4 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -22,6 +22,7 @@
#include "base/locks.h"
#include "base/macros.h"
+#include "obj_ptr.h"
#include "quick/quick_method_frame_info.h"
#include "stack_map.h"
@@ -236,6 +237,11 @@ class StackVisitor {
// Values will be set in debugger shadow frames. Debugger will make sure deoptimization
// is triggered to make the values effective.
+ bool SetVRegReference(ArtMethod* m, uint16_t vreg, ObjPtr<mirror::Object> new_value)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+ // Values will be set in debugger shadow frames. Debugger will make sure deoptimization
+ // is triggered to make the values effective.
bool SetVRegPair(ArtMethod* m,
uint16_t vreg,
uint64_t new_value,
@@ -328,6 +334,9 @@ class StackVisitor {
uint64_t* val) const
REQUIRES_SHARED(Locks::mutator_lock_);
+ ShadowFrame* PrepareSetVReg(ArtMethod* m, uint16_t vreg, bool wide)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
void SanityCheckFrame() const REQUIRES_SHARED(Locks::mutator_lock_);
Thread* const thread_;