summaryrefslogtreecommitdiffstats
path: root/runtime/quick_exception_handler.cc
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-02-10 15:37:27 -0800
committerAndreas Gampe <agampe@google.com>2015-02-13 12:58:33 -0800
commit2e04bb2d514434f2bedb14268996842010948e6c (patch)
treeef44da212347e17a5de29b138560fca1a173a935 /runtime/quick_exception_handler.cc
parente032d5d40b361066088f3855b1e76bc9a740a826 (diff)
downloadart-2e04bb2d514434f2bedb14268996842010948e6c.zip
art-2e04bb2d514434f2bedb14268996842010948e6c.tar.gz
art-2e04bb2d514434f2bedb14268996842010948e6c.tar.bz2
ART: Allow class-loading during deopt
When deoptimizing, we might touch code that uses unloaded classes. Bug: 19290147 (cherry picked from commit 44fb719e5f0f5ee7dcf4b1eae703593f1043a169) Change-Id: I5776f08ba366e9742336caba0d6af85f00629afc
Diffstat (limited to 'runtime/quick_exception_handler.cc')
-rw-r--r--runtime/quick_exception_handler.cc28
1 files changed, 16 insertions, 12 deletions
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 34f6713..85ec803 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -204,16 +204,18 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor {
CHECK(code_item != nullptr);
uint16_t num_regs = code_item->registers_size_;
uint32_t dex_pc = GetDexPc();
- ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, dex_pc);
- StackHandleScope<3> hs(self_);
+ StackHandleScope<3> hs(self_); // Dex cache, class loader and method.
mirror::Class* declaring_class = m->GetDeclaringClass();
Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
Handle<mirror::ArtMethod> h_method(hs.NewHandle(m));
verifier::MethodVerifier verifier(self_, h_dex_cache->GetDexFile(), h_dex_cache, h_class_loader,
&m->GetClassDef(), code_item, m->GetDexMethodIndex(),
- h_method, m->GetAccessFlags(), false, true, true, true);
- verifier.Verify();
+ h_method, m->GetAccessFlags(), true, true, true, true);
+ bool verifier_success = verifier.Verify();
+ CHECK(verifier_success) << PrettyMethod(h_method.Get());
+ 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));
for (uint16_t reg = 0; reg < num_regs; ++reg) {
VRegKind kind = GetVRegKind(reg, kinds);
@@ -226,40 +228,41 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor {
break;
case kReferenceVReg:
new_frame->SetVRegReference(reg,
- reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kind)));
+ reinterpret_cast<mirror::Object*>(GetVReg(h_method.Get(),
+ reg, kind)));
break;
case kLongLoVReg:
if (GetVRegKind(reg + 1, kinds) == kLongHiVReg) {
// Treat it as a "long" register pair.
- new_frame->SetVRegLong(reg, GetVRegPair(m, reg, kLongLoVReg, kLongHiVReg));
+ new_frame->SetVRegLong(reg, GetVRegPair(h_method.Get(), reg, kLongLoVReg, kLongHiVReg));
} else {
- new_frame->SetVReg(reg, GetVReg(m, reg, kind));
+ new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
}
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(m, reg, kind));
+ new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
}
break;
case kDoubleLoVReg:
if (GetVRegKind(reg + 1, kinds) == kDoubleHiVReg) {
// Treat it as a "double" register pair.
- new_frame->SetVRegLong(reg, GetVRegPair(m, reg, kDoubleLoVReg, kDoubleHiVReg));
+ new_frame->SetVRegLong(reg, GetVRegPair(h_method.Get(), reg, kDoubleLoVReg, kDoubleHiVReg));
} else {
- new_frame->SetVReg(reg, GetVReg(m, reg, kind));
+ new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
}
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(m, reg, kind));
+ new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
}
break;
default:
- new_frame->SetVReg(reg, GetVReg(m, reg, kind));
+ new_frame->SetVReg(reg, GetVReg(h_method.Get(), reg, kind));
break;
}
}
@@ -268,6 +271,7 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor {
} else {
self_->SetDeoptimizationShadowFrame(new_frame);
}
+ self_->ClearShadowFrameUnderConstruction();
prev_shadow_frame_ = new_frame;
return true;
}