From 29b07ab3ad3bc7cea2178035a94dfb61ddf6bb4a Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Mon, 3 Aug 2015 14:47:11 -0400 Subject: [PATCH] [runtime] Move AsyncResult.Invoke to managed --- .../System/System.Diagnostics/Process.cs | 2 +- .../System.Net.Sockets/SocketAsyncResult.cs | 2 +- .../AsyncResult.cs | 24 ++++- .../MonoMethodMessage.cs | 4 +- mcs/class/corlib/System/Environment.cs | 2 +- mcs/class/corlib/System/MonoAsyncCall.cs | 29 +++--- mono/metadata/appdomain.c | 2 +- mono/metadata/icall-def.h | 4 +- mono/metadata/object-internals.h | 10 +- mono/metadata/object.c | 93 ++++++------------- mono/metadata/threadpool-ms.c | 11 ++- 11 files changed, 81 insertions(+), 102 deletions(-) diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs index a7c793bedbf..dc2614c6749 100644 --- a/mcs/class/System/System.Diagnostics/Process.cs +++ b/mcs/class/System/System.Diagnostics/Process.cs @@ -1496,7 +1496,7 @@ namespace System.Diagnostics { void IThreadPoolWorkItem.ExecuteWorkItem() { - async_result.Invoke (); + ((IThreadPoolWorkItem) async_result).ExecuteWorkItem (); } void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) diff --git a/mcs/class/System/System.Net.Sockets/SocketAsyncResult.cs b/mcs/class/System/System.Net.Sockets/SocketAsyncResult.cs index f1cd229d865..467cafa139a 100644 --- a/mcs/class/System/System.Net.Sockets/SocketAsyncResult.cs +++ b/mcs/class/System/System.Net.Sockets/SocketAsyncResult.cs @@ -304,7 +304,7 @@ namespace System.Net.Sockets void IThreadPoolWorkItem.ExecuteWorkItem() { - async_result.Invoke (); + ((IThreadPoolWorkItem) async_result).ExecuteWorkItem (); if (completed && callback != null) { ThreadPool.UnsafeQueueCustomWorkItem (new AsyncResult (state => callback ((IAsyncResult) state), this, false), false); diff --git a/mcs/class/corlib/System.Runtime.Remoting.Messaging/AsyncResult.cs b/mcs/class/corlib/System.Runtime.Remoting.Messaging/AsyncResult.cs index 4d93c4a7575..bf696a37c29 100644 --- a/mcs/class/corlib/System.Runtime.Remoting.Messaging/AsyncResult.cs +++ b/mcs/class/corlib/System.Runtime.Remoting.Messaging/AsyncResult.cs @@ -32,6 +32,7 @@ using System; using System.Threading; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -207,14 +208,29 @@ public class AsyncResult : IAsyncResult, IMessageSink, IThreadPoolWorkItem { void IThreadPoolWorkItem.ExecuteWorkItem() { - Invoke (); + if (async_call == null) { + ((WaitCallback) async_delegate) (async_state); + } else { + try { + async_call.result = async_call.message.Invoke (async_delegate, out async_call.out_args); + async_call.message.exc = null; + } catch (Exception e) { + async_call.message.exc = e; + } + + lock (this) { + completed = true; + if (handle != null) + ((ManualResetEvent) handle).Set (); + } + + if (async_call.callback != null) + async_call.callback (this); + } } void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { } - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal extern object Invoke (); } } diff --git a/mcs/class/corlib/System.Runtime.Remoting.Messaging/MonoMethodMessage.cs b/mcs/class/corlib/System.Runtime.Remoting.Messaging/MonoMethodMessage.cs index 3b324d1eab7..f366e7fcbde 100644 --- a/mcs/class/corlib/System.Runtime.Remoting.Messaging/MonoMethodMessage.cs +++ b/mcs/class/corlib/System.Runtime.Remoting.Messaging/MonoMethodMessage.cs @@ -371,7 +371,9 @@ namespace System.Runtime.Remoting.Messaging { } return outCount > 0 || res; } - + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern object Invoke (object target, out object[] out_args); } internal enum CallType: int diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs index c6b01d789c9..81cad6caa28 100644 --- a/mcs/class/corlib/System/Environment.cs +++ b/mcs/class/corlib/System/Environment.cs @@ -57,7 +57,7 @@ namespace System { * of icalls, do not require an increment. */ #pragma warning disable 169 - private const int mono_corlib_version = 135; + private const int mono_corlib_version = 136; #pragma warning restore 169 [ComVisible (true)] diff --git a/mcs/class/corlib/System/MonoAsyncCall.cs b/mcs/class/corlib/System/MonoAsyncCall.cs index e6944a1bc4d..d996c0a8b31 100644 --- a/mcs/class/corlib/System/MonoAsyncCall.cs +++ b/mcs/class/corlib/System/MonoAsyncCall.cs @@ -3,7 +3,7 @@ // // Author: // Zoltan Varga (vargaz@gmail.com) -// +// Ludovic Henry (ludovic@xamarin.com) // // @@ -30,24 +30,31 @@ // // -// This is the managed counterpart of the ASyncCall structure used by the threadpools. +// This is the managed counterpart of the MonoAsyncCall structure used by the threadpools. // using System.Runtime.InteropServices; +using System.Runtime.Remoting.Messaging; namespace System { #pragma warning disable 169 [StructLayout (LayoutKind.Sequential)] - internal class MonoAsyncCall { - #region Sync with the unmanaged ASyncCall structure - object msg; - IntPtr cb_method; - object cb_target; - object state; - object res; - object out_args; - #endregion + internal class MonoAsyncCall + { + /* + * Keep in sync with runtime structure MonoAsyncCall + */ + + internal MonoMethodMessage message; + + internal AsyncCallback callback; + + internal object state; + + internal object result; + + internal object[] out_args; } #pragma warning restore 169 diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 2bfa5457e77..4685be77672 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -79,7 +79,7 @@ * Changes which are already detected at runtime, like the addition * of icalls, do not require an increment. */ -#define MONO_CORLIB_VERSION 135 +#define MONO_CORLIB_VERSION 136 typedef struct { diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 677769c97e5..3187a6b3876 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -705,11 +705,9 @@ ICALL_TYPE(CONTEXT, "System.Runtime.Remoting.Contexts.Context", CONTEXT_1) ICALL(CONTEXT_1, "RegisterContext", ves_icall_System_Runtime_Remoting_Contexts_Context_RegisterContext) ICALL(CONTEXT_2, "ReleaseContext", ves_icall_System_Runtime_Remoting_Contexts_Context_ReleaseContext) -ICALL_TYPE(ARES, "System.Runtime.Remoting.Messaging.AsyncResult", ARES_1) -ICALL(ARES_1, "Invoke", ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke) - ICALL_TYPE(MONOMM, "System.Runtime.Remoting.Messaging.MonoMethodMessage", MONOMM_1) ICALL(MONOMM_1, "InitMessage", ves_icall_MonoMethodMessage_InitMessage) +ICALL(MONOMM_2, "Invoke", ves_icall_System_Runtime_Remoting_Messaging_MonoMethodMessage_Invoke) #ifndef DISABLE_REMOTING ICALL_TYPE(REALP, "System.Runtime.Remoting.Proxies.RealProxy", REALP_1) diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index b41f2351351..e07acc2bedd 100644 --- a/mono/metadata/object-internals.h +++ b/mono/metadata/object-internals.h @@ -358,8 +358,7 @@ typedef struct { struct _MonoAsyncCall { MonoObject object; MonoMethodMessage *msg; - MonoMethod *cb_method; - MonoDelegate *cb_target; + MonoDelegate *callback; MonoObject *state; MonoObject *res; MonoArray *out_args; @@ -634,9 +633,6 @@ MONO_COLD void mono_set_pending_exception (MonoException *exc); MonoAsyncResult * mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data); -MonoObject * -ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this); - MonoWaitHandle * mono_wait_handle_new (MonoDomain *domain, HANDLE handle); @@ -648,8 +644,8 @@ mono_message_init (MonoDomain *domain, MonoMethodMessage *this_obj, MonoReflectionMethod *method, MonoArray *out_args); MonoObject * -mono_message_invoke (MonoObject *target, MonoMethodMessage *msg, - MonoObject **exc, MonoArray **out_args); +ves_icall_System_Runtime_Remoting_Messaging_MonoMethodMessage_Invoke (MonoMethodMessage *this, + MonoObject *target, MonoArray **out_args); MonoMethodMessage * mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *invoke, diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 2fac892d43c..4640730aec1 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -5781,43 +5781,6 @@ mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpo return res; } -MonoObject * -ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this) -{ - MonoObject *res; - - g_assert (this); - g_assert (this->async_delegate); - - if (!this->async_call) { - res = mono_runtime_delegate_invoke (this->async_delegate, (void**) &this->async_state, NULL); - } else { - gpointer wait_event = NULL; - - g_assert (this->async_call->msg); - this->async_call->msg->exc = NULL; - - res = mono_message_invoke (this->async_delegate, this->async_call->msg, &this->async_call->msg->exc, &this->async_call->out_args); - MONO_OBJECT_SETREF (this->async_call, res, res); - - mono_monitor_enter ((MonoObject*) this); - - this->completed = TRUE; - - if (this->handle) - wait_event = mono_wait_handle_get_handle ((MonoWaitHandle*) this->handle); - if (wait_event) - SetEvent (wait_event); - - mono_monitor_exit ((MonoObject*) this); - - if (this->async_call->cb_method) - mono_runtime_invoke (this->async_call->cb_method, this->async_call->cb_target, (gpointer*) &this, NULL); - } - - return res; -} - void mono_message_init (MonoDomain *domain, MonoMethodMessage *this_obj, @@ -5926,15 +5889,14 @@ mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, #endif MonoObject * -mono_message_invoke (MonoObject *target, MonoMethodMessage *msg, - MonoObject **exc, MonoArray **out_args) +ves_icall_System_Runtime_Remoting_Messaging_MonoMethodMessage_Invoke (MonoMethodMessage *this, + MonoObject *target, MonoArray **out_args) { - static MonoClass *object_array_klass; - MonoDomain *domain; + static MonoClass *object_array_klass = NULL; MonoMethod *method; MonoMethodSignature *sig; MonoObject *ret; - int i, j, outarg_count = 0; + int i, j, out_args_count = 0; #ifndef DISABLE_REMOTING if (target && mono_object_is_transparent_proxy (target)) { @@ -5942,43 +5904,40 @@ mono_message_invoke (MonoObject *target, MonoMethodMessage *msg, if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) { target = tp->rp->unwrapped_server; } else { - return mono_remoting_invoke ((MonoObject *)tp->rp, msg, exc, out_args); + MonoObject *exc = NULL; + MonoObject *ret = mono_remoting_invoke ((MonoObject *)tp->rp, this, &exc, out_args); + if (exc) + mono_raise_exception (exc); + return ret; } } #endif - domain = mono_domain_get (); - method = msg->method->method; - sig = mono_method_signature (method); + g_assert (out_args); - for (i = 0; i < sig->param_count; i++) { - if (sig->params [i]->byref) - outarg_count++; - } + if (!object_array_klass) + object_array_klass = mono_array_class_get (mono_defaults.object_class, 1); + g_assert (object_array_klass); - if (!object_array_klass) { - MonoClass *klass; + method = this->method->method; - klass = mono_array_class_get (mono_defaults.object_class, 1); - g_assert (klass); + if (method->klass->valuetype) + ret = mono_runtime_invoke_array (method, mono_object_unbox (target), this->args, NULL); + else + ret = mono_runtime_invoke_array (method, target, this->args, NULL); - mono_memory_barrier (); - object_array_klass = klass; - } + sig = mono_method_signature (method); - /* FIXME: GC ensure we insert a write barrier for out_args, maybe in the caller? */ - *out_args = mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count); - *exc = NULL; + for (i = 0; i < sig->param_count; i++) { + if (sig->params [i]->byref) + out_args_count++; + } - ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc); + mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (mono_domain_get (), object_array_klass), out_args_count)); for (i = 0, j = 0; i < sig->param_count; i++) { - if (sig->params [i]->byref) { - MonoObject* arg; - arg = mono_array_get (msg->args, gpointer, i); - mono_array_setref (*out_args, j, arg); - j++; - } + if (sig->params [i]->byref) + mono_array_setref (*out_args, j++, mono_array_get (this->args, gpointer, i)); } return ret; diff --git a/mono/metadata/threadpool-ms.c b/mono/metadata/threadpool-ms.c index 215740bcece..139f53910e4 100644 --- a/mono/metadata/threadpool-ms.c +++ b/mono/metadata/threadpool-ms.c @@ -1260,16 +1260,17 @@ mono_threadpool_ms_begin_invoke (MonoDomain *domain, MonoObject *target, MonoMet mono_lazy_initialize (&status, initialize); - message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), (params != NULL) ? (&async_callback) : NULL, (params != NULL) ? (&state) : NULL); + if (params) + message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), &async_callback, &state); + else + message = mono_method_call_message_new (method, params, mono_get_delegate_invoke (method->klass), NULL, NULL); async_call = (MonoAsyncCall*) mono_object_new (domain, async_call_klass); MONO_OBJECT_SETREF (async_call, msg, message); MONO_OBJECT_SETREF (async_call, state, state); - if (async_callback) { - MONO_OBJECT_SETREF (async_call, cb_method, mono_get_delegate_invoke (((MonoObject*) async_callback)->vtable->klass)); - MONO_OBJECT_SETREF (async_call, cb_target, async_callback); - } + if (async_callback) + MONO_OBJECT_SETREF (async_call, callback, async_callback); async_result = mono_async_result_new (domain, NULL, async_call->state, NULL); MONO_OBJECT_SETREF (async_result, async_delegate, target); -- 2.25.1