-
Notifications
You must be signed in to change notification settings - Fork 516
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
[dotnet] Integrate class handle rewriting into static registrar process. #18456
[dotnet] Integrate class handle rewriting into static registrar process. #18456
Conversation
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
<Compile Include="..\..\tools\common\Rewriter.cs"> | ||
<Link>external\ObjCNameIndex.cs</Link> | ||
</Compile> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why you need this if it's not being implemented as an MSBuild task anymore?
@@ -504,6 +504,7 @@ | |||
@(_MonoLibrary -> 'MonoLibrary=%(Identity)') | |||
MtouchFloat32=$(MtouchFloat32) | |||
Optimize=$(_BundlerOptimize) | |||
OptimizeClassHandles=$(OptimizeClassHandles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already added an optimization option here:
can't that one be used instead of adding another one?
tools/mtouch/BuildTasks.mtouch.cs
Outdated
if (Target.App.OptimizeClassHandles) { | ||
var rewriter = new Rewriter (assemblies, typeMap); | ||
rewriter.Process (); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This chunk of code is duplicated in a few places, would it make sense to move it inside the StaticRegistrar.Generate method so that there's only one copy of it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea - I didn't do it initially because I was worried about exception handling (which this code needs).
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also a test failure in a few tests:
error MM2362: The linker step 'Registrar' failed during processing: Unable to find ObjCRuntime.Runtime/ClassHandles type in
tools/common/StaticRegistrar.cs
Outdated
if (!string.IsNullOrEmpty (type_map_path)) { | ||
var doc = CSToObjCMap.ToXDocument (map_dict); | ||
doc.Save (type_map_path); | ||
if (rewriteClassHandles) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can access the optimization flag like this, that would avoid having to pass another extra parameter around:
if (rewriteClassHandles) { | |
if (App.Optimizations.RewriteClassHandles == true) { |
tools/common/StaticRegistrar.cs
Outdated
if (rewriteClassHandles) { | ||
var rewriter = new Rewriter (map_dict, GetAssemblies ()); | ||
rewriter.Process (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC the class redirect is .NET only, and not for legacy Xamarin:
if (rewriteClassHandles) { | |
var rewriter = new Rewriter (map_dict, GetAssemblies ()); | |
rewriter.Process (); | |
#if NET | |
if (rewriteClassHandles) { | |
var rewriter = new Rewriter (map_dict, GetAssemblies ()); | |
rewriter.Process (); | |
} | |
#endif |
tools/common/Rewriter.cs
Outdated
PatchClassPtrUsage (classMap, module); | ||
module.Write (ToOutputFileName (path)); | ||
module.Write (); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't write out the assembly, the linker will do that later.
However, it's important to tell the linker that the assembly was changed, and that's done by changing the action:
xamarin-macios/tools/dotnet-linker/AppBundleRewriter.cs
Lines 1092 to 1094 in cb34bfe
var annotations = configuration.Context.Annotations; | |
var action = annotations.GetAction (assembly); | |
if (action == AssemblyAction.Copy) { |
annotations.SetAction (assembly, AssemblyAction.Save); |
Note that you should only save the assembly if you actually modified it.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
} catch (Exception e) { | ||
// if this throws, no changes are made to the assemblies | ||
// so it's safe to log it on the far side. | ||
return e.Message; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason it's not a failure to fail to apply the class handle optimization? It should be easy enough for customers to turn it off if need be, and just printing a log message if something goes wrong feels like nobody will notice if it ever breaks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple reasons: if this throws an exception, it means that we've done something horribly, horribly wrong. It means that someone removed the ClassHandles
types or its InitializeClassHandles
method, or NativeHandle
or any of a number of things that need to be in place for the rest of the code to work. And while this seems like a "Holy cow, we should stop this immediately!" error - it actually isn't. The rest of the process won't run and no changes will have been made to the assemblies and the user is left with a build without NativeHandle
.
src/ObjCRuntime/Runtime.cs
Outdated
@@ -206,6 +206,7 @@ internal unsafe struct InitializationOptions { | |||
internal static unsafe InitializationOptions* options; | |||
|
|||
#if NET | |||
[Preserve (AllMembers = true)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you maybe just add this class + method dynamically in the rewriter? That way it would only be present when needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing that's missing is a call from Initialize that will run that code. It needs to be there and it's best if it's just empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the method is called from somewhere, then you won't need the Preserve attribute.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
📚 [PR Build] Artifacts 📚Packages generatedView packagesPipeline on Agent |
💻 [CI Build] Windows Integration Tests passed 💻✅ All Windows Integration Tests passed. Pipeline on Agent |
✅ API diff for current PR / commitLegacy Xamarin (No breaking changes)
NET (empty diffs)
✅ API diff vs stableLegacy Xamarin (No breaking changes).NET (No breaking changes)✅ Generator diffGenerator diff is empty Pipeline on Agent |
💻 [PR Build] Tests on macOS M1 - Mac Ventura (13.0) passed 💻✅ All tests on macOS M1 - Mac Ventura (13.0) passed. Pipeline on Agent |
💻 [PR Build] Tests on macOS M1 - Mac Big Sur (11.5) passed 💻✅ All tests on macOS M1 - Mac Big Sur (11.5) passed. Pipeline on Agent |
🚀 [CI Build] Test results 🚀Test results✅ All tests passed on VSTS: simulator tests. 🎉 All 235 tests passed 🎉 Tests counts✅ bcl: All 69 tests passed. Html Report (VSDrops) Download Pipeline on Agent |
…ss. (#18456) Integrate class handle rewriting into static registrar.
Integrate class handle rewriting into static registrar.
Since the class handle optimizations are fairly tightly coupled with the static registrar, it made more sense to me for it to happen in the same process.
In this PR, I refactored the code to
AssemblyDefinition
types instead of a directory of assembliesClassRedirector
taskThings that I'm concerned about that I don't know about:
No tests yet - they'll happen in a subsequent PR after the dust settles here