diff options
| author | 2019-05-08 03:33:04 -0700 | |
|---|---|---|
| committer | 2019-05-08 03:33:04 -0700 | |
| commit | ca87b0c0d6ae3546b74016f3700c42db856ee90e (patch) | |
| tree | 35e251f5b41e54fc684d9f922bf5b72a648bd9c2 | |
| parent | bd2a4db4c62da2796e2695206596f1a03aef83cb (diff) | |
| parent | 439d12691964780784a67f178384c0175780f665 (diff) | |
Add StackVisitor::SetVRegReference().
am: 439d126919
Change-Id: I0abade5f4ef9c787b405d2887bd04979cb47558c
| -rw-r--r-- | openjdkjvmti/ti_method.cc | 10 | ||||
| -rw-r--r-- | runtime/debugger.cc | 3 | ||||
| -rw-r--r-- | runtime/stack.cc | 51 | ||||
| -rw-r--r-- | runtime/stack.h | 9 |
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_; |