Skip to content

Remove the managed typemap implementation#12134

Open
simonrozsival wants to merge 6 commits into
mainfrom
android-remove-managed-type-map
Open

Remove the managed typemap implementation#12134
simonrozsival wants to merge 6 commits into
mainfrom
android-remove-managed-type-map

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Jul 16, 2026

Copy link
Copy Markdown
Member

Description

Now that NativeAOT defaults to the trimmable typemap (#12121), the reflection-based managed typemap is no longer needed. This PR removes all traces of it. _AndroidTypeMapImplementation now accepts only llvm-ir (Mono/CoreCLR) and trimmable.

Changes

Runtime (src/Mono.Android)

  • Delete ManagedTypeManager and ManagedTypeMapping.
  • Remove the RuntimeFeature.ManagedTypeMap feature switch.
  • Drop the managed branches in JNIEnvInit.CreateTypeManager, JNIEnv.ArrayCreateInstance, and JavaConvert (incl. their IL3050 suppression helpers).

NativeAOT host (src/Microsoft.Android.Runtime.NativeAOT)

  • JreRuntime.CreateDefaultTypeManager now returns TrimmableTypeMapTypeManager unconditionally.

Generator / assembly rewriting

  • Delete the ILLink TypeMappingStep (which rewrote the ManagedTypeMapping method bodies) and its registration in Microsoft.Android.Sdk.TypeMap.LlvmIr.targets.

MSBuild / SDK targets

  • Remove _AndroidUseManagedTypeMap and the ManagedTypeMap RuntimeHostConfigurationOption from RuntimeConfig.targets.
  • Drop managed from the _AndroidTypeMapImplementation validation in Xamarin.Android.Common.targets.
  • Remove the now-dead non-trimmable NativeAOT scaffolding (ILLink-before-ILC path) from Microsoft.Android.Sdk.NativeAOT.targets.

Tests & docs

  • Remove managed test cases (InstallAndRunTests, the obsolete BuildTest2.NativeAOT test).
  • Update .github/copilot-instructions.md and stale comments to list only llvm-ir and trimmable.

Kept intentionally

  • The llvm-ir native typemap path (TypeMapGenerator, GenerateTypeMappings, GenerateEmptyTypemapStub — the managed_to_java_map structures there are the native map's .NET→Java direction, not the managed implementation).
  • XAJavaTypeScanner / XA4212 (a general IJavaObject diagnostic, not managed-specific).
  • The trimmable typemap (SingleUniverseTypeMap, AggregateTypeMap, GenerateMissingTypeMapStubs, etc.).

simonrozsival and others added 4 commits July 16, 2026 13:33
Now that NativeAOT defaults to the trimmable typemap (#12121), the
reflection-based "managed" typemap is unused. Remove all traces of it:

* Runtime (src/Mono.Android): delete ManagedTypeManager and
  ManagedTypeMapping, remove the RuntimeFeature.ManagedTypeMap feature
  switch, and drop the managed branches in JNIEnvInit.CreateTypeManager,
  JNIEnv.ArrayCreateInstance, and JavaConvert.
* NativeAOT host: JreRuntime.CreateDefaultTypeManager always returns
  TrimmableTypeMapTypeManager.
* Generator / assembly rewriting: delete the ILLink TypeMappingStep and
  its registration in Microsoft.Android.Sdk.TypeMap.LlvmIr.targets.
* MSBuild/SDK: remove _AndroidUseManagedTypeMap and the ManagedTypeMap
  RuntimeHostConfigurationOption, drop "managed" from the
  _AndroidTypeMapImplementation validation, and remove the now-dead
  non-trimmable NativeAOT scaffolding in
  Microsoft.Android.Sdk.NativeAOT.targets.
* Tests/docs: remove "managed" test cases and update documentation to
  list only llvm-ir and trimmable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 40c65ba4-c9e2-442f-bc68-0bd274f0bf8c
The managed marshal methods lookup generated a managed IL table (indexed
by assembly/class/method) so native code could call back into managed to
resolve marshal-method function pointers. It was only ever used by
CoreCLR/NativeAOT; MonoVM always used the native `get_function_pointer`
path, and marshal methods default off for non-MonoVM. Remove the feature
entirely — marshal methods are now MonoVM-only.

* MSBuild codegen: delete ManagedMarshalMethodsLookupInfo and
  ManagedMarshalMethodsLookupGenerator; drop the managed-lookup branch in
  MarshalMethodsNativeAssemblyGenerator (keep the MonoVM native path), the
  index population in MarshalMethodCecilAdapter (+ the AssemblyIndex/
  ClassIndex/MethodIndex properties), the rewriter/generator/task plumbing,
  and the EnableManagedMarshalMethodsLookup task parameters.
* Native ABI: remove managed_marshal_methods_lookup_enabled from
  ApplicationConfig (mono + clr), the DSO stubs, and
  managedMarshalMethodsLookupEnabled from JnienvInitializeArgs; drop the
  CLR host invariant and the now-dead get_function_pointer_placeholder;
  MonoVM always wires up the native get_function_pointer callbacks.
* Runtime: delete ManagedMarshalMethodsLookupTable and the managed
  xamarin_app_init p/invoke; remove the struct field + init branch.
* Targets/tests: remove _AndroidUseManagedMarshalMethodsLookup, update
  EnvironmentHelper struct mirrors/field counts, and delete the device
  test that force-enabled the feature.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 40c65ba4-c9e2-442f-bc68-0bd274f0bf8c
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 676a2066-2e01-4963-86bc-942e444a22da
@simonrozsival simonrozsival changed the title Remove the "managed" typemap implementation Remove the managed typemap implementation Jul 17, 2026
@simonrozsival
simonrozsival marked this pull request as ready for review July 17, 2026 08:15
Copilot AI review requested due to automatic review settings July 17, 2026 08:16

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.

Pull request overview

This PR removes the reflection-based managed typemap implementation now that NativeAOT defaults to the trimmable typemap, and tightens _AndroidTypeMapImplementation support to only llvm-ir and trimmable. It also deletes the now-dead managed typemap ILLink step and related build/runtime plumbing.

Changes:

  • Removed managed typemap runtime code (ManagedTypeManager/ManagedTypeMapping) and the RuntimeFeature.ManagedTypeMap feature switch.
  • Deleted managed typemap generator/rewriter pieces (ILLink TypeMappingStep, managed marshal-method lookup table/generator, and associated MSBuild properties/targets).
  • Updated targets, tests, and docs to drop managed as a supported/covered configuration.
Show a summary per file
File Description
tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs Removes managed typemap coverage and deletes a managed marshal-method lookup integration test.
src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets Drops managed from _AndroidTypeMapImplementation validation; removes managed marshal-method lookup property plumbing; updates generator task parameters.
src/Xamarin.Android.Build.Tasks/Utilities/NativeCodeGenState.cs Removes ManagedMarshalMethodsLookupInfo from build pipeline state.
src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGeneratorMonoVM.cs Updates generator constructor signature after managed lookup removal.
src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGeneratorCoreCLR.cs Updates generator constructor signature after managed lookup removal.
src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsNativeAssemblyGenerator.cs Removes managed marshal-method lookup argument path and always emits token-based get_function_pointer calls.
src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodsAssemblyRewriter.cs Removes managed lookup generator invocation and corresponding constructor parameter.
src/Xamarin.Android.Build.Tasks/Utilities/MarshalMethodCecilAdapter.cs Removes managed-lookup index propagation into marshal-method entry objects.
src/Xamarin.Android.Build.Tasks/Utilities/ManagedMarshalMethodsLookupInfo.cs Deletes managed marshal-method lookup info type.
src/Xamarin.Android.Build.Tasks/Utilities/ManagedMarshalMethodsLookupGenerator.cs Deletes managed marshal-method lookup table generator.
src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGeneratorCLR.cs Removes managed marshal-method lookup flag from generated native application_config for CoreCLR.
src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigNativeAssemblyGenerator.cs Removes managed marshal-method lookup flag from generated native application_config for MonoVM.
src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfigCLR.cs Removes managed marshal-method lookup field from CoreCLR application_config structure definition.
src/Xamarin.Android.Build.Tasks/Utilities/ApplicationConfig.cs Removes managed marshal-method lookup field from MonoVM application_config structure definition.
src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs Updates application_config parsing field counts/cases to match native struct changes.
src/Xamarin.Android.Build.Tasks/Tasks/RewriteMarshalMethods.cs Removes managed lookup mode/ordering logic from rewrite pipeline.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateTypeMappings.cs Updates NativeAOT comment to reflect trimmable typemap generation and skips typemap generation for NativeAOT.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeMarshalMethodSources.cs Removes managed lookup task property and updates generator construction accordingly.
src/Xamarin.Android.Build.Tasks/Tasks/GenerateNativeApplicationConfigSources.cs Removes managed marshal-method lookup option and stops emitting it into native config inputs.
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.TypeMap.LlvmIr.targets Removes managed-lookup task parameter and deletes the ILLink TypeMappingStep registration for managed.
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.RuntimeConfig.targets Removes _AndroidUseManagedTypeMap and the RuntimeFeature.ManagedTypeMap runtimeconfig option emission.
src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.NativeAOT.targets Removes non-trimmable NativeAOT scaffolding and makes the trimmable/skip-ILLink path unconditional.
src/native/mono/xamarin-app-stub/xamarin-app.hh Removes managed marshal-method lookup flag from MonoVM application_config struct.
src/native/mono/xamarin-app-stub/application_dso_stub.cc Removes managed marshal-method lookup flag initialization in stub config.
src/native/mono/monodroid/xamarin-android-app-context.cc Removes placeholder get_function_pointer implementation used by the managed lookup path.
src/native/mono/monodroid/monodroid-glue.cc Simplifies marshal-method init: always calls xamarin_app_init with startup/runtime resolver, removing managed lookup branching.
src/native/mono/monodroid/monodroid-glue-internal.hh Removes placeholder get_function_pointer declaration.
src/native/common/include/managed-interface.hh Removes managed marshal-method lookup flag from managed initialization args.
src/native/clr/xamarin-app-stub/application_dso_stub.cc Removes managed marshal-method lookup flag initialization in stub config.
src/native/clr/include/xamarin-app.hh Removes managed marshal-method lookup flag from CoreCLR application_config struct.
src/native/clr/host/host.cc Removes passing/validation of managed marshal-method lookup enablement into managed init args.
src/Mono.Android/Mono.Android.csproj Stops compiling managed typemap and managed marshal-method lookup table sources.
src/Mono.Android/Microsoft.Android.Runtime/RuntimeFeature.cs Removes RuntimeFeature.ManagedTypeMap feature switch definition.
src/Mono.Android/Microsoft.Android.Runtime/ManagedTypeMapping.cs Deletes managed typemap mapping implementation.
src/Mono.Android/Microsoft.Android.Runtime/ManagedTypeManager.cs Deletes managed typemap type manager implementation.
src/Mono.Android/Java.Interop/ManagedMarshalMethodsLookupTable.cs Deletes managed marshal-method lookup table entrypoint.
src/Mono.Android/Java.Interop/JavaConvert.cs Removes managed typemap branch and its IL3050 suppression helper.
src/Mono.Android/Android.Runtime/JNIEnvInit.cs Removes managed marshal-method lookup init path; removes managed typemap type-manager selection.
src/Mono.Android/Android.Runtime/JNIEnv.cs Removes managed typemap dynamic array-creation fallback and suppression helper.
src/Microsoft.Android.Sdk.ILLink/TypeMappingStep.cs Deletes the ILLink custom step that rewrote ManagedTypeMapping bodies.
src/Microsoft.Android.Runtime.NativeAOT/Java.Interop/JreRuntime.cs Makes NativeAOT’s default type manager always TrimmableTypeMapTypeManager.
.github/copilot-instructions.md Updates docs/examples to list only llvm-ir and trimmable.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Mono.Android/Android.Runtime/JNIEnvInit.cs:151

  • JnienvInitializeArgs still includes marshalMethodsEnabled, but after removing the managedMarshalMethodsLookupEnabled branch there is no longer any CoreCLR initialization path that calls xamarin_app_init to populate the generated get_function_pointer global. Repo-wide search shows xamarin_app_init(...) is only invoked from the MonoVM runtime (src/native/mono/monodroid/monodroid-glue.cc), so CoreCLR apps with marshal methods enabled will likely dereference a null function pointer in the generated marshal method stubs (or never register them correctly).
			JniRuntime.SetCurrent (androidRuntime);
			RegisterTrimmableTypeMapNativeMethodsIfNeeded ();

			args->propagateUncaughtExceptionFn = (IntPtr)(delegate* unmanaged<IntPtr, IntPtr, IntPtr, void>)&PropagateUncaughtException;

			if (!RuntimeFeature.TrimmableTypeMap) {
				args->registerJniNativesFn = GetRegisterJniNativesFnPtr ();
			}
  • Files reviewed: 42/42 changed files
  • Comments generated: 2

Comment thread src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets
@simonrozsival

Copy link
Copy Markdown
Member Author

@copilot resolve the merge conflicts in this pull request

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>

Copilot AI commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merged origin/main (commits 143d5fb59 and b367d98cd) into this branch. Two conflicts needed manual resolution:

  1. GenerateNativeApplicationConfigSources.cs — kept the new AndroidEnableAssemblyStoreDecompressionCache property from main, dropped EnableManagedMarshalMethodsLookup (removed by this PR).
  2. EnvironmentHelper.cs — resolved ApplicationConfigFieldCount_CoreCLR to 20 (main's 21 minus the removed managed_marshal_methods_lookup_enabled field), and fixed case 20case 19 for assembly_store_decompression_cache_enabled since the preceding managed marshal methods lookup field no longer exists in the struct.

Merge commit: 917a1be85.

@simonrozsival

Copy link
Copy Markdown
Member Author

/review

@simonrozsival simonrozsival added the ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable). label Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@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.

🤖 Code Review — Remove the managed typemap implementation

⚠️ Needs Changes (one verification question) — otherwise a clean, well-scoped removal.

Summary

This PR removes the reflection-based managed typemap and the managed marshal-methods lookup table. I verified the removal is complete and internally consistent:

  • No dangling references remain to ManagedTypeMap, ManagedTypeManager, ManagedTypeMapping, ManagedMarshalMethodsLookup*, managed_marshal_methods_lookup_enabled, _AndroidUseManagedTypeMap, TypeMappingStep, or get_function_pointer_placeholder across src/ and tests/.
  • The managed↔native struct pairs stay in sync: the field dropped from JnienvInitializeArgs (C#) matches managed-interface.hh, and managed_marshal_methods_lookup_enabled is removed consistently from ApplicationConfig/ApplicationConfigCLR, both xamarin-app.hh headers, and both application_dso_stub.cc stubs.
  • EnvironmentHelper field counts are correctly decremented (MonoVM 27→26, CoreCLR 21→20) with the trailing case branches removed and remaining cases re-indexed.
  • Deleted files are removed from Mono.Android.csproj; MSBuild validation now correctly accepts only llvm-ir and trimmable.

Findings

  • ⚠️ 1 question (inline on src/native/clr/host/host.cc): with the managed lookup gone, nothing appears to call xamarin_app_init for the CoreCLR host, so CoreCLR marshal-method function-pointer resolution may be left unwired. Please confirm CoreCLR + marshal-methods Release is covered by device-test CI. This is the only thing I'd want verified before merge.

Positives

  • Excellent cleanup hygiene — dead ILLink step, feature switch, RuntimeHostConfigurationOption, and NativeAOT ILLink-before-ILC scaffolding all removed together.
  • Stale comments in GenerateTypeMappings.cs updated to point at the trimmable type map instead of the deleted TypeMappingStep.
  • Test matrix (InstallAndRunTests) and docs updated to drop the managed cases.

Note: GitHub combined status is currently pending/no checks reported — the Azure DevOps dotnet-android validation should be green (especially device tests) before merge.

Generated by Android PR Reviewer for #12134 · 163.4 AIC · ⌖ 18.9 AIC · ⊞ 6.8K
Comment /review to run again

@@ -431,9 +431,6 @@ void Host::Java_mono_android_Runtime_initInternal (
init.jniAddNativeMethodRegistrationAttributePresent = application_config.jni_add_native_method_registration_attribute_present ? 1 : 0;
init.jniRemappingInUse = application_config.jni_remapping_replacement_type_count > 0 || application_config.jni_remapping_replacement_method_index_entry_count > 0;
init.marshalMethodsEnabled = application_config.marshal_methods_enabled;

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.

🤖 ⚠️ JNI interop — Question: how do CoreCLR marshal methods resolve their function pointer now?

Previously, for the CoreCLR host, _AndroidUseManagedMarshalMethodsLookup defaulted to true (the removed Common.targets condition enabled it for any _AndroidRuntime != 'MonoVM'), and the only thing that called xamarin_app_init for CoreCLR was the managed p/invoke in JNIEnvInit.Initialize (xamarin_app_init(args->env, &ManagedMarshalMethodsLookupTable.GetFunctionPointer)) — both removed in this PR.

The generated marshal-method bodies still go through the base MarshalMethodsNativeAssemblyGenerator.WriteBody placeholder path, which loads the get_func_ptr global set by xamarin_app_init. But unlike MonoVM (monodroid-glue.cc calls xamarin_app_init(env, get_function_pointer_at_startup)), the CoreCLR host never calls xamarin_app_init, and there is no get_function_pointer_at_startup implementation under src/native/clr/. With the managed caller gone, that callback appears to stay unset.

Can you confirm a CoreCLR + EnableMarshalMethods=true Release app is covered by device-test CI on this PR? If CoreCLR marshal methods still rely on the managed lookup, removing it here may leave the get_function_pointer callback null at runtime.

(Not blocking review approval — flagging for CI verification.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Marshal methods are not supported with CoreCLR (without the trimmable typemap) because there are issues with the ordering of R2R and post-trimming assembly rewriting (generating marshal methods UCO methods) in outer and inner builds...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drop-javainterop1 ready-to-review This PR is ready to review/merge, I think any CI failures are just flaky (ignorable).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants