diff options
Diffstat (limited to 'runtime/stack.cc')
-rw-r--r-- | runtime/stack.cc | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/runtime/stack.cc b/runtime/stack.cc index 7e922c59f0..132ac3e795 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -142,7 +142,8 @@ size_t StackVisitor::GetNativePcOffset() const { return GetMethod()->NativePcOffset(cur_quick_frame_pc_); } -uint32_t StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind) const { +bool StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind, + uint32_t* val) const { if (cur_quick_frame_ != NULL) { DCHECK(context_ != NULL); // You can't reliably read registers without a context. DCHECK(m == GetMethod()); @@ -155,19 +156,30 @@ uint32_t StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kin if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) { bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask(); - return GetGPR(vmap_table.ComputeRegister(spill_mask, vmap_offset, kind)); + uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind); + uintptr_t ptr_val; + bool success = false; + if (is_float) { + success = GetFPR(reg, &ptr_val); + } else { + success = GetGPR(reg, &ptr_val); + } + *val = ptr_val; + return success; } else { const DexFile::CodeItem* code_item = m->GetCodeItem(); DCHECK(code_item != NULL) << PrettyMethod(m); // Can't be NULL or how would we compile its instructions? - return *GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(), + *val = *GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(), frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg); + return true; } } else { - return cur_shadow_frame_->GetVReg(vreg); + *val = cur_shadow_frame_->GetVReg(vreg); + return true; } } -void StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_value, +bool StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind) { if (cur_quick_frame_ != NULL) { DCHECK(context_ != NULL); // You can't reliably write registers without a context. @@ -181,8 +193,12 @@ void StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_val if (vmap_table.IsInContext(vreg, kind, &vmap_offset)) { bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask(); - const uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kReferenceVReg); - SetGPR(reg, new_value); + const uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind); + if (is_float) { + return SetFPR(reg, new_value); + } else { + return SetGPR(reg, new_value); + } } else { const DexFile::CodeItem* code_item = m->GetCodeItem(); DCHECK(code_item != NULL) << PrettyMethod(m); // Can't be NULL or how would we compile its instructions? @@ -190,9 +206,11 @@ void StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_val frame_info.FrameSizeInBytes(), vreg, kRuntimeISA); byte* vreg_addr = reinterpret_cast<byte*>(GetCurrentQuickFrame()) + offset; *reinterpret_cast<uint32_t*>(vreg_addr) = new_value; + return true; } } else { - return cur_shadow_frame_->SetVReg(vreg, new_value); + cur_shadow_frame_->SetVReg(vreg, new_value); + return true; } } @@ -201,14 +219,24 @@ uintptr_t* StackVisitor::GetGPRAddress(uint32_t reg) const { return context_->GetGPRAddress(reg); } -uintptr_t StackVisitor::GetGPR(uint32_t reg) const { +bool StackVisitor::GetGPR(uint32_t reg, uintptr_t* val) const { + DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine"; + return context_->GetGPR(reg, val); +} + +bool StackVisitor::SetGPR(uint32_t reg, uintptr_t value) { + DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine"; + return context_->SetGPR(reg, value); +} + +bool StackVisitor::GetFPR(uint32_t reg, uintptr_t* val) const { DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine"; - return context_->GetGPR(reg); + return context_->GetFPR(reg, val); } -void StackVisitor::SetGPR(uint32_t reg, uintptr_t value) { +bool StackVisitor::SetFPR(uint32_t reg, uintptr_t value) { DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine"; - context_->SetGPR(reg, value); + return context_->SetFPR(reg, value); } uintptr_t StackVisitor::GetReturnPc() const { |