diff options
| -rw-r--r-- | runtime/quick_exception_handler.cc | 10 | ||||
| -rw-r--r-- | runtime/stack.cc | 42 | ||||
| -rw-r--r-- | runtime/stack.h | 10 |
3 files changed, 56 insertions, 6 deletions
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 1777b3d0ff..727bdf02e1 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -325,10 +325,12 @@ void QuickExceptionHandler::SetCatchEnvironmentForOptimizedHandler(StackVisitor* // Get vreg value from its current location. uint32_t vreg_value; VRegKind vreg_kind = ToVRegKind(throw_vreg_map[vreg].GetKind()); - bool get_vreg_success = stack_visitor->GetVReg(stack_visitor->GetMethod(), - vreg, - vreg_kind, - &vreg_value); + bool get_vreg_success = + stack_visitor->GetVReg(stack_visitor->GetMethod(), + vreg, + vreg_kind, + &vreg_value, + throw_vreg_map[vreg]); CHECK(get_vreg_success) << "VReg " << vreg << " was optimized out (" << "method=" << ArtMethod::PrettyMethod(stack_visitor->GetMethod()) << ", dex_pc=" << stack_visitor->GetDexPc() << ", " 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); diff --git a/runtime/stack.h b/runtime/stack.h index aa741dfe81..ad73e75fb5 100644 --- a/runtime/stack.h +++ b/runtime/stack.h @@ -17,6 +17,7 @@ #ifndef ART_RUNTIME_STACK_H_ #define ART_RUNTIME_STACK_H_ +#include <optional> #include <stdint.h> #include <string> @@ -223,7 +224,12 @@ class StackVisitor { bool GetNextMethodAndDexPc(ArtMethod** next_method, uint32_t* next_dex_pc) REQUIRES_SHARED(Locks::mutator_lock_); - bool GetVReg(ArtMethod* m, uint16_t vreg, VRegKind kind, uint32_t* val) const + bool GetVReg(ArtMethod* m, + uint16_t vreg, + VRegKind kind, + uint32_t* val, + std::optional<DexRegisterLocation> location = + std::optional<DexRegisterLocation>()) const REQUIRES_SHARED(Locks::mutator_lock_); bool GetVRegPair(ArtMethod* m, uint16_t vreg, VRegKind kind_lo, VRegKind kind_hi, @@ -330,6 +336,8 @@ class StackVisitor { VRegKind kind_lo, VRegKind kind_hi, uint64_t* val) const REQUIRES_SHARED(Locks::mutator_lock_); + bool GetVRegFromOptimizedCode(DexRegisterLocation location, VRegKind kind, uint32_t* val) const + REQUIRES_SHARED(Locks::mutator_lock_); bool GetRegisterPairIfAccessible(uint32_t reg_lo, uint32_t reg_hi, VRegKind kind_lo, uint64_t* val) const REQUIRES_SHARED(Locks::mutator_lock_); |