[interpreter] use jit icall for delegate ctor
authorBernhard Urban <bernhard.urban@xamarin.com>
Mon, 27 Feb 2017 16:55:53 +0000 (17:55 +0100)
committerBernhard Urban <bernhard.urban@xamarin.com>
Tue, 28 Feb 2017 21:59:28 +0000 (22:59 +0100)
mono/mini/interpreter/interp-internals.h
mono/mini/interpreter/interp.c
mono/mini/interpreter/transform.c

index 603e20a191894e38582c6192abccb9918922737b..5e8597a6a6f8b915d09652acb30b29c6ca9c4829 100644 (file)
@@ -116,9 +116,6 @@ extern int mono_interp_traceopt;
 MonoException *
 mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *context);
 
-MonoDelegate*
-mono_interp_ftnptr_to_delegate (MonoClass *klass, gpointer ftn);
-
 void
 mono_interp_transform_init (void);
 
index 183a7bcbca10abce3d5f8389d038c36bfba6c5c7..be1365495d0e31e045e24c65a86b82e61d4db79d 100644 (file)
@@ -871,47 +871,6 @@ ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV a
        g_free (margs);
 }
 
-static void
-interp_delegate_ctor (MonoDomain *domain, MonoObject *this, MonoObject *target, RuntimeMethod *runtime_method)
-{
-       MonoDelegate *delegate = (MonoDelegate *)this;
-       MonoError error;
-
-       delegate->method_info = mono_method_get_object_checked (domain, runtime_method->method, NULL, &error);
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-       delegate->target = target;
-
-       if (target && mono_object_is_transparent_proxy (target)) {
-               MonoMethod *method = mono_marshal_get_remoting_invoke (runtime_method->method);
-               delegate->method_ptr = mono_interp_get_runtime_method (domain, method, &error);
-               mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-       } else {
-               delegate->method_ptr = runtime_method;
-       }
-}
-
-MonoDelegate*
-mono_interp_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
-{
-       MonoDelegate *d;
-       MonoJitInfo *ji;
-       MonoDomain *domain = mono_domain_get ();
-       MonoError error;
-
-       d = (MonoDelegate*)mono_object_new_checked (domain, klass, &error);
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-
-       ji = mono_jit_info_table_find (domain, ftn);
-       if (ji == NULL)
-               mono_raise_exception (mono_get_exception_argument ("", "Function pointer was not created by a Delegate."));
-
-       /* FIXME: discard the wrapper and call the original method */
-       interp_delegate_ctor (domain, (MonoObject*)d, NULL, mono_interp_get_runtime_method (domain, ji->d.method, &error));
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-
-       return d;
-}
-
 /*
  * From the spec:
  * runtime specifies that the implementation of the method is automatically
@@ -928,15 +887,6 @@ ves_runtime_method (MonoInvocation *frame, ThreadContext *context)
 
        mono_class_init (method->klass);
 
-       isinst_obj = mono_object_isinst_checked (obj, mono_defaults.multicastdelegate_class, &error);
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-       if (obj && isinst_obj) {
-               if (*name == '.' && (strcmp (name, ".ctor") == 0)) {
-                       interp_delegate_ctor (context->domain, obj, frame->stack_args [1].data.p, frame->stack_args[2].data.p);
-                       return;
-               }
-       }
-
        isinst_obj = mono_object_isinst_checked (obj, mono_defaults.array_class, &error);
        mono_error_cleanup (&error); /* FIXME: don't swallow the error */
        if (obj && isinst_obj) {
@@ -4332,24 +4282,6 @@ interp_ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_fi
        return res;
 }
 
-static MonoObject *
-ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target, MonoReflectionMethod *info)
-{
-       MonoClass *delegate_class = mono_class_from_mono_type (type->type);
-       MonoObject *delegate;
-       MonoError error;
-
-       g_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
-
-       delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-
-       interp_delegate_ctor (mono_object_domain (type), delegate, target, mono_interp_get_runtime_method (mono_get_root_domain (), info->method, &error));
-       mono_error_cleanup (&error); /* FIXME: don't swallow the error */
-
-       return delegate;
-}
-
 void
 mono_interp_init ()
 {
index 4a91c6cd1a0bb4b7eeee2f10fa82524933f1f9ec..8370c006eab91831f618aa56a9067e66beccf2dc 100644 (file)
@@ -2602,6 +2602,21 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
                                        --td.sp;
                                        interp_transform_call (&td, method, NULL, domain, generic_context, is_bb_start, body_start_offset, NULL);
                                        break;
+                               case CEE_MONO_JIT_ICALL_ADDR: {
+                                       guint32 token;
+                                       gpointer func;
+                                       MonoJitICallInfo *info;
+
+                                       token = read32 (td.ip + 1);
+                                       td.ip += 5;
+                                       func = mono_method_get_wrapper_data (method, token);
+                                       info = mono_find_jit_icall_by_addr (func);
+
+                                       ADD_CODE (&td, MINT_LDFTN);
+                                       ADD_CODE (&td, get_data_item_index (&td, func));
+                                       PUSH_SIMPLE_TYPE (&td, STACK_TYPE_I);
+                                       break;
+                               }
                                case CEE_MONO_ICALL: {
                                        guint32 token;
                                        gpointer func;
@@ -2653,7 +2668,6 @@ generate (MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start)
 
                                        if (func == mono_ftnptr_to_delegate) {
                                                g_error ("TODO: ?");
-                                               func = mono_interp_ftnptr_to_delegate;
                                        }
                                        ADD_CODE(&td, get_data_item_index (&td, func));
                                        td.sp -= info->sig->param_count;
@@ -3087,7 +3101,12 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont
                } else {
                        const char *name = method->name;
                        if (method->klass->parent == mono_defaults.multicastdelegate_class) {
-                               if (*name == 'I' && (strcmp (name, "Invoke") == 0)) {
+                               if (*name == '.' && (strcmp (name, ".ctor") == 0)) {
+                                       MonoJitICallInfo *mi = mono_find_jit_icall_by_name ("ves_icall_mono_delegate_ctor");
+                                       g_assert (mi);
+                                       char *wrapper_name = g_strdup_printf ("__icall_wrapper_%s", mi->name);
+                                       nm = mono_marshal_get_icall_wrapper (mi->sig, wrapper_name, mi->func, TRUE);
+                               } else if (*name == 'I' && (strcmp (name, "Invoke") == 0)) {
                                        nm = mono_marshal_get_delegate_invoke (method, NULL);
                                } else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0)) {
                                        nm = mono_marshal_get_delegate_begin_invoke (method);