Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Urban <bernhard.urban@xamarin.com>2017-02-27 19:55:53 +0300
committerBernhard Urban <bernhard.urban@xamarin.com>2017-03-01 00:59:28 +0300
commit550d7b00957b2e0695cc2b018237936e25db24ad (patch)
treee5c4a84b17e45e1ac3da01e1532cd0a0b0eb6b54
parent4accf0d718c238b3efcd50eed6fc6f86b9ae43cd (diff)
[interpreter] if unboxing is required on virtcall, point into object instead of copying
-rw-r--r--mono/mini/generics.cs1
-rw-r--r--mono/mini/interpreter/interp-internals.h1
-rw-r--r--mono/mini/interpreter/interp.c24
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);