Skip to content

Add trim-aware runtime EventSource foundation - #12843

Merged
simonrozsival merged 7 commits into
mainfrom
simonrozsival-eventsource-foundation
Sep 22, 2026
Merged

simonrozsival merged 7 commits into
mainfrom
simonrozsival-eventsource-foundation

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Add the EventSource/EventPipe provider foundation for runtime diagnostics without defining events or adding production instrumentation call sites.

  • add the empty Microsoft.Android.Runtime provider in the trimmable Mono.Android.dll
  • use the standard System.Diagnostics.Tracing.EventSource.IsSupported feature switch as the sole compile/trim gate
  • expose that internal CoreLib switch through an internal RuntimeFeature.EventSourceSupport wrapper whose fallback matches CoreLib: enabled unless AppContext explicitly disables it
  • create the provider lazily so EventSourceSupport=false removes its implementation and guarded call paths from trimmed Release applications
  • reserve the future event ID and keyword contract in documentation only:
  • document enabling EventSource support and enabling diagnostics separately for out-of-process dotnet-trace transport

Scope

This is Layer 1 and the bottom PR of registered GitHub stack 12855:

  1. Add trim-aware runtime EventSource foundation #12843 — EventSource foundation
  2. Add GC bridge EventSource timing #12849 — GC bridge timing
  3. Add trimmable typemap EventSource timing #12851 — trimmable typemap timing
  4. Deprecate Android.Runtime.TimingLogger #12853 — deprecate and detach Android.Runtime.TimingLogger
  5. Remove native FastTiming #12854 — remove FastTiming from CoreCLR

This layer intentionally does not:

Each concrete event and its call sites are added by the later layer that owns that instrumentation.

Validation

  • built Mono.Android.csproj
  • compiled Xamarin.Android.Build.Tests
  • passed the provider foundation test, which verifies the provider name/metadata, EventListener provider creation, and that the provider declares zero events
  • passed RuntimeEventSourceFeatureSwitch(false/true), including runtimeconfig validation and linked-assembly inspection proving the nested provider implementation is removed when EventSourceSupport=false and retained when EventSourceSupport=true
  • built Mono.Android.NET-Tests.csproj with EventSourceSupport=true using the local Android workload

Introduce the trim-aware Microsoft.Android.Runtime provider contract, wire its private feature switch to EventSource support, and cover metadata, emission, runtime configuration, and trimming behavior.

Co-authored-by: Copilot App <[email protected]>
Copilot AI lite review requested due to automatic review settings September 21, 2026 12:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The provider contract test fails with InvalidCastException, and the reserved event ID coverage and documentation wording need updates.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity · 1 Low severity

Open (3)
What changed in this PR

Adds an opt-in, trim-aware Microsoft.Android.Runtime EventSource foundation for future runtime diagnostics.

Changes:

  • Defines provider metadata, reserved IDs, keywords, and diagnostic events.
  • Adds feature-switch, runtimeconfig, and trimming support.
  • Adds tests and dotnet-trace documentation.
File Summary
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Mono.Android.NET-Tests.csproj Enables and includes runtime EventSource tests.
tests/​Mono.Android-Tests/​Mono.Android-Tests/​Android.Runtime/​RuntimeEventSourceTests.cs Tests provider metadata and event emission; enum constant casting currently causes InvalidCastException, and reserved IDs 1–6 are not asserted.
src/​Xamarin.Android.Build.Tasks/​Tests/​Xamarin.Android.Build.Tests/​Tasks/​LinkerTests.cs Validates runtime configuration, feature switches, and trimming behavior.
src/​Xamarin.Android.Build.Tasks/​Microsoft.Android.Sdk/​targets/​Microsoft.Android.Sdk.RuntimeConfig.targets Emits runtime configuration options.
src/​Xamarin.Android.Build.Tasks/​Microsoft.Android.Sdk/​targets/​Microsoft.Android.Sdk.DefaultProperties.targets Enables EventSource support for the opt-in feature.
src/​Mono.Android/​Mono.Android.csproj Includes the provider implementation.
src/​Mono.Android/​Microsoft.Android.Runtime/​RuntimeFeature.cs Defines the disabled-by-default feature switch.
src/​Mono.Android/​Microsoft.Android.Runtime/​RuntimeEventSource.cs Implements the lazy EventSource provider and events.
Documentation/​guides/​tracing.md Documents provider activation and collection; wording should clarify that the runtime option is overridden.

Comment thread Documentation/guides/tracing.md Outdated
simonrozsival and others added 2 commits September 21, 2026 16:21
Handle reflected enum constants correctly, lock the reserved event ID contract in tests, and clarify the runtime EventSource support override in the tracing guide.

Co-authored-by: Copilot App <[email protected]>
Remove the Android-specific EventSource opt-in and gate the provider directly on System.Diagnostics.Tracing.EventSource.IsSupported. Update trimming, runtimeconfig, emission tests, and tracing documentation to use EventSourceSupport.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

✅ Android PR Reviewer completed successfully!

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • azcliprod.blob.core.windows.net

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "azcliprod.blob.core.windows.net"

See Network Configuration for more information.

Generated by Android PR Reviewer for #12843

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Needs Changes — 0 errors, 0 warnings, 1 suggestion.

The trim-aware design is sound: the standard CoreLib feature switch gates a lazy provider holder, the linker test verifies both runtimeconfig propagation and removal/retention of the nested implementation, and the EventListener test validates the emitted IDs, keywords, tasks, and opcodes. Please complete the provider-contract coverage for the second type-map direction as noted inline.

CI is still in progress. The completed Linux/macOS build and Android Tools/Java.Interop lanes are green, with the remaining test matrix still running; this review therefore does not treat CI as green yet.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • azcliprod.blob.core.windows.net

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "azcliprod.blob.core.windows.net"

See Network Configuration for more information.

Generated by Android PR Reviewer for #12843 · copilot · gpt56 · 93.8 AIC · ⌖ 9.76 AIC · ⊞ 17.6K
Comment /review to run again

simonrozsival and others added 2 commits September 21, 2026 17:32
Remove the GC bridge, type-map, and interop event definitions from the bottom layer. Retain only the gated provider foundation, document the reserved contract for later layers, and verify the provider declares no events.

Co-authored-by: Copilot App <[email protected]>
Require future event helpers to guard the standard feature switch directly, validate the complete trimmed call path through a trimmable library, preserve the provider singleton lifetime in tests, and clarify Release defaults.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival
simonrozsival added this pull request to stack #12855 September 21, 2026 17:41
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

✅ Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12843

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Needs Changes — 0 errors, 0 warnings, 1 suggestion.

The trim-aware provider foundation is well scoped: the provider is lazy, the standard runtime switch is propagated into runtimeconfig, both enabled and disabled linked outputs are inspected, and the device test verifies provider creation without prematurely defining events. The remaining inline suggestion asks that the newly added production RuntimeFeature.EventSourceSupport wrapper be exercised directly instead of only testing a copied implementation.

CI is still in progress: all 42 completed checks are green, while MSBuild+Emulator 10 remains running and the aggregate dotnet-android check remains queued. This review therefore does not treat CI as fully green yet.

Generated by Android PR Reviewer for #12843 · copilot · gpt56 · 110.8 AIC · ⌖ 9.76 AIC · ⊞ 17.6K
Comment /review to run again

Comment thread src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs
Exercise RuntimeFeature.EventSourceSupport in the on-device provider foundation test so the production wrapper cannot drift independently from the linker fixture.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

✅ Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12843

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Needs Changes — 0 errors, 0 warnings, 1 suggestion.

The trim gate, provider metadata, project wiring, and enabled/disabled linker behavior are coherent with the stated foundation scope. I left one inline testing suggestion to lock the claimed lazy provider creation rather than only proving creation on access.

CI is still running: the Android Tools Tests Mac check has passed, while the remaining Azure DevOps checks are queued or in progress.

Generated by Android PR Reviewer for #12843 · copilot · gpt56 · 66.5 AIC · ⌖ 9.76 AIC · ⊞ 17.6K
Comment /review to run again

Assert the EventListener has not observed Microsoft.Android.Runtime before the provider holder is accessed, covering the foundation's lazy initialization contract.

Co-authored-by: Copilot App <[email protected]>
@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

✅ Android PR Reviewer completed successfully!

Generated by Android PR Reviewer for #12843

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — 0 errors, 0 warnings, 1 suggestion.

The foundation is appropriately scoped: it uses the standard CoreLib feature switch, creates the provider lazily, verifies enabled/disabled runtimeconfig and linked output, and directly tests provider metadata and creation without prematurely defining events. I left one non-blocking inline suggestion to cover the MonoVM trimming path in addition to CoreCLR.

CI is green: all 44 checks passed, including the aggregate dotnet-android Azure DevOps build and license/cla.

Generated by Android PR Reviewer for #12843 · copilot · gpt56 · 93.7 AIC · ⌖ 9.83 AIC · ⊞ 17.6K
Comment /review to run again

@simonrozsival simonrozsival added the do-not-merge PR should not be merged. label Sep 22, 2026
@simonrozsival simonrozsival added this to the .NET 12 milestone Sep 22, 2026
@simonrozsival simonrozsival removed the do-not-merge PR should not be merged. label Sep 22, 2026
@simonrozsival
simonrozsival merged commit 3dd2afc into main Sep 22, 2026
44 checks passed
@simonrozsival
simonrozsival deleted the simonrozsival-eventsource-foundation branch September 22, 2026 15:29
jonathanpeppers pushed a commit that referenced this pull request Sep 23, 2026
## Summary

Layer 2 of registered GitHub stack `12855`, built on the EventSource foundation merged by #12843.

- emit the reserved `Microsoft.Android.Runtime` GC bridge events (IDs 7/8, keyword `0x8`, task 1)
- measure the complete logical bridge round: Start after callback validation and before `EnsureAllContextsAreOurs`; Stop after collected-context processing, `JavaMarshal.FinishCrossReferenceProcessing`, and `AndroidRuntimeInternal.NotifyBridgeProcessingFinished`
- evaluate EventSource enablement once at Start, latch it on the dedicated serialized bridge thread, and use that decision at Stop
- initialize the enabled provider during bridge setup so the first event does not lazily construct EventSource while a GC is waiting
- preserve feature-off trimming of provider initialization and both production call sites
- document the boundary and zero-payload contract

This intentionally does not add typemap lookup instrumentation, modify `TimingLogger`, or remove/disable `FastTiming`.

## Validation

- `Mono.Android.Runtime.csproj` build
- `Mono.Android.csproj` build
- full Debug local SDK build
- `RuntimeEventSourceFeatureSwitch` linker tests: 2 passed
- CoreCLR Mono.Android.NET GC bridge/provider tests with `AndroidTypeMapImplementation=llvm-ir`: 3 passed, 1 pre-existing ignored
- CoreCLR Mono.Android.NET GC bridge/provider tests with `AndroidTypeMapImplementation=trimmable`: 3 passed, 1 pre-existing ignored

## Stack

- Foundation: #12843, merged into `main`
- Base: `main`
- This layer: #12849
- Next layer: #12851
- Registered GitHub stack: `12855`

Co-authored-by: Copilot App <[email protected]>
simonrozsival added a commit that referenced this pull request Sep 24, 2026
## Summary

Layer 3 of registered GitHub stack `12855`, above #12849 and foundation #12843.

- own the complete trimmable typemap provider contract: event IDs 9/10, keyword `0x4`, task 2, and `JavaToManaged` / `ManagedToJava` direction payloads
- instrument trimmable typemap cache-population misses in both directions
- check `RuntimeFeature.EventSourceSupport` and listener/keyword enablement only inside the `ConcurrentDictionary.GetOrAdd` miss factories
- latch Start emission and pair Stop in `finally`, including failed and throwing backend lookups
- preserve linker removal when `EventSourceSupport=false`
- document exact miss-only semantics and payloads

Cache hits perform no feature-switch or EventSource enablement check and emit no events. The Stop payload has no success/found field, matching the provider contract.

This layer remains scoped to the trimmable typemap path on the current CoreCLR-only runtime model. It does not add legacy runtime assumptions and does not modify TimingLogger or FastTiming.

## Validation

- `./dotnet-local.sh build src/Mono.Android/Mono.Android.csproj -v:minimal`
- `./dotnet-local.sh test bin/TestDebug/net10.0/Xamarin.Android.Build.Tests.dll --filter "Name~RuntimeEventSourceFeatureSwitch"` — 2 passed
- trimmable CoreCLR on-device `Mono.Android.NET-Tests`, categories `TypeMap,GCBridge` — 7 passed, 1 expected skip
- default CoreCLR on-device `Mono.Android.NET-Tests`, category `TypeMap` — 4 expected trimmable-only skips; no default-path timing assertion remains

## Stack

- Base: #12849 / `simonrozsival-gc-bridge-timing`
- This layer: #12851
- Next layer: #12853
- Registered GitHub stack: `12855`
simonrozsival added a commit that referenced this pull request Sep 26, 2026
## Summary

- mark `Android.Runtime.TimingLogger` obsolete with guidance to use `Stopwatch` or `EventSource`
- replace its native FastTiming-backed implementation with managed monotonic timing while preserving the `Logger.LogTiming` opt-in gate, `monodroid-timing` logcat tag, default message, elapsed format, and idempotent state transitions
- remove the remaining `monodroid_timing_start`/`monodroid_timing_stop` declarations, CoreCLR dispatch entries, NativeAOT stubs, and native managed-timing sequence allocator

## Stack

Layer 4 of registered GitHub stack `12855`, above #12851, #12849, and #12843.

- Base: `main` (the lower layers have merged)
- This layer: #12853
- Top layer: #12854

FastTiming instrumentation, timing properties/modes, dump handling, call sites, and FastTiming tests are intentionally retained here and deferred to Layer 5.

## Validation

- `Mono.Android.csproj` build with API compatibility checks
- `native-clr.csproj` x86_64 build
- `native-nativeaot.csproj` x86_64 build

The APK descriptions now use the versions from `main`. The Mono runtime and its generated P/Invoke table were removed upstream, so no Mono-specific validation remains in this layer.
simonrozsival added a commit that referenced this pull request Sep 30, 2026
## Summary

Layer 5 and the top PR of registered GitHub stack `12855`, above merged #12853, #12851, #12849, and #12843.

- remove native FastTiming instrumentation, event storage, formatting, summaries, configuration, and self-overhead measurement
- remove the shared FastTiming implementation/static library and all CoreCLR timing call sites
- remove FastTiming properties/modes, JNI/export dump entrypoint, broadcast receiver, manifest overlay, packaging hooks, and `_AndroidFastTiming`
- retain the exact plain `timing` log category for the obsolete managed `Android.Runtime.TimingLogger`
- remove the obsolete `FastTimingTests` device test
- direct runtime/JIT/loader diagnostics to EventPipe and Android bridge/type-map diagnostics to `Microsoft.Android.Runtime`
- refresh CoreCLR APK size references from a local rebuild after rebasing onto current `main`

## Size

The four `BuildReleaseArm64` CoreCLR references were regenerated locally after rebasing onto `main` (`64920590083e2d50e0d99d716ce2d82c46bdb4f9`):

| Variant | APK delta | `libmonodroid.so` | Delta | Assembly-store delta |
|---|---:|---:|---:|---:|
| Simple CoreCLR | -12,288 B | 158,792 → 120,096 B | -38,696 B (-24.37%) | +512 B |
| Simple CoreCLR + R8 | -16,384 B | 158,792 → 120,096 B | -38,696 B (-24.37%) | +664 B |
| XForms CoreCLR | -12,288 B | 151,488 → 120,096 B | -31,392 B (-20.72%) | -192 B |
| XForms CoreCLR + R8 | -12,288 B | 151,488 → 120,096 B | -31,392 B (-20.72%) | -200 B |

The size matrix passed all four `BuildReleaseArm64` regression tests after copying the freshly generated `.apkdesc` files.

The earlier managed-size investigation used isolated merge-base/PR builds and extracted every assembly. It found no managed DLL size growth: all extracted assemblies had identical uncompressed totals before and after this PR. The small assembly-store changes above are compressed/layout differences, not a ~100 KiB managed-code increase.

## Startup

Prior balanced startup measurements showed overlapping distributions and no measurable startup effect; no startup regression or improvement is claimed.

## Validation

- rebased onto current `main` and resolved `host.cc` plus four APK reference conflicts
- full `make all CONFIGURATION=Release`
- CoreCLR APK size regression tests: 4 passed
- CoreCLR EventSource linker feature-switch tests: 2 passed
- CoreCLR `RunWithLogging` property regression test verifies `debug.dotnet.log=default,assembly,timing`
- trimmable type-map tests: 1,277 passed, 1 skipped
- native no-op incrementality: `_ConfigureRuntimes` and `_BuildAndroidRuntimes` skip with no CMake/Ninja execution
- managed `TimingLogger` and lower-layer EventSource/type-map contract sources remain unchanged

## Stack

- Final base: `main`
- This layer: #12854
- Registered GitHub stack: `12855`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants