diff options
author | Bernhard Urban <bernhard.urban@xamarin.com> | 2017-02-27 19:55:53 +0300 |
---|---|---|
committer | Bernhard Urban <bernhard.urban@xamarin.com> | 2017-03-01 00:59:28 +0300 |
commit | 550d7b00957b2e0695cc2b018237936e25db24ad (patch) | |
tree | e5c4a84b17e45e1ac3da01e1532cd0a0b0eb6b54 | |
parent | 4accf0d718c238b3efcd50eed6fc6f86b9ae43cd (diff) |
[interpreter] if unboxing is required on virtcall, point into object instead of copying
-rw-r--r-- | mono/mini/generics.cs | 1 | ||||
-rw-r--r-- | mono/mini/interpreter/interp-internals.h | 1 | ||||
-rw-r--r-- | mono/mini/interpreter/interp.c | 24 |
3 files changed, 17 insertions, 9 deletions
diff --git a/mono/mini/generics.cs b/mono/mini/generics.cs index 186fb90db91..eae71e11f54 100644 --- a/mono/mini/generics.cs +++ b/mono/mini/generics.cs @@ -269,7 +269,6 @@ class Tests return s.return_field () + s.return_field (); } - [Category ("!INTERPRETER")] public static int test_0_generic_get_value_optimization_vtype () { TestStruct[] arr = new TestStruct[] { new TestStruct (100, 200), new TestStruct (300, 400) }; IEnumerator<TestStruct> enumerator = GenericClass<TestStruct>.Y (arr); diff --git a/mono/mini/interpreter/interp-internals.h b/mono/mini/interpreter/interp-internals.h index 5e8597a6a6f..f26e4ff57b3 100644 --- a/mono/mini/interpreter/interp-internals.h +++ b/mono/mini/interpreter/interp-internals.h @@ -82,7 +82,6 @@ typedef struct _RuntimeMethod guint32 *local_offsets; unsigned int param_count; unsigned int hasthis; - unsigned int valuetype; } RuntimeMethod; struct _MonoInvocation { diff --git a/mono/mini/interpreter/interp.c b/mono/mini/interpreter/interp.c index b3cc2297693..eee3a042a37 100644 --- a/mono/mini/interpreter/interp.c +++ b/mono/mini/interpreter/interp.c @@ -271,7 +271,6 @@ mono_interp_get_runtime_method (MonoDomain *domain, MonoMethod *method, MonoErro rtm->method = method; rtm->param_count = mono_method_signature (method)->param_count; rtm->hasthis = mono_method_signature (method)->hasthis; - rtm->valuetype = method->klass->valuetype; mono_internal_hash_table_insert (&domain->jit_code_hash, method, rtm); mono_os_mutex_unlock (&runtime_method_lookup_section); @@ -1806,6 +1805,15 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) mono_error_cleanup (&error); /* FIXME: don't swallow the error */ } + if (csignature->hasthis) { + MonoObject *this_arg = sp->data.p; + + if (this_arg->vtable->klass->valuetype) { + gpointer *unboxed = mono_object_unbox (this_arg); + sp [0].data.p = unboxed; + } + } + ves_exec_method_with_context (&child_frame, context); context->current_frame = frame; @@ -1885,7 +1893,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) child_frame.stack_args = sp; /* `this' can be NULL for string:.ctor */ - if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && sp->data.p && mono_object_is_transparent_proxy (sp->data.p)) { + if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->method->klass->valuetype && sp->data.p && mono_object_is_transparent_proxy (sp->data.p)) { child_frame.runtime_method = mono_interp_get_runtime_method (context->domain, mono_marshal_get_remoting_invoke (child_frame.runtime_method->method), &error); mono_error_cleanup (&error); /* FIXME: don't swallow the error */ } @@ -1920,7 +1928,7 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) --sp; child_frame.stack_args = sp; - if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->valuetype && mono_object_is_transparent_proxy (sp->data.p)) { + if (child_frame.runtime_method->hasthis && !child_frame.runtime_method->method->klass->valuetype && mono_object_is_transparent_proxy (sp->data.p)) { child_frame.runtime_method = mono_interp_get_runtime_method (context->domain, mono_marshal_get_remoting_invoke (child_frame.runtime_method->method), &error); mono_error_cleanup (&error); /* FIXME: don't swallow the error */ } @@ -1959,10 +1967,11 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) THROW_EX (mono_get_exception_null_reference(), ip - 2); child_frame.runtime_method = get_virtual_method (context->domain, child_frame.runtime_method, this_arg); - if (this_arg->vtable->klass->valuetype && child_frame.runtime_method->valuetype) { + MonoClass *this_class = this_arg->vtable->klass; + if (this_class->valuetype && child_frame.runtime_method->method->klass->valuetype) { /* unbox */ gpointer *unboxed = mono_object_unbox (this_arg); - stackval_from_data (&this_arg->vtable->klass->byval_arg, sp, (char *) unboxed, FALSE); + sp [0].data.p = unboxed; } ves_exec_method_with_context (&child_frame, context); @@ -2006,9 +2015,10 @@ ves_exec_method_with_context (MonoInvocation *frame, ThreadContext *context) THROW_EX (mono_get_exception_null_reference(), ip - 2); child_frame.runtime_method = get_virtual_method (context->domain, child_frame.runtime_method, this_arg); - if (this_arg->vtable->klass->valuetype && child_frame.runtime_method->valuetype) { + MonoClass *this_class = this_arg->vtable->klass; + if (this_class->valuetype && child_frame.runtime_method->method->klass->valuetype) { gpointer *unboxed = mono_object_unbox (this_arg); - stackval_from_data (&this_arg->vtable->klass->byval_arg, sp, (char *) unboxed, FALSE); + sp [0].data.p = unboxed; } ves_exec_method_with_context (&child_frame, context); |