-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[mono] Hot Reload: initial push to support adding lambdas (#63513)
Adds support for: * Adding static lambdas to existing methods, whether or not they had lambdas before. * Adding lambdas that capture `this` to existing methods that already captured `this` before * Adding new static or instance methods to existing types * Adding static fields to existing types * Adding new types (note that adding instance fields currently will fail. It'll go in in a future PR that will address #63643). Note that reflection on newly added members isn't tested yet and likely doesn't work. Fixes #50249 Contributes to #57365 * Add AddStaticField test; cleanup AddLambdaCapturingThis * Add AddNestedClass testcase * hot_reload: add a comment about remaining work * move per-class metadata update info to MonoClassMetadataUpdateInfo Use a property on the class instead of a hash table in the baseline image to keep track of added fields and methods * Cleanup pass1 to check add/update against prior gen Instead of the baseline image * adding a class Working on making mono_metadata_nested_in_typedef do the right thing for nested classes Contributes to making mono_class_create_from_typedef do the right thing for nested classes. * fix: correct mutant table population when the baseline table is empty In that case the table row_size and size_bitmap of the baseline are both 0, so offset calculations don't work. In that case when we know we need to add rows to the mutant table, use the uncompressed layout (32-bit columns, always) same as the EnC delta. * Calling new methods on a nested class works * adding fields Doesn't work yet. Dies in mono_class_get_field, called from mono_field_from_token_checked. The problem we're going to have to deal with is that unlike MonoMethod which is allocated upon lookup, the MonoClassFields of a class are allocated contiguously in class initialization. And there are not really enough fields in MonoClassField to indicate "this is not an ordinary field, don't do pointer arithmetic with it". One idea is to steal a bit from MonoClassField:parent and always check it as a trigger to go on a slower path. * adding static fields Rework the delta info to store info about "members" (rather than methods and fields separately). Add a MonoClassMetadataUpdateField subclass of MonoClassField that has extra info. Add new component methods to go from a MonoClassField to an index, and from a field token to a MonoClassField. Set MonoClassField:offset to -1 to generally go down the "special static field" codepath since we will need to do some one-off work to make a storage area for added static fields. Instance fields are not supported yet and error out during the update pass for now. * fix custom attribute lookups on new classes/methods/fields * Add a sketch of HotReloadInstanceFieldTable This is a class that manages the lifetime for added instance fields for reference types that had new fields added to them by EnC It's basically ConditionalWeakTable<object, Dictionary<uint, Store>> where the outer key is the object instance, the inner key is the fielddef token, and the value is a Store. The store has a single object? field which the location where the field's value will go. For reference types this is the reference directly, and for valuetypes and primitives, this is the boxed object (so to get the actual storage address you need to add sizeof(MonoObject)). * mono_metadata_update_get_static_field_addr two reminders: 1. The static field area needs to be GC-visible 2. We should really handle added fields on un-inited classes by allocating the instances in the normal way - in the layout algorithm. * Free MonoClassMetadataUpdateInfo when BaselineInfo is destroyed * placeholder struct for runtime class data; instance offset placeholder * static field storage Need to store the fields in a GC root, and in pinned allocations. * Implement hot_reload_get_static_field_addr() * Add mono_metadata_update_find_method_by_name Now we can find .cctor This is enough that a basic sample with an added static lambda works * Fix infinite loop * fix build * fix dynamic components builds * fix windows build * Fix inadvertent fallthru in previous fix * Report new capabilities NewTypeDefinition is not completely functional because adding instance fields is not supported yet. But adding classes with only static methods works. * tests: describe what existing tests do, add placeholder static lambda test * tests: Add AddStaticLambda test case Adding a brand new static lambda to an existing method body is supported * Destroy the runtime part of MonoClassMetadataUpdateInfo, too * rename Mono.HotReload file it has more classes than just the instance table * tests: add ActiveIssue for supporting adding instance fields * ifdef out Mono.HotReload.InstanceFieldTable it's not ready yet * Remove get_added_members from hot reload component interface Doesn't seem necessary to expose this yet. It's only used in hot_reload.c right now * Change the AddStaticLambda sample to use Func<string,string> To check that lambdas with parameters work * Use a mempool allocated GSlist for the added members This avoids invalidating iterators in case we add members on one thread while another thread is iterating. If it turns out we need random access, we can switch to a GArray with locking. But so far we only ever iterate. * Use mono_get_corlib instead of passing MonoDefaults to hot_reload * use normal GENERATE_TRY_GET_CLASS_WITH_CACHE * [metadata] make m_field_set_parent and m_field_set_meta_flags inline m_ prefix functions are supposed to be inline
- Loading branch information
1 parent
d2844eb
commit c50185b
Showing
38 changed files
with
1,366 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
.../ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass/AddNestedClass.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 AddNestedClass | ||
{ | ||
public AddNestedClass() | ||
{ | ||
} | ||
|
||
public string TestMethod() | ||
{ | ||
return "123"; | ||
} | ||
|
||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
...plyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass/AddNestedClass_v1.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// 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 AddNestedClass | ||
{ | ||
public AddNestedClass() | ||
{ | ||
} | ||
|
||
public string TestMethod() | ||
{ | ||
var n = new Nested(); | ||
n.f = "123"; | ||
return n.M(); | ||
} | ||
|
||
private class Nested { | ||
public Nested() { } | ||
internal string f; | ||
public string M () { | ||
return f + "456"; | ||
} | ||
} | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...ate.Test.AddNestedClass/System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<RootNamespace>System.Runtime.Loader.Tests</RootNamespace> | ||
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks> | ||
<TestRuntime>true</TestRuntime> | ||
<DeltaScript>deltascript.json</DeltaScript> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="AddNestedClass.cs" /> | ||
</ItemGroup> | ||
</Project> |
6 changes: 6 additions & 0 deletions
6
...s/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass/deltascript.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"changes": [ | ||
{"document": "AddNestedClass.cs", "update": "AddNestedClass_v1.cs"}, | ||
] | ||
} | ||
|
22 changes: 22 additions & 0 deletions
22
.../ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField/AddStaticField.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 AddStaticField | ||
{ | ||
public AddStaticField () { | ||
} | ||
|
||
public string GetField => s_field; | ||
|
||
private static string s_field; | ||
|
||
public void TestMethod () { | ||
s_field = "abcd"; | ||
} | ||
|
||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
...plyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField/AddStaticField_v1.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 AddStaticField | ||
{ | ||
public AddStaticField () { | ||
} | ||
|
||
public string GetField => s_field2; | ||
|
||
private static string s_field; | ||
|
||
private static string s_field2; | ||
|
||
public void TestMethod () { | ||
s_field = "spqr"; | ||
s_field2 = "4567"; | ||
} | ||
|
||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...ate.Test.AddStaticField/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<RootNamespace>System.Runtime.Loader.Tests</RootNamespace> | ||
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks> | ||
<TestRuntime>true</TestRuntime> | ||
<DeltaScript>deltascript.json</DeltaScript> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="AddStaticField.cs" /> | ||
</ItemGroup> | ||
</Project> |
6 changes: 6 additions & 0 deletions
6
...s/ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField/deltascript.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"changes": [ | ||
{"document": "AddStaticField.cs", "update": "AddStaticField_v1.cs"}, | ||
] | ||
} | ||
|
18 changes: 18 additions & 0 deletions
18
...pplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda/AddStaticLambda.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 AddStaticLambda | ||
{ | ||
public string TestMethod() | ||
{ | ||
return "abcd"; | ||
} | ||
|
||
public string Double(Func<string,string> f) => f("") + f("1"); | ||
|
||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...yUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda/AddStaticLambda_v1.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 AddStaticLambda | ||
{ | ||
public string TestMethod() | ||
{ | ||
return Double(static (s) => s + "abcd"); | ||
} | ||
|
||
public string Double(Func<string,string> f) => f("") + f("1"); | ||
|
||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
...e.Test.AddStaticLambda/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<RootNamespace>System.Runtime.Loader.Tests</RootNamespace> | ||
<TargetFrameworks>$(NetCoreAppCurrent)</TargetFrameworks> | ||
<TestRuntime>true</TestRuntime> | ||
<DeltaScript>deltascript.json</DeltaScript> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<Compile Include="AddStaticLambda.cs" /> | ||
</ItemGroup> | ||
</Project> |
6 changes: 6 additions & 0 deletions
6
.../ApplyUpdate/System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda/deltascript.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"changes": [ | ||
{"document": "AddStaticLambda.cs", "update": "AddStaticLambda_v1.cs"}, | ||
] | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.