Handlerize MethodVerifier::mirror_method_.
The method (mirror_method_) wasn't handlerized across some
allocation/GC points such as the ResolveType() call in
ScanTryCatchBlocks() and the GetReturnType() calls in
CodeFlowVerifyInstruction().
Bug: 12687968
Change-Id: I95323de14459eb5a7c4abfcf44f882f86d59be64
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 75bc49b..2114ada 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -427,12 +427,13 @@
Runtime* runtime = Runtime::Current();
if (runtime != nullptr) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
+ StackHandleScope<2> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(
hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file)));
NullHandle<mirror::ClassLoader> class_loader;
+ Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr));
verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def,
- code_item, dex_method_idx, nullptr, method_access_flags,
+ code_item, dex_method_idx, method, method_access_flags,
true, true, true);
verifier.Verify();
DumpCode(*indent2_os, &verifier, oat_method, code_item);
@@ -698,12 +699,13 @@
uint32_t method_access_flags) {
if ((method_access_flags & kAccNative) == 0) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<2> hs(soa.Self());
+ StackHandleScope<3> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(
hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file)));
auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr));
+ Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr));
verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache,
- class_loader, &class_def, code_item, nullptr,
+ class_loader, &class_def, code_item, method,
method_access_flags);
}
}
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 6d2f21e..5b00a37 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -3031,12 +3031,13 @@
// should never be null. We could just check we never encounter this case.
return false;
}
- StackHandleScope<2> hs(self);
+ StackHandleScope<3> hs(self);
mirror::Class* declaring_class = m->GetDeclaringClass();
Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
verifier::MethodVerifier verifier(dex_cache->GetDexFile(), &dex_cache, &class_loader,
- &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ &m->GetClassDef(), code_item, m->GetDexMethodIndex(), method,
m->GetAccessFlags(), false, true, false);
// Note: we don't need to verify the method.
return InlineMethodAnalyser::AnalyseMethodCode(&verifier, nullptr);
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index 98eeda7..1e933a2 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -206,12 +206,13 @@
const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc);
uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits();
ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc);
- StackHandleScope<2> hs(self_);
+ StackHandleScope<3> hs(self_);
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(h_dex_cache->GetDexFile(), &h_dex_cache, &h_class_loader,
- &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m,
+ &m->GetClassDef(), code_item, m->GetDexMethodIndex(), h_method,
m->GetAccessFlags(), false, true, true);
verifier.Verify();
const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc));
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 69627f5..e2a3335 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -138,6 +138,7 @@
while (it.HasNextStaticField() || it.HasNextInstanceField()) {
it.Next();
}
+ Thread* self = Thread::Current();
size_t error_count = 0;
bool hard_fail = false;
ClassLinker* linker = Runtime::Current()->GetClassLinker();
@@ -156,17 +157,19 @@
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
NullHandle<mirror::ArtMethod>(), type);
if (method == NULL) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ DCHECK(self->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
- Thread::Current()->ClearException();
+ self->ClearException();
}
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
MethodVerifier::FailureKind result = VerifyMethod(method_idx,
dex_file,
dex_cache,
class_loader,
class_def,
it.GetMethodCodeItem(),
- method,
+ h_method,
it.GetMemberAccessFlags(),
allow_soft_failures,
false);
@@ -200,17 +203,19 @@
linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
NullHandle<mirror::ArtMethod>(), type);
if (method == NULL) {
- DCHECK(Thread::Current()->IsExceptionPending());
+ DCHECK(self->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
- Thread::Current()->ClearException();
+ self->ClearException();
}
+ StackHandleScope<1> hs(self);
+ Handle<mirror::ArtMethod> h_method(hs.NewHandle(method));
MethodVerifier::FailureKind result = VerifyMethod(method_idx,
dex_file,
dex_cache,
class_loader,
class_def,
it.GetMethodCodeItem(),
- method,
+ h_method,
it.GetMemberAccessFlags(),
allow_soft_failures,
false);
@@ -242,7 +247,7 @@
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method,
+ Handle<mirror::ArtMethod> method,
uint32_t method_access_flags,
bool allow_soft_failures,
bool need_precise_constants) {
@@ -250,8 +255,8 @@
uint64_t start_ns = NanoTime();
MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
- method_idx, method, method_access_flags, true, allow_soft_failures,
- need_precise_constants);
+ method_idx, method, method_access_flags, true, allow_soft_failures,
+ need_precise_constants);
if (verifier.Verify()) {
// Verification completed, however failures may be pending that didn't cause the verification
// to hard fail.
@@ -289,7 +294,7 @@
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method,
+ Handle<mirror::ArtMethod> method,
uint32_t method_access_flags) {
MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
dex_method_idx, method, method_access_flags, true, true, true);
@@ -303,7 +308,7 @@
Handle<mirror::ClassLoader>* class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item, uint32_t dex_method_idx,
- mirror::ArtMethod* method, uint32_t method_access_flags,
+ Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
bool can_load_classes, bool allow_soft_failures,
bool need_precise_constants)
: reg_types_(can_load_classes),
@@ -340,12 +345,13 @@
void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
std::vector<uint32_t>* monitor_enter_dex_pcs) {
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<3> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
- true, false);
+ m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+ false, true, false);
verifier.interesting_dex_pc_ = dex_pc;
verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
verifier.FindLocksAtDexPc();
@@ -364,12 +370,13 @@
mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<3> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
- true, false);
+ m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+ true, true, false);
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
@@ -394,12 +401,13 @@
mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
- StackHandleScope<2> hs(Thread::Current());
+ StackHandleScope<3> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
+ Handle<mirror::ArtMethod> method(hs.NewHandle(m));
MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
- m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
- true, false);
+ m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(),
+ true, true, false);
return verifier.FindInvokedMethodAtDexPc(dex_pc);
}
@@ -4017,14 +4025,10 @@
RegType& MethodVerifier::GetMethodReturnType() {
if (return_type_ == nullptr) {
- if (mirror_method_ != NULL) {
+ if (mirror_method_.Get() != nullptr) {
Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
mirror::Class* return_type_class;
- {
- HandleWrapper<mirror::ArtMethod> h_mirror_method(hs.NewHandleWrapper(&mirror_method_));
- return_type_class = MethodHelper(h_mirror_method).GetReturnType(can_load_classes_);
- }
+ return_type_class = MethodHelper(mirror_method_).GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
return_type_ = ®_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
return_type_class,
@@ -4050,7 +4054,7 @@
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
const char* descriptor
= dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
- if (mirror_method_ != NULL) {
+ if (mirror_method_.Get() != nullptr) {
mirror::Class* klass = mirror_method_->GetDeclaringClass();
declaring_class_ = ®_types_.FromClass(descriptor, klass,
klass->CannotBeAssignedFromOtherTypes());
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index e63a90c..78cbe06 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -27,6 +27,7 @@
#include "class_reference.h"
#include "dex_file.h"
#include "dex_instruction.h"
+#include "handle.h"
#include "instruction_flags.h"
#include "method_reference.h"
#include "reg_type.h"
@@ -152,7 +153,7 @@
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method, uint32_t method_access_flags)
+ Handle<mirror::ArtMethod> method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
uint8_t EncodePcToReferenceMapData() const;
@@ -203,7 +204,7 @@
MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache>* dex_cache,
Handle<mirror::ClassLoader>* class_loader, const DexFile::ClassDef* class_def,
- const DexFile::CodeItem* code_item, uint32_t method_idx, mirror::ArtMethod* method,
+ const DexFile::CodeItem* code_item, uint32_t method_idx, Handle<mirror::ArtMethod> method,
uint32_t access_flags, bool can_load_classes, bool allow_soft_failures,
bool need_precise_constants)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -256,7 +257,7 @@
Handle<mirror::ClassLoader> class_loader,
const DexFile::ClassDef* class_def_idx,
const DexFile::CodeItem* code_item,
- mirror::ArtMethod* method, uint32_t method_access_flags,
+ Handle<mirror::ArtMethod> method, uint32_t method_access_flags,
bool allow_soft_failures, bool need_precise_constants)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -639,7 +640,7 @@
const uint32_t dex_method_idx_; // The method we're working on.
// Its object representation if known.
- mirror::ArtMethod* mirror_method_ GUARDED_BY(Locks::mutator_lock_);
+ Handle<mirror::ArtMethod> mirror_method_ GUARDED_BY(Locks::mutator_lock_);
const uint32_t method_access_flags_; // Method's access flags.
RegType* return_type_; // Lazily computed return type of the method.
const DexFile* const dex_file_; // The dex file containing the method.