[runtime] MonoError-ize mono_compile_method
[mono.git] / mono / mini / mini.c
index 94062ec4b84ef71dcc6d6b01c97042e268f4f217..9bb50e93302e010f63c3f7bd77b69f07dd125414 100644 (file)
@@ -192,114 +192,15 @@ guint8 *mono_nacl_align(guint8 *code) {
 
 void mono_nacl_fix_patches(const guint8 *code, MonoJumpInfo *ji)
 {
-#ifndef USE_JUMP_TABLES
   MonoJumpInfo *patch_info;
   for (patch_info = ji; patch_info; patch_info = patch_info->next) {
     unsigned char *ip = patch_info->ip.i + code;
     ip = mono_arch_nacl_skip_nops(ip);
     patch_info->ip.i = ip - code;
   }
-#endif
 }
 #endif  /* __native_client_codegen__ */
 
-#ifdef USE_JUMP_TABLES
-
-#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
-
-typedef struct MonoJumpTableChunk {
-       guint32 total;
-       guint32 active;
-       struct MonoJumpTableChunk *previous;
-       /* gpointer entries[total]; */
-} MonoJumpTableChunk;
-
-static MonoJumpTableChunk* g_jumptable;
-#define mono_jumptable_lock() mono_os_mutex_lock (&jumptable_mutex)
-#define mono_jumptable_unlock() mono_os_mutex_unlock (&jumptable_mutex)
-static mono_mutex_t jumptable_mutex;
-
-static  MonoJumpTableChunk*
-mono_create_jumptable_chunk (guint32 max_entries)
-{
-       guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
-       MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
-       chunk->total = max_entries;
-       return chunk;
-}
-
-void
-mono_jumptable_init (void)
-{
-       if (g_jumptable == NULL) {
-               mono_os_mutex_init_recursive (&jumptable_mutex);
-               g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
-       }
-}
-
-gpointer*
-mono_jumptable_add_entry (void)
-{
-       return mono_jumptable_add_entries (1);
-}
-
-gpointer*
-mono_jumptable_add_entries (guint32 entries)
-{
-       guint32 index;
-       gpointer *result;
-
-       mono_jumptable_init ();
-       mono_jumptable_lock ();
-       index = g_jumptable->active;
-       if (index + entries >= g_jumptable->total) {
-               /*
-                * Grow jumptable, by adding one more chunk.
-                * We cannot realloc jumptable, as there could be pointers
-                * to existing jump table entries in the code, so instead
-                * we just add one more chunk.
-                */
-               guint32 max_entries = entries;
-               MonoJumpTableChunk *new_chunk;
-
-               if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
-                       max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
-               new_chunk = mono_create_jumptable_chunk (max_entries);
-               /* Link old jumptable, so that we could free it up later. */
-               new_chunk->previous = g_jumptable;
-               g_jumptable = new_chunk;
-               index = 0;
-       }
-       g_jumptable->active = index + entries;
-       result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
-       mono_jumptable_unlock();
-
-       return result;
-}
-
-void
-mono_jumptable_cleanup (void)
-{
-       if (g_jumptable) {
-               MonoJumpTableChunk *current = g_jumptable, *prev;
-               while (current != NULL) {
-                       prev = current->previous;
-                       g_free (current);
-                       current = prev;
-               }
-               g_jumptable = NULL;
-               mono_os_mutex_destroy (&jumptable_mutex);
-       }
-}
-
-gpointer*
-mono_jumptable_get_entry (guint8 *code_ptr)
-{
-       return mono_arch_jumptable_entry_from_code (code_ptr);
-}
-
-#endif /* USE_JUMP_TABLES */
-
 typedef struct {
        MonoExceptionClause *clause;
        MonoBasicBlock *basic_block;
@@ -3143,6 +3044,10 @@ static void
 mono_create_gc_safepoint (MonoCompile *cfg, MonoBasicBlock *bblock)
 {
        MonoInst *poll_addr, *ins;
+
+       if (cfg->disable_gc_safe_points)
+               return;
+
        if (cfg->verbose_level > 1)
                printf ("ADDING SAFE POINT TO BB %d\n", bblock->block_num);
 
@@ -3228,8 +3133,7 @@ mono_insert_safepoints (MonoCompile *cfg)
 
                if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER &&
                        (info->d.icall.func == mono_thread_interruption_checkpoint ||
-                       info->d.icall.func == mono_threads_finish_blocking ||
-                       info->d.icall.func == mono_threads_reset_blocking_start)) {
+                       info->d.icall.func == mono_threads_exit_gc_safe_region_unbalanced)) {
                        /* These wrappers are called from the wrapper for the polling function, leading to potential stack overflow */
                        if (cfg->verbose_level > 1)
                                printf ("SKIPPING SAFEPOINTS for wrapper %s\n", cfg->method->name);
@@ -3645,6 +3549,17 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
 
        mini_gc_init_cfg (cfg);
 
+       if (method->wrapper_type == MONO_WRAPPER_UNKNOWN) {
+               WrapperInfo *info = mono_marshal_get_wrapper_info (method);
+
+               /* These wrappers are using linkonce linkage, so they can't access GOT slots */
+               if ((info && (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG || info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG))) {
+                       cfg->disable_gc_safe_points = TRUE;
+                       /* This is safe, these wrappers only store to the stack */
+                       cfg->gen_write_barriers = FALSE;
+               }
+       }
+
        if (COMPILE_LLVM (cfg)) {
                cfg->opt |= MONO_OPT_ABCREM;
        }
@@ -4301,7 +4216,9 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                                mono_lookup_pinvoke_call (method, NULL, NULL);
                }
                nm = mono_marshal_get_native_wrapper (method, TRUE, mono_aot_only);
-               code = mono_get_addr_from_ftnptr (mono_compile_method (nm));
+               gpointer compiled_method = mono_compile_method_checked (nm, error);
+               return_val_if_nok (error, NULL);
+               code = mono_get_addr_from_ftnptr (compiled_method);
                jinfo = mono_jit_info_table_find (target_domain, (char *)code);
                if (!jinfo)
                        jinfo = mono_jit_info_table_find (mono_domain_get (), (char *)code);
@@ -4331,15 +4248,21 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                        } else if (*name == 'I' && (strcmp (name, "Invoke") == 0)) {
                                if (mono_llvm_only) {
                                        nm = mono_marshal_get_delegate_invoke (method, NULL);
-                                       return mono_get_addr_from_ftnptr (mono_compile_method (nm));
+                                       gpointer compiled_ptr = mono_compile_method_checked (nm, error);
+                                       mono_error_assert_ok (error);
+                                       return mono_get_addr_from_ftnptr (compiled_ptr);
                                }
                                return mono_create_delegate_trampoline (target_domain, method->klass);
                        } else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0)) {
                                nm = mono_marshal_get_delegate_begin_invoke (method);
-                               return mono_get_addr_from_ftnptr (mono_compile_method (nm));
+                               gpointer compiled_ptr = mono_compile_method_checked (nm, error);
+                               mono_error_assert_ok (error);
+                               return mono_get_addr_from_ftnptr (compiled_ptr);
                        } else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0)) {
                                nm = mono_marshal_get_delegate_end_invoke (method);
-                               return mono_get_addr_from_ftnptr (mono_compile_method (nm));
+                               gpointer compiled_ptr = mono_compile_method_checked (nm, error);
+                               mono_error_assert_ok (error);
+                               return mono_get_addr_from_ftnptr (compiled_ptr);
                        }
                }