Skip to content
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

[XABT] Move JLO scanning needed for typemap generation to a linker step. #10015

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jpobst
Copy link
Contributor

@jpobst jpobst commented Apr 8, 2025

Context: #9893
Context: #9930

This commit moves the process of scanning for JLOs needed for the typemap generation task to a new FindTypeMapObjectsStep "linker step".

The types are serialized to a new <assembly>.typemap.xml files that sits beside the source assembly. A new file was used rather than adding more sections to the .jlo.xml file because this file contains a lot more types and will likely change more often on incremental builds, and we don't want to trigger ie: creating new Java stubs when it isn't needed.

This file is then read in the existing <GenerateTypeMappings> to generate the final typemap file.

Like #9893, this temporarily leaves the old typemap generation code in place, guarded behind the $(_AndroidJLOCheckedBuild) flag. This flag generates the typemap both the new and old way, and errors the build if there are differences.

@jpobst jpobst force-pushed the dev/jpobst/link-step-typemaps branch from e187164 to 4a00982 Compare April 8, 2025 20:57
@jpobst
Copy link
Contributor Author

jpobst commented Apr 8, 2025

A potential issue here is with cross-assembly duplicate detection.

Today, we are scanning all JLO derived types from all assemblies in a single loop, so duplicate detection logic like the following finds duplicates even if they are in different assemblies:

TypeMapDebugEntry oldEntry = duplicates [0];
if ((td.IsAbstract || td.IsInterface) &&
!oldEntry.TypeDefinition.IsAbstract &&
!oldEntry.TypeDefinition.IsInterface &&
td.IsAssignableFrom (oldEntry.TypeDefinition, cache)) {
// We found the `Invoker` type *before* the declared type
// Fix things up so the abstract type is first, and the `Invoker` is considered a duplicate.
duplicates.Insert (0, entry);
oldEntry.SkipInJavaToManaged = false;
} else {
// ¯\_(ツ)_/¯
duplicates.Add (entry);

Because the new process only scans a single assembly at a time with Cecil, it will find duplicates in the same assembly, but not duplicates that may exist in other assemblies. An example is Java.Lang.Object:

Existing process:
- JavaName: "java/lang/Object" 
- ManagedName: "Java.Interop.JavaObject, Java.Interop" 
- SkipInJavaToManaged: "False" 
- DuplicateForJavaToManaged
  - JavaName: "java/lang/Object" 
  - ManagedName: "Java.Lang.Object, Mono.Android" 

New process:
- JavaName: "java/lang/Object" 
- ManagedName: "Java.Interop.JavaObject, Java.Interop" 
- SkipInJavaToManaged: "False" 
- DuplicateForJavaToManaged: null

It looks like we have 2 ordering semantics we have to preserve in replicating this logic:

  • A declared type should take precedence over an "invoker" type.
  • Types in Mono.Android should take precedence over other assemblies.

Aside from these 2 cases, which type is considered the "primary" and which type(s) are considered the "duplicates" seems to be luck of the draw.

@jonpryor
Copy link
Member

jonpryor commented Apr 8, 2025

@jpobst wrote:

type is considered the "primary" and which type(s) are considered the "duplicates" seems to be luck of the draw.

This is correct and incomplete. If you're only going by Java.Lang.Object.GetObject(handle), then you are correct.

However, most codepaths are not hitting Object.GetObject(IntPtr). Most codepaths are hitting Object.GetObject<T>(…) or Object.GetObject(…, Type targetType), which constrains which type that is used.

Thus, even if there are duplicate types (because bindings for a .jar are present in multiple assemblies), it generally won't matter because the APIs you're using will dictate the actual types used.

@jpobst jpobst force-pushed the dev/jpobst/link-step-typemaps branch from 4a00982 to 27023c8 Compare April 8, 2025 23:00
@jpobst jpobst force-pushed the dev/jpobst/link-step-typemaps branch from 27023c8 to 9b84897 Compare April 8, 2025 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants