Remove the managed typemap implementation#12134
Conversation
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
managed typemap implementation
There was a problem hiding this comment.
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 theRuntimeFeature.ManagedTypeMapfeature 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
managedas 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
JnienvInitializeArgsstill includesmarshalMethodsEnabled, but after removing themanagedMarshalMethodsLookupEnabledbranch there is no longer any CoreCLR initialization path that callsxamarin_app_initto populate the generatedget_function_pointerglobal. Repo-wide search showsxamarin_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
|
@copilot resolve the merge conflicts in this pull request |
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Merged
Merge commit: |
2af4625 to
917a1be
Compare
|
/review |
|
✅ Android PR Reviewer completed successfully! |
There was a problem hiding this comment.
🤖 Code Review — Remove the managed typemap implementation
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, orget_function_pointer_placeholderacrosssrc/andtests/. - The managed↔native struct pairs stay in sync: the field dropped from
JnienvInitializeArgs(C#) matchesmanaged-interface.hh, andmanaged_marshal_methods_lookup_enabledis removed consistently fromApplicationConfig/ApplicationConfigCLR, bothxamarin-app.hhheaders, and bothapplication_dso_stub.ccstubs. EnvironmentHelperfield counts are correctly decremented (MonoVM 27→26, CoreCLR 21→20) with the trailingcasebranches removed and remaining cases re-indexed.- Deleted files are removed from
Mono.Android.csproj; MSBuild validation now correctly accepts onlyllvm-irandtrimmable.
Findings
⚠️ 1 question (inline onsrc/native/clr/host/host.cc): with the managed lookup gone, nothing appears to callxamarin_app_initfor 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.csupdated to point at the trimmable type map instead of the deletedTypeMappingStep. - Test matrix (
InstallAndRunTests) and docs updated to drop themanagedcases.
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; | |||
There was a problem hiding this comment.
🤖
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.)
There was a problem hiding this comment.
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...
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.
_AndroidTypeMapImplementationnow accepts onlyllvm-ir(Mono/CoreCLR) andtrimmable.Changes
Runtime (
src/Mono.Android)ManagedTypeManagerandManagedTypeMapping.RuntimeFeature.ManagedTypeMapfeature switch.JNIEnvInit.CreateTypeManager,JNIEnv.ArrayCreateInstance, andJavaConvert(incl. theirIL3050suppression helpers).NativeAOT host (
src/Microsoft.Android.Runtime.NativeAOT)JreRuntime.CreateDefaultTypeManagernow returnsTrimmableTypeMapTypeManagerunconditionally.Generator / assembly rewriting
TypeMappingStep(which rewrote theManagedTypeMappingmethod bodies) and its registration inMicrosoft.Android.Sdk.TypeMap.LlvmIr.targets.MSBuild / SDK targets
_AndroidUseManagedTypeMapand theManagedTypeMapRuntimeHostConfigurationOptionfromRuntimeConfig.targets.managedfrom the_AndroidTypeMapImplementationvalidation inXamarin.Android.Common.targets.Microsoft.Android.Sdk.NativeAOT.targets.Tests & docs
managedtest cases (InstallAndRunTests, the obsoleteBuildTest2.NativeAOTtest)..github/copilot-instructions.mdand stale comments to list onlyllvm-irandtrimmable.Kept intentionally
llvm-irnative typemap path (TypeMapGenerator,GenerateTypeMappings,GenerateEmptyTypemapStub— themanaged_to_java_mapstructures there are the native map's .NET→Java direction, not the managed implementation).XAJavaTypeScanner/ XA4212 (a generalIJavaObjectdiagnostic, not managed-specific).SingleUniverseTypeMap,AggregateTypeMap,GenerateMissingTypeMapStubs, etc.).