Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Hot Reload: initial push to support adding lambdas #63513

Merged
merged 45 commits into from
Jan 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4c564c3
Add AddStaticField test; cleanup AddLambdaCapturingThis
lambdageek Nov 29, 2021
6a32923
Add AddNestedClass testcase
lambdageek Dec 16, 2021
c8cd6eb
hot_reload: add a comment about remaining work
lambdageek Nov 29, 2021
6ec639a
move per-class metadata update info to MonoClassMetadataUpdateInfo
lambdageek Nov 30, 2021
560046b
wip
lambdageek Dec 6, 2021
9f5d73b
Cleanup pass1 to check add/update against prior gen
lambdageek Dec 17, 2021
5c8908e
XXX no merge - mess with sample
lambdageek Dec 20, 2021
520a92c
WIP: adding a class
lambdageek Dec 20, 2021
8d63497
fix: correct mutant table population when the baseline table is empty
lambdageek Dec 21, 2021
3ed1f39
Calling new methods on a nested class works
lambdageek Dec 21, 2021
e4a3f57
XXX no merge - change the sample to add a static lambda
lambdageek Dec 21, 2021
0b1f927
WIP: adding fields
lambdageek Dec 21, 2021
eec222a
WIP: adding static fields
lambdageek Dec 22, 2021
2b92f0b
WIP: custom attribute lookups
lambdageek Dec 23, 2021
bf57011
WIP: Add a sketch of HotReloadInstanceFieldTable
lambdageek Dec 23, 2021
df207dc
WIP: placeholder for mono_metadata_update_get_static_field_addr
lambdageek Dec 23, 2021
e8c021d
Free MonoClassMetadataUpdateInfo when BaselineInfo is destroyed
lambdageek Jan 3, 2022
ebeb21e
WIP: placeholder struct for runtime class data; instance offset place…
lambdageek Jan 3, 2022
5fc7496
WIP: static field storage
lambdageek Jan 5, 2022
7d4c8f0
Implement hot_reload_get_static_field_addr()
lambdageek Jan 6, 2022
30c075a
Add mono_metadata_update_find_method_by_name
lambdageek Jan 7, 2022
ab5143e
Fix infinite loop
lambdageek Jan 7, 2022
8c8bdd5
fix build
lambdageek Jan 7, 2022
805b4dd
fix dynamic components builds
lambdageek Jan 7, 2022
6dbaa86
fix windows build
lambdageek Jan 7, 2022
9a572c2
Fix inadvertent fallthru in previous fix
lambdageek Jan 10, 2022
f694875
Report new capabilities
lambdageek Jan 11, 2022
ad51dd6
tests: describe what existing tests do, add placeholder static lambda…
lambdageek Jan 11, 2022
d4e506e
tests: Add AddStaticLambda test case
lambdageek Jan 11, 2022
b84b38b
Revert "WIP: adding static fields" changes to sample
lambdageek Jan 11, 2022
10d83a0
Revert changes to mbr sample
lambdageek Jan 11, 2022
a445e5b
fix whitespace
lambdageek Jan 11, 2022
c58b061
fix whitespace and comments
lambdageek Jan 11, 2022
6135274
Destroy the runtime part of MonoClassMetadataUpdateInfo, too
lambdageek Jan 11, 2022
e0c3376
fix whitespace
lambdageek Jan 11, 2022
a2b674e
rename Mono.HotReload file
lambdageek Jan 11, 2022
2a0be07
tests: add ActiveIssue for supporting adding instance fields
lambdageek Jan 11, 2022
08fa426
ifdef out Mono.HotReload.InstanceFieldTable
lambdageek Jan 11, 2022
493341f
Remove get_added_members from hot reload component interface
lambdageek Jan 12, 2022
79f2243
Change the AddStaticLambda sample to use Func<string,string>
lambdageek Jan 12, 2022
d2f009a
Use a mempool allocated GSlist for the added members
lambdageek Jan 12, 2022
f83ecac
Use mono_get_corlib instead of passing MonoDefaults to hot_reload
lambdageek Jan 14, 2022
7250d36
use normal GENERATE_TRY_GET_CLASS_WITH_CACHE
lambdageek Jan 15, 2022
924c6e3
fix formatting
lambdageek Jan 18, 2022
0a56e88
[metadata] make m_field_set_parent and m_field_set_meta_flags inline
lambdageek Jan 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ namespace System.Reflection.Metadata.ApplyUpdate.Test
{
public class AddLambdaCapturingThis
{
public AddLambdaCapturingThis () {
field = "abcd";
}
public AddLambdaCapturingThis()
{
field = "abcd";
}

public string GetField => field;
public string GetField => field;

private string field;
private string field;

public string TestMethod () {
// capture 'this' but no locals
Func<string,string> fn = s => field;
return "123";
}
public string TestMethod()
{
// capture 'this' but no locals
Func<string,string> fn = s => field;
return "123";
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,21 @@ namespace System.Reflection.Metadata.ApplyUpdate.Test
{
public class AddLambdaCapturingThis
{
public AddLambdaCapturingThis () {
field = "abcd";
}
public AddLambdaCapturingThis()
{
field = "abcd";
}

public string GetField => field;
public string GetField => field;

private string field;

public string TestMethod () {
// capture 'this' but no locals
Func<string,string> fn = s => NewMethod (s + field, 42);
return fn ("123");
}

private string NewMethod (string s, int i) {
return i.ToString() + s;
}
private string field;

public string TestMethod()
{
// capture 'this' but no locals
Func<string,string> fn = s => field;
Func<string,string> fn2 = s => "42" + s + field;
return fn2 ("123");
}
}
}
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";
}

}
}
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";
}
}
}
}
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"changes": [
{"document": "AddNestedClass.cs", "update": "AddNestedClass_v1.cs"},
]
}

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";
}

}
}
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";
}

}
}
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"changes": [
{"document": "AddStaticField.cs", "update": "AddStaticField_v1.cs"},
]
}

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");

}
}
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");

}
}
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"changes": [
{"document": "AddStaticLambda.cs", "update": "AddStaticLambda_v1.cs"},
]
}

96 changes: 82 additions & 14 deletions src/libraries/System.Runtime.Loader/tests/ApplyUpdateTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ void LambdaBodyChange()
[ActiveIssue("https://github.com/dotnet/runtime/issues/54617", typeof(PlatformDetection), nameof(PlatformDetection.IsBrowser), nameof(PlatformDetection.IsMonoAOT))]
void LambdaCapturesThis()
{
// Tests that changes to the body of a lambda that captures 'this' is supported.
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof (ApplyUpdate.Test.LambdaCapturesThis).Assembly;
Expand Down Expand Up @@ -263,25 +264,92 @@ public void AsyncMethodChanges()
});
}

[ActiveIssue ("https://github.com/dotnet/runtime/issues/50249", TestRuntimes.Mono)]
[ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))]
public static void TestAddLambdaCapturingThis()
{
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.AddLambdaCapturingThis).Assembly;
[ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))]
public static void TestAddLambdaCapturingThis()
{
// Test that adding a lambda that captures 'this' (to a method that already has a lambda that captures 'this') is supported
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.AddLambdaCapturingThis).Assembly;

var x = new System.Reflection.Metadata.ApplyUpdate.Test.AddLambdaCapturingThis();

Assert.Equal("123", x.TestMethod());

ApplyUpdateUtil.ApplyUpdate(assm);

string result = x.TestMethod();
Assert.Equal("42123abcd", result);
});
}

[ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))]
public static void TestAddStaticField()
{
// Test that adding a new static field to an existing class is supported
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField).Assembly;

var x = new System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField();

x.TestMethod();

Assert.Equal ("abcd", x.GetField);

ApplyUpdateUtil.ApplyUpdate(assm);

x.TestMethod();

string result = x.GetField;
Assert.Equal("4567", result);
});
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/63643", TestRuntimes.Mono)]
[ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))]
public static void TestAddNestedClass()
{
// Test that adding a new nested class to an existing class is supported
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass).Assembly;

var x = new System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass();

var r = x.TestMethod();

Assert.Equal ("123", r);

ApplyUpdateUtil.ApplyUpdate(assm);

r = x.TestMethod();

var x = new System.Reflection.Metadata.ApplyUpdate.Test.AddLambdaCapturingThis();
Assert.Equal("123456", r);
});
}

[ConditionalFact(typeof(ApplyUpdateUtil), nameof(ApplyUpdateUtil.IsSupported))]
public static void TestAddStaticLambda()
{
// Test that adding a new static lambda to an existing method body is supported
ApplyUpdateUtil.TestCase(static () =>
{
var assm = typeof(System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda).Assembly;

Assert.Equal("123", x.TestMethod());
var x = new System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda();

ApplyUpdateUtil.ApplyUpdate(assm);
var r = x.TestMethod();

string result = x.TestMethod();
Assert.Equal("42123abcd", result);
});
}
Assert.Equal ("abcd", r);

ApplyUpdateUtil.ApplyUpdate(assm);

r = x.TestMethod();

Assert.Equal("abcd1abcd", r);
});
}

class NonRuntimeAssembly : Assembly
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.LambdaCapturesThis\System.Reflection.Metadata.ApplyUpdate.Test.LambdaCapturesThis.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.FirstCallAfterUpdate\System.Reflection.Metadata.ApplyUpdate.Test.FirstCallAfterUpdate.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.AddLambdaCapturingThis\System.Reflection.Metadata.ApplyUpdate.Test.AddLambdaCapturingThis.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField\System.Reflection.Metadata.ApplyUpdate.Test.AddStaticField.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass\System.Reflection.Metadata.ApplyUpdate.Test.AddNestedClass.csproj" />
<ProjectReference Include="ApplyUpdate\System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda\System.Reflection.Metadata.ApplyUpdate.Test.AddStaticLambda.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetOS)' == 'Browser'">
<WasmFilesToIncludeFromPublishDir Include="$(AssemblyName).dll" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@
<Compile Include="$(LibrariesProjectRoot)\System.Private.CoreLib\src\System\Threading\ThreadPoolBoundHandle.PlatformNotSupported.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\Mono\HotReload.cs" />
<Compile Include="$(BclSourcesRoot)\Mono\RuntimeStructs.cs" />
<Compile Include="$(BclSourcesRoot)\Mono\RuntimeMarshal.cs" />
<Compile Include="$(BclSourcesRoot)\Mono\SafeStringMarshal.cs" />
Expand Down
Loading