summaryrefslogtreecommitdiffstats
path: root/runtime/stack.cc
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-01-22 18:57:14 +0100
committerSebastien Hertz <shertz@google.com>2015-01-26 16:45:38 +0100
commit96ba8dc82e7bd859106af837623fe8b2e9e772c3 (patch)
treed7df58e8a9fb853621700d90ec4864129f6b3a0a /runtime/stack.cc
parent081d27817608c2ea035f2473c4ea1062a79bccef (diff)
downloadart-96ba8dc82e7bd859106af837623fe8b2e9e772c3.zip
art-96ba8dc82e7bd859106af837623fe8b2e9e772c3.tar.gz
art-96ba8dc82e7bd859106af837623fe8b2e9e772c3.tar.bz2
Refactor register access from StackVisitor
Moves register access checking up to StackVisitor by adding methods IsAccessibleGPR and IsAccessibleFPR in Context class. It allows to simplify GetGPR/FPR and SetGPR/FPR methods in the Context class (and its subclasses). Also simplifies code in StackVisitor by adding IsAccessibleRegister, GetRegister and SetRegister methods which then call either GPR or FPR specific methods in Context depending on the nature of the accessed register. Bug: 18547544 Bug: 19106446 Change-Id: I6e707608d935a71571d0e975a6e766053de3763a
Diffstat (limited to 'runtime/stack.cc')
-rw-r--r--runtime/stack.cc99
1 files changed, 58 insertions, 41 deletions
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 3165898..b771aa7 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -172,11 +172,10 @@ bool StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind,
bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg);
uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
uint32_t reg = vmap_table.ComputeRegister(spill_mask, vmap_offset, kind);
- uintptr_t ptr_val;
- bool success = is_float ? GetFPR(reg, &ptr_val) : GetGPR(reg, &ptr_val);
- if (!success) {
+ if (!IsAccessibleRegister(reg, is_float)) {
return false;
}
+ uintptr_t ptr_val = GetRegister(reg, is_float);
bool target64 = Is64BitInstructionSet(kRuntimeISA);
if (target64) {
bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg);
@@ -194,11 +193,14 @@ bool StackVisitor::GetVReg(mirror::ArtMethod* m, uint16_t vreg, VRegKind kind,
const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be NULL or how would we compile
// its instructions?
- *val = *GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
- frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+ uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
+ frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+ DCHECK(addr != nullptr);
+ *val = *addr;
return true;
}
} else {
+ DCHECK(cur_shadow_frame_ != nullptr);
*val = cur_shadow_frame_->GetVReg(vreg);
return true;
}
@@ -228,12 +230,11 @@ bool StackVisitor::GetVRegPair(mirror::ArtMethod* m, uint16_t vreg, VRegKind kin
uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo);
uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi);
- uintptr_t ptr_val_lo, ptr_val_hi;
- bool success = is_float ? GetFPR(reg_lo, &ptr_val_lo) : GetGPR(reg_lo, &ptr_val_lo);
- success &= is_float ? GetFPR(reg_hi, &ptr_val_hi) : GetGPR(reg_hi, &ptr_val_hi);
- if (!success) {
+ if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) {
return false;
}
+ uintptr_t ptr_val_lo = GetRegister(reg_lo, is_float);
+ uintptr_t ptr_val_hi = GetRegister(reg_hi, is_float);
bool target64 = Is64BitInstructionSet(kRuntimeISA);
if (target64) {
int64_t value_long_lo = static_cast<int64_t>(ptr_val_lo);
@@ -249,10 +250,12 @@ bool StackVisitor::GetVRegPair(mirror::ArtMethod* m, uint16_t vreg, VRegKind kin
// its instructions?
uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+ DCHECK(addr != nullptr);
*val = *reinterpret_cast<uint64_t*>(addr);
return true;
}
} else {
+ DCHECK(cur_shadow_frame_ != nullptr);
*val = cur_shadow_frame_->GetVRegLong(vreg);
return true;
}
@@ -273,17 +276,16 @@ bool StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_val
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, kind);
+ if (!IsAccessibleRegister(reg, is_float)) {
+ return false;
+ }
bool target64 = Is64BitInstructionSet(kRuntimeISA);
// Deal with 32 or 64-bit wide registers in a way that builds on all targets.
if (target64) {
bool wide_lo = (kind == kLongLoVReg) || (kind == kDoubleLoVReg);
bool wide_hi = (kind == kLongHiVReg) || (kind == kDoubleHiVReg);
if (wide_lo || wide_hi) {
- uintptr_t old_reg_val;
- bool success = is_float ? GetFPR(reg, &old_reg_val) : GetGPR(reg, &old_reg_val);
- if (!success) {
- return false;
- }
+ uintptr_t old_reg_val = GetRegister(reg, is_float);
uint64_t new_vreg_portion = static_cast<uint64_t>(new_value);
uint64_t old_reg_val_as_wide = static_cast<uint64_t>(old_reg_val);
uint64_t mask = 0xffffffff;
@@ -295,21 +297,20 @@ bool StackVisitor::SetVReg(mirror::ArtMethod* m, uint16_t vreg, uint32_t new_val
new_value = static_cast<uintptr_t>((old_reg_val_as_wide & mask) | new_vreg_portion);
}
}
- if (is_float) {
- return SetFPR(reg, new_value);
- } else {
- return SetGPR(reg, new_value);
- }
+ SetRegister(reg, new_value, is_float);
+ return true;
} else {
const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be NULL or how would we compile
// its instructions?
uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+ DCHECK(addr != nullptr);
*addr = new_value;
return true;
}
} else {
+ DCHECK(cur_shadow_frame_ != nullptr);
cur_shadow_frame_->SetVReg(vreg, new_value);
return true;
}
@@ -339,17 +340,16 @@ bool StackVisitor::SetVRegPair(mirror::ArtMethod* m, uint16_t vreg, uint64_t new
uint32_t spill_mask = is_float ? frame_info.FpSpillMask() : frame_info.CoreSpillMask();
uint32_t reg_lo = vmap_table.ComputeRegister(spill_mask, vmap_offset_lo, kind_lo);
uint32_t reg_hi = vmap_table.ComputeRegister(spill_mask, vmap_offset_hi, kind_hi);
+ if (!IsAccessibleRegister(reg_lo, is_float) || !IsAccessibleRegister(reg_hi, is_float)) {
+ return false;
+ }
uintptr_t new_value_lo = static_cast<uintptr_t>(new_value & 0xFFFFFFFF);
uintptr_t new_value_hi = static_cast<uintptr_t>(new_value >> 32);
bool target64 = Is64BitInstructionSet(kRuntimeISA);
// Deal with 32 or 64-bit wide registers in a way that builds on all targets.
if (target64) {
- uintptr_t old_reg_val_lo, old_reg_val_hi;
- bool success = is_float ? GetFPR(reg_lo, &old_reg_val_lo) : GetGPR(reg_lo, &old_reg_val_lo);
- success &= is_float ? GetFPR(reg_hi, &old_reg_val_hi) : GetGPR(reg_hi, &old_reg_val_hi);
- if (!success) {
- return false;
- }
+ uintptr_t old_reg_val_lo = GetRegister(reg_lo, is_float);
+ uintptr_t old_reg_val_hi = GetRegister(reg_hi, is_float);
uint64_t new_vreg_portion_lo = static_cast<uint64_t>(new_value_lo);
uint64_t new_vreg_portion_hi = static_cast<uint64_t>(new_value_hi) << 32;
uint64_t old_reg_val_lo_as_wide = static_cast<uint64_t>(old_reg_val_lo);
@@ -359,47 +359,64 @@ bool StackVisitor::SetVRegPair(mirror::ArtMethod* m, uint16_t vreg, uint64_t new
new_value_lo = static_cast<uintptr_t>((old_reg_val_lo_as_wide & mask_lo) | new_vreg_portion_lo);
new_value_hi = static_cast<uintptr_t>((old_reg_val_hi_as_wide & mask_hi) | new_vreg_portion_hi);
}
- bool success = is_float ? SetFPR(reg_lo, new_value_lo) : SetGPR(reg_lo, new_value_lo);
- success &= is_float ? SetFPR(reg_hi, new_value_hi) : SetGPR(reg_hi, new_value_hi);
- return success;
+ SetRegister(reg_lo, new_value_lo, is_float);
+ SetRegister(reg_hi, new_value_hi, is_float);
+ return true;
} else {
const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be NULL or how would we compile
// its instructions?
uint32_t* addr = GetVRegAddr(cur_quick_frame_, code_item, frame_info.CoreSpillMask(),
frame_info.FpSpillMask(), frame_info.FrameSizeInBytes(), vreg);
+ DCHECK(addr != nullptr);
*reinterpret_cast<uint64_t*>(addr) = new_value;
return true;
}
} else {
+ DCHECK(cur_shadow_frame_ != nullptr);
cur_shadow_frame_->SetVRegLong(vreg, new_value);
return true;
}
}
+bool StackVisitor::IsAccessibleGPR(uint32_t reg) const {
+ DCHECK(context_ != nullptr);
+ return context_->IsAccessibleGPR(reg);
+}
+
uintptr_t* StackVisitor::GetGPRAddress(uint32_t reg) const {
- DCHECK(cur_quick_frame_ != NULL) << "This is a quick frame routine";
+ DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine";
+ DCHECK(context_ != nullptr);
return context_->GetGPRAddress(reg);
}
-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);
+uintptr_t StackVisitor::GetGPR(uint32_t reg) const {
+ DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine";
+ DCHECK(context_ != nullptr);
+ return context_->GetGPR(reg);
+}
+
+void StackVisitor::SetGPR(uint32_t reg, uintptr_t value) {
+ DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine";
+ DCHECK(context_ != nullptr);
+ context_->SetGPR(reg, value);
}
-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::IsAccessibleFPR(uint32_t reg) const {
+ DCHECK(context_ != nullptr);
+ return context_->IsAccessibleFPR(reg);
}
-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);
+uintptr_t StackVisitor::GetFPR(uint32_t reg) const {
+ DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine";
+ DCHECK(context_ != nullptr);
+ return context_->GetFPR(reg);
}
-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);
+void StackVisitor::SetFPR(uint32_t reg, uintptr_t value) {
+ DCHECK(cur_quick_frame_ != nullptr) << "This is a quick frame routine";
+ DCHECK(context_ != nullptr);
+ context_->SetFPR(reg, value);
}
uintptr_t StackVisitor::GetReturnPc() const {