Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZoltan Varga <vargaz@gmail.com>2016-07-08 06:42:26 +0300
committerZoltan Varga <vargaz@gmail.com>2016-07-08 06:42:26 +0300
commite262b595b2f5a7ae30c17d75b829417062ee1846 (patch)
treef0bf26f74b8edf87aa4b9533c8fb7ee26bd13c89
parentec8e6139f4f7fef01c5d248efdcfa64c882c8233 (diff)
[llvmonly] Fix support for synchronized methods.
-rw-r--r--mono/mini/generics.cs1
-rw-r--r--mono/mini/jit-icalls.c22
-rw-r--r--mono/mini/method-to-ir.c28
-rw-r--r--mono/mini/mini-generic-sharing.c18
-rw-r--r--mono/mini/mini-llvm.c3
-rw-r--r--mono/mini/mini-runtime.c4
-rw-r--r--mono/mini/mini-trampolines.c3
7 files changed, 59 insertions, 20 deletions
diff --git a/mono/mini/generics.cs b/mono/mini/generics.cs
index 1284cb292ae..80638b5048e 100644
--- a/mono/mini/generics.cs
+++ b/mono/mini/generics.cs
@@ -898,6 +898,7 @@ class Tests
}
[Category ("!FULLAOT")]
+ [Category ("!BITCODE")]
public static int test_0_regress_668095_synchronized_gshared () {
return DoSomething (new DefaultRetriever ());
}
diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c
index 8651aa25ec4..d7c6d9a232f 100644
--- a/mono/mini/jit-icalls.c
+++ b/mono/mini/jit-icalls.c
@@ -1630,6 +1630,9 @@ resolve_vcall (MonoVTable *vt, int slot, MonoMethod *imt_method, gpointer *out_a
need_unbox_tramp = TRUE;
}
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
// FIXME: This can throw exceptions
addr = compiled_method = mono_compile_method_checked (m, error);
mono_error_assert_ok (error);
@@ -1751,9 +1754,11 @@ mono_resolve_generic_virtual_iface_call (MonoVTable *vt, int imt_slot, MonoMetho
if (vt->klass->valuetype)
need_unbox_tramp = TRUE;
- // FIXME: This can throw exceptions
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
addr = compiled_method = mono_compile_method_checked (m, &error);
- mono_error_assert_ok (&error);
+ mono_error_raise_exception (&error);
g_assert (addr);
addr = mini_add_method_wrappers_llvmonly (m, addr, FALSE, need_unbox_tramp, &arg);
@@ -1816,12 +1821,16 @@ mono_llvmonly_init_delegate (MonoDelegate *del)
* but we don't have a a structure which could own its memory.
*/
if (G_UNLIKELY (!ftndesc)) {
- gpointer addr = mono_compile_method_checked (del->method, &error);
+ MonoMethod *m = del->method;
+ if (m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ m = mono_marshal_get_synchronized_wrapper (m);
+
+ gpointer addr = mono_compile_method_checked (m, &error);
if (mono_error_set_pending_exception (&error))
return;
- if (del->method->klass->valuetype && mono_method_signature (del->method)->hasthis)
- addr = mono_aot_get_unbox_trampoline (del->method);
+ if (m->klass->valuetype && mono_method_signature (m)->hasthis)
+ addr = mono_aot_get_unbox_trampoline (m);
gpointer arg = mini_get_delegate_arg (del->method, addr);
@@ -1842,6 +1851,9 @@ mono_llvmonly_init_delegate_virtual (MonoDelegate *del, MonoObject *target, Mono
method = mono_object_get_virtual_method (target, method);
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ method = mono_marshal_get_synchronized_wrapper (method);
+
del->method = method;
del->method_ptr = mono_compile_method_checked (method, &error);
if (mono_error_set_pending_exception (&error))
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 348fae0b947..d0232dd540f 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -9746,6 +9746,20 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
inline_costs += 10 * num_calls++;
/*
+ * Synchronized wrappers.
+ * Its hard to determine where to replace a method with its synchronized
+ * wrapper without causing an infinite recursion. The current solution is
+ * to add the synchronized wrapper in the trampolines, and to
+ * change the called method to a dummy wrapper, and resolve that wrapper
+ * to the real method in mono_jit_compile_method ().
+ */
+ if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
+ MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
+ if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
+ cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
+ }
+
+ /*
* Making generic calls out of gsharedvt methods.
* This needs to be used for all generic calls, not just ones with a gsharedvt signature, to avoid
* patching gshared method addresses into a gsharedvt method.
@@ -9964,20 +9978,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
}
}
- /*
- * Synchronized wrappers.
- * Its hard to determine where to replace a method with its synchronized
- * wrapper without causing an infinite recursion. The current solution is
- * to add the synchronized wrapper in the trampolines, and to
- * change the called method to a dummy wrapper, and resolve that wrapper
- * to the real method in mono_jit_compile_method ().
- */
- if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
- MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
- if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
- cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
- }
-
/*
* Virtual calls in llvm-only mode.
*/
diff --git a/mono/mini/mini-generic-sharing.c b/mono/mini/mini-generic-sharing.c
index e1e2eb19b43..aca368c9dba 100644
--- a/mono/mini/mini-generic-sharing.c
+++ b/mono/mini/mini-generic-sharing.c
@@ -607,6 +607,7 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co
MonoMethod *inflated_method;
MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ WrapperInfo *winfo = NULL;
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
MonoJumpInfoGSharedVtCall *res;
@@ -620,7 +621,13 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co
mono_class_init (inflated_class);
- g_assert (!method->wrapper_type);
+ if (method->wrapper_type) {
+ winfo = mono_marshal_get_wrapper_info (method);
+
+ g_assert (winfo);
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ method = winfo->d.synchronized_inner.method;
+ }
if (inflated_class->byval_arg.type == MONO_TYPE_ARRAY ||
inflated_class->byval_arg.type == MONO_TYPE_SZARRAY) {
@@ -633,6 +640,12 @@ inflate_info (MonoRuntimeGenericContextInfoTemplate *oti, MonoGenericContext *co
}
mono_class_init (inflated_method->klass);
g_assert (inflated_method->klass == inflated_class);
+
+ if (winfo) {
+ g_assert (winfo->subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
+ inflated_method = mono_marshal_get_synchronized_inner_wrapper (inflated_method);
+ }
+
res->method = inflated_method;
return res;
@@ -1758,6 +1771,9 @@ instantiate_info (MonoDomain *domain, MonoRuntimeGenericContextInfoTemplate *oti
g_assert (method->is_inflated);
+ if (mono_llvm_only && (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED))
+ method = mono_marshal_get_synchronized_wrapper (method);
+
if (!virtual_) {
addr = mono_compile_method_checked (method, error);
return_val_if_nok (error, NULL);
diff --git a/mono/mini/mini-llvm.c b/mono/mini/mini-llvm.c
index c385f625a29..e2f963bff04 100644
--- a/mono/mini/mini-llvm.c
+++ b/mono/mini/mini-llvm.c
@@ -8680,6 +8680,9 @@ mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
while (g_hash_table_iter_next (&iter, (void**)&method, (void**)&callers)) {
LLVMValueRef lmethod;
+ if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ continue;
+
lmethod = (LLVMValueRef)g_hash_table_lookup (module->method_to_lmethod, method);
if (lmethod) {
for (l = callers; l; l = l->next) {
diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c
index 1bef455a1ee..83420c52244 100644
--- a/mono/mini/mini-runtime.c
+++ b/mono/mini/mini-runtime.c
@@ -1810,6 +1810,10 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoError *er
mono_error_init (error);
+ if (mono_llvm_only)
+ /* Should be handled by the caller */
+ g_assert (!(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED));
+
/*
* ICALL wrappers are handled specially, since there is only one copy of them
* shared by all appdomains.
diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c
index da6f70e82b3..fbc9674fb52 100644
--- a/mono/mini/mini-trampolines.c
+++ b/mono/mini/mini-trampolines.c
@@ -1509,6 +1509,9 @@ mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *e
mono_error_init (error);
if (mono_aot_only) {
+ if (mono_llvm_only && method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)
+ method = mono_marshal_get_synchronized_wrapper (method);
+
/* Avoid creating trampolines if possible */
gpointer code = mono_jit_find_compiled_method (domain, method);