[interp] add --aot=interp, so we can run `mono --full-aot --interpreter`
authorBernhard Urban <bernhard.urban@xamarin.com>
Wed, 7 Jun 2017 16:24:14 +0000 (18:24 +0200)
committerBernhard Urban <bernhard.urban@xamarin.com>
Wed, 7 Jun 2017 21:27:44 +0000 (23:27 +0200)
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/interp/interp.c

index 59a042984997c31746f7cc869e02bb9e9d1414fb..fb372baa5e1b39852f89994e24211c5ea36fb2dd 100644 (file)
@@ -4427,7 +4427,13 @@ method_has_type_vars (MonoMethod *method)
 static
 gboolean mono_aot_mode_is_full (MonoAotOptions *opts)
 {
-       return opts->mode == MONO_AOT_MODE_FULL;
+       return opts->mode == MONO_AOT_MODE_FULL || opts->mode == MONO_AOT_MODE_INTERP;
+}
+
+static
+gboolean mono_aot_mode_is_interp (MonoAotOptions *opts)
+{
+       return opts->mode == MONO_AOT_MODE_INTERP;
 }
 
 static
@@ -6821,6 +6827,11 @@ emit_trampolines (MonoAotCompile *acfg)
 
 #endif /* #ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES */
 
+               if (mono_aot_mode_is_interp (&acfg->aot_opts)) {
+                       mono_arch_get_enter_icall_trampoline (&info);
+                       emit_trampoline (acfg, acfg->got_offset, info);
+               }
+
                /* Emit trampolines which are numerous */
 
                /*
@@ -7161,6 +7172,8 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
                        opts->mode = MONO_AOT_MODE_FULL;
                } else if (str_begins_with (arg, "hybrid")) {
                        opts->mode = MONO_AOT_MODE_HYBRID;                      
+               } else if (str_begins_with (arg, "interp")) {
+                       opts->mode = MONO_AOT_MODE_INTERP;
                } else if (str_begins_with (arg, "threads=")) {
                        opts->nthreads = atoi (arg + strlen ("threads="));
                } else if (str_begins_with (arg, "static")) {
@@ -11517,7 +11530,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                }
        }
 
-       {
+       if (!mono_aot_mode_is_interp (&acfg->aot_opts)) {
                int method_index;
 
        for (method_index = 0; method_index < acfg->image->tables [MONO_TABLE_METHOD].rows; ++method_index) {
@@ -11580,9 +11593,12 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        if (mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts))
                mono_set_partial_sharing_supported (TRUE);
 
-       res = collect_methods (acfg);
-       if (!res)
-               return 1;
+       if (!mono_aot_mode_is_interp (&acfg->aot_opts)) {
+               res = collect_methods (acfg);
+
+               if (!res)
+                       return 1;
+       }
 
        {
                GList *l;
@@ -11607,6 +11623,26 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        }
 #endif
 
+       if (mono_aot_mode_is_interp (&acfg->aot_opts)) {
+               MonoMethod *wrapper;
+               MonoMethodSignature *sig;
+
+               /* object object:interp_in_static (object,intptr,intptr,intptr) */
+               sig = mono_create_icall_signature ("object object ptr ptr ptr");
+               wrapper = mini_get_interp_in_wrapper (sig);
+               add_method (acfg, wrapper);
+
+               /* int object:interp_in_static (intptr,int,intptr) */
+               sig = mono_create_icall_signature ("int32 ptr int32 ptr");
+               wrapper = mini_get_interp_in_wrapper (sig);
+               add_method (acfg, wrapper);
+
+               /* void object:interp_in_static (object,intptr,intptr,intptr) */
+               sig = mono_create_icall_signature ("void object ptr ptr ptr");
+               wrapper = mini_get_interp_in_wrapper (sig);
+               add_method (acfg, wrapper);
+       }
+
        TV_GETTIME (atv);
 
        compile_methods (acfg);
index a1ee87fd60b8c8e247099d1da51ee9bdf65c5155..a93776da15a6b4f6a3a024ab68856eb9cfdb8044 100644 (file)
@@ -1015,6 +1015,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                ref->method = mono_marshal_get_gsharedvt_in_wrapper ();
                        } else if (subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT) {
                                ref->method = mono_marshal_get_gsharedvt_out_wrapper ();
+                       } else if (subtype == WRAPPER_SUBTYPE_INTERP_IN) {
+                               ref->method = mini_get_interp_in_wrapper (target->signature);
                        } else if (subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG) {
                                MonoMethodSignature *sig = decode_signature (module, p, &p);
                                if (!sig)
@@ -2017,7 +2019,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                        }
                }
                if (!sofile) {
-                       if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows) {
+                       if (mono_aot_only && !mono_use_interpreter && assembly->image->tables [MONO_TABLE_METHOD].rows) {
                                aot_name = g_strdup_printf ("%s%s", assembly->image->name, MONO_SOLIB_EXT);
                                g_error ("Failed to load AOT module '%s' in aot-only mode.\n", aot_name);
                                g_free (aot_name);
@@ -2061,7 +2063,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        }
 
        if (!usable) {
-               if (mono_aot_only) {
+               if (mono_aot_only && !mono_use_interpreter) {
                        g_error ("Failed to load AOT module '%s' while running in aot-only mode: %s.\n", found_aot_name, msg);
                } else {
                        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable: %s.", found_aot_name, msg);
index 3f09dc5caf36405328acd7f88359d25d71bdb7d0..a103ed22b6a851c332eed65ef8484189bd284847 100644 (file)
@@ -992,10 +992,14 @@ ves_pinvoke_method (MonoInvocation *frame, MonoMethodSignature *sig, MonoFuncV a
 
        g_assert (!frame->runtime_method);
        if (!mono_interp_enter_icall_trampoline) {
-               MonoTrampInfo *info;
-               mono_interp_enter_icall_trampoline = mono_arch_get_enter_icall_trampoline (&info);
-               // TODO:
-               // mono_tramp_info_register (info, NULL);
+               if (mono_aot_only) {
+                       mono_interp_enter_icall_trampoline = mono_aot_get_trampoline ("enter_icall_trampoline");
+               } else {
+                       MonoTrampInfo *info;
+                       mono_interp_enter_icall_trampoline = mono_arch_get_enter_icall_trampoline (&info);
+                       // TODO:
+                       // mono_tramp_info_register (info, NULL);
+               }
        }
 
        InterpMethodArguments *margs = build_args_from_sig (sig, frame);
@@ -2270,9 +2274,10 @@ mono_interp_create_method_pointer (MonoMethod *method, MonoError *error)
         * rgctx register using a trampoline.
         */
 
-       // FIXME: AOT
-       g_assert (!mono_aot_only);
-       addr = mono_arch_get_static_rgctx_trampoline (ftndesc, jit_wrapper);
+       if (mono_aot_only)
+               addr = mono_aot_get_static_rgctx_trampoline (ftndesc, jit_wrapper);
+       else
+               addr = mono_arch_get_static_rgctx_trampoline (ftndesc, jit_wrapper);
 
        mono_memory_barrier ();
        rmethod->jit_entry = addr;