Merge pull request #4621 from alexanderkyte/strdup_env
[mono.git] / mono / mini / mini-runtime.c
index 9c3f28cbb8f6075370b2a9d6d7a1ef40df7d29da..190af5cec63edf4eb598a5d9811ec21587a59e26 100644 (file)
@@ -1,6 +1,6 @@
-
-/*
- * mini-runtime.c: Runtime code for the JIT
+/**
+ * \file
+ * Runtime code for the JIT
  *
  * Authors:
  *   Paolo Molaro (lupus@ximian.com)
@@ -218,15 +218,15 @@ get_method_from_ip (void *ip)
 
 /**
  * mono_pmip:
- * @ip: an instruction pointer address
+ * \param ip an instruction pointer address
  *
  * This method is used from a debugger to get the name of the
- * method at address @ip.   This routine is typically invoked from
+ * method at address \p ip.   This routine is typically invoked from
  * a debugger like this:
  *
  * (gdb) print mono_pmip ($pc)
  *
- * Returns: the name of the method at address @ip.
+ * \returns the name of the method at address \p ip.
  */
 G_GNUC_UNUSED char *
 mono_pmip (void *ip)
@@ -235,21 +235,17 @@ mono_pmip (void *ip)
 }
 
 /**
- * mono_print_method_from_ip
- * @ip: an instruction pointer address
+ * mono_print_method_from_ip:
+ * \param ip an instruction pointer address
  *
  * This method is used from a debugger to get the name of the
- * method at address @ip.
+ * method at address \p ip.
  *
- * This prints the name of the method at address @ip in the standard
- * output.  Unlike mono_pmip which returns a string, this routine
+ * This prints the name of the method at address \p ip in the standard
+ * output.  Unlike \c mono_pmip which returns a string, this routine
  * prints the value on the standard output.
  */
-#ifdef __GNUC__
-/* Prevent the linker from optimizing this away in embedding setups to help debugging */
- __attribute__ ((__used__))
-#endif
-void
+MONO_ATTR_USED void
 mono_print_method_from_ip (void *ip)
 {
        MonoJitInfo *ji;
@@ -474,8 +470,8 @@ register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info)
  * INFO can be NULL.
  * Frees INFO.
  */
-void
-mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
+static void
+mono_tramp_info_register_internal (MonoTrampInfo *info, MonoDomain *domain, gboolean aot)
 {
        MonoTrampInfo *copy;
 
@@ -506,7 +502,8 @@ mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
        mono_lldb_save_trampoline_info (info);
 
 #ifdef MONO_ARCH_HAVE_UNWIND_TABLE
-       mono_arch_unwindinfo_install_tramp_unwind_info (info->unwind_ops, info->code, info->code_size);
+       if (!aot)
+               mono_arch_unwindinfo_install_tramp_unwind_info (info->unwind_ops, info->code, info->code_size);
 #endif
 
        /* Only register trampolines that have unwind infos */
@@ -519,6 +516,18 @@ mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
        mono_tramp_info_free (info);
 }
 
+void
+mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
+{
+       mono_tramp_info_register_internal (info, domain, FALSE);
+}
+
+void
+mono_aot_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
+{
+       mono_tramp_info_register_internal (info, domain, TRUE);
+}
+
 static void
 mono_tramp_info_cleanup (void)
 {
@@ -722,9 +731,6 @@ register_dyn_icall (gpointer func, const char *name, const char *sigstr, gboolea
 MonoLMF *
 mono_get_lmf (void)
 {
-#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR)
-       return (MonoLMF *)mono_tls_get_lmf ();
-#else
        MonoJitTlsData *jit_tls;
 
        if ((jit_tls = mono_tls_get_jit_tls ()))
@@ -735,7 +741,6 @@ mono_get_lmf (void)
         * (the thread object allocation can trigger a collection).
         */
        return NULL;
-#endif
 }
 
 MonoLMF **
@@ -747,11 +752,7 @@ mono_get_lmf_addr (void)
 void
 mono_set_lmf (MonoLMF *lmf)
 {
-#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR)
-       mono_tls_set_lmf (lmf);
-#else
        (*mono_get_lmf_addr ()) = lmf;
-#endif
 }
 
 MonoJitTlsData*
@@ -841,9 +842,8 @@ mono_jit_set_domain (MonoDomain *domain)
 
 /**
  * mono_thread_abort:
- * @obj: exception object
- *
- * abort the thread, print exception information and stack trace
+ * \param obj exception object
+ * Abort the thread, print exception information and stack trace
  */
 static void
 mono_thread_abort (MonoObject *obj)
@@ -883,23 +883,9 @@ setup_jit_tls_data (gpointer stack_start, gpointer abort_func)
 
        jit_tls->first_lmf = lmf;
 
-       /*
-        * We can have 2 configurations for accessing lmf.
-        * We can use only the tls_lmf_addr variable, which will store the address of
-        * jit_tls->lmf, or, if we have MONO_ARCH_ENABLE_MONO_LMF_VAR enabled, we can
-        * use both tls_lmf_addr and tls_lmf variables (in this case we need to have
-        * means of getting the address of a tls variable; this can be done always
-        * when using __thread or, on osx, even when using pthread)
-        */
-#if defined(MONO_ARCH_ENABLE_MONO_LMF_VAR) && defined(HAVE_GET_TLS_ADDR)
-       /* jit_tls->lmf is unused */
-       mono_tls_set_lmf (lmf);
-       mono_set_lmf_addr (mono_tls_get_tls_addr (TLS_KEY_LMF));
-#else
        mono_set_lmf_addr (&jit_tls->lmf);
 
        jit_tls->lmf = lmf;
-#endif
 
 #ifdef MONO_ARCH_HAVE_TLS_INIT
        mono_arch_tls_init ();
@@ -1768,7 +1754,7 @@ no_gsharedvt_in_wrapper (void)
 }
 
 static gpointer
-mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *error)
+mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, gboolean jit_only, MonoError *error)
 {
        MonoDomain *target_domain, *domain = mono_domain_get ();
        MonoJitInfo *info;
@@ -1780,8 +1766,11 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er
        error_init (error);
 
 #ifdef ENABLE_INTERPRETER
-       if (mono_use_interpreter)
-               return mono_interp_create_method_pointer (method, error);
+       if (mono_use_interpreter && !jit_only) {
+               code = mono_interp_create_method_pointer (method, error);
+               if (code)
+                       return code;
+       }
 #endif
 
        if (mono_llvm_only)
@@ -1938,7 +1927,21 @@ mono_jit_compile_method (MonoMethod *method, MonoError *error)
 {
        gpointer code;
 
-       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), error);
+       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), FALSE, error);
+       return code;
+}
+
+/*
+ * mono_jit_compile_method_jit_only:
+ *
+ *   Compile METHOD using the JIT/AOT, even in interpreted mode.
+ */
+gpointer
+mono_jit_compile_method_jit_only (MonoMethod *method, MonoError *error)
+{
+       gpointer code;
+
+       code = mono_jit_compile_method_with_opt (method, mono_get_optimizations_for_method (method, default_opt), TRUE, error);
        return code;
 }
 
@@ -2350,13 +2353,14 @@ mono_llvmonly_runtime_invoke (MonoMethod *method, RuntimeInvokeInfo *info, void
 
 /**
  * mono_jit_runtime_invoke:
- * @method: the method to invoke
- * @obj: this pointer
- * @params: array of parameter values.
- * @exc: Set to the exception raised in the managed method.  If NULL, error is thrown instead.
- *       If coop is enabled, this argument is ignored - all exceptoins are caught and propagated
- *       through @error
- * @error: error or caught exception object
+ * \param method: the method to invoke
+ * \param obj: this pointer
+ * \param params: array of parameter values.
+ * \param exc: Set to the exception raised in the managed method.
+ * \param error: error or caught exception object
+ * If \p exc is NULL, \p error is thrown instead.
+ * If coop is enabled, \p exc argument is ignored -
+ * all exceptions are caught and propagated through \p error
  */
 static MonoObject*
 mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc, MonoError *error)
@@ -2424,7 +2428,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                }
 
                if (callee) {
-                       compiled_method = mono_jit_compile_method_with_opt (callee, mono_get_optimizations_for_method (callee, default_opt), error);
+                       compiled_method = mono_jit_compile_method (callee, error);
                        if (!compiled_method) {
                                g_assert (!mono_error_ok (error));
                                return NULL;
@@ -3371,6 +3375,7 @@ mini_create_jit_domain_info (MonoDomain *domain)
        info->seq_points = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, mono_seq_point_info_free);
        info->arch_seq_points = g_hash_table_new (mono_aligned_addr_hash, NULL);
        info->jump_target_hash = g_hash_table_new (NULL, NULL);
+       mono_jit_code_hash_init (&info->interp_code_hash);
 
        domain->runtime_info = info;
 }
@@ -3836,7 +3841,7 @@ register_icalls (void)
                register_icall (mono_threads_state_poll, "mono_threads_state_poll", "void", FALSE);
 
 #ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
-       register_opcode_emulation (OP_LMUL, "__emul_lmul", "long long long", mono_llmult, "mono_llmult", TRUE);
+       register_opcode_emulation (OP_LMUL, "__emul_lmul", "long long long", mono_llmult, "mono_llmult", FALSE);
        register_opcode_emulation (OP_LDIV, "__emul_ldiv", "long long long", mono_lldiv, "mono_lldiv", FALSE);
        register_opcode_emulation (OP_LDIV_UN, "__emul_ldiv_un", "long long long", mono_lldiv_un, "mono_lldiv_un", FALSE);
        register_opcode_emulation (OP_LREM, "__emul_lrem", "long long long", mono_llrem, "mono_llrem", FALSE);
@@ -4039,13 +4044,11 @@ register_icalls (void)
        register_icall_no_wrapper (mono_tls_get_thread, "mono_tls_get_thread", "ptr");
        register_icall_no_wrapper (mono_tls_get_jit_tls, "mono_tls_get_jit_tls", "ptr");
        register_icall_no_wrapper (mono_tls_get_domain, "mono_tls_get_domain", "ptr");  
-       register_icall_no_wrapper (mono_tls_get_lmf, "mono_tls_get_lmf", "ptr");
        register_icall_no_wrapper (mono_tls_get_sgen_thread_info, "mono_tls_get_sgen_thread_info", "ptr");
        register_icall_no_wrapper (mono_tls_get_lmf_addr, "mono_tls_get_lmf_addr", "ptr");
        register_icall_no_wrapper (mono_tls_set_thread, "mono_tls_set_thread", "void ptr");
        register_icall_no_wrapper (mono_tls_set_jit_tls, "mono_tls_set_jit_tls", "void ptr");
        register_icall_no_wrapper (mono_tls_set_domain, "mono_tls_set_domain", "void ptr");
-       register_icall_no_wrapper (mono_tls_set_lmf, "mono_tls_set_lmf", "void ptr");
        register_icall_no_wrapper (mono_tls_set_sgen_thread_info, "mono_tls_set_sgen_thread_info", "void ptr");
        register_icall_no_wrapper (mono_tls_set_lmf_addr, "mono_tls_set_lmf_addr", "void ptr");
 }
@@ -4215,10 +4218,9 @@ mono_set_verbose_level (guint32 level)
 
 /**
  * mono_get_runtime_build_info:
- *
- * Return the runtime version + build date in string format.
  * The returned string is owned by the caller. The returned string
- * format is "VERSION (FULL_VERSION BUILD_DATE)" and build date is optional.
+ * format is <code>VERSION (FULL_VERSION BUILD_DATE)</code> and build date is optional.
+ * \returns the runtime version + build date in string format.
  */
 char*
 mono_get_runtime_build_info (void)