Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / mini / jit-icalls.c
index 2b66be22f182a3b0b0289899dd46a4e02fe054bb..fa3d7a4681971e74fafa19d297ab476de42c470d 100644 (file)
@@ -23,6 +23,7 @@
 #include <mono/metadata/exception-internals.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/reflection-internals.h>
+#include <mono/utils/unlocked.h>
 
 #ifdef ENABLE_LLVM
 #include "mini-llvm-cpp.h"
@@ -1097,7 +1098,7 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe
        gpointer addr;
        MonoGenericContext *context = mono_method_get_context (method);
 
-       mono_jit_stats.generic_virtual_invocations++;
+       UnlockedIncrement (&mono_jit_stats.generic_virtual_invocations);
 
        if (obj == NULL) {
                mono_set_pending_exception (mono_get_exception_null_reference ());
@@ -1327,12 +1328,15 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
 {
        MonoMethod *m;
        int vt_slot, iface_offset;
+       gboolean is_iface = FALSE;
 
        error_init (error);
 
        if (mono_class_is_interface (klass)) {
                MonoObject *this_obj;
 
+               is_iface = TRUE;
+
                /* Have to use the receiver's type instead of klass, the receiver is a ref type */
                this_obj = *(MonoObject**)mp;
                g_assert (this_obj);
@@ -1358,21 +1362,33 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k
                        m = mono_class_inflate_generic_method (m, mono_method_get_context (cmethod));
        }
 
-       if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class))
+       if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class)) {
                /*
                 * Calling a non-vtype method with a vtype receiver, has to box.
                 */
                *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
-       else if (klass->valuetype)
-               /*
-                * Calling a vtype method with a vtype receiver
-                */
-               *this_arg = mp;
-       else
+       } else if (klass->valuetype) {
+               if (is_iface) {
+                       /*
+                        * The original type is an interface, so the receiver is a ref,
+                          the called method is a vtype method, need to unbox.
+                       */
+                       MonoObject *this_obj = *(MonoObject**)mp;
+
+                       *this_arg = mono_object_unbox (this_obj);
+               } else {
+                       /*
+                        * Calling a vtype method with a vtype receiver
+                        */
+                       *this_arg = mp;
+               }
+       } else {
                /*
                 * Calling a non-vtype method
                 */
                *this_arg = *(gpointer*)mp;
+       }
+
        return m;
 }
 
@@ -1911,8 +1927,8 @@ mono_interruption_checkpoint_from_trampoline (void)
 void
 mono_throw_method_access (MonoMethod *caller, MonoMethod *callee)
 {
-       char *caller_name = mono_method_full_name (caller, 1);
-       char *callee_name = mono_method_full_name (callee, 1);
+       char *caller_name = mono_method_get_reflection_name (caller);
+       char *callee_name = mono_method_get_reflection_name (callee);
        MonoError error;
 
        error_init (&error);