From 6e0cf754b95e25e48f84ad723f0866b42fa59bd0 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 30 May 2023 09:57:33 -0400 Subject: [PATCH 01/11] WIP: adding a generic field --- .../GenericAddStaticField.cs | 22 ++++++++++++++ .../GenericAddStaticField_v1.cs | 25 ++++++++++++++++ ...lyUpdate.Test.GenericAddStaticField.csproj | 11 +++++++ .../deltascript.json | 6 ++++ .../tests/ApplyUpdateTest.cs | 30 ++++++++++++++++++- .../tests/System.Runtime.Loader.Tests.csproj | 1 + 6 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField.csproj create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs new file mode 100644 index 0000000000000..40744a65d8273 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class GenericAddStaticField + { + public GenericAddStaticField () { + } + + public T GetField => s_field; + + private static T s_field; + + public void TestMethod () { + s_field = (T)(object)"abcd"; + } + + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs new file mode 100644 index 0000000000000..cf4b2d3d31c88 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class GenericAddStaticField + { + public GenericAddStaticField () { + } + + public T GetField => s_field2; + + private static T s_field; + + private static T s_field2; + + public void TestMethod () { + s_field = (T)(object)"spqr"; + s_field2 = (T)(object)"4567"; + } + + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField.csproj b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField.csproj new file mode 100644 index 0000000000000..2a9400c53dda6 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField.csproj @@ -0,0 +1,11 @@ + + + System.Runtime.Loader.Tests + $(NetCoreAppCurrent) + true + deltascript.json + + + + + diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json new file mode 100644 index 0000000000000..ea7aa3c3bb2d1 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json @@ -0,0 +1,6 @@ +{ + "changes": [ + {"document": "GenericAddStaticField.cs", "update": "GenericAddStaticField_v1.cs"}, + ] +} + diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index e4f39888aeb07..d5eaa1202c50b 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -825,6 +825,34 @@ public static void TestReflectionAddNewMethod() Assert.Null(parms[3].DefaultValue); Assert.Equal(string.Empty, parms[4].DefaultValue); }); - } + } + + [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))] + public static void TestGenericAddStaticField() + { + ApplyUpdateUtil.TestCase(static () => + { + var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField<>).Assembly; + + var x = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField(); + + x.TestMethod(); + + Assert.Equal ("abcd", x.GetField); + + var y = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField(); + + Assert.Equal (0.0, y.GetField); + + ApplyUpdateUtil.ApplyUpdate(assm); + + x.TestMethod(); + + string result = x.GetField; + Assert.Equal("4567", result); + + Assert.Equal(0.0, y.GetField); + }); + } } } diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index 9062c6b5e03c1..3d48a7650ef5c 100644 --- a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -64,6 +64,7 @@ + From 2ae4927b28e9765401e03e7cad18b9b26493a6ca Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 7 Jun 2023 15:23:22 -0400 Subject: [PATCH 02/11] workaround roslyn issue to generate generic static field test https://github.com/dotnet/roslyn/issues/68293 we get an error if we add a generic field and try to use it during the same edit. workaround is to do two separate edits --- .../GenericAddStaticField.cs | 2 +- .../GenericAddStaticField_v1.cs | 6 +- .../GenericAddStaticField_v2.cs | 25 ++++++++ .../deltascript.json | 2 + .../tests/ApplyUpdateTest.cs | 58 ++++++++++--------- 5 files changed, 62 insertions(+), 31 deletions(-) create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v2.cs diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs index 40744a65d8273..ecea62abb4ad7 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField.cs @@ -10,7 +10,7 @@ public class GenericAddStaticField public GenericAddStaticField () { } - public T GetField => s_field; + public T GetField () => s_field; private static T s_field; diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs index cf4b2d3d31c88..ab6c8ebc2ba76 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v1.cs @@ -10,15 +10,15 @@ public class GenericAddStaticField public GenericAddStaticField () { } - public T GetField => s_field2; + public T GetField () => s_field; private static T s_field; - private static T s_field2; + public static T s_field2; public void TestMethod () { s_field = (T)(object)"spqr"; - s_field2 = (T)(object)"4567"; + //s_field2 = (T)(object)"4567"; } } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v2.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v2.cs new file mode 100644 index 0000000000000..2257051d7f70e --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/GenericAddStaticField_v2.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class GenericAddStaticField + { + public GenericAddStaticField () { + } + + public T GetField () => s_field2; + + private static T s_field; + + public static T s_field2; + + public void TestMethod () { + s_field = (T)(object)"spqr"; + s_field2 = (T)(object)"4567"; + } + + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json index ea7aa3c3bb2d1..d167f0b39a281 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField/deltascript.json @@ -1,6 +1,8 @@ { + "capabilities": ["Baseline", "AddStaticFieldToExistingType", "AddInstanceFieldToExistingType", "GenericUpdateMethod", "GenericAddFieldToExistingType"], "changes": [ {"document": "GenericAddStaticField.cs", "update": "GenericAddStaticField_v1.cs"}, + {"document": "GenericAddStaticField.cs", "update": "GenericAddStaticField_v2.cs"}, ] } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index d5eaa1202c50b..1e144f969f01e 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -753,7 +753,7 @@ public static void TestReflectionAddNewMethod() var ty = typeof(System.Reflection.Metadata.ApplyUpdate.Test.ReflectionAddNewMethod); var assm = ty.Assembly; - var bindingFlags = BindingFlags.Instance | BindingFlags.Public; + var bindingFlags = BindingFlags.Instance | BindingFlags.Public; var allMethods = ty.GetMethods(bindingFlags); int objectMethods = typeof(object).GetMethods(bindingFlags).Length; @@ -799,33 +799,33 @@ public static void TestReflectionAddNewMethod() parmPos++; } - var parmAttrs = parms[4].GetCustomAttributes(false); + var parmAttrs = parms[4].GetCustomAttributes(false); Assert.Equal (2, parmAttrs.Length); - bool foundCallerMemberName = false; - bool foundOptional = false; - foreach (var pa in parmAttrs) { - if (typeof (CallerMemberNameAttribute).Equals(pa.GetType())) - { - foundCallerMemberName = true; - } - if (typeof (OptionalAttribute).Equals(pa.GetType())) - { - foundOptional = true; - } - } - Assert.True(foundCallerMemberName); - Assert.True(foundOptional); - - // n.b. this typeof() also makes the rest of the test work on Wasm with aggressive trimming. - Assert.Equal (typeof(System.Threading.CancellationToken), parms[3].ParameterType); + bool foundCallerMemberName = false; + bool foundOptional = false; + foreach (var pa in parmAttrs) { + if (typeof (CallerMemberNameAttribute).Equals(pa.GetType())) + { + foundCallerMemberName = true; + } + if (typeof (OptionalAttribute).Equals(pa.GetType())) + { + foundOptional = true; + } + } + Assert.True(foundCallerMemberName); + Assert.True(foundOptional); + + // n.b. this typeof() also makes the rest of the test work on Wasm with aggressive trimming. + Assert.Equal (typeof(System.Threading.CancellationToken), parms[3].ParameterType); Assert.True(parms[3].HasDefaultValue); - Assert.True(parms[4].HasDefaultValue); + Assert.True(parms[4].HasDefaultValue); - Assert.Null(parms[3].DefaultValue); - Assert.Equal(string.Empty, parms[4].DefaultValue); + Assert.Null(parms[3].DefaultValue); + Assert.Equal(string.Empty, parms[4].DefaultValue); }); - } + } [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))] public static void TestGenericAddStaticField() @@ -838,20 +838,24 @@ public static void TestGenericAddStaticField() x.TestMethod(); - Assert.Equal ("abcd", x.GetField); + Assert.Equal ("abcd", x.GetField()); var y = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddStaticField(); - Assert.Equal (0.0, y.GetField); + Assert.Equal (0.0, y.GetField()); ApplyUpdateUtil.ApplyUpdate(assm); + // there are two updates - the first adds the fields, the second one updates the + // methods to use the new fields + ApplyUpdateUtil.ApplyUpdate(assm); + x.TestMethod(); - string result = x.GetField; + string result = x.GetField(); Assert.Equal("4567", result); - Assert.Equal(0.0, y.GetField); + Assert.Equal(0.0, y.GetField()); }); } } From a97f7375e5b73a06b53bcc8617ef9996aa90854d Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 7 Jun 2023 15:25:32 -0400 Subject: [PATCH 03/11] implement hot reload for static fields in generics ldsflda seems to be working --- src/mono/mono/component/hot_reload.c | 55 ++++++++++++++++++++++++++-- src/mono/mono/metadata/class.c | 4 +- src/mono/mono/metadata/metadata.c | 14 ++++--- 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index ac8236f78775a..ef7a80b9ecbcd 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -178,6 +178,9 @@ add_event_to_existing_class (MonoImage *image_base, BaselineInfo *base_info, uin static void add_semantic_method_to_existing_event (MonoImage *image_base, BaselineInfo *base_info, uint32_t semantics, uint32_t klass_token, uint32_t event_token, uint32_t method_token); +static MonoClassMetadataUpdateInfo * +hot_reload_get_or_add_ginst_update_info(MonoClass *ginst); + static MonoComponentHotReload fn_table = { { MONO_COMPONENT_ITF_VERSION, &hot_reload_available }, &hot_reload_set_fastpath_data, @@ -3005,7 +3008,12 @@ hot_reload_get_field_idx (MonoClassField *field) static MonoClassField * hot_reload_get_field (MonoClass *klass, uint32_t fielddef_token) { - MonoClassMetadataUpdateInfo *info = mono_class_get_or_add_metadata_update_info (klass); + MonoClassMetadataUpdateInfo *info; + if (mono_class_is_ginst (klass)) { + info = hot_reload_get_or_add_ginst_update_info (klass); + } else { + info = mono_class_get_metadata_update_info (klass); + } g_assert (mono_metadata_token_table (fielddef_token) == MONO_TABLE_FIELD); GSList *added_fields = info->added_fields; @@ -3274,7 +3282,12 @@ hot_reload_get_static_field_addr (MonoClassField *field) g_assert (!m_type_is_byref(f->field.type)); // byref fields only in ref structs, which aren't allowed in EnC updates MonoClass *parent = m_field_get_parent (&f->field); - MonoClassMetadataUpdateInfo *parent_info = mono_class_get_or_add_metadata_update_info (parent); + MonoClassMetadataUpdateInfo *parent_info; + if (mono_class_is_ginst (parent)) { + parent_info = hot_reload_get_or_add_ginst_update_info (parent); + } else { + parent_info = mono_class_get_metadata_update_info (parent); + } MonoClassRuntimeMetadataUpdateInfo *runtime_info = &parent_info->runtime; ensure_class_runtime_info_inited (parent, runtime_info); @@ -3416,7 +3429,12 @@ hot_reload_added_methods_iter (MonoClass *klass, gpointer *iter) static MonoClassField * hot_reload_added_fields_iter (MonoClass *klass, gboolean lazy G_GNUC_UNUSED, gpointer *iter) { - MonoClassMetadataUpdateInfo *info = mono_class_get_metadata_update_info (klass); + MonoClassMetadataUpdateInfo *info; + if (mono_class_is_ginst (klass)) { + info = hot_reload_get_or_add_ginst_update_info (klass); + } else { + info = mono_class_get_metadata_update_info (klass); + } if (!info) return NULL; @@ -3444,7 +3462,12 @@ hot_reload_added_fields_iter (MonoClass *klass, gboolean lazy G_GNUC_UNUSED, gpo static uint32_t hot_reload_get_num_fields_added (MonoClass *klass) { - MonoClassMetadataUpdateInfo *info = mono_class_get_metadata_update_info (klass); + MonoClassMetadataUpdateInfo *info; + if (mono_class_is_ginst (klass)) { + info = hot_reload_get_or_add_ginst_update_info (klass); + } else { + info = mono_class_get_metadata_update_info (klass); + } if (!info) return 0; return g_slist_length (info->added_fields); @@ -3454,6 +3477,7 @@ static uint32_t hot_reload_get_num_methods_added (MonoClass *klass) { uint32_t count = 0; + // FIXME: this might need to look at the generic class if `klass` is a ginst GSList *members = hot_reload_get_added_members (klass); for (GSList *ptr = members; ptr; ptr = ptr->next) { uint32_t token = GPOINTER_TO_UINT(ptr->data); @@ -3630,6 +3654,29 @@ recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataU info->added_events = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_events, (gpointer)added_event); } + info->added_fields = NULL; + for (GSList *ptr = gtd_info->added_fields; ptr; ptr = ptr->next) { + MonoClassMetadataUpdateField *gtd_added_field = (MonoClassMetadataUpdateField *)ptr->data; + MonoClassMetadataUpdateField *added_field = mono_class_new0 (ginst, MonoClassMetadataUpdateField, 1); + + ERROR_DECL (error); + mono_field_resolve_type (>d_added_field->field, error); + mono_error_assert_ok (error); + g_assert (gtd_added_field->field.type != NULL); + + added_field->field = gtd_added_field->field; + added_field->token = gtd_added_field->token; + + added_field->field.type = mono_class_inflate_generic_type_checked ( + added_field->field.type, mono_class_get_context (ginst), error); + mono_error_assert_ok (error); /*FIXME proper error handling*/ + + m_field_set_parent (&added_field->field, ginst); + m_field_set_meta_flags (&added_field->field, MONO_CLASS_FIELD_META_FLAG_FROM_UPDATE); + + info->added_fields = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_fields, (gpointer)added_field); + } + // finally, update the generation of the ginst info to the same one as the gtd info->generation = gtd_info->generation; // we're done info is now up to date diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index 053a13ccc71bf..834921ffd69bb 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -2479,7 +2479,9 @@ mono_class_get_field_from_name_full (MonoClass *klass, const char *name, MonoTyp continue; if (type) { - MonoType *field_type = mono_metadata_get_corresponding_field_from_generic_type_definition (field)->type; + MonoClassField *gfield = mono_metadata_get_corresponding_field_from_generic_type_definition (field); + g_assert (gfield != NULL); + MonoType *field_type = gfield->type; if (!mono_metadata_type_equal_full (type, field_type, TRUE)) continue; } diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index b9b30d622349f..0e5543d671e46 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -7730,13 +7730,15 @@ mono_metadata_get_corresponding_field_from_generic_type_definition (MonoClassFie if (!mono_class_is_ginst (m_field_get_parent (field))) return field; - /* - * metadata-update: nothing to do. can't add fields to existing generic - * classes; for new gtds added in updates, this is correct. - */ gtd = mono_class_get_generic_class (m_field_get_parent (field))->container_class; - offset = field - m_class_get_fields (m_field_get_parent (field)); - return m_class_get_fields (gtd) + offset; + + if (G_LIKELY (!m_field_is_from_update (field))) { + offset = field - m_class_get_fields (m_field_get_parent (field)); + return m_class_get_fields (gtd) + offset; + } else { + uint32_t token = mono_class_get_field_token (field); + return mono_class_get_field (gtd, token); + } } /* From 214740dfc50d42c31101215c5e4a720090435242 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 8 Jun 2023 13:24:45 -0400 Subject: [PATCH 04/11] clean up a bit --- src/mono/mono/component/hot_reload.c | 52 +++++++++++++++++++++------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index ef7a80b9ecbcd..d4b40421afb66 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -3598,14 +3598,10 @@ hot_reload_get_or_add_ginst_update_info(MonoClass *ginst) ((struct_type *) mono_class_alloc0 ((klass), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs)))) static void -recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info) +recompute_ginst_props (MonoClass *ginst, MonoClassMetadataUpdateInfo *info, + MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info, + MonoError *error) { - // if ginst has a `MonoClassMetadataUpdateInfo`, use it to start with, otherwise, allocate a new one - MonoClassMetadataUpdateInfo *info = mono_class_get_or_add_metadata_update_info (ginst); - - if (!info) - info = mono_class_new0 (ginst, MonoClassMetadataUpdateInfo, 1); - // replace info->added_props by a new list re-computed from gtd_info->added_props info->added_props = NULL; for (GSList *ptr = gtd_info->added_props; ptr; ptr = ptr->next) { @@ -3615,20 +3611,25 @@ recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataU added_prop->prop = gtd_added_prop->prop; added_prop->token = gtd_added_prop->token; - ERROR_DECL (error); if (added_prop->prop.get) added_prop->prop.get = mono_class_inflate_generic_method_full_checked ( added_prop->prop.get, ginst, mono_class_get_context (ginst), error); if (added_prop->prop.set) added_prop->prop.set = mono_class_inflate_generic_method_full_checked ( added_prop->prop.set, ginst, mono_class_get_context (ginst), error); - g_assert (is_ok (error)); /*FIXME proper error handling*/ + mono_error_assert_ok (error); /*FIXME proper error handling*/ added_prop->prop.parent = ginst; info->added_props = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_props, (gpointer)added_prop); } +} +static void +recompute_ginst_events (MonoClass *ginst, MonoClassMetadataUpdateInfo *info, + MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info, + MonoError *error) +{ // replace info->added_events by a new list re-computed from gtd_info->added_events info->added_events = NULL; for (GSList *ptr = gtd_info->added_events; ptr; ptr = ptr->next) { @@ -3637,7 +3638,6 @@ recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataU added_event->evt = gtd_added_event->evt; - ERROR_DECL (error); if (added_event->evt.add) added_event->evt.add = mono_class_inflate_generic_method_full_checked ( added_event->evt.add, ginst, mono_class_get_context (ginst), error); @@ -3647,19 +3647,24 @@ recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataU if (added_event->evt.raise) added_event->evt.raise = mono_class_inflate_generic_method_full_checked ( added_event->evt.raise, ginst, mono_class_get_context (ginst), error); - g_assert (is_ok (error)); /*FIXME proper error handling*/ + mono_error_assert_ok (error); /*FIXME proper error handling*/ added_event->evt.parent = ginst; info->added_events = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_events, (gpointer)added_event); } - +} + +static void +recompute_ginst_fields (MonoClass *ginst, MonoClassMetadataUpdateInfo *info, + MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info, + MonoError *error) +{ info->added_fields = NULL; for (GSList *ptr = gtd_info->added_fields; ptr; ptr = ptr->next) { MonoClassMetadataUpdateField *gtd_added_field = (MonoClassMetadataUpdateField *)ptr->data; MonoClassMetadataUpdateField *added_field = mono_class_new0 (ginst, MonoClassMetadataUpdateField, 1); - ERROR_DECL (error); mono_field_resolve_type (>d_added_field->field, error); mono_error_assert_ok (error); g_assert (gtd_added_field->field.type != NULL); @@ -3676,6 +3681,27 @@ recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataU info->added_fields = g_slist_prepend_mem_manager (m_class_get_mem_manager (ginst), info->added_fields, (gpointer)added_field); } +} + +static void +recompute_ginst_update_info(MonoClass *ginst, MonoClass *gtd, MonoClassMetadataUpdateInfo *gtd_info) +{ + // if ginst has a `MonoClassMetadataUpdateInfo`, use it to start with, otherwise, allocate a new one + MonoClassMetadataUpdateInfo *info = mono_class_get_or_add_metadata_update_info (ginst); + + if (!info) + info = mono_class_new0 (ginst, MonoClassMetadataUpdateInfo, 1); + + ERROR_DECL (error); + + recompute_ginst_props (ginst, info, gtd, gtd_info, error); + mono_error_assert_ok (error); + + recompute_ginst_events (ginst, info, gtd, gtd_info, error); + mono_error_assert_ok (error); + + recompute_ginst_fields (ginst, info, gtd, gtd_info, error); + mono_error_assert_ok (error); // finally, update the generation of the ginst info to the same one as the gtd info->generation = gtd_info->generation; From caab3f15df92fff11eaa395cae2c53aea18a4dd2 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 8 Jun 2023 15:43:20 -0400 Subject: [PATCH 05/11] Add a generic instance add instance field test --- .../GenericAddInstanceField.cs | 18 +++++++++ .../GenericAddInstanceField_v1.cs | 20 ++++++++++ .../GenericAddInstanceField_v2.cs | 21 ++++++++++ ...Update.Test.GenericAddInstanceField.csproj | 11 ++++++ .../deltascript.json | 7 ++++ .../tests/ApplyUpdateTest.cs | 38 +++++++++++++++++++ .../tests/System.Runtime.Loader.Tests.csproj | 1 + 7 files changed, 116 insertions(+) create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v1.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v2.cs create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField.csproj create mode 100644 src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/deltascript.json diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField.cs new file mode 100644 index 0000000000000..98a07ef78fba0 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class GenericAddInstanceField + { + public GenericAddInstanceField (T p) { + } + + public T GetIt() + { + return default(T); + } + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v1.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v1.cs new file mode 100644 index 0000000000000..a333e7372d94c --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v1.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class GenericAddInstanceField + { + public GenericAddInstanceField (T p) { + } + + T myAddedField; + + public T GetIt() + { + return default(T); + } + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v2.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v2.cs new file mode 100644 index 0000000000000..39bf3ff0b896b --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/GenericAddInstanceField_v2.cs @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System; + + +namespace System.Reflection.Metadata.ApplyUpdate.Test +{ + public class GenericAddInstanceField + { + public GenericAddInstanceField (T p) { + myAddedField = p; + } + + T myAddedField; + + public T GetIt() + { + return myAddedField; + } + } +} diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField.csproj b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField.csproj new file mode 100644 index 0000000000000..9779fa6c9f662 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField.csproj @@ -0,0 +1,11 @@ + + + System.Runtime.Loader.Tests + $(NetCoreAppCurrent) + true + deltascript.json + + + + + diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/deltascript.json b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/deltascript.json new file mode 100644 index 0000000000000..885807f5d1dd5 --- /dev/null +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField/deltascript.json @@ -0,0 +1,7 @@ +{ + "changes": [ + {"document": "GenericAddInstanceField.cs", "update": "GenericAddInstanceField_v1.cs"}, + {"document": "GenericAddInstanceField.cs", "update": "GenericAddInstanceField_v2.cs"}, + ] +} + diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index 1e144f969f01e..1ce74a262008a 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -858,5 +858,43 @@ public static void TestGenericAddStaticField() Assert.Equal(0.0, y.GetField()); }); } + + [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))] + public static void TestGenericAddInstanceField() + { + ApplyUpdateUtil.TestCase(static () => + { + var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField<>).Assembly; + + var x = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField("abcd"); + + Assert.Null (x.GetIt()); + + var y = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField(45.0); + + Assert.Equal (0.0, y.GetIt()); + + ApplyUpdateUtil.ApplyUpdate(assm); + + // there are two updates - the first adds the fields, the second one updates the + // methods to use the new fields + ApplyUpdateUtil.ApplyUpdate(assm); + + Assert.Null (x.GetIt()); + Assert.Equal (0.0, y.GetIt()); + + x = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField("spqr"); + + string result = x.GetIt(); + Assert.Equal("spqr", result); + + y = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField(2.717); + Assert.Equal(2.717, y.GetIt()); + + var dt = DateTime.Now; + var z = new System.Reflection.Metadata.ApplyUpdate.Test.GenericAddInstanceField(dt); + Assert.Equal(dt, z.GetIt()); + }); + } } } diff --git a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index 3d48a7650ef5c..293105e20d434 100644 --- a/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/libraries/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -65,6 +65,7 @@ + From fb39dcc1f642484419c89275d8b736a5a71ec405 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Tue, 13 Jun 2023 16:22:07 -0400 Subject: [PATCH 06/11] add reflection testing to the generic instance added field test --- .../tests/ApplyUpdateTest.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index 1ce74a262008a..983f4b0860f4e 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -876,6 +876,22 @@ public static void TestGenericAddInstanceField() ApplyUpdateUtil.ApplyUpdate(assm); + var fi = x.GetType().GetField("myAddedField", BindingFlags.Instance | BindingFlags.NonPublic); + + Assert.NotNull(fi); + + Assert.Equal ("myAddedField", fi.Name); + + Assert.Equal (typeof(string), fi.FieldType); + + var fi2 = y.GetType().GetField("myAddedField", BindingFlags.Instance | BindingFlags.NonPublic); + + Assert.NotNull(fi2); + + Assert.Equal ("myAddedField", fi2.Name); + + Assert.Equal (typeof(double), fi2.FieldType); + // there are two updates - the first adds the fields, the second one updates the // methods to use the new fields ApplyUpdateUtil.ApplyUpdate(assm); From e89594631f0d3b82c89cfa02b7d2e84ef7c361ac Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 8 Jun 2023 15:59:53 -0400 Subject: [PATCH 07/11] fixup valuetype loads --- src/mono/mono/mini/interp/transform.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index e3f938a108f80..0799aaf2f2baf 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -6580,7 +6580,11 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, MonoClass *field_class = mono_class_from_mono_type_internal (ftype); interp_emit_metadata_update_ldflda (td, field, error); goto_if_nok (error, exit); - interp_add_ins (td, interp_get_ldind_for_mt (mt)); + if (mt == MINT_TYPE_VT) { + interp_emit_ldobj (td, field_class); + } else { + interp_add_ins (td, interp_get_ldind_for_mt (mt)); + } interp_ins_set_sreg (td->last_ins, td->sp [-1].local); td->sp--; push_type (td, stack_type [mt], field_class); From b7c52f7da252cdd1ca884d2e4167a2d165d24c01 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 14 Jun 2023 13:19:11 -0400 Subject: [PATCH 08/11] add non-generic valuetype ldflda test --- .../AddInstanceField.cs | 2 ++ .../AddInstanceField_v1.cs | 5 +++++ .../AddInstanceField_v2.cs | 5 +++++ .../System.Runtime.Loader/tests/ApplyUpdateTest.cs | 7 +++++++ 4 files changed, 19 insertions(+) diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField.cs index 0b10a8b11fc9c..327014d806936 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField.cs @@ -47,5 +47,7 @@ public double FireEvents() { return Accumulator; } + + public DateTime GetDateTime() => default(DateTime); } } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs index 51768ff26f2a0..04e3fdafda548 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v1.cs @@ -85,6 +85,11 @@ public double FireEvents() { return Accumulator; } + public DateTime GetDateTime() => default(DateTime); + public double AddedFirstProp {get => 0.0; set { Console.WriteLine (value); } } + + public DateTime AddedDateTime; + } } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs index 87ad6f32526f0..3958f12dc11ec 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddInstanceField/AddInstanceField_v2.cs @@ -85,7 +85,12 @@ public double FireEvents() { return Accumulator; } + public DateTime GetDateTime() => AddedDateTime; + public double AddedFirstProp {get => 0.0; set { Console.WriteLine (value+value); } } public short AddedSecondProp {get; set; } + + public DateTime AddedDateTime; + } } diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index 983f4b0860f4e..6fdf9607f1282 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -408,6 +408,11 @@ public static void TestAddInstanceField() Assert.True ((addedEventToken & 0x00ffffff) < 4); + fi = x2.GetType().GetField("AddedDateTime"); + Assert.NotNull(fi); + var dt = DateTime.Now; + fi.SetValue(x2, dt); + Assert.Equal(dt, fi.GetValue(x2)); ApplyUpdateUtil.ApplyUpdate(assm); @@ -419,6 +424,8 @@ public static void TestAddInstanceField() var secondPropGetter = addedSecondPropInfo.GetGetMethod(); Assert.NotNull (secondPropGetter); + Assert.Equal(dt, x2.GetDateTime()); + }); } From b56cdf939bcbd3e87ff07023d2b44a3b4e7bda06 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Wed, 14 Jun 2023 15:22:29 -0400 Subject: [PATCH 09/11] Mark failing tests for CoreCLR --- src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs index 6fdf9607f1282..3593c5588eee7 100644 --- a/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs @@ -834,6 +834,7 @@ public static void TestReflectionAddNewMethod() }); } + [ActiveIssue("https://github.com/dotnet/runtime/issues/87574", TestRuntimes.CoreCLR)] [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))] public static void TestGenericAddStaticField() { @@ -866,6 +867,7 @@ public static void TestGenericAddStaticField() }); } + [ActiveIssue("https://github.com/dotnet/runtime/issues/87574", TestRuntimes.CoreCLR)] [ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))] public static void TestGenericAddInstanceField() { From f268e3e6bf9e00b89c3bfbb909c45b4344445e8a Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 15 Jun 2023 15:16:30 -0400 Subject: [PATCH 10/11] light up GenericAddFieldToExistingType capability --- src/mono/mono/component/hot_reload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index d4b40421afb66..e8a897d2f63f6 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -3517,7 +3517,7 @@ hot_reload_get_method_params (MonoImage *base_image, uint32_t methoddef_token, u static const char * hot_reload_get_capabilities (void) { - return "Baseline AddMethodToExistingType AddStaticFieldToExistingType NewTypeDefinition ChangeCustomAttributes AddInstanceFieldToExistingType GenericAddMethodToExistingType GenericUpdateMethod"; + return "Baseline AddMethodToExistingType AddStaticFieldToExistingType NewTypeDefinition ChangeCustomAttributes AddInstanceFieldToExistingType GenericAddMethodToExistingType GenericUpdateMethod GenericAddFieldToExistingType"; } static GENERATE_GET_CLASS_WITH_CACHE_DECL (hot_reload_instance_field_table); From 91396f5ad995608d6642ccd6dadc13f635e7e860 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 16 Jun 2023 09:01:41 -0400 Subject: [PATCH 11/11] use inter_emit_ldobj for metadata-update; add barrier if volatile --- src/mono/mono/mini/interp/transform.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 95e0e7c747724..9089733a47675 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -6571,16 +6571,9 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, MonoClass *field_class = mono_class_from_mono_type_internal (ftype); interp_emit_metadata_update_ldflda (td, field, error); goto_if_nok (error, exit); - if (mt == MINT_TYPE_VT) { - interp_emit_ldobj (td, field_class); - } else { - interp_add_ins (td, interp_get_ldind_for_mt (mt)); - } - interp_ins_set_sreg (td->last_ins, td->sp [-1].local); - td->sp--; - push_type (td, stack_type [mt], field_class); - interp_ins_set_dreg (td->last_ins, td->sp[-1].local); + interp_emit_ldobj (td, field_class); td->ip += 5; + BARRIER_IF_VOLATILE (td, MONO_MEMORY_BARRIER_ACQ); break; } int opcode = MINT_LDFLD_I1 + mt - MINT_TYPE_I1;