X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-runtime.c;h=c73c19ffcef9b013900144ce5da667272a6ec2c1;hb=55df1b0b94a318394923236d6f848cb205e5c9a1;hp=3c1b0cf37e5aa1d5b452e0e91343e953efdbc545;hpb=364d06d7224ff8b04249fa11ac7fe2b2ddc182da;p=mono.git diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 3c1b0cf37e5..c73c19ffcef 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -1262,6 +1262,8 @@ mono_patch_info_hash (gconstpointer data) } case MONO_PATCH_INFO_JIT_ICALL_ADDR: return (ji->type << 8) | g_str_hash (ji->data.target); + case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: + return (ji->type << 8) | mono_signature_hash (ji->data.sig); default: printf ("info type: %d\n", ji->type); mono_print_ji (ji); printf ("\n"); @@ -1326,6 +1328,8 @@ mono_patch_info_equal (gconstpointer ka, gconstpointer kb) if (ji1->data.target == ji2->data.target) return 1; return strcmp (ji1->data.target, ji2->data.target) == 0 ? 1 : 0; + case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: + return mono_metadata_signature_equal (ji1->data.sig, ji2->data.sig) ? 1 : 0; default: if (ji1->data.target != ji2->data.target) return 0; @@ -1698,6 +1702,9 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, break; } + case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: + target = mini_get_gsharedvt_wrapper (TRUE, NULL, patch_info->data.sig, NULL, -1, FALSE); + break; default: g_assert_not_reached (); } @@ -1858,14 +1865,10 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException /* Must be domain neutral since there is only one copy */ opt |= MONO_OPT_SHARED; - } - - if (method->dynamic) - opt &= ~MONO_OPT_SHARED; - - /* These methods can become invalid when a domain is unloaded */ - if (method->klass->image != mono_get_corlib () || method->is_inflated) + } else { + /* MONO_OPT_SHARED is no longer supported, we only use it for icall wrappers */ opt &= ~MONO_OPT_SHARED; + } if (opt & MONO_OPT_SHARED) target_domain = mono_get_root_domain (); @@ -2115,6 +2118,32 @@ mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *met return NULL; } +static guint32 bisect_opt = 0; +static GHashTable *bisect_methods_hash = NULL; + +void +mono_set_bisect_methods (guint32 opt, const char *method_list_filename) +{ + FILE *file; + char method_name [2048]; + + bisect_opt = opt; + bisect_methods_hash = g_hash_table_new (g_str_hash, g_str_equal); + g_assert (bisect_methods_hash); + + file = fopen (method_list_filename, "r"); + g_assert (file); + + while (fgets (method_name, sizeof (method_name), file)) { + size_t len = strlen (method_name); + g_assert (len > 0); + g_assert (method_name [len - 1] == '\n'); + method_name [len - 1] = 0; + g_hash_table_insert (bisect_methods_hash, g_strdup (method_name), GINT_TO_POINTER (1)); + } + g_assert (feof (file)); +} + gboolean mono_do_single_method_regression = FALSE; guint32 mono_single_method_regression_opt = 0; MonoMethod *mono_current_single_method; @@ -2126,6 +2155,13 @@ mono_get_optimizations_for_method (MonoMethod *method, guint32 default_opt) { g_assert (method); + if (bisect_methods_hash) { + char *name = mono_method_full_name (method, TRUE); + void *res = g_hash_table_lookup (bisect_methods_hash, name); + g_free (name); + if (res) + return default_opt | bisect_opt; + } if (!mono_do_single_method_regression) return default_opt; if (!mono_current_single_method) { @@ -2155,38 +2191,22 @@ typedef struct { MonoVTable *vtable; MonoDynCallInfo *dyn_call_info; MonoClass *ret_box_class; - gboolean needs_rgctx; MonoMethodSignature *sig; + gboolean gsharedvt_invoke; gpointer *wrapper_arg; } RuntimeInvokeInfo; -gboolean -mini_gsharedvt_runtime_invoke_supported (MonoMethodSignature *sig) -{ - gboolean supported = TRUE; - int i; - - for (i = 0; i < sig->param_count; ++i) { - MonoType *t = sig->params [i]; - - if (t->byref && t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t))) - supported = FALSE; - } - - return supported; -} - static RuntimeInvokeInfo* -create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method) +create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer compiled_method, gboolean callee_gsharedvt) { MonoMethod *invoke; RuntimeInvokeInfo *info; info = g_new0 (RuntimeInvokeInfo, 1); - info->needs_rgctx = mono_llvm_only && mono_method_needs_static_rgctx_invoke (method, TRUE); info->compiled_method = compiled_method; + info->sig = mono_method_signature (method); - invoke = mono_marshal_get_runtime_invoke (method, FALSE, info->needs_rgctx); + invoke = mono_marshal_get_runtime_invoke (method, FALSE); info->vtable = mono_class_vtable_full (domain, method->klass, TRUE); g_assert (info->vtable); @@ -2205,7 +2225,6 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com if (method->string_ctor) sig = mono_marshal_get_string_ctor_signature (method); - g_assert (!info->needs_rgctx); for (i = 0; i < sig->param_count; ++i) { MonoType *t = sig->params [i]; @@ -2265,31 +2284,32 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com if (!info->dyn_call_info) { if (mono_llvm_only) { - gboolean supported; - - supported = mini_gsharedvt_runtime_invoke_supported (sig); - - if (mono_class_is_contextbound (method->klass) || !info->compiled_method) - supported = FALSE; - #ifndef ENABLE_GSHAREDVT - supported = FALSE; + g_assert_not_reached (); #endif - - if (supported) { + info->gsharedvt_invoke = TRUE; + if (!callee_gsharedvt) { /* Invoke a gsharedvt out wrapper instead */ MonoMethod *wrapper = mini_get_gsharedvt_out_sig_wrapper (sig); MonoMethodSignature *wrapper_sig = mini_get_gsharedvt_out_sig_wrapper_signature (sig->hasthis, sig->ret->type != MONO_TYPE_VOID, sig->param_count); info->wrapper_arg = g_malloc0 (2 * sizeof (gpointer)); - info->wrapper_arg [0] = info->compiled_method; - info->wrapper_arg [1] = mono_method_needs_static_rgctx_invoke (method, TRUE) ? mini_method_get_rgctx (method) : NULL; + info->wrapper_arg [0] = mini_add_method_wrappers_llvmonly (method, info->compiled_method, FALSE, FALSE, &(info->wrapper_arg [1])); /* Pass has_rgctx == TRUE since the wrapper has an extra arg */ invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig); g_free (wrapper_sig); info->compiled_method = mono_jit_compile_method (wrapper); + } else { + /* Gsharedvt methods can be invoked the same way */ + /* The out wrapper has the same signature as the compiled gsharedvt method */ + MonoMethodSignature *wrapper_sig = mini_get_gsharedvt_out_sig_wrapper_signature (sig->hasthis, sig->ret->type != MONO_TYPE_VOID, sig->param_count); + + info->wrapper_arg = mono_method_needs_static_rgctx_invoke (method, TRUE) ? mini_method_get_rgctx (method) : NULL; + + invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig); + g_free (wrapper_sig); } } info->runtime_invoke = mono_jit_compile_method (invoke); @@ -2298,6 +2318,77 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com return info; } +static MonoObject* +mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void *obj, void **params, MonoObject **exc) +{ + MonoMethodSignature *sig = info->sig; + MonoDomain *domain = mono_domain_get (); + MonoObject *(*runtime_invoke) (MonoObject *this_obj, void **params, MonoObject **exc, void* compiled_method); + gpointer *args; + gpointer retval_ptr; + guint8 retval [256]; + gpointer *param_refs; + int i, pindex; + + g_assert (info->gsharedvt_invoke); + + /* + * Instead of invoking the method directly, we invoke a gsharedvt out wrapper. + * The advantage of this is the gsharedvt out wrappers have a reduced set of + * signatures, so we only have to generate runtime invoke wrappers for these + * signatures. + * This code also handles invocation of gsharedvt methods directly, no + * out wrappers are used in that case. + */ + args = (void **)g_alloca ((sig->param_count + sig->hasthis + 2) * sizeof (gpointer)); + param_refs = (gpointer*)g_alloca ((sig->param_count + sig->hasthis + 2) * sizeof (gpointer)); + pindex = 0; + /* + * The runtime invoke wrappers expects pointers to primitive types, so have to + * use indirections. + */ + if (sig->hasthis) + args [pindex ++] = &obj; + if (sig->ret->type != MONO_TYPE_VOID) { + retval_ptr = (gpointer)&retval; + args [pindex ++] = &retval_ptr; + } + for (i = 0; i < sig->param_count; ++i) { + MonoType *t = sig->params [i]; + + if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t))) { + MonoClass *klass = mono_class_from_mono_type (t); + guint8 *nullable_buf; + int size; + + size = mono_class_value_size (klass, NULL); + nullable_buf = g_alloca (size); + g_assert (nullable_buf); + + /* The argument pointed to by params [i] is either a boxed vtype or null */ + mono_nullable_init (nullable_buf, (MonoObject*)params [i], klass); + params [i] = nullable_buf; + } + + if (!t->byref && (MONO_TYPE_IS_REFERENCE (t) || t->type == MONO_TYPE_PTR)) { + param_refs [i] = params [i]; + params [i] = &(param_refs [i]); + } + args [pindex ++] = ¶ms [i]; + } + /* The gsharedvt out wrapper has an extra argument which contains the method to call */ + args [pindex ++] = &info->wrapper_arg; + + runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke; + + runtime_invoke (NULL, args, exc, info->compiled_method); + + if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class) + return mono_value_box (domain, info->ret_box_class, retval); + else + return *(MonoObject**)retval; +} + /** * mono_jit_runtime_invoke: * @method: the method to invoke @@ -2313,6 +2404,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec MonoDomain *domain = mono_domain_get (); MonoJitDomainInfo *domain_info; RuntimeInvokeInfo *info, *info2; + MonoJitInfo *ji = NULL; + gboolean callee_gsharedvt = FALSE; if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) { g_warning ("Ignoring invocation of an instance method on a NULL instance.\n"); @@ -2355,7 +2448,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec MonoMethod *wrapper; wrapper = mono_marshal_get_array_accessor_wrapper (method); - invoke = mono_marshal_get_runtime_invoke (wrapper, FALSE, FALSE); + invoke = mono_marshal_get_runtime_invoke (wrapper, FALSE); callee = wrapper; } else { callee = NULL; @@ -2377,12 +2470,20 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec } } - compiled_method = mini_add_method_trampoline (callee, compiled_method, mono_method_needs_static_rgctx_invoke (callee, TRUE), FALSE); + if (mono_llvm_only) { + ji = mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (compiled_method), NULL); + callee_gsharedvt = mini_jit_info_is_gsharedvt (ji); + if (callee_gsharedvt) + callee_gsharedvt = mini_is_gsharedvt_variable_signature (mono_method_signature (jinfo_get_method (ji))); + } + + if (!callee_gsharedvt) + compiled_method = mini_add_method_trampoline (callee, compiled_method, mono_method_needs_static_rgctx_invoke (callee, TRUE), FALSE); } else { compiled_method = NULL; } - info = create_runtime_invoke_info (domain, method, compiled_method); + info = create_runtime_invoke_info (domain, method, compiled_method, callee_gsharedvt); mono_domain_lock (domain); info2 = (RuntimeInvokeInfo *)mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info); @@ -2417,7 +2518,6 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec int i, pindex; guint8 buf [512]; guint8 retval [256]; - gpointer rgctx; if (!dyn_runtime_invoke) { invoke = mono_marshal_get_runtime_invoke_dynamic (); @@ -2425,7 +2525,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec } /* Convert the arguments to the format expected by start_dyn_call () */ - args = (void **)g_alloca ((sig->param_count + sig->hasthis + info->needs_rgctx) * sizeof (gpointer)); + args = (void **)g_alloca ((sig->param_count + sig->hasthis) * sizeof (gpointer)); pindex = 0; if (sig->hasthis) args [pindex ++] = &obj; @@ -2440,10 +2540,6 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec args [pindex ++] = params [i]; } } - if (info->needs_rgctx) { - rgctx = mini_method_get_rgctx (method); - args [pindex ++] = &rgctx; - } //printf ("M: %s\n", mono_method_full_name (method, TRUE)); @@ -2460,70 +2556,12 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec } #endif - runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke; - - if (info->wrapper_arg) { - MonoMethodSignature *sig = mono_method_signature (method); - gpointer *args; - gpointer retval_ptr; - guint8 retval [256]; - gpointer param_refs [256]; - int i, pindex; - - /* - * Instead of invoking the method directly, we invoke a gsharedvt out wrapper. - * The advantage of this is the gsharedvt out wrappers have a reduced set of - * signatures, so we only have to generate runtime invoke wrappers for these - * signatures. - */ - args = (void **)g_alloca ((sig->param_count + sig->hasthis + 2) * sizeof (gpointer)); - pindex = 0; - /* - * The runtime invoke wrappers expects pointers to primitive types, so have to - * use indirections. - */ - if (sig->hasthis) - args [pindex ++] = &obj; - if (sig->ret->type != MONO_TYPE_VOID) { - retval_ptr = (gpointer)&retval; - args [pindex ++] = &retval_ptr; - } - for (i = 0; i < sig->param_count; ++i) { - MonoType *t = sig->params [i]; - - if (MONO_TYPE_IS_REFERENCE (t)) { - param_refs [i] = params [i]; - params [i] = &(param_refs [i]); - } - args [pindex ++] = ¶ms [i]; - } - /* The gsharedvt out wrapper has an extra argument which contains the method to call */ - args [pindex ++] = &info->wrapper_arg; - runtime_invoke (NULL, args, exc, info->compiled_method); - - if (sig->ret->type != MONO_TYPE_VOID && info->ret_box_class) - return mono_value_box (domain, info->ret_box_class, retval); - else - return *(MonoObject**)retval; - } + if (mono_llvm_only) + return mono_llvmonly_runtime_invoke (method, info, obj, params, exc); - // FIXME: Cache this - if (info->needs_rgctx) { - MonoMethodSignature *sig = mono_method_signature (method); - gpointer rgctx; - gpointer *args; - int i, pindex; + runtime_invoke = (MonoObject *(*)(MonoObject *, void **, MonoObject **, void *))info->runtime_invoke; - args = (void **)g_alloca ((sig->param_count + sig->hasthis + info->needs_rgctx) * sizeof (gpointer)); - pindex = 0; - rgctx = mini_method_get_rgctx (method); - for (i = 0; i < sig->param_count; ++i) - args [pindex ++] = params [i]; - args [pindex ++] = &rgctx; - return runtime_invoke ((MonoObject *)obj, args, exc, info->compiled_method); - } else { - return runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method); - } + return runtime_invoke ((MonoObject *)obj, params, exc, info->compiled_method); } typedef struct { @@ -2607,14 +2645,14 @@ mono_llvmonly_imt_thunk_3 (gpointer *arg, MonoMethod *imt_method) } /* - * A version of the imt thunk used for generic virtual methods. + * A version of the imt thunk used for generic virtual/variant iface methods. * Unlikely a normal imt thunk, its possible that IMT_METHOD is not found * in the search table. The original JIT code had a 'fallback' trampoline it could * call, but we can't do that, so we just return NULL, and the compiled code * will handle it. */ static gpointer -mono_llvmonly_generic_virtual_imt_thunk (gpointer *arg, MonoMethod *imt_method) +mono_llvmonly_fallback_imt_thunk (gpointer *arg, MonoMethod *imt_method) { int i = 0; @@ -2702,8 +2740,8 @@ mono_llvmonly_get_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTChec res [0] = mono_llvmonly_imt_thunk; break; } - if (virtual_generic) - res [0] = mono_llvmonly_generic_virtual_imt_thunk; + if (virtual_generic || fail_tramp) + res [0] = mono_llvmonly_fallback_imt_thunk; res [1] = buf; return res; @@ -2977,6 +3015,42 @@ mini_imt_entry_inited (MonoVTable *vt, int imt_slot_index) return (imt [imt_slot_index] != mini_get_imt_trampoline (vt, imt_slot_index)); } +static gboolean +is_callee_gsharedvt_variable (gpointer addr) +{ + MonoJitInfo *ji; + gboolean callee_gsharedvt; + + ji = mini_jit_info_table_find (mono_domain_get (), (char *)mono_get_addr_from_ftnptr (addr), NULL); + g_assert (ji); + callee_gsharedvt = mini_jit_info_is_gsharedvt (ji); + if (callee_gsharedvt) + callee_gsharedvt = mini_is_gsharedvt_variable_signature (mono_method_signature (jinfo_get_method (ji))); + return callee_gsharedvt; +} + +void +mini_init_delegate (MonoDelegate *del) +{ + if (mono_llvm_only) { + MonoMethod *method = del->method; + + if (mono_method_needs_static_rgctx_invoke (method, FALSE)) + del->rgctx = mini_method_get_rgctx (method); + + /* + * Avoid adding gsharedvt in wrappers since they might not exist if + * this delegate is called through a gsharedvt delegate invoke wrapper. + * Instead, encode that the method is gsharedvt in del->rgctx, + * the CEE_MONO_CALLI_EXTRA_ARG implementation in the JIT depends on this. + */ + if (is_callee_gsharedvt_variable (del->method_ptr)) { + g_assert ((((mgreg_t)del->rgctx) & 1) == 0); + del->rgctx = (gpointer)(((mgreg_t)del->rgctx) | 1); + } + } +} + gpointer mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method) { @@ -2996,7 +3070,7 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met is_interface = method->klass->flags & TYPE_ATTRIBUTE_INTERFACE ? TRUE : FALSE; load_imt_reg = is_virtual_generic || is_interface; - if (is_interface && !is_virtual_generic) + if (is_interface) offset = ((gint32)mono_method_get_imt_slot (method) - MONO_IMT_SIZE) * SIZEOF_VOID_P; else offset = G_STRUCT_OFFSET (MonoVTable, vtable) + ((mono_method_get_vtable_index (method)) * (SIZEOF_VOID_P)); @@ -3041,6 +3115,73 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met return cache [idx]; } +/** + * mini_parse_debug_option: + * @option: The option to parse. + * + * Parses debug options for the mono runtime. The options are the same as for + * the MONO_DEBUG environment variable. + * + */ +gboolean +mini_parse_debug_option (const char *option) +{ + if (!strcmp (option, "handle-sigint")) + debug_options.handle_sigint = TRUE; + else if (!strcmp (option, "keep-delegates")) + debug_options.keep_delegates = TRUE; + else if (!strcmp (option, "reverse-pinvoke-exceptions")) + debug_options.reverse_pinvoke_exceptions = TRUE; + else if (!strcmp (option, "collect-pagefault-stats")) + debug_options.collect_pagefault_stats = TRUE; + else if (!strcmp (option, "break-on-unverified")) + debug_options.break_on_unverified = TRUE; + else if (!strcmp (option, "no-gdb-backtrace")) + debug_options.no_gdb_backtrace = TRUE; + else if (!strcmp (option, "suspend-on-sigsegv")) + debug_options.suspend_on_sigsegv = TRUE; + else if (!strcmp (option, "suspend-on-exception")) + debug_options.suspend_on_exception = TRUE; + else if (!strcmp (option, "suspend-on-unhandled")) + debug_options.suspend_on_unhandled = TRUE; + else if (!strcmp (option, "dont-free-domains")) + mono_dont_free_domains = TRUE; + else if (!strcmp (option, "dyn-runtime-invoke")) + debug_options.dyn_runtime_invoke = TRUE; + else if (!strcmp (option, "gdb")) + debug_options.gdb = TRUE; + else if (!strcmp (option, "explicit-null-checks")) + debug_options.explicit_null_checks = TRUE; + else if (!strcmp (option, "gen-seq-points")) + debug_options.gen_sdb_seq_points = TRUE; + else if (!strcmp (option, "gen-compact-seq-points")) + debug_options.gen_seq_points_compact_data = TRUE; + else if (!strcmp (option, "single-imm-size")) + debug_options.single_imm_size = TRUE; + else if (!strcmp (option, "init-stacks")) + debug_options.init_stacks = TRUE; + else if (!strcmp (option, "casts")) + debug_options.better_cast_details = TRUE; + else if (!strcmp (option, "soft-breakpoints")) + debug_options.soft_breakpoints = TRUE; + else if (!strcmp (option, "check-pinvoke-callconv")) + debug_options.check_pinvoke_callconv = TRUE; + else if (!strcmp (option, "arm-use-fallback-tls")) + debug_options.arm_use_fallback_tls = TRUE; + else if (!strcmp (option, "debug-domain-unload")) + mono_enable_debug_domain_unload (TRUE); + else if (!strcmp (option, "partial-sharing")) + mono_set_partial_sharing_supported (TRUE); + else if (!strcmp (option, "align-small-structs")) + mono_align_small_structs = TRUE; + else if (!strcmp (option, "native-debugger-break")) + debug_options.native_debugger_break = TRUE; + else + return FALSE; + + return TRUE; +} + static void mini_parse_debug_options (void) { @@ -3055,57 +3196,7 @@ mini_parse_debug_options (void) for (ptr = args; ptr && *ptr; ptr++) { const char *arg = *ptr; - if (!strcmp (arg, "handle-sigint")) - debug_options.handle_sigint = TRUE; - else if (!strcmp (arg, "keep-delegates")) - debug_options.keep_delegates = TRUE; - else if (!strcmp (arg, "reverse-pinvoke-exceptions")) - debug_options.reverse_pinvoke_exceptions = TRUE; - else if (!strcmp (arg, "collect-pagefault-stats")) - debug_options.collect_pagefault_stats = TRUE; - else if (!strcmp (arg, "break-on-unverified")) - debug_options.break_on_unverified = TRUE; - else if (!strcmp (arg, "no-gdb-backtrace")) - debug_options.no_gdb_backtrace = TRUE; - else if (!strcmp (arg, "suspend-on-sigsegv")) - debug_options.suspend_on_sigsegv = TRUE; - else if (!strcmp (arg, "suspend-on-exception")) - debug_options.suspend_on_exception = TRUE; - else if (!strcmp (arg, "suspend-on-unhandled")) - debug_options.suspend_on_unhandled = TRUE; - else if (!strcmp (arg, "dont-free-domains")) - mono_dont_free_domains = TRUE; - else if (!strcmp (arg, "dyn-runtime-invoke")) - debug_options.dyn_runtime_invoke = TRUE; - else if (!strcmp (arg, "gdb")) - debug_options.gdb = TRUE; - else if (!strcmp (arg, "explicit-null-checks")) - debug_options.explicit_null_checks = TRUE; - else if (!strcmp (arg, "gen-seq-points")) - debug_options.gen_sdb_seq_points = TRUE; - else if (!strcmp (arg, "gen-compact-seq-points")) - debug_options.gen_seq_points_compact_data = TRUE; - else if (!strcmp (arg, "single-imm-size")) - debug_options.single_imm_size = TRUE; - else if (!strcmp (arg, "init-stacks")) - debug_options.init_stacks = TRUE; - else if (!strcmp (arg, "casts")) - debug_options.better_cast_details = TRUE; - else if (!strcmp (arg, "soft-breakpoints")) - debug_options.soft_breakpoints = TRUE; - else if (!strcmp (arg, "check-pinvoke-callconv")) - debug_options.check_pinvoke_callconv = TRUE; - else if (!strcmp (arg, "arm-use-fallback-tls")) - debug_options.arm_use_fallback_tls = TRUE; - else if (!strcmp (arg, "debug-domain-unload")) - mono_enable_debug_domain_unload (TRUE); - else if (!strcmp (arg, "partial-sharing")) - mono_set_partial_sharing_supported (TRUE); - else if (!strcmp (arg, "align-small-structs")) - mono_align_small_structs = TRUE; - else if (!strcmp (arg, "native-debugger-break")) - debug_options.native_debugger_break = TRUE; - else { + if (!mini_parse_debug_option (arg)) { fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg); fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dont-free-domains', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'gen-seq-points', 'gen-compact-seq-points', 'single-imm-size', 'init-stacks', 'casts', 'soft-breakpoints', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs', 'native-debugger-break'\n"); exit (1); @@ -3388,10 +3479,10 @@ mini_init (const char *filename, const char *runtime_version) callbacks.debug_log = mono_debugger_agent_debug_log; callbacks.debug_log_is_enabled = mono_debugger_agent_debug_log_is_enabled; callbacks.tls_key_supported = mini_tls_key_supported; - callbacks.get_vtable_trampoline = mini_get_vtable_trampoline; callbacks.get_imt_trampoline = mini_get_imt_trampoline; callbacks.imt_entry_inited = mini_imt_entry_inited; + callbacks.init_delegate = mini_init_delegate; mono_install_callbacks (&callbacks); @@ -3768,7 +3859,7 @@ register_icalls (void) register_icall (mono_ldstr, "mono_ldstr", "object ptr ptr int32", FALSE); register_icall (mono_helper_stelem_ref_check, "mono_helper_stelem_ref_check", "void object object", FALSE); register_icall (mono_object_new, "mono_object_new", "object ptr ptr", FALSE); - register_icall (mono_object_new_specific, "mono_object_new_specific", "object ptr", FALSE); + register_icall (ves_icall_object_new_specific, "ves_icall_object_new_specific", "object ptr", FALSE); register_icall (mono_array_new, "mono_array_new", "object ptr ptr int32", FALSE); register_icall (mono_array_new_specific, "mono_array_new_specific", "object ptr int32", FALSE); register_icall (mono_runtime_class_init, "mono_runtime_class_init", "void ptr", FALSE); @@ -3806,17 +3897,21 @@ register_icalls (void) register_icall (mono_aot_init_llvm_method, "mono_aot_init_llvm_method", "void ptr int", TRUE); register_icall (mono_aot_init_gshared_method_this, "mono_aot_init_gshared_method_this", "void ptr int object", TRUE); - register_icall (mono_aot_init_gshared_method_rgctx, "mono_aot_init_gshared_method_rgctx", "void ptr int ptr", TRUE); + register_icall (mono_aot_init_gshared_method_mrgctx, "mono_aot_init_gshared_method_mrgctx", "void ptr int ptr", TRUE); + register_icall (mono_aot_init_gshared_method_vtable, "mono_aot_init_gshared_method_vtable", "void ptr int ptr", TRUE); register_icall_no_wrapper (mono_resolve_iface_call_gsharedvt, "mono_resolve_iface_call_gsharedvt", "ptr object int ptr ptr"); register_icall_no_wrapper (mono_resolve_vcall_gsharedvt, "mono_resolve_vcall_gsharedvt", "ptr object int ptr ptr"); register_icall_no_wrapper (mono_resolve_generic_virtual_call, "mono_resolve_generic_virtual_call", "ptr ptr int ptr"); register_icall_no_wrapper (mono_resolve_generic_virtual_iface_call, "mono_resolve_generic_virtual_iface_call", "ptr ptr int ptr"); + register_icall_no_wrapper (mono_llvmonly_set_calling_assembly, "mono_llvmonly_set_calling_assembly", "void ptr"); + register_icall_no_wrapper (mono_llvmonly_get_calling_assembly, "mono_llvmonly_get_calling_assembly", "object"); /* This needs a wrapper so it can have a preserveall cconv */ register_icall (mono_init_vtable_slot, "mono_init_vtable_slot", "ptr ptr int", FALSE); - register_icall (mono_init_delegate, "mono_init_delegate", "void object object ptr", TRUE); - register_icall (mono_init_delegate_virtual, "mono_init_delegate_virtual", "void object object ptr", TRUE); + register_icall (mono_llvmonly_init_delegate, "mono_llvmonly_init_delegate", "void object object ptr", TRUE); + register_icall (mono_llvmonly_init_delegate_virtual, "mono_llvmonly_init_delegate_virtual", "void object object ptr", TRUE); register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE); + register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE); #ifdef TARGET_IOS register_icall (pthread_getspecific, "pthread_getspecific", "ptr ptr", TRUE); @@ -4030,7 +4125,7 @@ mono_precompile_assembly (MonoAssembly *ass, void *user_data) } mono_compile_method (method); if (strcmp (method->name, "Finalize") == 0) { - invoke = mono_marshal_get_runtime_invoke (method, FALSE, FALSE); + invoke = mono_marshal_get_runtime_invoke (method, FALSE); mono_compile_method (invoke); } #ifndef DISABLE_REMOTING