From: Aleksey Kliger (λgeek) Date: Tue, 26 Jul 2016 16:47:45 +0000 (-0400) Subject: Merge pull request #3199 from lambdageek/dev/proxy-setter X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=6b8e96c44d40fa68eff6032445b3767585348b5a;hp=00e633549a9ce664286285c88a1338d41ff41046;p=mono.git Merge pull request #3199 from lambdageek/dev/proxy-setter [remoting] Convert mono_store_remote_field_new_checked to managed code --- diff --git a/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs b/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs index 74bc4764adc..74b8b65b3f1 100644 --- a/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs +++ b/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs @@ -81,8 +81,10 @@ namespace System.Runtime.Remoting.Proxies return field.GetValue(o); } - object[] inArgs = new object[] { Type.GetTypeFromHandle(typeHandle).FullName, - field.Name }; + string typeName = Type.GetTypeFromHandle(typeHandle).FullName; + string fieldName = field.Name; + object[] inArgs = new object[] { typeName, + fieldName }; object[] outArgsMsg = new object[1]; MethodInfo minfo = typeof(object).GetMethod("FieldGetter", BindingFlags.NonPublic | BindingFlags.Instance); if (minfo == null) @@ -95,6 +97,36 @@ namespace System.Runtime.Remoting.Proxies throw exc; return outArgs[0]; } + + internal void StoreRemoteField (IntPtr classPtr, IntPtr fieldPtr, object arg) { + Mono.RuntimeClassHandle classHandle = new Mono.RuntimeClassHandle (classPtr); + RuntimeFieldHandle fieldHandle = new RuntimeFieldHandle (fieldPtr); + RuntimeTypeHandle typeHandle = classHandle.GetTypeHandle (); + FieldInfo field = FieldInfo.GetFieldFromHandle (fieldHandle); + + if (InCurrentContext ()) { + object o = _rp._server; + field.SetValue (o, arg); + return; + } + + string typeName = Type.GetTypeFromHandle (typeHandle).FullName; + string fieldName = field.Name; + object [] inArgs = new object[] { typeName, + fieldName, + arg }; + MethodInfo minfo = typeof(object).GetMethod ("FieldSetter", BindingFlags.NonPublic | BindingFlags.Instance); + if (minfo == null) + throw new MissingMethodException ("System.Object", "FieldSetter"); + + MonoMethodMessage msg = new MonoMethodMessage (minfo, inArgs, null); + object [] outArgs; + Exception exc; + RealProxy.PrivateInvoke (_rp, msg, out exc, out outArgs); + if (exc != null) + throw exc; + } + } #pragma warning restore 169, 649 diff --git a/mcs/tools/linker/Descriptors/mscorlib.xml b/mcs/tools/linker/Descriptors/mscorlib.xml index bc8fddc327d..28279d9322a 100644 --- a/mcs/tools/linker/Descriptors/mscorlib.xml +++ b/mcs/tools/linker/Descriptors/mscorlib.xml @@ -299,6 +299,7 @@ + diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index a6e5ab52699..9ce52a3515a 100644 --- a/mono/metadata/object-internals.h +++ b/mono/metadata/object-internals.h @@ -1462,9 +1462,6 @@ mono_load_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mono gboolean mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, void* val, MonoError *error); -void -mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg); - gboolean mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg, MonoError *error); diff --git a/mono/metadata/object.c b/mono/metadata/object.c index 5abeed72821..7bb2b43beaf 100644 --- a/mono/metadata/object.c +++ b/mono/metadata/object.c @@ -8288,65 +8288,24 @@ mono_store_remote_field_checked (MonoObject *this_obj, MonoClass *klass, MonoCla MONO_REQ_GC_UNSAFE_MODE; - static MonoMethod *setter = NULL; + mono_error_init (error); MonoDomain *domain = mono_domain_get (); - MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj; MonoClass *field_class; - MonoMethodMessage *msg; - MonoArray *out_args; - MonoObject *exc; MonoObject *arg; - char* full_name; - - mono_error_init (error); g_assert (mono_object_is_transparent_proxy (this_obj)); field_class = mono_class_from_mono_type (field->type); - if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) { - if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, val); - else mono_field_set_value (tp->rp->unwrapped_server, field, *((MonoObject **)val)); - return TRUE; - } - - if (!setter) { - setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1); - if (!setter) { - mono_error_set_not_supported (error, "Linked away."); - return FALSE; - } - } - if (field_class->valuetype) { arg = mono_value_box_checked (domain, field_class, val, error); return_val_if_nok (error, FALSE); - } else - arg = *((MonoObject **)val); - - - msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error); - return_val_if_nok (error, FALSE); - MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error); - return_val_if_nok (error, FALSE); - mono_message_init (domain, msg, rm, NULL, error); - return_val_if_nok (error, FALSE); - - full_name = mono_type_get_full_name (klass); - mono_array_setref (msg->args, 0, mono_string_new (domain, full_name)); - mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field))); - mono_array_setref (msg->args, 2, arg); - g_free (full_name); - - mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error); - return_val_if_nok (error, FALSE); - - if (exc) { - mono_error_set_exception_instance (error, (MonoException *)exc); - return FALSE; + } else { + arg = *((MonoObject**)val); } - return TRUE; + + return mono_store_remote_field_new_checked (this_obj, klass, field, arg, error); } /** @@ -8366,23 +8325,6 @@ mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassFi mono_error_cleanup (&error); } -/** - * mono_store_remote_field_new_icall: - * @this_obj: - * @klass: - * @field: - * @arg: - * - * Missing documentation - */ -void -mono_store_remote_field_new_icall (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg) -{ - MonoError error; - (void) mono_store_remote_field_new_checked (this_obj, klass, field, arg, &error); - mono_error_set_pending_exception (&error); -} - /** * mono_store_remote_field_new_checked: * @this_obj: @@ -8398,56 +8340,27 @@ mono_store_remote_field_new_checked (MonoObject *this_obj, MonoClass *klass, Mon { MONO_REQ_GC_UNSAFE_MODE; - static MonoMethod *setter = NULL; - MonoDomain *domain = mono_domain_get (); - MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj; - MonoClass *field_class; - MonoMethodMessage *msg; - MonoArray *out_args; - MonoObject *exc; - char* full_name; + static MonoMethod *tp_store = NULL; mono_error_init (error); g_assert (mono_object_is_transparent_proxy (this_obj)); - field_class = mono_class_from_mono_type (field->type); - - if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) { - if (field_class->valuetype) mono_field_set_value (tp->rp->unwrapped_server, field, ((gchar *) arg) + sizeof (MonoObject)); - else mono_field_set_value (tp->rp->unwrapped_server, field, arg); - return TRUE; - } - - if (!setter) { - setter = mono_class_get_method_from_name (mono_defaults.object_class, "FieldSetter", -1); - if (!setter) { + if (!tp_store) { + tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1); + if (!tp_store) { mono_error_set_not_supported (error, "Linked away."); return FALSE; } } - msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, error); - return_val_if_nok (error, FALSE); - MonoReflectionMethod *rm = mono_method_get_object_checked (domain, setter, NULL, error); - return_val_if_nok (error, FALSE); - mono_message_init (domain, msg, rm, NULL, error); - return_val_if_nok (error, FALSE); - - full_name = mono_type_get_full_name (klass); - mono_array_setref (msg->args, 0, mono_string_new (domain, full_name)); - mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field))); - mono_array_setref (msg->args, 2, arg); - g_free (full_name); - - mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, error); - return_val_if_nok (error, FALSE); + gpointer args[3]; + args [0] = &klass; + args [1] = &field; + args [2] = arg; - if (exc) { - mono_error_set_exception_instance (error, (MonoException *)exc); - return FALSE; - } - return TRUE; + mono_runtime_invoke_checked (tp_store, this_obj, args, error); + return is_ok (error); } #endif diff --git a/mono/metadata/remoting.c b/mono/metadata/remoting.c index 62379f245e9..30595ee5410 100644 --- a/mono/metadata/remoting.c +++ b/mono/metadata/remoting.c @@ -198,7 +198,6 @@ mono_remoting_marshal_init (void) register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE); register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE); register_icall (mono_compile_method_icall, "mono_compile_method_icall", "ptr ptr", FALSE); - /* mono_store_remote_field_new_icall registered by mini-runtime.c */ } @@ -1619,73 +1618,6 @@ mono_marshal_get_ldflda_wrapper (MonoType *type) return res; } -/* - * mono_marshal_get_stfld_remote_wrapper: - * klass: The type of the field - * - * This function generates a wrapper for calling mono_store_remote_field_new - * with the appropriate signature. - * Similarly to mono_marshal_get_ldfld_remote_wrapper () this doesn't depend on the - * klass argument anymore. - */ -MonoMethod * -mono_marshal_get_stfld_remote_wrapper (MonoClass *klass) -{ - MonoMethodSignature *sig; - MonoMethodBuilder *mb; - MonoMethod *res; - static MonoMethod *cached = NULL; - - mono_marshal_lock_internal (); - if (cached) { - mono_marshal_unlock_internal (); - return cached; - } - mono_marshal_unlock_internal (); - - mb = mono_mb_new_no_dup_name (mono_defaults.object_class, "__mono_store_remote_field_new_wrapper", MONO_WRAPPER_STFLD_REMOTE); - - mb->method->save_lmf = 1; - - sig = mono_metadata_signature_alloc (mono_defaults.corlib, 4); - sig->params [0] = &mono_defaults.object_class->byval_arg; - sig->params [1] = &mono_defaults.int_class->byval_arg; - sig->params [2] = &mono_defaults.int_class->byval_arg; - sig->params [3] = &mono_defaults.object_class->byval_arg; - sig->ret = &mono_defaults.void_class->byval_arg; - -#ifndef DISABLE_JIT - mono_mb_emit_ldarg (mb, 0); - mono_mb_emit_ldarg (mb, 1); - mono_mb_emit_ldarg (mb, 2); - mono_mb_emit_ldarg (mb, 3); - - mono_mb_emit_icall (mb, mono_store_remote_field_new_icall); - - mono_mb_emit_byte (mb, CEE_RET); -#endif - - mono_marshal_lock_internal (); - res = cached; - mono_marshal_unlock_internal (); - if (!res) { - MonoMethod *newm; - newm = mono_mb_create (mb, sig, 6, NULL); - mono_marshal_lock_internal (); - res = cached; - if (!res) { - res = newm; - cached = res; - mono_marshal_unlock_internal (); - } else { - mono_marshal_unlock_internal (); - mono_free_method (newm); - } - } - mono_mb_free (mb); - - return res; -} /* * mono_marshal_get_stfld_wrapper: @@ -1706,6 +1638,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type) WrapperInfo *info; char *name; int t, pos; + static MonoMethod *tp_store = NULL; type = mono_type_get_underlying_type (type); t = type->type; @@ -1735,6 +1668,13 @@ mono_marshal_get_stfld_wrapper (MonoType *type) if ((res = mono_marshal_find_in_cache (cache, klass))) return res; +#ifndef DISABLE_REMOTING + if (!tp_store) { + tp_store = mono_class_get_method_from_name (mono_defaults.transparent_proxy_class, "StoreRemoteField", -1); + g_assert (tp_store != NULL); + } +#endif + /* we add the %p pointer value of klass because class names are not unique */ name = g_strdup_printf ("__stfld_wrapper_%p_%s.%s", klass, klass->name_space, klass->name); mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_STFLD); @@ -1752,6 +1692,7 @@ mono_marshal_get_stfld_wrapper (MonoType *type) mono_mb_emit_ldarg (mb, 0); pos = mono_mb_emit_proxy_check (mb, CEE_BNE_UN); +#ifndef DISABLE_REMOTING mono_mb_emit_ldarg (mb, 0); mono_mb_emit_ldarg (mb, 1); mono_mb_emit_ldarg (mb, 2); @@ -1759,9 +1700,10 @@ mono_marshal_get_stfld_wrapper (MonoType *type) if (klass->valuetype) mono_mb_emit_op (mb, CEE_BOX, klass); - mono_mb_emit_managed_call (mb, mono_marshal_get_stfld_remote_wrapper (klass), NULL); + mono_mb_emit_managed_call (mb, tp_store, NULL); mono_mb_emit_byte (mb, CEE_RET); +#endif mono_mb_patch_branch (mb, pos); diff --git a/mono/metadata/remoting.h b/mono/metadata/remoting.h index 9b495b2fb59..b0307aed93d 100644 --- a/mono/metadata/remoting.h +++ b/mono/metadata/remoting.h @@ -38,12 +38,6 @@ mono_marshal_get_ldfld_wrapper (MonoType *type); MonoMethod * mono_marshal_get_ldflda_wrapper (MonoType *type); -MonoMethod * -mono_marshal_get_ldfld_remote_wrapper (MonoClass *klass); - -MonoMethod * -mono_marshal_get_stfld_remote_wrapper (MonoClass *klass); - MonoMethod * mono_marshal_get_proxy_cancast (MonoClass *klass); diff --git a/mono/metadata/wrapper-types.h b/mono/metadata/wrapper-types.h index 909113cae8e..fc2c8954426 100644 --- a/mono/metadata/wrapper-types.h +++ b/mono/metadata/wrapper-types.h @@ -17,7 +17,6 @@ WRAPPER(XDOMAIN_INVOKE, "xdomain-invoke") WRAPPER(XDOMAIN_DISPATCH, "xdomain-dispatch") WRAPPER(LDFLD, "ldfld") WRAPPER(STFLD, "stfld") -WRAPPER(STFLD_REMOTE, "stfld-remote") WRAPPER(SYNCHRONIZED, "synchronized") WRAPPER(DYNAMIC_METHOD, "dynamic-method") WRAPPER(ISINST, "isinst") diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 7791ec26d0b..5719f5f1207 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -3104,8 +3104,6 @@ encode_method_ref (MonoAotCompile *acfg, MonoMethod *method, guint8 *buf, guint8 encode_klass_ref (acfg, info->d.proxy.klass, p, &p); break; } - case MONO_WRAPPER_STFLD_REMOTE: - break; case MONO_WRAPPER_ALLOC: { /* The GC name is saved once in MonoAotFileInfo */ g_assert (info->d.alloc.alloc_type != -1); @@ -7209,7 +7207,6 @@ can_encode_method (MonoAotCompile *acfg, MonoMethod *method) case MONO_WRAPPER_STFLD: case MONO_WRAPPER_LDFLD: case MONO_WRAPPER_LDFLDA: - case MONO_WRAPPER_STFLD_REMOTE: case MONO_WRAPPER_STELEMREF: case MONO_WRAPPER_ISINST: case MONO_WRAPPER_PROXY_ISINST: diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index 14fcfbabc05..2f818c6821c 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -922,9 +922,6 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod } break; } - case MONO_WRAPPER_STFLD_REMOTE: - ref->method = mono_marshal_get_stfld_remote_wrapper (NULL); - break; #endif case MONO_WRAPPER_ALLOC: { int atype = decode_value (p, &p); diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index dfce66481ea..e1918076a8a 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -3776,9 +3776,6 @@ register_icalls (void) register_icall (mono_thread_get_undeniable_exception, "mono_thread_get_undeniable_exception", "object", FALSE); register_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", "object", FALSE); register_icall (mono_thread_force_interruption_checkpoint_noraise, "mono_thread_force_interruption_checkpoint_noraise", "object", FALSE); -#ifndef DISABLE_REMOTING - register_icall (mono_store_remote_field_new_icall, "mono_store_remote_field_new_icall", "void object ptr ptr object", FALSE); -#endif #if defined(__native_client__) || defined(__native_client_codegen__) register_icall (mono_nacl_gc, "mono_nacl_gc", "void", FALSE); diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index 12be87a1fab..8c1fe23297b 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -1522,8 +1522,7 @@ mono_create_jit_trampoline (MonoDomain *domain, MonoMethod *method, MonoError *e if (code) return code; if (mono_llvm_only) { - if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST || - method->wrapper_type == MONO_WRAPPER_STFLD_REMOTE) + if (method->wrapper_type == MONO_WRAPPER_PROXY_ISINST) /* These wrappers are not generated */ return method_not_found; /* Methods are lazily initialized on first call, so this can't lead recursion */