Fix support for MONO_PATCH_INFO_GSHAREDVT_CALL in mono_patch_info_dup_mp ().
[mono.git] / mono / mini / mini.c
index 3706759f2e7d65b2fdfbfe6987fdc6ea5b2695d6..01576ad569872f7facbd768c0d41c8a9fc608479 100644 (file)
@@ -2922,6 +2922,10 @@ mono_patch_info_dup_mp (MonoMemPool *mp, MonoJumpInfo *patch_info)
                memcpy (res->data.rgctx_entry, patch_info->data.rgctx_entry, sizeof (MonoJumpInfoRgctxEntry));
                res->data.rgctx_entry->data = mono_patch_info_dup_mp (mp, res->data.rgctx_entry->data);
                break;
+       case MONO_PATCH_INFO_GSHAREDVT_CALL:
+               res->data.gsharedvt = mono_mempool_alloc (mp, sizeof (MonoJumpInfoGSharedVtCall));
+               memcpy (res->data.gsharedvt, patch_info->data.gsharedvt, sizeof (MonoJumpInfoGSharedVtCall));
+               break;
        default:
                break;
        }
@@ -2958,6 +2962,8 @@ mono_patch_info_hash (gconstpointer data)
        case MONO_PATCH_INFO_SFLDA:
        case MONO_PATCH_INFO_SEQ_POINT_INFO:
                return (ji->type << 8) | (gssize)ji->data.target;
+       case MONO_PATCH_INFO_GSHAREDVT_CALL:
+               return (ji->type << 8) | (gssize)ji->data.gsharedvt->method;
        default:
                return (ji->type << 8);
        }
@@ -3274,6 +3280,16 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                case MONO_PATCH_INFO_FIELD:
                        slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.field, entry->info_type, mono_method_get_context (entry->method));
                        break;
+               case MONO_PATCH_INFO_SIGNATURE:
+                       slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, entry->data->data.sig, entry->info_type, mono_method_get_context (entry->method));
+                       break;
+               case MONO_PATCH_INFO_GSHAREDVT_CALL: {
+                       MonoJumpInfoGSharedVtCall *call_info = mono_domain_alloc0 (domain, sizeof (MonoJumpInfoGSharedVtCall));
+
+                       memcpy (call_info, entry->data->data.gsharedvt, sizeof (MonoJumpInfoGSharedVtCall));
+                       slot = mono_method_lookup_or_register_info (entry->method, entry->in_mrgctx, call_info, entry->info_type, mono_method_get_context (entry->method));
+                       break;
+               }
                default:
                        g_assert_not_reached ();
                        break;
@@ -3929,7 +3945,12 @@ create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
        guint8 *uw_info;
        guint32 info_len;
 
-       uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+       if (info->uw_info) {
+               uw_info = info->uw_info;
+               info_len = info->uw_info_len;
+       } else {
+               uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+       }
 
        jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
        jinfo->method = wrapper;
@@ -5510,26 +5531,32 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                WrapperInfo *info = mono_marshal_get_wrapper_info (method);
 
                if (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN || info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT) {
-                       static MonoTrampInfo *tinfo;
+                       static MonoTrampInfo *in_tinfo, *out_tinfo;
+                       MonoTrampInfo *tinfo;
                        MonoJitInfo *jinfo;
+                       gboolean is_in = info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN;
 
-                       if (tinfo)
-                               return tinfo->code;
+                       if (is_in && in_tinfo)
+                               return in_tinfo->code;
+                       else if (!is_in && out_tinfo)
+                               return out_tinfo->code;
 
                        /*
                         * This is a special wrapper whose body is implemented in assembly, like a trampoline. We use a wrapper so EH
                         * works.
                         * FIXME: The caller signature doesn't match the callee, which might cause problems on some platforms
                         */
-                       if (mono_aot_only) {
-                               // FIXME: No EH
-                               return mono_aot_get_trampoline ("gsharedvt_trampoline");
-                       } else {
+                       if (mono_aot_only)
+                               mono_aot_get_trampoline_full (is_in ? "gsharedvt_trampoline" : "gsharedvt_out_trampoline", &tinfo);
+                       else
                                mono_arch_get_gsharedvt_trampoline (&tinfo, FALSE);
-                               jinfo = create_jit_info_for_trampoline (method, tinfo);
-                               mono_jit_info_table_add (mono_get_root_domain (), jinfo);
-                               return tinfo->code;
-                       }
+                       jinfo = create_jit_info_for_trampoline (method, tinfo);
+                       mono_jit_info_table_add (mono_get_root_domain (), jinfo);
+                       if (is_in)
+                               in_tinfo = tinfo;
+                       else
+                               out_tinfo = tinfo;
+                       return tinfo->code;
                }
        }
 
@@ -6631,6 +6658,11 @@ mini_init (const char *filename, const char *runtime_version)
        if (!default_opt_set)
                default_opt = mono_parse_default_optimizations (NULL);
 
+#ifdef MONO_ARCH_GSHAREDVT_SUPPORTED
+       if (mono_aot_only)
+               mono_set_generic_sharing_vt_supported (TRUE);
+#endif
+
        InitializeCriticalSection (&jit_mutex);
 
 #ifdef MONO_DEBUGGER_SUPPORTED
@@ -6998,6 +7030,7 @@ mini_init (const char *filename, const char *runtime_version)
        register_icall (mono_array_new_3, "mono_array_new_3", "object ptr int int int", FALSE);
        register_icall (mono_get_native_calli_wrapper, "mono_get_native_calli_wrapper", "ptr ptr ptr ptr", FALSE);
        register_icall (mono_resume_unwind, "mono_resume_unwind", "void", TRUE);
+       register_icall (mono_object_tostring_gsharedvt, "mono_object_tostring_gsharedvt", "object ptr ptr ptr", TRUE);
 
        register_icall (mono_gc_wbarrier_value_copy_bitmap, "mono_gc_wbarrier_value_copy_bitmap", "void ptr ptr int int", FALSE);
 
@@ -7318,7 +7351,7 @@ mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig)
 }
 
 gpointer
-mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethod *normal_method, MonoMethod *gsharedvt_method, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gboolean virtual)
+mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
 {
        g_assert_not_reached ();
        return NULL;
@@ -7338,4 +7371,39 @@ mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
        return NULL;
 }
 
-#endif 
+#endif
+
+#ifdef DISABLE_JIT
+
+gpointer
+mono_arch_get_gsharedvt_arg_trampoline (MonoDomain *domain, gpointer arg, gpointer addr)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+gpointer
+mono_arch_get_gsharedvt_trampoline (MonoTrampInfo **info, gboolean aot)
+{
+       g_assert_not_reached ();
+       return NULL;
+}
+
+#endif
+
+#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED) && !defined(MONOTOUCH) && !defined(MONO_EXTENSIONS)
+
+gboolean
+mono_arch_gsharedvt_sig_supported (MonoMethodSignature *sig)
+{
+       return FALSE;
+}
+
+gpointer
+mono_arch_get_gsharedvt_call_info (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli)
+{
+       NOT_IMPLEMENTED;
+       return NULL;
+}
+
+#endif