From 7449e51bbadf59857242d6ef800a6ec23c37d63b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Fri, 26 Oct 2018 00:46:28 -0500 Subject: [PATCH] [2018-08][watchos] Use mono_dangerous_add_raw_internal_call for watchOS icalls (#5030) * Add optional mono_dangerous_add_raw_internal_call to exports.t4 * Use mono_dangerous_add_raw_internal_call on watchOS for icall registration Internal calls added with mono_dangerous_add_raw_internal_call run in GC Unsafe mode under cooperative and hybrid suspend, whereas internal calls added with mono_add_internal_call run in GC Safe mode since mono/mono@5756ba4b46f43d4f1c61c0d7dbbcf27a271f24ab in order for hybrid suspend to be a transparent replacement for preemptive suspend (the old default). The icalls in GC Unsafe mode have a responsibility not to block indefinitely without manually performing a thread state transition to GC Safe mode, and in return they avoid a thread state transition when the icall is invoked from a managed method. --- runtime/exports.t4 | 5 +++++ runtime/runtime.m | 25 ++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/runtime/exports.t4 b/runtime/exports.t4 index 17a89b57f63d..19b08dc31757 100644 --- a/runtime/exports.t4 +++ b/runtime/exports.t4 @@ -311,6 +311,11 @@ "const void *", "method" ), + new Export (true, "void", "mono_dangerous_add_raw_internal_call", + "const char *", "name", + "const void *", "method" + ), + new Export ("MonoMethodSignature *", "mono_method_signature", "MonoMethod *", "method" ), diff --git a/runtime/runtime.m b/runtime/runtime.m index 8e829b39a987..9d18b79f2755 100644 --- a/runtime/runtime.m +++ b/runtime/runtime.m @@ -194,6 +194,25 @@ uint8_t flags; }; +static void +xamarin_add_internal_call (const char *name, const void *method) +{ + /* COOP: With cooperative GC, icalls will run, like manageed methods, + * in GC Unsafe mode, avoiding a thread state trandition. In return + * the icalls must guarantee that they won't block, or run indefinitely + * without a safepoint, by manually performing a transition to GC Safe + * mode. With backward-compatible hybrid GC, icalls run in GC Safe + * mode and the Mono API functions take care of thread state + * transitions, so don't need to perform GC thread state transitions + * themselves. + * + */ + if (xamarin_is_gc_coop) + mono_dangerous_add_raw_internal_call (name, method); + else + mono_add_internal_call (name, method); +} + id xamarin_get_nsobject_handle (MonoObject *obj) { @@ -881,7 +900,7 @@ -(void) xamarinSetGCHandle: (int) gc_handle; mono_gc_toggleref_register_callback (gc_toggleref_callback); - mono_add_internal_call (xamarin_use_new_assemblies ? "Foundation.NSObject::RegisterToggleRef" : PRODUCT_COMPAT_NAMESPACE ".Foundation.NSObject::RegisterToggleRef", (const void *) gc_register_toggleref); + xamarin_add_internal_call (xamarin_use_new_assemblies ? "Foundation.NSObject::RegisterToggleRef" : PRODUCT_COMPAT_NAMESPACE ".Foundation.NSObject::RegisterToggleRef", (const void *) gc_register_toggleref); mono_profiler_install ((MonoProfiler *) prof, NULL); mono_profiler_install_gc (gc_event_callback, NULL); } @@ -1359,8 +1378,8 @@ -(void) xamarinSetGCHandle: (int) gc_handle; nsvalue_class = get_class_from_name (platform_image, foundation, "NSValue", true); nsstring_class = get_class_from_name (platform_image, foundation, "NSString", true); - mono_add_internal_call (xamarin_use_new_assemblies ? "Foundation.NSObject::xamarin_release_managed_ref" : PRODUCT_COMPAT_NAMESPACE ".Foundation.NSObject::xamarin_release_managed_ref", (const void *) xamarin_release_managed_ref); - mono_add_internal_call (xamarin_use_new_assemblies ? "Foundation.NSObject::xamarin_create_managed_ref" : PRODUCT_COMPAT_NAMESPACE ".Foundation.NSObject::xamarin_create_managed_ref", (const void *) xamarin_create_managed_ref); + xamarin_add_internal_call (xamarin_use_new_assemblies ? "Foundation.NSObject::xamarin_release_managed_ref" : PRODUCT_COMPAT_NAMESPACE ".Foundation.NSObject::xamarin_release_managed_ref", (const void *) xamarin_release_managed_ref); + xamarin_add_internal_call (xamarin_use_new_assemblies ? "Foundation.NSObject::xamarin_create_managed_ref" : PRODUCT_COMPAT_NAMESPACE ".Foundation.NSObject::xamarin_create_managed_ref", (const void *) xamarin_create_managed_ref); runtime_initialize = mono_class_get_method_from_name (runtime_class, "Initialize", 1);