diff options
| author | 2019-07-01 15:31:41 +0100 | |
|---|---|---|
| committer | 2019-07-22 13:11:49 +0000 | |
| commit | cffa254b3b7c307b557ba2250fc822db352d3293 (patch) | |
| tree | ef49730b09bd0f4ebb26387311ed4501db3e29bf /runtime/stack.cc | |
| parent | 9a8634a7bc4f69e6c89933f906ddd0a45dd05aa7 (diff) | |
Add fast path for exception vreg copying.
It is not necessary to decode CodeInfo in GetVReg
since the caller already did it.
Test: ./art/test.py -b --host --64 --interpreter
Change-Id: I0f8941f43acdc0f2c43b78ef87d3e796e320c959
Diffstat (limited to 'runtime/stack.cc')
| -rw-r--r-- | runtime/stack.cc | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/runtime/stack.cc b/runtime/stack.cc index 3fc6fd11db..6d1e3849de 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -201,7 +201,11 @@ bool StackVisitor::GetVRegFromDebuggerShadowFrame(uint16_t vreg, return false; } -bool StackVisitor::GetVReg(ArtMethod* m, uint16_t vreg, VRegKind kind, uint32_t* val) const { +bool StackVisitor::GetVReg(ArtMethod* m, + uint16_t vreg, + VRegKind kind, + uint32_t* val, + std::optional<DexRegisterLocation> location) const { if (cur_quick_frame_ != nullptr) { DCHECK(context_ != nullptr); // You can't reliably read registers without a context. DCHECK(m == GetMethod()); @@ -210,6 +214,16 @@ bool StackVisitor::GetVReg(ArtMethod* m, uint16_t vreg, VRegKind kind, uint32_t* return true; } DCHECK(cur_oat_quick_method_header_->IsOptimized()); + if (location.has_value() && kind != kReferenceVReg) { + uint32_t val2 = *val; + // The caller already known the register location, so we can use the faster overload + // which does not decode the stack maps. + bool ok = GetVRegFromOptimizedCode(location.value(), kind, val); + // Compare to the slower overload. + DCHECK_EQ(ok, GetVRegFromOptimizedCode(m, vreg, kind, &val2)); + DCHECK_EQ(*val, val2); + return ok; + } return GetVRegFromOptimizedCode(m, vreg, kind, val); } else { DCHECK(cur_shadow_frame_ != nullptr); @@ -290,6 +304,32 @@ bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKin } } +bool StackVisitor::GetVRegFromOptimizedCode(DexRegisterLocation location, + VRegKind kind, + uint32_t* val) const { + switch (location.GetKind()) { + case DexRegisterLocation::Kind::kInvalid: + break; + case DexRegisterLocation::Kind::kInStack: { + const uint8_t* sp = reinterpret_cast<const uint8_t*>(cur_quick_frame_); + *val = *reinterpret_cast<const uint32_t*>(sp + location.GetStackOffsetInBytes()); + return true; + } + case DexRegisterLocation::Kind::kInRegister: + case DexRegisterLocation::Kind::kInRegisterHigh: + case DexRegisterLocation::Kind::kInFpuRegister: + case DexRegisterLocation::Kind::kInFpuRegisterHigh: + return GetRegisterIfAccessible(location.GetMachineRegister(), kind, val); + case DexRegisterLocation::Kind::kConstant: + *val = location.GetConstant(); + return true; + case DexRegisterLocation::Kind::kNone: + return false; + } + LOG(FATAL) << "Unexpected location kind " << location.GetKind(); + UNREACHABLE(); +} + bool StackVisitor::GetRegisterIfAccessible(uint32_t reg, VRegKind kind, uint32_t* val) const { const bool is_float = (kind == kFloatVReg) || (kind == kDoubleLoVReg) || (kind == kDoubleHiVReg); |