summaryrefslogtreecommitdiff
path: root/runtime/class_linker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r--runtime/class_linker.cc75
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,