ART: support for const-method-{handle,type}
Adds support for const-method-handle and const-method-type bytecodes.
Bug: 66562269
Test: art/test/run-test --host 979
Test: art/test/dexdump/run-all-tests
Change-Id: I812eaf0f2439d6126b4287483fe2348366cacf90
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 50bd7e7..fafb2a3 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -202,6 +202,25 @@
}
}
+static inline mirror::MethodHandle* ResolveMethodHandle(uint32_t method_handle_index,
+ ArtMethod* referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ return class_linker->ResolveMethodHandle(method_handle_index, referrer);
+}
+
+static inline mirror::MethodType* ResolveMethodType(Thread* self,
+ uint32_t method_type_index,
+ ArtMethod* referrer)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ const DexFile* dex_file = referrer->GetDexFile();
+ StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader()));
+ return class_linker->ResolveMethodType(*dex_file, method_type_index, dex_cache, class_loader);
+}
+
// Performs a signature polymorphic invoke (invoke-polymorphic/invoke-polymorphic-range).
template<bool is_range>
bool DoInvokePolymorphic(Thread* self,
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 850419b..2514f0c 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -525,6 +525,30 @@
}
break;
}
+ case Instruction::CONST_METHOD_HANDLE: {
+ PREAMBLE();
+ ObjPtr<mirror::MethodHandle> mh =
+ Runtime::Current()->GetClassLinker()->ResolveMethodHandle(inst->VRegB_21c(), method);
+ if (UNLIKELY(mh == nullptr)) {
+ HANDLE_PENDING_EXCEPTION();
+ } else {
+ shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh.Ptr());
+ inst = inst->Next_2xx();
+ }
+ break;
+ }
+ case Instruction::CONST_METHOD_TYPE: {
+ PREAMBLE();
+ ObjPtr<mirror::MethodType> mt =
+ Runtime::Current()->GetClassLinker()->ResolveMethodType(inst->VRegB_21c(), method);
+ if (UNLIKELY(mt == nullptr)) {
+ HANDLE_PENDING_EXCEPTION();
+ } else {
+ shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt.Ptr());
+ inst = inst->Next_2xx();
+ }
+ break;
+ }
case Instruction::MONITOR_ENTER: {
PREAMBLE();
ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
@@ -2435,10 +2459,8 @@
inst = inst->Next_2xx();
break;
case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
+ case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
- case Instruction::UNUSED_FE ... Instruction::UNUSED_FF:
- case Instruction::UNUSED_79:
- case Instruction::UNUSED_7A:
UnexpectedOpcode(inst, shadow_frame);
}
} while (!interpret_one_instruction);