X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=4da25a4d439edda2babe9a41e70d0ea1912c2b05;hb=98aa3fd560646d0fac8be990deaa8003e677662a;hp=da9f3bb6a2061d3efafc67a3cee6a9e797ad10eb;hpb=4239ddd9f18d778e03cc979c9d15135e47fb0e28;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index da9f3bb6a20..4da25a4d439 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -419,6 +419,8 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type) case MONO_TYPE_TYPEDBYREF: return OP_LOADV_MEMBASE; case MONO_TYPE_GENERICINST: + if (MONO_CLASS_IS_SIMD (cfg, mono_class_from_mono_type (type))) + return OP_LOADX_MEMBASE; if (mono_type_generic_inst_is_valuetype (type)) return OP_LOADV_MEMBASE; else @@ -1052,7 +1054,7 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method, gboolean fail_compile) else if (info->exception_type == MONO_EXCEPTION_FIELD_ACCESS) mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "%s", msg); else if (info->exception_type == MONO_EXCEPTION_UNVERIFIABLE_IL) - mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", msg); + mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", "%s", msg); if (!mono_error_ok (&cfg->error)) { mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); g_free (msg); @@ -1169,7 +1171,7 @@ mono_allocate_stack_slots2 (MonoCompile *cfg, gboolean backward, guint32 *stack_ vars = g_list_prepend (vars, vmv); } - vars = g_list_sort (g_list_copy (vars), compare_by_interval_start_pos_func); + vars = g_list_sort (vars, compare_by_interval_start_pos_func); /* Sanity check */ /* @@ -1886,28 +1888,59 @@ mono_verify_cfg (MonoCompile *cfg) mono_verify_bblock (bb); } +// This will free many fields in cfg to save +// memory. Note that this must be safe to call +// multiple times. It must be idempotent. +void +mono_empty_compile (MonoCompile *cfg) +{ + mono_free_loop_info (cfg); + + // These live in the mempool, and so must be freed + // first + for (GSList *l = cfg->headers_to_free; l; l = l->next) { + mono_metadata_free_mh ((MonoMethodHeader *)l->data); + } + cfg->headers_to_free = NULL; + + if (cfg->mempool) { + //mono_mempool_stats (cfg->mempool); + mono_mempool_destroy (cfg->mempool); + cfg->mempool = NULL; + } + + g_free (cfg->varinfo); + cfg->varinfo = NULL; + + g_free (cfg->vars); + cfg->vars = NULL; + + if (cfg->rs) { + mono_regstate_free (cfg->rs); + cfg->rs = NULL; + } +} + void mono_destroy_compile (MonoCompile *cfg) { - GSList *l; + mono_empty_compile (cfg); if (cfg->header) mono_metadata_free_mh (cfg->header); - //mono_mempool_stats (cfg->mempool); - mono_free_loop_info (cfg); - if (cfg->rs) - mono_regstate_free (cfg->rs); + if (cfg->spvars) g_hash_table_destroy (cfg->spvars); if (cfg->exvars) g_hash_table_destroy (cfg->exvars); - for (l = cfg->headers_to_free; l; l = l->next) - mono_metadata_free_mh ((MonoMethodHeader *)l->data); + g_list_free (cfg->ldstr_list); - g_hash_table_destroy (cfg->token_info_hash); + + if (cfg->token_info_hash) + g_hash_table_destroy (cfg->token_info_hash); + if (cfg->abs_patches) g_hash_table_destroy (cfg->abs_patches); - mono_mempool_destroy (cfg->mempool); mono_debug_free_method (cfg); @@ -1952,6 +1985,18 @@ mono_create_tls_get (MonoCompile *cfg, MonoTlsKey key) if (!cfg->backend->have_tls_get) return NULL; +#ifdef HAVE_KW_THREAD + /* + * MONO_THREAD_VAR_OFFSET definitions don't work when loading mono as a + * dynamic library. This means that we need to be conservative and don't + * aot code that contains these tls chunks. + * + * FIXME Remove HAVE_KW_THREAD altogether and use only pthread since it + * simplifies the code alot. + */ + if (!cfg->full_aot) + cfg->disable_aot = TRUE; +#endif /* * TLS offsets might be different at AOT time, so load them from a GOT slot and * use a different opcode. @@ -2379,7 +2424,7 @@ mono_codegen (MonoCompile *cfg) gboolean is_generic = FALSE; if (cfg->method->is_inflated || mono_method_get_generic_container (cfg->method) || - cfg->method->klass->generic_container || cfg->method->klass->generic_class) { + mono_class_is_gtd (cfg->method->klass) || mono_class_is_ginst (cfg->method->klass)) { is_generic = TRUE; } @@ -3093,8 +3138,8 @@ init_backend (MonoBackend *backend) #ifdef MONO_ARCH_HAVE_OBJC_GET_SELECTOR backend->have_objc_get_selector = 1; #endif -#ifdef MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK - backend->have_generalized_imt_thunk = 1; +#ifdef MONO_ARCH_HAVE_GENERALIZED_IMT_TRAMPOLINE + backend->have_generalized_imt_trampoline = 1; #endif #ifdef MONO_ARCH_GSHARED_SUPPORTED backend->gshared_supported = 1; @@ -3132,6 +3177,9 @@ init_backend (MonoBackend *backend) #ifdef MONO_ARCH_DYN_CALL_PARAM_AREA backend->dyn_call_param_area = MONO_ARCH_DYN_CALL_PARAM_AREA; #endif +#ifdef MONO_ARCH_NO_DIV_WITH_MUL + backend->disable_div_with_mul = 1; +#endif } /* @@ -3241,7 +3289,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->disable_omit_fp = debug_options.disable_omit_fp; cfg->skip_visibility = method->skip_visibility; cfg->orig_method = method; - cfg->gen_seq_points = debug_options.gen_seq_points_compact_data || debug_options.gen_sdb_seq_points; + cfg->gen_seq_points = !debug_options.no_seq_points_compact_data || debug_options.gen_sdb_seq_points; cfg->gen_sdb_seq_points = debug_options.gen_sdb_seq_points; cfg->llvm_only = (flags & JIT_FLAG_LLVM_ONLY) != 0; cfg->backend = current_backend; @@ -3253,6 +3301,11 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->gen_sdb_seq_points = FALSE; } #endif + if (cfg->method->wrapper_type == MONO_WRAPPER_ALLOC) { + /* We can't have seq points inside gc critical regions */ + cfg->gen_seq_points = FALSE; + cfg->gen_sdb_seq_points = FALSE; + } /* coop / nacl requires loop detection to happen */ #if defined(__native_client_codegen__) cfg->opt |= MONO_OPT_LOOP; @@ -3264,6 +3317,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->soft_breakpoints = debug_options.soft_breakpoints; cfg->check_pinvoke_callconv = debug_options.check_pinvoke_callconv; cfg->disable_direct_icalls = disable_direct_icalls; + cfg->direct_pinvoke = (flags & JIT_FLAG_DIRECT_PINVOKE) != 0; if (try_generic_shared) cfg->gshared = TRUE; cfg->compile_llvm = try_llvm; @@ -3284,7 +3338,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->seq_points = g_ptr_array_new (); mono_error_init (&cfg->error); - if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container || method_is_gshared)) { + if (cfg->compile_aot && !try_generic_shared && (method->is_generic || mono_class_is_gtd (method->klass) || method_is_gshared)) { cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED; return cfg; } @@ -3363,6 +3417,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl //g_free (nm); } if (cfg->llvm_only) { + g_free (cfg->exception_message); cfg->disable_aot = TRUE; return cfg; } @@ -4004,7 +4059,7 @@ void mono_cfg_set_exception_invalid_program (MonoCompile *cfg, char *msg) { mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR); - mono_error_set_generic_error (&cfg->error, "System", "InvalidProgramException", msg); + mono_error_set_generic_error (&cfg->error, "System", "InvalidProgramException", "%s", msg); } #endif /* DISABLE_JIT */ @@ -4192,7 +4247,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in if (mono_aot_only) { char *fullname = mono_method_full_name (method, TRUE); - mono_error_set_execution_engine (error, "Attempting to JIT compile method '%s' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.\n", fullname); + mono_error_set_execution_engine (error, "Attempting to JIT compile method '%s' while running in aot-only mode. See https://developer.xamarin.com/guides/ios/advanced_topics/limitations/ for more information.\n", fullname); g_free (fullname); return NULL; @@ -4348,9 +4403,8 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in vtable = mono_class_vtable (target_domain, method->klass); if (!vtable) { - ex = mono_class_get_exception_for_failure (method->klass); - g_assert (ex); - mono_error_set_exception_instance (error, ex); + g_assert (mono_class_has_failure (method->klass)); + mono_error_set_for_class_failure (error, method->klass); return NULL; }