summaryrefslogtreecommitdiffstats
path: root/runtime/quick_exception_handler.cc
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2015-03-12 15:05:13 +0000
committerNicolas Geoffray <ngeoffray@google.com>2015-03-13 10:26:47 +0000
commit15b9d5274399736ac09705f0507df24fac4f00c1 (patch)
tree04564a9265f5dccefdd32ea7bdd25adc0267f80b /runtime/quick_exception_handler.cc
parent8bc616d09f93523f4bc982cc60c377b00161522a (diff)
downloadandroid_art-15b9d5274399736ac09705f0507df24fac4f00c1.tar.gz
android_art-15b9d5274399736ac09705f0507df24fac4f00c1.tar.bz2
android_art-15b9d5274399736ac09705f0507df24fac4f00c1.zip
API change in StackVisitor::GetVReg*.
- Remove GetVReg() and SetVReg() that were expecting to always succeed. - Change Quick-only methods to take a FromQuickCode suffix. - Change deopt to use dead values when GetVReg does not succeed: the optimizing compiler will not have a location for uninitialized Dex registers and potentially dead registers. Change-Id: Ida05773a97aff8aa69e0caf42ea961f80f854b77
Diffstat (limited to 'runtime/quick_exception_handler.cc')
-rw-r--r--runtime/quick_exception_handler.cc71
1 files changed, 58 insertions, 13 deletions
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 0eb8eca7d2..243260345e 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -205,52 +205,97 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor {
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, h_method.Get(), dex_pc);
self_->SetShadowFrameUnderConstruction(new_frame);
const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc));
+
+ // Markers for dead values, used when the verifier knows a Dex register is undefined,
+ // or when the compiler knows the register has not been initialized, or is not used
+ // anymore in the method.
+ static constexpr uint32_t kDeadValue = 0xEBADDE09;
+ static constexpr uint64_t kLongDeadValue = 0xEBADDE09EBADDE09;
for (uint16_t reg = 0; reg < num_regs; ++reg) {
VRegKind kind = GetVRegKind(reg, kinds);
switch (kind) {
case kUndefined:
- new_frame->SetVReg(reg, 0xEBADDE09);
+ new_frame->SetVReg(reg, kDeadValue);
break;
case kConstant:
new_frame->SetVReg(reg, kinds.at((reg * 2) + 1));
break;
- case kReferenceVReg:
- new_frame->SetVRegReference(reg,
- reinterpret_cast<mirror::Object*>(GetVReg(h_method.Get(),
- reg, kind)));
+ case kReferenceVReg: {
+ uint32_t value = 0;
+ if (GetVReg(h_method.Get(), reg, kind, &value)) {
+ new_frame->SetVRegReference(reg, reinterpret_cast<mirror::Object*>(value));
+ } else {
+ new_frame->SetVReg(reg, kDeadValue);
+ }
break;
+ }
case kLongLoVReg:
if (GetVRegKind(reg + 1, kinds) == kLongHiVReg) {
// Treat it as a "long" register pair.
- new_frame->SetVRegLong(reg, GetVRegPair(h_method.Get(), reg, kLongLoVReg, kLongHiVReg));
+ uint64_t value = 0;
+ if (GetVRegPair(h_method.Get(), reg, kLongLoVReg, kLongHiVReg, &value)) {
+ new_frame->SetVRegLong(reg, value);
+ } else {
+ new_frame->SetVRegLong(reg, kLongDeadValue);
+ }
} else {
- new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+ uint32_t value = 0;
+ if (GetVReg(h_method.Get(), reg, kind, &value)) {
+ new_frame->SetVReg(reg, value);
+ } else {
+ new_frame->SetVReg(reg, kDeadValue);
+ }
}
break;
case kLongHiVReg:
if (GetVRegKind(reg - 1, kinds) == kLongLoVReg) {
// Nothing to do: we treated it as a "long" register pair.
} else {
- new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+ uint32_t value = 0;
+ if (GetVReg(h_method.Get(), reg, kind, &value)) {
+ new_frame->SetVReg(reg, value);
+ } else {
+ new_frame->SetVReg(reg, kDeadValue);
+ }
}
break;
case kDoubleLoVReg:
if (GetVRegKind(reg + 1, kinds) == kDoubleHiVReg) {
- // Treat it as a "double" register pair.
- new_frame->SetVRegLong(reg, GetVRegPair(h_method.Get(), reg, kDoubleLoVReg, kDoubleHiVReg));
+ uint64_t value = 0;
+ if (GetVRegPair(h_method.Get(), reg, kDoubleLoVReg, kDoubleHiVReg, &value)) {
+ // Treat it as a "double" register pair.
+ new_frame->SetVRegLong(reg, value);
+ } else {
+ new_frame->SetVRegLong(reg, kLongDeadValue);
+ }
} else {
- new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+ uint32_t value = 0;
+ if (GetVReg(h_method.Get(), reg, kind, &value)) {
+ new_frame->SetVReg(reg, value);
+ } else {
+ new_frame->SetVReg(reg, kDeadValue);
+ }
}
break;
case kDoubleHiVReg:
if (GetVRegKind(reg - 1, kinds) == kDoubleLoVReg) {
// Nothing to do: we treated it as a "double" register pair.
} else {
- new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+ uint32_t value = 0;
+ if (GetVReg(h_method.Get(), reg, kind, &value)) {
+ new_frame->SetVReg(reg, value);
+ } else {
+ new_frame->SetVReg(reg, kDeadValue);
+ }
}
break;
default:
- new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
+ uint32_t value = 0;
+ if (GetVReg(h_method.Get(), reg, kind, &value)) {
+ new_frame->SetVReg(reg, value);
+ } else {
+ new_frame->SetVReg(reg, kDeadValue);
+ }
break;
}
}