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;
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);
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);
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;
}
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);
} 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);
}
}