diff options
author | Ian Rogers <irogers@google.com> | 2014-10-28 18:12:55 -0700 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2014-10-28 18:36:32 -0700 |
commit | ded66a01f81812e0129d17c3d08d5eda18433062 (patch) | |
tree | 74a3f7bad1c020b0136d6c173633a361a479f5cb | |
parent | e0205d519dd417f749243b42b8711dfa313e5390 (diff) | |
download | art-ded66a01f81812e0129d17c3d08d5eda18433062.zip art-ded66a01f81812e0129d17c3d08d5eda18433062.tar.gz art-ded66a01f81812e0129d17c3d08d5eda18433062.tar.bz2 |
Move MethodHelper::GetReturnType to mirror::ArtMethod.
Also, fix missing handle in HasSameSignatureWithDifferentClassLoaders.
Change-Id: I9e1ffd09be950ecc8346fc3c485760d82d9ecab3
-rw-r--r-- | runtime/class_linker.cc | 12 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.cc | 20 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_goto_table_impl.cc | 4 | ||||
-rw-r--r-- | runtime/interpreter/interpreter_switch_impl.cc | 4 | ||||
-rw-r--r-- | runtime/method_helper-inl.h | 10 | ||||
-rw-r--r-- | runtime/method_helper.cc | 18 | ||||
-rw-r--r-- | runtime/method_helper.h | 6 | ||||
-rw-r--r-- | runtime/mirror/art_method-inl.h | 14 | ||||
-rw-r--r-- | runtime/mirror/art_method.h | 4 | ||||
-rw-r--r-- | runtime/reflection.cc | 4 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 10 |
11 files changed, 50 insertions, 56 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index a6ff530..e4d9baa 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -4051,13 +4051,10 @@ static void CheckProxyMethod(Handle<mirror::ArtMethod> method, CHECK(prototype->HasSameDexCacheResolvedTypes(method.Get())); CHECK_EQ(prototype->GetDexMethodIndex(), method->GetDexMethodIndex()); - StackHandleScope<2> hs(Thread::Current()); - MethodHelper mh(hs.NewHandle(method.Get())); - MethodHelper mh2(hs.NewHandle(prototype.Get())); CHECK_STREQ(method->GetName(), prototype->GetName()); CHECK_STREQ(method->GetShorty(), prototype->GetShorty()); // More complex sanity - via dex cache - CHECK_EQ(mh.GetReturnType(), mh2.GetReturnType()); + CHECK_EQ(method->GetInterfaceMethodIfProxy()->GetReturnType(), prototype->GetReturnType()); } static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics, @@ -4322,7 +4319,8 @@ bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) { return true; } // Begin with the methods local to the superclass. - StackHandleScope<2> hs(Thread::Current()); + Thread* self = Thread::Current(); + StackHandleScope<2> hs(self); MutableMethodHelper mh(hs.NewHandle<mirror::ArtMethod>(nullptr)); MutableMethodHelper super_mh(hs.NewHandle<mirror::ArtMethod>(nullptr)); if (klass->HasSuperClass() && @@ -4331,7 +4329,7 @@ bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) { mh.ChangeMethod(klass->GetVTableEntry(i)); super_mh.ChangeMethod(klass->GetSuperClass()->GetVTableEntry(i)); if (mh.GetMethod() != super_mh.GetMethod() && - !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) { + !mh.HasSameSignatureWithDifferentClassLoaders(self, &super_mh)) { ThrowLinkageError(klass.Get(), "Class %s method %s resolves differently in superclass %s", PrettyDescriptor(klass.Get()).c_str(), @@ -4348,7 +4346,7 @@ bool ClassLinker::ValidateSuperClassDescriptors(Handle<mirror::Class> klass) { mh.ChangeMethod(klass->GetIfTable()->GetMethodArray(i)->GetWithoutChecks(j)); super_mh.ChangeMethod(klass->GetIfTable()->GetInterface(i)->GetVirtualMethod(j)); if (mh.GetMethod() != super_mh.GetMethod() && - !mh.HasSameSignatureWithDifferentClassLoaders(&super_mh)) { + !mh.HasSameSignatureWithDifferentClassLoaders(self, &super_mh)) { ThrowLinkageError(klass.Get(), "Class %s method %s resolves differently in interface %s", PrettyDescriptor(klass.Get()).c_str(), diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index 7b90339..da2dfe1 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -218,17 +218,14 @@ void CheckReferenceResult(mirror::Object* o, Thread* self) { if (o == nullptr) { return; } - mirror::ArtMethod* m = self->GetCurrentMethod(nullptr); // Make sure that the result is an instance of the type this method was expected to return. - StackHandleScope<1> hs(self); - Handle<mirror::ArtMethod> h_m(hs.NewHandle(m)); - mirror::Class* return_type = MethodHelper(h_m).GetReturnType(); + mirror::Class* return_type = self->GetCurrentMethod(nullptr)->GetReturnType(); if (!o->InstanceOf(return_type)) { Runtime::Current()->GetJavaVM()->JniAbortF(nullptr, "attempt to return an instance of %s from %s", PrettyTypeOf(o).c_str(), - PrettyMethod(h_m.Get()).c_str()); + PrettyMethod(self->GetCurrentMethod(nullptr)).c_str()); } } @@ -283,20 +280,19 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons return zero; } else { StackHandleScope<1> hs(soa.Self()); - MethodHelper mh_interface_method( + Handle<mirror::ArtMethod> h_interface_method( hs.NewHandle(soa.Decode<mirror::ArtMethod*>(interface_method_jobj))); // This can cause thread suspension. - mirror::Class* result_type = mh_interface_method.GetReturnType(); + mirror::Class* result_type = h_interface_method->GetReturnType(); mirror::Object* result_ref = soa.Decode<mirror::Object*>(result); mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj); mirror::ArtMethod* proxy_method; - if (mh_interface_method.GetMethod()->GetDeclaringClass()->IsInterface()) { - proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface( - mh_interface_method.GetMethod()); + if (h_interface_method->GetDeclaringClass()->IsInterface()) { + proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface(h_interface_method.Get()); } else { // Proxy dispatch to a method defined in Object. - DCHECK(mh_interface_method.GetMethod()->GetDeclaringClass()->IsObjectClass()); - proxy_method = mh_interface_method.GetMethod(); + DCHECK(h_interface_method->GetDeclaringClass()->IsObjectClass()); + proxy_method = h_interface_method.Get(); } ThrowLocation throw_location(rcvr, proxy_method, -1); JValue result_unboxed; diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index b970879..3a177eb 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -321,9 +321,7 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* const uint8_t vreg_index = inst->VRegA_11x(inst_data); Object* obj_result = shadow_frame.GetVRegReference(vreg_index); if (do_assignability_check && obj_result != NULL) { - StackHandleScope<1> hs(self); - MethodHelper mh(hs.NewHandle(shadow_frame.GetMethod())); - Class* return_type = mh.GetReturnType(); + Class* return_type = shadow_frame.GetMethod()->GetReturnType(); obj_result = shadow_frame.GetVRegReference(vreg_index); if (return_type == NULL) { // Return the pending exception. diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index 1364ed2..9fb90f1 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -233,9 +233,7 @@ JValue ExecuteSwitchImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem const size_t ref_idx = inst->VRegA_11x(inst_data); Object* obj_result = shadow_frame.GetVRegReference(ref_idx); if (do_assignability_check && obj_result != NULL) { - StackHandleScope<1> hs(self); - MethodHelper mhs(hs.NewHandle(shadow_frame.GetMethod())); - Class* return_type = mhs.GetReturnType(); + Class* return_type = shadow_frame.GetMethod()->GetReturnType(); // Re-load since it might have moved. obj_result = shadow_frame.GetVRegReference(ref_idx); if (return_type == NULL) { diff --git a/runtime/method_helper-inl.h b/runtime/method_helper-inl.h index fca5cf7..7a7949e 100644 --- a/runtime/method_helper-inl.h +++ b/runtime/method_helper-inl.h @@ -57,16 +57,6 @@ inline mirror::Class* MethodHelperT<HandleKind>::GetClassFromTypeIdx(uint16_t ty return type; } -template <template <class T> class HandleKind> -inline mirror::Class* MethodHelperT<HandleKind>::GetReturnType(bool resolve) { - mirror::ArtMethod* method = GetMethod(); - const DexFile* dex_file = method->GetDexFile(); - const DexFile::MethodId& method_id = dex_file->GetMethodId(method->GetDexMethodIndex()); - const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); - uint16_t return_type_idx = proto_id.return_type_idx_; - return GetClassFromTypeIdx(return_type_idx, resolve); -} - } // namespace art #endif // ART_RUNTIME_METHOD_HELPER_INL_H_ diff --git a/runtime/method_helper.cc b/runtime/method_helper.cc index 79c2b91..0799bb0 100644 --- a/runtime/method_helper.cc +++ b/runtime/method_helper.cc @@ -39,10 +39,14 @@ mirror::String* MethodHelperT<HandleKind>::GetNameAsString(Thread* self) { template <template <class T> class HandleKind> template <template <class T2> class HandleKind2> -bool MethodHelperT<HandleKind>::HasSameSignatureWithDifferentClassLoaders( +bool MethodHelperT<HandleKind>::HasSameSignatureWithDifferentClassLoaders(Thread* self, MethodHelperT<HandleKind2>* other) { - if (UNLIKELY(GetReturnType() != other->GetReturnType())) { - return false; + { + StackHandleScope<1> hs(self); + Handle<mirror::Class> return_type(hs.NewHandle(GetMethod()->GetReturnType())); + if (UNLIKELY(other->GetMethod()->GetReturnType() != return_type.Get())) { + return false; + } } const DexFile::TypeList* types = method_->GetParameterTypeList(); const DexFile::TypeList* other_types = other->method_->GetParameterTypeList(); @@ -158,19 +162,19 @@ uint32_t MethodHelperT<MutableHandle>::FindDexMethodIndexInOtherDexFile( const DexFile& other_dexfile, uint32_t name_and_signature_idx); template -bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<Handle>( +bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self, MethodHelperT<Handle>* other); template -bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>( +bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(Thread* self, MethodHelperT<MutableHandle>* other); template -bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<Handle>( +bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self, MethodHelperT<Handle>* other); template bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>( - MethodHelperT<MutableHandle>* other); + Thread* self, MethodHelperT<MutableHandle>* other); } // namespace art diff --git a/runtime/method_helper.h b/runtime/method_helper.h index 1458f88..14ba7d1 100644 --- a/runtime/method_helper.h +++ b/runtime/method_helper.h @@ -72,10 +72,6 @@ class MethodHelperT { return refs; } - // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large - // number of bugs at call sites. - mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { // "1 +" because the first in Args is the receiver. // "- 1" because we don't count the return type. @@ -109,7 +105,7 @@ class MethodHelperT { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); template <template <class T> class HandleKind2> - bool HasSameSignatureWithDifferentClassLoaders(MethodHelperT<HandleKind2>* other) + bool HasSameSignatureWithDifferentClassLoaders(Thread* self, MethodHelperT<HandleKind2>* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true) diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h index a0b6adf..ca361f8 100644 --- a/runtime/mirror/art_method-inl.h +++ b/runtime/mirror/art_method-inl.h @@ -467,6 +467,20 @@ inline void ArtMethod::SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cach new_dex_cache_classes); } +inline mirror::Class* ArtMethod::GetReturnType(bool resolve) { + DCHECK(!IsProxyMethod()); + const DexFile* dex_file = GetDexFile(); + const DexFile::MethodId& method_id = dex_file->GetMethodId(GetDexMethodIndex()); + const DexFile::ProtoId& proto_id = dex_file->GetMethodPrototype(method_id); + uint16_t return_type_idx = proto_id.return_type_idx_; + mirror::Class* type = GetDexCacheResolvedType(return_type_idx); + if (type == nullptr && resolve) { + type = Runtime::Current()->GetClassLinker()->ResolveType(return_type_idx, this); + CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); + } + return type; +} + } // namespace mirror } // namespace art diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index 92b2c30..9bb838b 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -505,6 +505,10 @@ class MANAGED ArtMethod FINAL : public Object { const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large + // number of bugs at call sites. + mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); diff --git a/runtime/reflection.cc b/runtime/reflection.cc index b57e48f..228d200 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -632,8 +632,8 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM } // Box if necessary and return. - return soa.AddLocalReference<jobject>(BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), - result)); + return soa.AddLocalReference<jobject>( + BoxPrimitive(Primitive::GetType(mh.GetMethod()->GetReturnTypeDescriptor()[0]), result)); } bool VerifyObjectIsClass(mirror::Object* o, mirror::Class* c) { diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index fb07ba0..8012451 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -2256,8 +2256,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { if (called_method != nullptr) { StackHandleScope<1> hs(self_); Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method)); - MethodHelper mh(h_called_method); - mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_); + mirror::Class* return_type_class = h_called_method->GetReturnType(can_load_classes_); if (return_type_class != nullptr) { return_type = ®_types_.FromClass(h_called_method->GetReturnTypeDescriptor(), return_type_class, @@ -2301,8 +2300,7 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) { return_type_descriptor = called_method->GetReturnTypeDescriptor(); StackHandleScope<1> hs(self_); Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method)); - MethodHelper mh(h_called_method); - mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_); + mirror::Class* return_type_class = h_called_method->GetReturnType(can_load_classes_); if (return_type_class != nullptr) { return_type = ®_types_.FromClass(return_type_descriptor, return_type_class, @@ -4112,9 +4110,7 @@ InstructionFlags* MethodVerifier::CurrentInsnFlags() { const RegType& MethodVerifier::GetMethodReturnType() { if (return_type_ == nullptr) { if (mirror_method_.Get() != nullptr) { - StackHandleScope<1> hs(self_); - mirror::Class* return_type_class = - MethodHelper(hs.NewHandle(mirror_method_.Get())).GetReturnType(can_load_classes_); + mirror::Class* return_type_class = mirror_method_->GetReturnType(can_load_classes_); if (return_type_class != nullptr) { return_type_ = ®_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(), return_type_class, |