ART: Compiler support for const-method-type
Implemented as a runtime call.
Bug: 66890674
Test: art/test.py --target -r -t 979
Test: art/test.py --target --64 -r -t 979
Test: art/test.py --host -r -t 979
Change-Id: I4b3d3969d455d0198cfe122eea8abd54e0ea20ee
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index a930cc4..1a1f4ed 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -1015,7 +1015,10 @@
END \name
.endm
-// Macro for string and type resolution and initialization.
+ /*
+ * Macro for resolution and initialization of indexed DEX file
+ * constants such as classes and strings.
+ */
.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
.extern \entrypoint
ENTRY \name
@@ -1040,6 +1043,7 @@
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 9ff5ebe..9919e98 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1533,7 +1533,10 @@
END \name
.endm
-// Macro for string and type resolution and initialization.
+ /*
+ * Macro for resolution and initialization of indexed DEX file
+ * constants such as classes and strings.
+ */
.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
.extern \entrypoint
ENTRY \name
@@ -1577,6 +1580,7 @@
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
// Note: Functions `art{Get,Set}<Kind>{Static,Instance}FromCompiledCode` are
diff --git a/runtime/arch/mips/entrypoints_init_mips.cc b/runtime/arch/mips/entrypoints_init_mips.cc
index 9418caf..58b9d48 100644
--- a/runtime/arch/mips/entrypoints_init_mips.cc
+++ b/runtime/arch/mips/entrypoints_init_mips.cc
@@ -203,6 +203,8 @@
static_assert(!IsDirectEntrypoint(kQuickInitializeType), "Non-direct C stub marked direct.");
qpoints->pResolveString = art_quick_resolve_string;
static_assert(!IsDirectEntrypoint(kQuickResolveString), "Non-direct C stub marked direct.");
+ qpoints->pResolveMethodType = art_quick_resolve_method_type;
+ static_assert(!IsDirectEntrypoint(kQuickResolveMethodType), "Non-direct C stub marked direct.");
// Field
qpoints->pSet8Instance = art_quick_set8_instance;
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index d8fe480..104a4ca 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -2027,8 +2027,11 @@
GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32
GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64
-// Macro for string and type resolution and initialization.
-// $a0 is both input and output.
+ /*
+ * Macro for resolution and initialization of indexed DEX file
+ * constants such as classes and strings. $a0 is both input and
+ * output.
+ */
.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
.extern \entrypoint
ENTRY_NO_GP \name
@@ -2053,6 +2056,12 @@
.endm
/*
+ * Entry from managed code to resolve a method type. On entry, A0 holds the method type index.
+ * On success the MethodType is returned, otherwise an exception is raised.
+ */
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
+
+ /*
* Entry from managed code to resolve a string, this stub will allocate a String and deliver an
* exception on error. On success the String is returned. A0 holds the string index. The fast
* path check for hit in strings cache has already been performed.
diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S
index 8d2a7bd..1e94e07 100644
--- a/runtime/arch/mips64/quick_entrypoints_mips64.S
+++ b/runtime/arch/mips64/quick_entrypoints_mips64.S
@@ -1930,8 +1930,11 @@
GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved32_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_32
GENERATE_ALLOC_ARRAY_TLAB art_quick_alloc_array_resolved64_tlab, artAllocArrayFromCodeResolvedTLAB, COMPUTE_ARRAY_SIZE_64
-// Macro for string and type resolution and initialization.
-// $a0 is both input and output.
+ /*
+ * Macro for resolution and initialization of indexed DEX file
+ * constants such as classes and strings. $a0 is both input and
+ * output.
+ */
.macro ONE_ARG_SAVE_EVERYTHING_DOWNCALL name, entrypoint, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET
.extern \entrypoint
ENTRY_NO_GP \name
@@ -1953,6 +1956,12 @@
.endm
/*
+ * Entry from managed code to resolve a method type. On entry, A0 holds the method type index.
+ * On success the MethodType is returned, otherwise an exception is raised.
+ */
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
+
+ /*
* Entry from managed code to resolve a string, this stub will allocate a String and deliver an
* exception on error. On success the String is returned. A0 holds the string index. The fast
* path check for hit in strings cache has already been performed.
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index df43aef..0ae6914 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -923,7 +923,10 @@
END_FUNCTION VAR(c_name)
END_MACRO
-// Macro for string and type resolution and initialization.
+ /*
+ * Macro for resolution and initialization of indexed DEX file
+ * constants such as classes and strings.
+ */
MACRO3(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET)
DEFINE_FUNCTION VAR(c_name)
SETUP_SAVE_EVERYTHING_FRAME ebx, ebx, \runtime_method_offset // save ref containing registers for GC
@@ -932,7 +935,7 @@
CFI_ADJUST_CFA_OFFSET(8)
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
CFI_ADJUST_CFA_OFFSET(4)
- PUSH eax // pass arg1
+ PUSH eax // pass the index of the constant as arg1
call CALLVAR(cxx_name) // cxx_name(arg1, Thread*)
addl MACRO_LITERAL(16), %esp // pop arguments
CFI_ADJUST_CFA_OFFSET(-16)
@@ -1278,6 +1281,7 @@
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index 4f941e1..8fef802 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -951,12 +951,15 @@
END_FUNCTION VAR(c_name)
END_MACRO
-// Macro for string and type resolution and initialization.
+ /*
+ * Macro for resolution and initialization of indexed DEX file
+ * constants such as classes and strings.
+ */
MACRO3(ONE_ARG_SAVE_EVERYTHING_DOWNCALL, c_name, cxx_name, runtime_method_offset = RUNTIME_SAVE_EVERYTHING_METHOD_OFFSET)
DEFINE_FUNCTION VAR(c_name)
SETUP_SAVE_EVERYTHING_FRAME \runtime_method_offset // save everything for GC
// Outgoing argument set up
- movl %eax, %edi // pass string index
+ movl %eax, %edi // pass the index of the constant as arg0
movq %gs:THREAD_SELF_OFFSET, %rsi // pass Thread::Current()
call CALLVAR(cxx_name) // cxx_name(arg0, Thread*)
testl %eax, %eax // If result is null, deliver the OOME.
@@ -1298,6 +1301,7 @@
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_static_storage, artInitializeStaticStorageFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL_FOR_CLINIT art_quick_initialize_type, artInitializeTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode
+ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_method_type, artResolveMethodTypeFromCode
ONE_ARG_SAVE_EVERYTHING_DOWNCALL art_quick_resolve_string, artResolveStringFromCode
TWO_ARG_REF_DOWNCALL art_quick_handle_fill_data, artHandleFillArrayDataFromCode, RETURN_IF_EAX_ZERO
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 2f7d6ab..705e1ff 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -73,7 +73,7 @@
// Offset of field Thread::tlsPtr_.mterp_current_ibase.
#define THREAD_CURRENT_IBASE_OFFSET \
- (THREAD_LOCAL_OBJECTS_OFFSET + __SIZEOF_SIZE_T__ + (1 + 162) * __SIZEOF_POINTER__)
+ (THREAD_LOCAL_OBJECTS_OFFSET + __SIZEOF_SIZE_T__ + (1 + 163) * __SIZEOF_POINTER__)
ADD_TEST_EQ(THREAD_CURRENT_IBASE_OFFSET,
art::Thread::MterpCurrentIBaseOffset<POINTER_SIZE>().Int32Value())
// Offset of field Thread::tlsPtr_.mterp_default_ibase.
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 246c703..df184bc 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -260,4 +260,19 @@
return DoGetCalleeSaveMethodOuterCallerAndPc(sp, type).first;
}
+ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer,
+ uint32_t proto_idx) {
+ Thread::PoisonObjectPointersIfDebug();
+ ObjPtr<mirror::MethodType> method_type =
+ referrer->GetDexCache()->GetResolvedMethodType(proto_idx);
+ if (UNLIKELY(method_type == nullptr)) {
+ StackHandleScope<2> hs(Thread::Current());
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(referrer->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(referrer->GetClassLoader()));
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ method_type = class_linker->ResolveMethodType(hs.Self(), proto_idx, dex_cache, class_loader);
+ }
+ return method_type;
+}
+
} // namespace art
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index eb32153..203ff3d 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -34,6 +34,7 @@
namespace mirror {
class Array;
class Class;
+class MethodType;
class Object;
class String;
} // namespace mirror
@@ -151,6 +152,10 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
+ObjPtr<mirror::MethodType> ResolveMethodTypeFromCode(ArtMethod* referrer, uint32_t proto_idx)
+ REQUIRES_SHARED(Locks::mutator_lock_)
+ REQUIRES(!Roles::uninterruptible_);
+
inline ObjPtr<mirror::String> ResolveStringFromCode(ArtMethod* referrer,
dex::StringIndex string_idx)
REQUIRES_SHARED(Locks::mutator_lock_)
diff --git a/runtime/entrypoints/quick/quick_default_externs.h b/runtime/entrypoints/quick/quick_default_externs.h
index 2d0932a..d934a53 100644
--- a/runtime/entrypoints/quick/quick_default_externs.h
+++ b/runtime/entrypoints/quick/quick_default_externs.h
@@ -37,6 +37,7 @@
extern "C" void* art_quick_initialize_static_storage(uint32_t);
extern "C" void* art_quick_initialize_type(uint32_t);
extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t);
+extern "C" void* art_quick_resolve_method_type(uint32_t);
extern "C" void* art_quick_resolve_string(uint32_t);
// Field entrypoints.
diff --git a/runtime/entrypoints/quick/quick_default_init_entrypoints.h b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
index 8c90800..a4572f6 100644
--- a/runtime/entrypoints/quick/quick_default_init_entrypoints.h
+++ b/runtime/entrypoints/quick/quick_default_init_entrypoints.h
@@ -37,6 +37,7 @@
qpoints->pInitializeStaticStorage = art_quick_initialize_static_storage;
qpoints->pInitializeTypeAndVerifyAccess = art_quick_initialize_type_and_verify_access;
qpoints->pInitializeType = art_quick_initialize_type;
+ qpoints->pResolveMethodType = art_quick_resolve_method_type;
qpoints->pResolveString = art_quick_resolve_string;
// Field
diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
index cfb427f..09cbfff 100644
--- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
@@ -183,6 +183,16 @@
return result.Ptr();
}
+extern "C" mirror::MethodType* artResolveMethodTypeFromCode(uint32_t proto_idx, Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ ScopedQuickEntrypointChecks sqec(self);
+ auto caller_and_outer = GetCalleeSaveMethodCallerAndOuterMethod(self,
+ CalleeSaveType::kSaveEverything);
+ ArtMethod* caller = caller_and_outer.caller;
+ ObjPtr<mirror::MethodType> result = ResolveMethodTypeFromCode(caller, proto_idx);
+ return result.Ptr();
+}
+
extern "C" mirror::String* artResolveStringFromCode(int32_t string_idx, Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
diff --git a/runtime/entrypoints/quick/quick_entrypoints_list.h b/runtime/entrypoints/quick/quick_entrypoints_list.h
index 48a56f2..39dcd39 100644
--- a/runtime/entrypoints/quick/quick_entrypoints_list.h
+++ b/runtime/entrypoints/quick/quick_entrypoints_list.h
@@ -38,6 +38,7 @@
V(InitializeStaticStorage, void*, uint32_t) \
V(InitializeTypeAndVerifyAccess, void*, uint32_t) \
V(InitializeType, void*, uint32_t) \
+ V(ResolveMethodType, void*, uint32_t) \
V(ResolveString, void*, uint32_t) \
\
V(Set8Instance, int, uint32_t, void*, int8_t) \
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index 1fdf439..b0689f6 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -183,7 +183,8 @@
sizeof(void*));
EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pInitializeTypeAndVerifyAccess, pInitializeType,
sizeof(void*));
- EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pInitializeType, pResolveString, sizeof(void*));
+ EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pInitializeType, pResolveMethodType, sizeof(void*));
+ EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pResolveMethodType, pResolveString, sizeof(void*));
EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pResolveString, pSet8Instance, sizeof(void*));
EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pSet8Instance, pSet8Static, sizeof(void*));
EXPECT_OFFSET_DIFFNP(QuickEntryPoints, pSet8Static, pSet16Instance, sizeof(void*));
diff --git a/runtime/oat.h b/runtime/oat.h
index 0318606..9a58ded 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,8 +32,8 @@
class PACKED(4) OatHeader {
public:
static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
- // Last oat version changed reason: Use rMR as temp in Baker RB introspection marking.
- static constexpr uint8_t kOatVersion[] = { '1', '4', '1', '\0' };
+ // Last oat version changed reason: compiler support const-method-type
+ static constexpr uint8_t kOatVersion[] = { '1', '4', '2', '\0' };
static constexpr const char* kImageLocationKey = "image-location";
static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index bc29aac..5cd6091 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2293,8 +2293,6 @@
case Instruction::CONST_METHOD_TYPE:
work_line_->SetRegisterType<LockOp::kClear>(
this, inst->VRegA_21c(), reg_types_.JavaLangInvokeMethodType());
- // TODO: add compiler support for const-method-{handle,type} (b/66890674)
- Fail(VERIFY_ERROR_FORCE_INTERPRETER);
break;
case Instruction::MONITOR_ENTER:
work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_);