From: Hiroshi Yamauchi Date: Fri, 22 Aug 2014 18:13:12 +0000 (-0700) Subject: Handlerize MethodVerifier::mirror_method_. X-Git-Tag: android-x86-7.1-r1~889^2~3263^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=dc3761719fb5e2d1ced5708e3c73b965f9ef0c73;p=android-x86%2Fart.git 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 75bc49b7d..2114ada05 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -427,12 +427,13 @@ class OatDumper { Runtime* runtime = Runtime::Current(); if (runtime != nullptr) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle dex_cache( hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file))); NullHandle class_loader; + Handle method(hs.NewHandle(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 @@ class OatDumper { 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 dex_cache( hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file))); auto class_loader(hs.NewHandle(nullptr)); + Handle method(hs.NewHandle(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 6d2f21e1e..5b00a37f0 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -3031,12 +3031,13 @@ static bool IsMethodPossiblyInlined(Thread* self, mirror::ArtMethod* m) // 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 dex_cache(hs.NewHandle(declaring_class->GetDexCache())); Handle class_loader(hs.NewHandle(declaring_class->GetClassLoader())); + Handle 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 98eeda726..1e933a2b8 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -206,12 +206,13 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { 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 h_dex_cache(hs.NewHandle(declaring_class->GetDexCache())); Handle h_class_loader(hs.NewHandle(declaring_class->GetClassLoader())); + Handle 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 kinds(verifier.DescribeVRegs(dex_pc)); diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 69627f51d..e2a3335a7 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -138,6 +138,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, 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 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NullHandle(), 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 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 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NullHandle(), 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 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 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, Handle class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, + Handle method, uint32_t method_access_flags, bool allow_soft_failures, bool need_precise_constants) { @@ -250,8 +255,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, 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 @@ void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_i Handle class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, + Handle 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 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, Handle Handle* 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 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 @@ MethodVerifier::~MethodVerifier() { void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc, std::vector* monitor_enter_dex_pcs) { - StackHandleScope<2> hs(Thread::Current()); + StackHandleScope<3> hs(Thread::Current()); Handle dex_cache(hs.NewHandle(m->GetDexCache())); Handle class_loader(hs.NewHandle(m->GetClassLoader())); + Handle 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 @@ void MethodVerifier::FindLocksAtDexPc() { mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc) { - StackHandleScope<2> hs(Thread::Current()); + StackHandleScope<3> hs(Thread::Current()); Handle dex_cache(hs.NewHandle(m->GetDexCache())); Handle class_loader(hs.NewHandle(m->GetClassLoader())); + Handle 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::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) { mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc) { - StackHandleScope<2> hs(Thread::Current()); + StackHandleScope<3> hs(Thread::Current()); Handle dex_cache(hs.NewHandle(m->GetDexCache())); Handle class_loader(hs.NewHandle(m->GetClassLoader())); + Handle 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 @@ InstructionFlags* MethodVerifier::CurrentInsnFlags() { 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 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 @@ RegType& MethodVerifier::GetDeclaringClass() { 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 e63a90c2b..78cbe0693 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 @@ class MethodVerifier { Handle class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, uint32_t method_access_flags) + Handle method, uint32_t method_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); uint8_t EncodePcToReferenceMapData() const; @@ -203,7 +204,7 @@ class MethodVerifier { MethodVerifier(const DexFile* dex_file, Handle* dex_cache, Handle* 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 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 @@ class MethodVerifier { Handle class_loader, const DexFile::ClassDef* class_def_idx, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, uint32_t method_access_flags, + Handle method, uint32_t method_access_flags, bool allow_soft_failures, bool need_precise_constants) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -639,7 +640,7 @@ class MethodVerifier { 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_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.