From 47682802b0b1fc90bc4dae5e8ef28281b83c77c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tautvydas=20=C5=BDilys?= Date: Fri, 10 Jul 2020 19:50:07 -0700 Subject: [PATCH 1/2] Use mono_runtime_invoke to invoke finalizers. This way managed runtime can do whatever is necessary to transition to executing managed code, like marking JIT memory executable on macOS ARM64. --- mono/metadata/gc.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 22b0275c98b2..54f8d98d292f 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -335,17 +335,6 @@ mono_gc_run_finalize (void *obj, void *data) if (log_finalizers) g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Compiling finalizer.", o->vtable->klass->name, o); -#ifndef HOST_WASM - if (!domain->finalize_runtime_invoke) { - MonoMethod *invoke = mono_marshal_get_runtime_invoke (mono_class_get_method_from_name_flags (mono_defaults.object_class, "Finalize", 0, 0), TRUE); - - domain->finalize_runtime_invoke = mono_compile_method_checked (invoke, &error); - mono_error_assert_ok (&error); /* expect this not to fail */ - } - - RuntimeInvokeFunction runtime_invoke = (RuntimeInvokeFunction)domain->finalize_runtime_invoke; -#endif - mono_runtime_class_init_full (o->vtable, &error); goto_if_nok (&error, unhandled_error); @@ -359,12 +348,8 @@ mono_gc_run_finalize (void *obj, void *data) MONO_PROFILER_RAISE (gc_finalizing_object, (o)); -#ifdef HOST_WASM gpointer params[] = { NULL }; mono_runtime_try_invoke (finalizer, o, params, &exc, &error); -#else - runtime_invoke (o, NULL, &exc, NULL); -#endif MONO_PROFILER_RAISE (gc_finalized_object, (o)); From 1ad3768368db98d29502a7f78ae13f7e149a7180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tautvydas=20=C5=BDilys?= Date: Sat, 11 Jul 2020 17:56:56 -0700 Subject: [PATCH 2/2] Add a null check before invoking finalizer. Before, we would do a callvirt Finalize() on the object and if it didn't have a finalizer, it would call Object::Finalize(). However, since now we use mono_method_invoke with a concrete method, we crash if it's null. So we just --- mono/metadata/gc.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 54f8d98d292f..227b555833e2 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -327,14 +327,6 @@ mono_gc_run_finalize (void *obj, void *data) return; } - /* - * To avoid the locking plus the other overhead of mono_runtime_invoke_checked (), - * create and precompile a wrapper which calls the finalize method using - * a CALLVIRT. - */ - if (log_finalizers) - g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Compiling finalizer.", o->vtable->klass->name, o); - mono_runtime_class_init_full (o->vtable, &error); goto_if_nok (&error, unhandled_error); @@ -343,18 +335,20 @@ mono_gc_run_finalize (void *obj, void *data) o->vtable->klass->name_space, o->vtable->klass->name); } - if (log_finalizers) - g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o->vtable->klass->name, o); + if (finalizer) { + if (log_finalizers) + g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Calling finalizer.", o->vtable->klass->name, o); - MONO_PROFILER_RAISE (gc_finalizing_object, (o)); + MONO_PROFILER_RAISE (gc_finalizing_object, (o)); - gpointer params[] = { NULL }; - mono_runtime_try_invoke (finalizer, o, params, &exc, &error); + gpointer params[] = { NULL }; + mono_runtime_try_invoke (finalizer, o, params, &exc, &error); - MONO_PROFILER_RAISE (gc_finalized_object, (o)); + MONO_PROFILER_RAISE (gc_finalized_object, (o)); - if (log_finalizers) - g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o->vtable->klass->name, o); + if (log_finalizers) + g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Returned from finalizer.", o->vtable->klass->name, o); + } unhandled_error: if (!is_ok (&error))