Revert "Revert "Fix access to FP registers when visiting stack""
This reverts commit 8ebd94ab2e0d9867a7d384f00fa4cab24235216f.
Fixes StackVisitor::GetVReg to read register value in a uintptr_t local and
cast it into uint32_t pointer argument.
Bug: 15433097
Change-Id: I4e13ed5446e823e9ec50fbc378b16be5b17b2294
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 7e922c5..132ac3e 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -142,7 +142,8 @@
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 @@
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 @@
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 @@
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 @@
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);
+ return context_->GetGPR(reg, val);
}
-void StackVisitor::SetGPR(uint32_t reg, uintptr_t value) {
+bool StackVisitor::SetGPR(uint32_t reg, uintptr_t value) {
DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine";
- context_->SetGPR(reg, value);
+ 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_->GetFPR(reg, val);
+}
+
+bool StackVisitor::SetFPR(uint32_t reg, uintptr_t value) {
+ DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine";
+ return context_->SetFPR(reg, value);
}
uintptr_t StackVisitor::GetReturnPc() const {