diff options
author | Zoltan Varga <vargaz@gmail.com> | 2004-09-07 15:10:30 +0400 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2004-09-07 15:10:30 +0400 |
commit | d2db8246a3757b59cee42fa84dda6b75e939bfde (patch) | |
tree | 233302dd5ab910904a0a0f6ed6eb6773dd774d57 | |
parent | 69cc6c891fe5134c6391bb23e3329b1cce05048b (diff) |
2004-09-07 Zoltan Varga <vargaz@freemail.hu>
* mini.c mini.h mini-x86.h tramp-x86.c: Instead of freeing delegate
trampolines, make them call an error function so people can fix their
code.
svn path=/trunk/mono/; revision=33486
-rw-r--r-- | mono/mini/ChangeLog | 6 | ||||
-rw-r--r-- | mono/mini/mini-x86.h | 2 | ||||
-rw-r--r-- | mono/mini/mini.c | 21 | ||||
-rw-r--r-- | mono/mini/mini.h | 2 | ||||
-rw-r--r-- | mono/mini/tramp-x86.c | 10 |
5 files changed, 40 insertions, 1 deletions
diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 6f0908b50ac..ec8b0246ef7 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,9 @@ +2004-09-07 Zoltan Varga <vargaz@freemail.hu> + + * mini.c mini.h mini-x86.h tramp-x86.c: Instead of freeing delegate + trampolines, make them call an error function so people can fix their + code. + 2004-09-06 Martin Baulig <martin@ximian.com> * mini.c (mono_method_to_ir): When initializing locals, handle a diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h index d187d320654..93af9c07d44 100644 --- a/mono/mini/mini-x86.h +++ b/mono/mini/mini-x86.h @@ -157,5 +157,7 @@ typedef struct sigcontext MonoContext; #define MONO_ARCH_NEED_DIV_CHECK 1 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1 +#define MONO_ARCH_HAVE_INVALIDATE_METHOD 1 + #endif /* __MONO_MINI_X86_H__ */ diff --git a/mono/mini/mini.c b/mono/mini/mini.c index ba3be30eeea..ad6c1d158c1 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -8010,6 +8010,12 @@ mono_jit_compile_method (MonoMethod *method) return mono_jit_compile_method_with_opt (method, default_opt); } +static void +invalidated_delegate_trampoline (MonoClass *klass) +{ + g_error ("Unmanaged code called delegate of type %s which was already garbage collected.\n See http://blogs.msdn.com/adam_nathan/archive/2003/06/01/56693.aspx for an explanation and ways to fix this.", mono_type_full_name (&klass->byval_arg)); +} + /* * mono_jit_free_method: * @@ -8022,6 +8028,21 @@ mono_jit_free_method (MonoMethod *method) g_assert (method->dynamic); +#ifdef MONO_ARCH_HAVE_INVALIDATE_METHOD + if (method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) { + /* + * Instead of freeing the code, change it to call an error routine + * so people can fix their code. + */ + EnterCriticalSection (&jit_mutex); + ji = g_hash_table_lookup (dynamic_code_hash, method); + LeaveCriticalSection (&jit_mutex); + if (ji) + mono_arch_invalidate_method (ji->ji, invalidated_delegate_trampoline, method->klass); + return; + } +#endif + EnterCriticalSection (&jit_mutex); ji = g_hash_table_lookup (dynamic_code_hash, method); if (!ji) { diff --git a/mono/mini/mini.h b/mono/mini/mini.h index d31cac86a1d..d9e098cf8f4 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -795,7 +795,7 @@ gboolean mono_arch_is_inst_imm (gint64 imm); MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg); MonoInst* mono_arch_get_thread_intrinsic (MonoCompile* cfg); gboolean mono_arch_is_int_overflow (void *sigctx); -gboolean mono_arch_can_inline_alloc (MonoVTable *vtable); +void mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg); /* Exception handling */ gboolean mono_handle_exception (MonoContext *ctx, gpointer obj, diff --git a/mono/mini/tramp-x86.c b/mono/mini/tramp-x86.c index 51b1f0a28ef..0cf283432cf 100644 --- a/mono/mini/tramp-x86.c +++ b/mono/mini/tramp-x86.c @@ -458,6 +458,16 @@ mono_arch_create_class_init_trampoline (MonoVTable *vtable) return code; } +void +mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg) +{ + /* FIXME: This is not thread safe */ + guint8 *code = ji->code_start; + + x86_push_imm (code, func_arg); + x86_call_code (code, (guint8*)func); +} + /* * This method is only called when running in the Mono Debugger. */ |