Add MIBC profile generator for InitializeComponent methods#34837
Add MIBC profile generator for InitializeComponent methods#34837jkoritzinsky wants to merge 15 commits into
Conversation
Add a build tool that scans compiled MAUI assemblies for all InitializeComponent* methods (InitializeComponent, InitializeComponentRuntime, InitializeComponentXamlC, InitializeComponentSourceGen) and produces a MIBC profile file consumable by crossgen2 and the .NET AOT compiler for PGO. The tool is integrated into the MSBuild pipeline via the _MauiGenerateMibcProfile target, which runs after XamlC and is opt-in via the MauiGenerateMibcProfile property. The generated file is exposed as the @(MauiMibcProfile) MSBuild item for downstream consumption. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add explicit ret instructions to group and AssemblyDictionary IL methods - Fix nested type namespace resolution (walk to outermost declaring type) - Include deps.json in NuGet package and local dev copy - Fix comment to match actual property/item names - Fix indentation to use tabs consistently in targets file Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cios repo and use item groups from dotnet/sdk#53635 to enable partial generation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34837Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34837" |
There was a problem hiding this comment.
Pull request overview
Adds an MSBuild-integrated tool to generate MIBC profile files containing MAUI InitializeComponent* methods, enabling partial ReadyToRun (R2R) compilation for XAML-generated code paths (notably for CoreCLR Debug scenarios).
Changes:
- Introduces
MibcProfileGenerator, a console tool that scans assemblies viaSystem.Reflection.Metadataand emits a MIBC PE (optionally compressed). - Adds an opt-in MSBuild target (
_MauiGenerateMibcProfile) to generate the profile and wire it intoPublishReadyToRun*items. - Packages the tool alongside existing build tasks and hooks it into the build tasks project/pack output.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| src/Controls/src/Build.Tasks/nuget/buildTransitive/netstandard2.0/Microsoft.Maui.Controls.targets | Adds _MauiGenerateMibcProfile target and R2R/PGO item wiring. |
| src/Controls/src/Build.Tasks/MibcProfileGenerator/Program.cs | New implementation for discovering InitializeComponent* methods and emitting MIBC output. |
| src/Controls/src/Build.Tasks/MibcProfileGenerator/MibcProfileGenerator.csproj | New net10.0 tool project and local dev copy target. |
| src/Controls/src/Build.Tasks/Controls.Build.Tasks.csproj | References/packaging updates to include the tool in the build tasks NuGet output. |
- Fix MVID write ordering: write GUID before Serialize() so it's included in output - Key assembly references by full identity (name+version+pkt) not just simple name - Add MauiXaml condition to skip non-XAML projects - Fix comment: 'method names' not 'method name prefixes' (exact matching) - Fix comment: describe actual enabling mechanism (FilterReadyToRunAssemblies) - Fix indentation in targets file ItemGroup (tabs not spaces) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add response file (@file) support to MibcProfileGenerator tool - Restructure targets into wrapper + write-rsp + run-tool pattern - Use WriteOnlyWhenDifferent for incremental build correctness - Pass all PublishReadyToRunExclude assemblies to the generator - Move all excluded assemblies to partial R2R after generation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kotlarmilos
left a comment
There was a problem hiding this comment.
The CI is failing with Could not find a part of the path '/Users/cloudtest/vss/_work/1/s/artifacts/bin/MibcProfileGenerator/Release/net10.0, please find the path.
|
I would like to see the impact of this feature on the sample content app (create via |
|
I think I should be able to get the perf data during the next week :) |
Replace FilterReadyToRunAssemblies condition with new EmitPartialR2RXamlProfile property (defaults to false) for explicit opt-in control of the partial R2R XAML profile feature. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The tool now writes a companion .matched file listing input assemblies that contributed InitializeComponent* methods. The MSBuild target reads this list and only moves those assemblies from PublishReadyToRunExclude to PublishReadyToRunPartialAssemblies, leaving unmatched assemblies excluded. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ions Replace hardcoded net10.0 TFM references with $(_MauiDotNetTfm) in both the MibcProfileGenerator project file and the Controls.Build.Tasks packaging paths to avoid manual updates during TFM version bumps. Add MibcProfileGenerator to all solution files and solution filters so that AssignProjectConfiguration can resolve it during solution-based builds. Without this, the Arcade pack step (build.sh -restore -pack) would build MibcProfileGenerator in Debug (the default) instead of the requested Release configuration, causing pack to fail with 'Could not find' errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@copilot please resolve the merge conflicts |
…generator # Conflicts: # .vscode/settings.json Co-authored-by: jkoritzinsky <1571408+jkoritzinsky@users.noreply.github.com>
Merge conflicts resolved in commit
Fixed in commit |
|
/review -b feature/enhanced-reviewer -p android |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 4 findings
See inline comments for details.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
…ost path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
/review -b feature/enhanced-reviewer |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
| static class MibcProfileGenerator | ||
| { | ||
| /// <summary> | ||
| /// Method names generated by the MAUI XAML toolchain. | ||
| /// See CodeBehindCodeWriter.cs and XamlCTask.cs for where these names are produced. | ||
| /// Matched by exact name (not prefix). | ||
| /// </summary> | ||
| static readonly string[] InitializeComponentMethodNames = | ||
| [ | ||
| "InitializeComponent", | ||
| "InitializeComponentRuntime", | ||
| "InitializeComponentXamlC", | ||
| "InitializeComponentSourceGen", | ||
| ]; |
There was a problem hiding this comment.
Just a thought, but is this useful enough, it could be in the .NET SDK and you could pick what assemblies & methods you'd like this to be done for?
| Runs after R2R assembly selection. --> | ||
| <Target Name="_MauiGenerateMibcProfile" | ||
| AfterTargets="_SelectR2RAssemblies" | ||
| Condition=" '$(EmitPartialR2RXamlProfile)' == 'true' AND ('$(TargetPlatformIdentifier)' == 'ios' OR '$(TargetPlatformIdentifier)' == 'maccatalyst' OR '$(TargetPlatformIdentifier)' == 'tvos') AND '$(Configuration)' != 'Release' AND '$(DesignTimeBuild)' != 'True' AND '@(MauiXaml)' != '' " |
There was a problem hiding this comment.
How does this impact hot reload? If InitializeComponent() has a R2R image, and I change my XAML -> source generator -> dotnet watch (or IDE) sends diff. Does EnC still work?
There was a problem hiding this comment.
I'm afraid this is a valid concern. When we started this we only considered debugger - and decided that inability to debug the generated version of InitializeComponts would not be such a big deal. but hot-reload is different. Not being able to hot-reload InitializeComponents would mean no XAML hot-reload, which is not acceptable.
I don't know if it would work or not though - if hot-reload does full method body replacement, then the presence of R2R should not make much of a difference. We would have to test this.
|
/review rerun |
|
/review -b feature/enhanced-reviewer -p android |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 2 findings
See inline comments for details.
| </Target> | ||
|
|
||
| <PropertyGroup> | ||
| <EmitPartialR2RXamlProfile Condition=" '$(EmitPartialR2RXamlProfile)' == '' ">false</EmitPartialR2RXamlProfile> |
There was a problem hiding this comment.
[moderate] Build & MSBuild - This introduces a new user-facing MSBuild feature flag without the Maui prefix. Once shipped from buildTransitive targets, EmitPartialR2RXamlProfile becomes part of the public build surface and can collide with app/SDK/imported target properties. Please rename this to a MAUI-scoped property such as MauiEmitPartialR2RXamlProfile before shipping.
| if (!File.Exists(responseFile)) | ||
| { | ||
| Console.Error.WriteLine($"Error: Response file not found: {responseFile}"); | ||
| continue; |
There was a problem hiding this comment.
[moderate] Logic and Correctness - A missing response file logs an error but then continues, so MibcProfileGenerator output.mibc @missing.rsp succeeds by emitting an empty profile. That can silently disable the partial R2R promotion path if the response-file path is wrong. Please make a missing response file fail the tool, matching the existing behavior for missing input assemblies.
kubaflo
left a comment
There was a problem hiding this comment.
Could you check the suggestions please? :)
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@jkoritzinsky — new AI review results are available based on this last commit:
f543953.
Harden MIBC generator: content-derived MVID, empty-input no-op, SDK host path To request a fresh review after new comments or commits, comment/review rerun.
Review Sessions — click to expand
Gate — Test Before & After Fix
Gate Result: ⚠️ SKIPPED
No tests were detected in this PR.
Recommendation: Add tests to verify the fix using the write-tests-agent.
UI Tests
Full UI test matrix will run (no specific categories detected from PR changes).
Pre-Flight — Context & Validation
Issue: N/A - No linked issue detected; PR is tracked as #34837.
PR: #34837 - Add MIBC profile generator for InitializeComponent methods
Platforms Affected: iOS, MacCatalyst, tvOS build/publish path; Android requested for testing but target is platform-gated to no-op on Android.
Files Changed: 12 implementation/build files, 0 test files
Key Findings
- PR adds a standalone
MibcProfileGeneratortool, packages it withMicrosoft.Maui.Controls.Build.Tasks, and wires_MauiGenerateMibcProfileinto the R2R assembly selection path. - The generator scans
PublishReadyToRunExcludeassemblies through a response file and writes a.matchedsidecar so only assemblies containingInitializeComponent*methods are promoted to partial R2R. - Gate was already completed separately and skipped because no tests were detected in the PR.
- Prior discussion requested perf and size impact; PR comments report a synthetic XAML startup improvement and no measurable MAUI template-app device savings.
Code Review Summary
Verdict: LGTM
Confidence: medium
Errors: 0 | Warnings: 0 | Suggestions: 0
Key code review findings:
- No new actionable, non-duplicative code-review findings were found by the independent code-review sub-agent.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #34837 | Standalone MIBC generator invoked via dotnet exec, response-file input, .matched sidecar, and MSBuild target promotion of matched assemblies only. |
MibcProfileGenerator/*, Controls.Build.Tasks.csproj, Microsoft.Maui.Controls.targets, solution/filter files |
Original PR |
Code Review — Deep Analysis
Code Review — PR #34837
Independent Assessment
What this changes: Adds a packaged MIBC profile generator and opt-in MSBuild target for partial R2R of MAUI XAML InitializeComponent* methods.
Inferred motivation: Improve no-JIT platform startup/debug performance by selectively precompiling XAML entry points.
Reconciliation with PR Narrative
Author claims: Matches implementation.
Agreement/disagreement: Narrative says _SelectUserAssemblies; code uses _SelectR2RAssemblies, discussed as intentional for macios.
Findings
No new actionable, non-duplicative findings.
Devil's Advocate
Could not locally verify macios _SelectR2RAssemblies; CI iOS legs passed.
Verdict: LGTM
Confidence: medium
Summary: No GitHub comments posted. Wrote review artifacts to CustomAgentLogsTmp/PRState/34837/PRAgent/.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | maui-expert-reviewer | Replace standalone generator with an in-process MSBuild task returning matched assemblies directly. | ❌ BLOCKED | Not applied | Meaningfully different but too broad/high-risk for safe validation in this loop. |
| 2 | try-fix | Hard-fail missing @response files instead of logging and continuing with an empty input list. |
✅ PASS | 1 file | Improves error signaling for the PR's response-file protocol. |
| 3 | try-fix | Sort discovered methods before metadata emission and set deterministic ZIP entry timestamp for .mibc output. |
✅ PASS | 1 file | Improves reproducibility of generated profiles. |
| PR | PR #34837 | Standalone generator invoked by MSBuild through dotnet exec, response-file input, .matched sidecar, and matched-assembly partial R2R promotion. |
12 implementation/build files | Original PR. Android testing is effectively no-op because the target is iOS/MacCatalyst/tvOS-gated. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| maui-expert-reviewer | 1 | Yes | Suggested replacing the standalone tool with an in-process MSBuild task; recorded as Candidate 1 and blocked as too broad for safe validation. |
| maui-expert-reviewer | 2 | No | NO NEW IDEAS after reviewing Candidates 1-3 and their test results. |
Narrative
Candidate 1 explored a different architecture, removing the external tool and sidecar protocol entirely. It was not applied because it would require a broad rewrite of packaging, solution membership, and netstandard2.0-compatible task implementation before it could be validated.
Candidate 2 passed targeted checks and is a small, demonstrably safer change: if the MSBuild-generated response file is missing, the generator now fails instead of producing an empty profile with exit code 0.
Candidate 3 passed targeted checks and is also additive: sorting method emission and fixing the ZIP timestamp makes generated .mibc files reproducible for the same logical output name.
Exhausted: Yes
Selected Fix: Candidate #2 + Candidate #3 — They are the best validated improvements from the loop. They do not replace the PR's core standalone-generator approach, but they are safer additive changes than the broad in-process-task rewrite.
Report — Final Recommendation
Comparative Report - PR #34837
Candidates compared
| Rank | Candidate | Regression status | Assessment |
|---|---|---|---|
| 1 | pr-plus-reviewer |
Targeted validation passed; gate was skipped because no tests were detected | Best candidate. Preserves the PR's standalone-generator approach while applying expert reviewer feedback: MAUI-scoped MSBuild property naming and non-zero failure for missing response files. |
| 2 | try-fix-2 |
Passed | Good narrow improvement for response-file correctness, but it does not address the unscoped public MSBuild property. |
| 3 | try-fix-3 |
Passed | Useful reproducibility improvement, but it is less critical than correctness/API-surface feedback and does not address either expert finding except indirectly improving determinism. |
| 4 | pr |
Gate skipped; no tests detected | Functional baseline, but expert review found two actionable issues: unprefixed public build property and silent success for missing response files. |
| 5 | try-fix-1 |
Blocked | Potentially cleaner long-term architecture, but it was not applied or validated and is too broad/high-risk for this loop. |
Analysis
The raw PR implements the core behavior: generating a MIBC profile from assemblies in PublishReadyToRunExclude, writing a .matched sidecar, and promoting only assemblies that contain InitializeComponent* methods into partial ReadyToRun. That approach is acceptable as a baseline, but expert review found two issues that should be corrected before shipping: the opt-in property should be MAUI-scoped, and missing response files should fail instead of producing an empty profile with exit code 0.
try-fix-2 directly addresses the missing response-file failure mode and passed targeted validation. try-fix-3 also passed and improves deterministic output by sorting methods and fixing the ZIP timestamp. However, neither standalone try-fix candidate addresses the full expert feedback set. try-fix-1 is ranked last because blocked candidates must be below validated candidates; it proposes a broader in-process MSBuild task rewrite that was not safely validated.
pr-plus-reviewer is the single best candidate because it keeps the submitted PR architecture, incorporates the validated missing-response-file fix from try-fix-2, and additionally resolves the MSBuild property naming issue identified by the expert reviewer. The determinism improvement from try-fix-3 remains a reasonable optional follow-up, but it is not more important than the correctness and public build-surface issues fixed by pr-plus-reviewer.
Winner
pr-plus-reviewer
Rationale: This candidate is a PR-fix candidate that preserves the original implementation while addressing all actionable expert-review feedback. It ranks above the raw PR and individual try-fix candidates because it combines the most important validated correctness improvement with the MAUI build-property naming fix.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
|
@kubaflo it will take us a couple of days to get to this - we need to solve the debuggers first. This needs special testing with hot-reload (which currently is blocked on the debuggers work) and possibly some design discussions. I would like to see another perf test - the numbers in the description are off the mark - the test seems to have run on desktop runtime (with real JIT), while the mobile runtime has interpreter, so the timings will be very different. |
|
@vitek-karas sure! I will convert it to draft then for now :) |
Summary
Adds a build tool that generates MIBC (Managed Instrumented Binary Code) profile files listing all
InitializeComponent*methods from compiled MAUI assemblies. These files do not have any actual profile data, but they can be consumed by crossgen2 for partial compilation. Also add MSBuild targets to enable partial R2R for just XAML-generated code when the .NET for iOS SDK is enabling their partial R2R support.What's included
MibcProfileGenerator tool (src/Controls/src/Build.Tasks/MibcProfileGenerator/)
A standalone .NET console app that:
System.Reflection.MetadataInitializeComponent— primary entry pointInitializeComponentRuntime— runtime XAML inflationInitializeComponentXamlC— XamlC IL-compiled pathInitializeComponentSourceGen— source generator compiled path.mibc) and uncompressed (.dll) outputdotnet-pgo dumpMSBuild integration
_MauiGenerateMibcProfileinMicrosoft.Maui.Controls.targets_SelectUserAssembliesso it can see all user assemblies that may have XAML in the application.Packaging
_CopyToBuildTasksDirtargetUsage
Enabled in .NET for iOS Debug builds when targeting CoreCLR.
Supersedes #34660 so CI can run
Impact
Synthetic XAML startup benchmark on osx-arm64 Release: a console host loads 30 generated MAUI pages and calls
InitializeComponenton each.MAUI template app on device doesn't provide measurable savings in this experiment. Composite-mode publish on ios-arm64 succeeded and the generated MIBC was passed to crossgen2, but
R2RDumpon the emitted composite image showed zeroInitializeComponentmethods compiled. The iOS SDK's composite path appears to drop the per-method include list from the MIBC at the bubble level.