Merge pull request #1936 from esdrubal/DotNetRelativeOrAbsolute
[mono.git] / mono / metadata / marshal.c
index c1b0ae86d127afb609f6169b75df521f954b5a2b..4c6ae67820d24b42774f5805cb50cda488060a20 100644 (file)
@@ -244,8 +244,8 @@ mono_marshal_init (void)
 #ifdef USE_COOP_GC
                register_icall (mono_threads_prepare_blocking, "mono_threads_prepare_blocking", "int", FALSE);
                register_icall (mono_threads_finish_blocking, "mono_threads_finish_blocking", "void int", FALSE);
-               register_icall (mono_threads_reset_blocking_start, "mono_threads_reset_blocking_start","int", FALSE);
-               register_icall (mono_threads_reset_blocking_end, "mono_threads_reset_blocking_end","void int", FALSE);
+               register_icall (mono_threads_reset_blocking_start, "mono_threads_reset_blocking_start","int", TRUE);
+               register_icall (mono_threads_reset_blocking_end, "mono_threads_reset_blocking_end","void int", TRUE);
 #endif
        }
 }
@@ -11112,6 +11112,9 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        GHashTable *cache;
        MonoMethod *res;
        int i, param_count, sig_size, pos_leave;
+#ifdef USE_COOP_GC
+       int coop_gc_var;
+#endif
 
        g_assert (method);
 
@@ -11165,11 +11168,23 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        if (!MONO_TYPE_IS_VOID (sig->ret))
                mono_mb_add_local (mb, sig->ret);
 
+#ifdef USE_COOP_GC
+       /* local 4, the local to be used when calling the reset_blocking funcs */
+       /* tons of code hardcode 3 to be the return var */
+       coop_gc_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+#endif
+
        /* clear exception arg */
        mono_mb_emit_ldarg (mb, param_count - 1);
        mono_mb_emit_byte (mb, CEE_LDNULL);
        mono_mb_emit_byte (mb, CEE_STIND_REF);
 
+#ifdef USE_COOP_GC
+       /* FIXME this is technically wrong as the callback itself must be executed in gc unsafe context. */
+       mono_mb_emit_icall (mb, mono_threads_reset_blocking_start);
+       mono_mb_emit_stloc (mb, coop_gc_var);
+#endif
+
        /* try */
        clause = mono_image_alloc0 (image, sizeof (MonoExceptionClause));
        clause->try_offset = mono_mb_get_label (mb);
@@ -11239,6 +11254,12 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
                        mono_mb_emit_op (mb, CEE_BOX, mono_class_from_mono_type (sig->ret));
        }
 
+#ifdef USE_COOP_GC
+       /* XXX merge reset_blocking_end with detach */
+       mono_mb_emit_ldloc (mb, coop_gc_var);
+       mono_mb_emit_icall (mb, mono_threads_reset_blocking_end);
+#endif
+
        mono_mb_emit_byte (mb, CEE_RET);
 #endif
 
@@ -11278,12 +11299,3 @@ mono_marshal_free_dynamic_wrappers (MonoMethod *method)
        if (marshal_mutex_initialized)
                mono_marshal_unlock ();
 }
-
-static gboolean
-signature_pointer_pair_matches_signature (gpointer key, gpointer value, gpointer user_data)
-{
-       SignaturePointerPair *pair = (SignaturePointerPair*)key;
-       MonoMethodSignature *sig = (MonoMethodSignature*)user_data;
-
-       return mono_metadata_signature_equal (pair->sig, sig);
-}