diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index c9505fe838b3..2069375f2852 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -141,7 +141,7 @@ static GPtrArray *profile_options; static GSList *tramp_infos; GSList *mono_interp_only_classes; -static void register_icalls (void); +static void mini_runtime_register_icalls (void); gboolean mono_running_on_valgrind (void) @@ -4418,7 +4418,8 @@ mini_init (const char *filename, const char *runtime_version) mono_arch_register_lowlevel_calls (); - register_icalls (); + mini_runtime_register_icalls (); + mini_jit_register_icalls (); mini_jit_register_icalls (); @@ -4510,14 +4511,23 @@ mjit_initialize (void) } static gpointer -compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error) +mjit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error) { - if (!g_hasenv("MONO_MJIT")) - return mono_jit_compile_method_inner (method, target_domain, opt, NULL, error); - + static __thread gboolean is_mjit_compiling = FALSE; MonoObject *compiler, *method_info, *ret; MonoNativeCodeHandle native_code; gpointer params[4]; + gboolean bootstrapping; + + bootstrapping = is_mjit_compiling; + + // g_printerr("%s: method = %s%s%s:%s (%p), bootstrapping = %s\n", + // __func__, (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? m_class_get_name_space(method->klass) : "", + // (m_class_get_name_space(method->klass) && m_class_get_name_space(method->klass)[0] != '\0') ? "." : "", m_class_get_name (method->klass), method->name, method, + // bootstrapping ? "TRUE" : "FALSE"); + + if (!bootstrapping) + is_mjit_compiling = TRUE; mono_lazy_initialize (&mjit_initialized, mjit_initialize); @@ -4527,7 +4537,12 @@ compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, /* Invoke methodInfo..ctor */ params [0] = &method; - mono_runtime_invoke_interpreter (MethodInfo_ctor_method, method_info, params, error); + + if (bootstrapping) + mono_runtime_invoke_interpreter (MethodInfo_ctor_method, method_info, params, error); + else + mono_runtime_invoke_checked (MethodInfo_ctor_method, method_info, params, error); + return_val_if_nok (error, NULL); /* Create compiler object */ @@ -4539,9 +4554,17 @@ compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, params[1] = method_info; params[2] = &opt; params[3] = &native_code; - ret = mono_runtime_invoke_interpreter (ICompiler_CompileMethod_method, compiler, params, error); + + if (bootstrapping) + ret = mono_runtime_invoke_interpreter (ICompiler_CompileMethod_method, compiler, params, error); + else + ret = mono_runtime_invoke_checked (ICompiler_CompileMethod_method, compiler, params, error); + return_val_if_nok (error, NULL); + if (!bootstrapping) + is_mjit_compiling = FALSE; + if (*(gint16*)mono_object_unbox (ret) != 0 /* CompilationResult.Ok */) { /* set error */ return NULL; @@ -4550,6 +4573,43 @@ compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, return native_code.blob; } +static gpointer +njit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error) +{ + return mono_jit_compile_method_inner (method, target_domain, opt, NULL, error); +} + +/* + * This function is to be used to call the compiler, and it needs be the single point of entry to the compiler. + */ +static gpointer +compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gint32 opt, MonoError *error) +{ + MonoVTable *vtable; + gpointer res; + + if (g_hasenv("MONO_MJIT")) + res = mjit_compile_method_inner (method, target_domain, opt, error); + else + res = njit_compile_method_inner (method, target_domain, opt, error); + + if (res == NULL) + return NULL; + + vtable = mono_class_vtable_checked (target_domain, method->klass, error); + return_val_if_nok (error, NULL); + + if (method->wrapper_type != MONO_WRAPPER_REMOTING_INVOKE + && method->wrapper_type != MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK + && method->wrapper_type != MONO_WRAPPER_XDOMAIN_INVOKE) + { + mono_runtime_class_init_full (vtable, error); + return_val_if_nok (error, NULL); + } + + return res; +} + typedef struct _InstalledRuntimeCode { MonoJitInfo *jinfo; } InstalledRuntimeCode; @@ -4631,7 +4691,7 @@ ves_icall_mjit_execute_installed_method (InstalledRuntimeCode *irc, MonoArray *a } static void -register_icalls (void) +mini_runtime_register_icalls (void) { mono_add_internal_call ("System.Diagnostics.StackFrame::get_frame_info", ves_icall_get_frame_info); diff --git a/mono/mini/mini.c b/mono/mini/mini.c index f9f333c4cfe0..d3e4cfbfb23e 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -4041,7 +4041,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi MonoCompile *cfg; gpointer code = NULL; MonoJitInfo *jinfo, *info; - MonoVTable *vtable; MonoException *ex = NULL; GTimer *jit_timer; MonoMethod *prof_method, *shared; @@ -4176,12 +4175,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi return NULL; } - vtable = mono_class_vtable_checked (target_domain, method->klass, error); - if (!mono_error_ok (error)) { - mono_destroy_compile (cfg); - return NULL; - } - if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) { if (mono_marshal_method_from_wrapper (method)) { /* Native func wrappers have no method */ @@ -4193,24 +4186,12 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, gi if (prof_method != method) MONO_PROFILER_RAISE (jit_done, (prof_method, jinfo)); - if (!(method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE || - method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK || - method->wrapper_type == MONO_WRAPPER_XDOMAIN_INVOKE)) { - if (!mono_runtime_class_init_full (vtable, error)) { - mono_destroy_compile (cfg); - return NULL; - } - } - - if (!code) { - mono_destroy_compile (cfg); - return NULL; - } - if (code_length) *code_length = cfg->code_len; mono_destroy_compile (cfg); + + g_assert (code); return code; }