summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/quick_exception_handler.cc10
-rw-r--r--runtime/stack.cc42
-rw-r--r--runtime/stack.h10
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_);