Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono][aot] Optimize constrained calls made from gsharedvt methods. #79339

Merged
merged 1 commit into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/mono/mono/metadata/icall-signatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ ICALL_SIG (6, (ptr, ptr, ptr, ptr, ptr, ptr)) \
ICALL_SIG (7, (int32, ptr, ptr, ptr, ptr, ptr, int32)) \
ICALL_SIG (7, (void, ptr, ptr, ptr, ptr, ptr, ptr)) \
ICALL_SIG (7, (ptr, ptr, ptr, ptr, ptr, ptr, ptr)) \
ICALL_SIG (7, (object, ptr, ptr, ptr, ptr, ptr, ptr)) \
ICALL_SIG (8, (void, ptr, ptr, int32, ptr, ptrref, ptr, ptrref)) \

// ICALL_SIG_NAME: mono_icall_sig pasted with its parameters with underscores between each.
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/metadata/jit-icall-reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ MONO_JIT_ICALL (ves_icall_string_alloc) \
MONO_JIT_ICALL (ves_icall_string_new_wrapper) \
MONO_JIT_ICALL (ves_icall_thread_finish_async_abort) \
MONO_JIT_ICALL (mono_marshal_lookup_pinvoke) \
MONO_JIT_ICALL (mono_gsharedvt_constrained_call_fast) \
\
MONO_JIT_ICALL (count) \

Expand Down
66 changes: 52 additions & 14 deletions src/mono/mono/mini/jit-icalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,29 @@ mono_get_native_calli_wrapper (MonoImage *image, MonoMethodSignature *sig, gpoin
return compiled_ptr;
}

gpointer
mono_gsharedvt_constrained_call_fast (gpointer mp, MonoGsharedvtConstrainedCallInfo *info, gpointer *out_receiver)
{
switch (info->call_type) {
case MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_VTYPE:
/* Calling a vtype method with a vtype receiver */
*out_receiver = mp;
return info->code;
case MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_REF:
/* Calling a ref method with a ref receiver */
*out_receiver = *(gpointer*)mp;
return info->code;
case MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_BOX: {
ERROR_DECL (error);
*out_receiver = mono_value_box_checked (info->klass, mp, error);
mono_error_assert_ok (error);
return info->code;
}
default:
return NULL;
}
}

static MonoMethod*
constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg, MonoError *error)
{
Expand Down Expand Up @@ -1427,34 +1450,49 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
* MP is NULL if CMETHOD is a static virtual method.
*/
MonoObject*
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, guint8 *deref_args, gpointer *args)
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass,
MonoGsharedvtConstrainedCallInfo *info, guint8 *deref_args, gpointer *args)
{
ERROR_DECL (error);
MonoObject *o;
MonoMethod *m;
gpointer this_arg;
gpointer new_args [16];

/* Object.GetType () is an intrinsic under netcore */
if (!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType")) {
MonoVTable *vt;
switch (info->call_type) {
case MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_VTYPE:
/* Calling a vtype method with a vtype receiver */
this_arg = mp;
m = info->method;
break;
case MONO_GSHAREDVT_CONSTRAINT_CALL_TYPE_REF:
/* Calling a ref method with a ref receiver */
this_arg = *(gpointer*)mp;
m = info->method;
break;
default:
/* Object.GetType () is an intrinsic under netcore */
if (!mono_class_is_ginst (cmethod->klass) && !cmethod->is_inflated && !strcmp (cmethod->name, "GetType")) {
MonoVTable *vt;

vt = mono_class_vtable_checked (klass, error);
if (!is_ok (error)) {
mono_error_set_pending_exception (error);
return NULL;
}
return vt->type;
}

vt = mono_class_vtable_checked (klass, error);
m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg, error);
if (!is_ok (error)) {
mono_error_set_pending_exception (error);
return NULL;
}
return vt->type;
}

m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg, error);
if (!is_ok (error)) {
mono_error_set_pending_exception (error);
return NULL;
if (!m)
return NULL;
break;
}

if (!m)
return NULL;
if (deref_args) {
/* Have to deref gsharedvt ref arguments since the runtime invoke expects it */
MonoMethodSignature *fsig = mono_method_signature_internal (m);
Expand Down
5 changes: 4 additions & 1 deletion src/mono/mono/mini/jit-icalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,10 @@ ICALL_EXPORT
void
ves_icall_mono_delegate_ctor_interp (MonoObject *this_obj, MonoObject *target, gpointer addr);

ICALL_EXPORT MonoObject* mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, guint8 *deref_args, gpointer *args);
ICALL_EXPORT gpointer mono_gsharedvt_constrained_call_fast (gpointer mp, MonoGsharedvtConstrainedCallInfo *info, gpointer *out_receiver);

ICALL_EXPORT MonoObject* mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass,
MonoGsharedvtConstrainedCallInfo *info, guint8 *deref_args, gpointer *args);

ICALL_EXPORT void mono_gsharedvt_value_copy (gpointer dest, gpointer src, MonoClass *klass);

Expand Down
Loading