You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Java.Interop.Tools.JavaCallableWrappers] use IMetadataResolver more (dotnet#1069)
Context: b81cfbb
Reviewing code in `JavaCallableWrapperGenerator`, I found codepaths
where we weren't caching `TypeReference.Resolve()` calls *at all*,
e.g. `JavaNativeTypeManager.GetPrimitiveClass(TypeDefinition)`.
We thus appear to be calling `TypeReference.Resolve()` potentially on
the same types.
For example, `dotnet trace` output of an incremental build of a `dotnet new maui` project:
41.65ms xamarin.android.cecil!Mono.Cecil.TypeReference.Resolve()
It appears that, in trying to make our maintenance lives easier by
preserving backward API compatibility with callers that couldn't
provide a `TypeDefinitionCache` or `IMetadataResolver` instance -- by
providing method overloads which took e.g.
`IMetadataResolver? resolver` parameters which could be `null` -- we
made our optimization and performance lives *harder*, because not
all codepaths which needed to use caching *were* using caching, as
they were overlooked.
As the `Java.Interop.Tools.*` assemblies are internal API, introduce
an *API break* while preserving *ABI*:
`IMetadataResolver` is now required.
Thus, previous/current "compatibility methods" which allow *not*
providing an `IMetadataResolver` instance such as:
// old and busted
partial class TypeDefinitionRocks {
[Obsolete ("Use the TypeDefinitionCache overload for better performance.")]
public static TypeDefinition? GetBaseType (this TypeDefinition type) => GetBaseType (type, resolver: null);
}
will now become *errors* to use:
// new hawtness
partial class TypeDefinitionRocks {
[Obsolete ("Use the TypeDefinitionCache overload for better performance.", error:true)]
public static TypeDefinition? GetBaseType (this TypeDefinition type) => throw new NotSupportedException ();
}
This allows the C# compiler to help us audit our codebase, ensuring
that *all* codepaths which call `TypeReference.Resolve()` instead use
`IMetadataResolver.Resolve()`, including:
* `JavaCallableWrapperGenerator.GetAnnotationsString()`
* `JavaCallableWrapperGenerator.WriteAnnotations()`
* `JavaNativeTypeManager.GetPrimitiveClass()`
Requiring caching results in:
23.89ms xamarin.android.cecil!Mono.Cecil.TypeReference.Resolve()
Additionally, I updated two places to use plain `foreach` loops
instead of using System.Linq.
* Before:
1.03s xamarin.android.build.tasks!Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
* After:
944.48ms xamarin.android.build.tasks!Xamarin.Android.Tasks.GenerateJavaStubs.RunTask()
I think this likely saves about ~50ms off incremental builds of a
`dotnet new maui` project.
0 commit comments