diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 75 |
1 files changed, 38 insertions, 37 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 3b0dda299e..42027cc223 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -118,7 +118,7 @@ #include "mirror/method.h" #include "mirror/method_handle_impl.h" #include "mirror/method_handles_lookup.h" -#include "mirror/method_type.h" +#include "mirror/method_type-inl.h" #include "mirror/object-inl.h" #include "mirror/object-refvisitor-inl.h" #include "mirror/object.h" @@ -10112,58 +10112,59 @@ ObjPtr<mirror::MethodType> ClassLinker::ResolveMethodType( return resolved; } - StackHandleScope<4> hs(self); + VariableSizedHandleScope raw_method_type_hs(self); + mirror::RawMethodType raw_method_type(&raw_method_type_hs); + if (!ResolveMethodType(self, proto_idx, dex_cache, class_loader, raw_method_type)) { + DCHECK(self->IsExceptionPending()); + return nullptr; + } + + // The handle scope was filled with return type and paratemer types. + DCHECK_EQ(raw_method_type_hs.Size(), + dex_cache->GetDexFile()->GetShortyView(proto_idx).length()); + ObjPtr<mirror::MethodType> method_type = mirror::MethodType::Create(self, raw_method_type); + if (method_type != nullptr) { + // Ensure all stores for the newly created MethodType are visible, before we attempt to place + // it in the DexCache (b/224733324). + std::atomic_thread_fence(std::memory_order_release); + dex_cache->SetResolvedMethodType(proto_idx, method_type.Ptr()); + } + return method_type; +} + +bool ClassLinker::ResolveMethodType(Thread* self, + dex::ProtoIndex proto_idx, + Handle<mirror::DexCache> dex_cache, + Handle<mirror::ClassLoader> class_loader, + /*out*/ mirror::RawMethodType method_type) { + DCHECK(Runtime::Current()->IsMethodHandlesEnabled()); + DCHECK(dex_cache != nullptr); + DCHECK(dex_cache->GetClassLoader() == class_loader.Get()); // First resolve the return type. const DexFile& dex_file = *dex_cache->GetDexFile(); const dex::ProtoId& proto_id = dex_file.GetProtoId(proto_idx); - Handle<mirror::Class> return_type(hs.NewHandle( - ResolveType(proto_id.return_type_idx_, dex_cache, class_loader))); + ObjPtr<mirror::Class> return_type = + ResolveType(proto_id.return_type_idx_, dex_cache, class_loader); if (return_type == nullptr) { DCHECK(self->IsExceptionPending()); - return nullptr; + return false; } + method_type.SetRType(return_type); // Then resolve the argument types. - // - // TODO: Is there a better way to figure out the number of method arguments - // other than by looking at the shorty ? - const size_t num_method_args = strlen(dex_file.StringDataByIdx(proto_id.shorty_idx_)) - 1; - - ObjPtr<mirror::Class> array_of_class = GetClassRoot<mirror::ObjectArray<mirror::Class>>(this); - Handle<mirror::ObjectArray<mirror::Class>> method_params(hs.NewHandle( - mirror::ObjectArray<mirror::Class>::Alloc(self, array_of_class, num_method_args))); - if (method_params == nullptr) { - DCHECK(self->IsExceptionPending()); - return nullptr; - } - DexFileParameterIterator it(dex_file, proto_id); - int32_t i = 0; - MutableHandle<mirror::Class> param_class = hs.NewHandle<mirror::Class>(nullptr); for (; it.HasNext(); it.Next()) { const dex::TypeIndex type_idx = it.GetTypeIdx(); - param_class.Assign(ResolveType(type_idx, dex_cache, class_loader)); - if (param_class == nullptr) { + ObjPtr<mirror::Class> param_type = ResolveType(type_idx, dex_cache, class_loader); + if (param_type == nullptr) { DCHECK(self->IsExceptionPending()); - return nullptr; + return false; } - - method_params->Set(i++, param_class.Get()); + method_type.AddPType(param_type); } - DCHECK(!it.HasNext()); - - Handle<mirror::MethodType> type = hs.NewHandle( - mirror::MethodType::Create(self, return_type, method_params)); - if (type != nullptr) { - // Ensure all stores for the newly created MethodType are visible, before we attempt to place - // it in the DexCache (b/224733324). - std::atomic_thread_fence(std::memory_order_release); - dex_cache->SetResolvedMethodType(proto_idx, type.Get()); - } - - return type.Get(); + return true; } ObjPtr<mirror::MethodType> ClassLinker::ResolveMethodType(Thread* self, |