Skip to content

Commit

Permalink
[generator] Avoid C#11 delegate cache overhead. (#1053)
Browse files Browse the repository at this point in the history
Fixes: #1034

Context: dotnet/roslyn#62832 (comment)
Context: 
Context: dotnet/android@938b2cb

[The C#11 compiler was updated][0] so that "method group conversions"
are now cached:

> The C# 11 compiler caches the delegate object created from a method
> group conversion and reuses that single delegate object.

Our marshal method infrastructure uses method group conversions,
e.g. the cast to `(_JniMarshal_PP_L)` is a method group conversion:

	static Delegate GetGetActionBarHandler ()
	{
	    if (cb_getActionBar == null)
	        cb_getActionBar = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_GetActionBar);
	    return cb_getActionBar;
	}

This C# 11 compiler change resulted in `Mono.Android.dll` and
.NET Android apps being ~4.5% *larger*.

This was worked around in dotnet/android@938b2cbe by setting
`$(LangVersion)`=10 (i.e. "don't use C# 11").

Update `generator` output to avoid use of method group conversion
for delegate types.  This allows us to use C# 11 without increasing
the size of `Mono.Android.dll` and .NET Android apps:

	static Delegate GetGetActionBarHandler ()
	{
	    if (cb_getActionBar == null)
	        cb_getActionBar = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_GetActionBar));
	    return cb_getActionBar;
	}

[0]: https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-11#improved-method-group-conversion-to-delegate
  • Loading branch information
jpobst authored Oct 25, 2022
1 parent 2d8b6d2 commit 8e18c90
Show file tree
Hide file tree
Showing 61 changed files with 167 additions and 158 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, Anima
static Delegate GetOnAnimationEnd_IHandler ()
{
if (cb_OnAnimationEnd_I == null)
cb_OnAnimationEnd_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_Z) n_OnAnimationEnd_I);
cb_OnAnimationEnd_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_Z (n_OnAnimationEnd_I));
return cb_OnAnimationEnd_I;
}

Expand All @@ -97,7 +97,7 @@ internal partial class AnimatorListenerInvoker : global::Java.Lang.Object, Anima
static Delegate GetOnAnimationEnd_IIHandler ()
{
if (cb_OnAnimationEnd_II == null)
cb_OnAnimationEnd_II = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPII_Z) n_OnAnimationEnd_II);
cb_OnAnimationEnd_II = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPII_Z (n_OnAnimationEnd_II));
return cb_OnAnimationEnd_II;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,77 +4,86 @@ public partial interface IMyInterface2 : java.code.IMyInterface {
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]"
[Register ("DoSomething", "()V", "GetDoSomethingHandler:java.code.IMyInterface2Invoker, MyAssembly")]
void DoSomething ();

}

[global::Android.Runtime.Register ("java/code/IMyInterface2", DoNotGenerateAcw=true)]
internal partial class IMyInterface2Invoker : global::Java.Lang.Object, IMyInterface2 {
static readonly JniPeerMembers _members = new JniPeerMembers ("java/code/IMyInterface2", typeof (IMyInterface2Invoker));
static readonly JniPeerMembers _members = new XAPeerMembers ("java/code/IMyInterface2", typeof (IMyInterface2Invoker));

static IntPtr java_class_ref {
get { return _members.JniPeerType.PeerReference.Handle; }
}


[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
public override global::Java.Interop.JniPeerMembers JniPeerMembers {
get { return _members; }
}


[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
protected override IntPtr ThresholdClass {
get { return class_ref; }
}


[global::System.Diagnostics.DebuggerBrowsable (global::System.Diagnostics.DebuggerBrowsableState.Never)]
[global::System.ComponentModel.EditorBrowsable (global::System.ComponentModel.EditorBrowsableState.Never)]
protected override global::System.Type ThresholdType {
get { return _members.ManagedPeerType; }
}

IntPtr class_ref;

public static IMyInterface2 GetObject (IntPtr handle, JniHandleOwnership transfer)
{
return global::Java.Lang.Object.GetObject<IMyInterface2> (handle, transfer);
}

static IntPtr Validate (IntPtr handle)
{
if (!JNIEnv.IsInstanceOf (handle, java_class_ref))
throw new InvalidCastException (string.Format ("Unable to convert instance of type '{0}' to type '{1}'.", JNIEnv.GetClassNameFromInstance (handle), "java.code.IMyInterface2"));
throw new InvalidCastException ($"Unable to convert instance of type '{JNIEnv.GetClassNameFromInstance (handle)}' to type 'java.code.IMyInterface2'.");
return handle;
}

protected override void Dispose (bool disposing)
{
if (this.class_ref != IntPtr.Zero)
JNIEnv.DeleteGlobalRef (this.class_ref);
this.class_ref = IntPtr.Zero;
base.Dispose (disposing);
}

public IMyInterface2Invoker (IntPtr handle, JniHandleOwnership transfer) : base (Validate (handle), transfer)
{
IntPtr local_ref = JNIEnv.GetObjectClass (((global::Java.Lang.Object) this).Handle);
this.class_ref = JNIEnv.NewGlobalRef (local_ref);
JNIEnv.DeleteLocalRef (local_ref);
}

static Delegate cb_DoSomething;
#pragma warning disable 0169
#pragma warning disable 0169
static Delegate GetDoSomethingHandler ()
{
if (cb_DoSomething == null)
cb_DoSomething = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_V) n_DoSomething);
cb_DoSomething = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_V (n_DoSomething));
return cb_DoSomething;
}

static void n_DoSomething (IntPtr jnienv, IntPtr native__this)
{
var __this = global::Java.Lang.Object.GetObject<java.code.IMyInterface2> (jnienv, native__this, JniHandleOwnership.DoNotTransfer);
__this.DoSomething ();
}
#pragma warning restore 0169
#pragma warning restore 0169

IntPtr id_DoSomething;
public unsafe void DoSomething ()
{
if (id_DoSomething == IntPtr.Zero)
id_DoSomething = JNIEnv.GetMethodID (class_ref, "DoSomething", "()V");
JNIEnv.CallVoidMethod (((global::Java.Lang.Object) this).Handle, id_DoSomething);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public partial class MyClass {
static Delegate Getget_CountHandler ()
{
if (cb_get_Count == null)
cb_get_Count = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_Count);
cb_get_Count = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_I (n_get_Count));
return cb_get_Count;
}

Expand All @@ -70,7 +70,7 @@ public partial class MyClass {
static Delegate Getset_Count_IHandler ()
{
if (cb_set_Count_I == null)
cb_set_Count_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_Count_I);
cb_set_Count_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_V (n_set_Count_I));
return cb_set_Count_I;
}

Expand Down Expand Up @@ -110,7 +110,7 @@ public partial class MyClass {
static Delegate Getget_KeyHandler ()
{
if (cb_get_Key == null)
cb_get_Key = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_get_Key);
cb_get_Key = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_get_Key));
return cb_get_Key;
}

Expand All @@ -126,7 +126,7 @@ public partial class MyClass {
static Delegate Getset_Key_Ljava_lang_String_Handler ()
{
if (cb_set_Key_Ljava_lang_String_ == null)
cb_set_Key_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_V) n_set_Key_Ljava_lang_String_);
cb_set_Key_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_V (n_set_Key_Ljava_lang_String_));
return cb_set_Key_Ljava_lang_String_;
}

Expand Down Expand Up @@ -193,7 +193,7 @@ public partial class MyClass {
static Delegate Getget_AbstractCountHandler ()
{
if (cb_get_AbstractCount == null)
cb_get_AbstractCount = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_AbstractCount);
cb_get_AbstractCount = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_I (n_get_AbstractCount));
return cb_get_AbstractCount;
}

Expand All @@ -209,7 +209,7 @@ public partial class MyClass {
static Delegate Getset_AbstractCount_IHandler ()
{
if (cb_set_AbstractCount_I == null)
cb_set_AbstractCount_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_AbstractCount_I);
cb_set_AbstractCount_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_V (n_set_AbstractCount_I));
return cb_set_AbstractCount_I;
}

Expand All @@ -235,7 +235,7 @@ public partial class MyClass {
static Delegate GetGetCountForKey_Ljava_lang_String_Handler ()
{
if (cb_GetCountForKey_Ljava_lang_String_ == null)
cb_GetCountForKey_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_I) n_GetCountForKey_Ljava_lang_String_);
cb_GetCountForKey_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_I (n_GetCountForKey_Ljava_lang_String_));
return cb_GetCountForKey_Ljava_lang_String_;
}

Expand Down Expand Up @@ -269,7 +269,7 @@ public partial class MyClass {
static Delegate GetKeyHandler ()
{
if (cb_Key == null)
cb_Key = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_Key);
cb_Key = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_Key));
return cb_Key;
}

Expand Down Expand Up @@ -308,7 +308,7 @@ public partial class MyClass {
static Delegate GetAbstractMethodHandler ()
{
if (cb_AbstractMethod == null)
cb_AbstractMethod = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_V) n_AbstractMethod);
cb_AbstractMethod = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_V (n_AbstractMethod));
return cb_AbstractMethod;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate Getget_CountHandler ()
{
if (cb_get_Count == null)
cb_get_Count = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_Count);
cb_get_Count = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_I (n_get_Count));
return cb_get_Count;
}

Expand All @@ -151,7 +151,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate Getset_Count_IHandler ()
{
if (cb_set_Count_I == null)
cb_set_Count_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_Count_I);
cb_set_Count_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_V (n_set_Count_I));
return cb_set_Count_I;
}

Expand Down Expand Up @@ -184,7 +184,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate Getget_KeyHandler ()
{
if (cb_get_Key == null)
cb_get_Key = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_get_Key);
cb_get_Key = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_get_Key));
return cb_get_Key;
}

Expand All @@ -200,7 +200,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate Getset_Key_Ljava_lang_String_Handler ()
{
if (cb_set_Key_Ljava_lang_String_ == null)
cb_set_Key_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_V) n_set_Key_Ljava_lang_String_);
cb_set_Key_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_V (n_set_Key_Ljava_lang_String_));
return cb_set_Key_Ljava_lang_String_;
}

Expand Down Expand Up @@ -236,7 +236,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate Getget_AbstractCountHandler ()
{
if (cb_get_AbstractCount == null)
cb_get_AbstractCount = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_AbstractCount);
cb_get_AbstractCount = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_I (n_get_AbstractCount));
return cb_get_AbstractCount;
}

Expand All @@ -252,7 +252,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate Getset_AbstractCount_IHandler ()
{
if (cb_set_AbstractCount_I == null)
cb_set_AbstractCount_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_AbstractCount_I);
cb_set_AbstractCount_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_V (n_set_AbstractCount_I));
return cb_set_AbstractCount_I;
}

Expand Down Expand Up @@ -285,7 +285,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate GetGetCountForKey_Ljava_lang_String_Handler ()
{
if (cb_GetCountForKey_Ljava_lang_String_ == null)
cb_GetCountForKey_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_I) n_GetCountForKey_Ljava_lang_String_);
cb_GetCountForKey_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_I (n_GetCountForKey_Ljava_lang_String_));
return cb_GetCountForKey_Ljava_lang_String_;
}

Expand Down Expand Up @@ -316,7 +316,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate GetKeyHandler ()
{
if (cb_Key == null)
cb_Key = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_Key);
cb_Key = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_Key));
return cb_Key;
}

Expand All @@ -340,7 +340,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate GetAbstractMethodHandler ()
{
if (cb_AbstractMethod == null)
cb_AbstractMethod = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_V) n_AbstractMethod);
cb_AbstractMethod = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_V (n_AbstractMethod));
return cb_AbstractMethod;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public partial class MyClass : Java.Lang.Object {
static Delegate GetEcho_arrayLjava_lang_CharSequence_Handler ()
{
if (cb_echo_arrayLjava_lang_CharSequence_ == null)
cb_echo_arrayLjava_lang_CharSequence_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_L) n_Echo_arrayLjava_lang_CharSequence_);
cb_echo_arrayLjava_lang_CharSequence_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_L (n_Echo_arrayLjava_lang_CharSequence_));
return cb_echo_arrayLjava_lang_CharSequence_;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public partial class MyClass {
static Delegate Getget_CountHandler ()
{
if (cb_get_Count == null)
cb_get_Count = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_Count);
cb_get_Count = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_I (n_get_Count));
return cb_get_Count;
}

Expand All @@ -70,7 +70,7 @@ public partial class MyClass {
static Delegate Getset_Count_IHandler ()
{
if (cb_set_Count_I == null)
cb_set_Count_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_Count_I);
cb_set_Count_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_V (n_set_Count_I));
return cb_set_Count_I;
}

Expand Down Expand Up @@ -110,7 +110,7 @@ public partial class MyClass {
static Delegate Getget_KeyHandler ()
{
if (cb_get_Key == null)
cb_get_Key = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_get_Key);
cb_get_Key = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_get_Key));
return cb_get_Key;
}

Expand All @@ -126,7 +126,7 @@ public partial class MyClass {
static Delegate Getset_Key_Ljava_lang_String_Handler ()
{
if (cb_set_Key_Ljava_lang_String_ == null)
cb_set_Key_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_V) n_set_Key_Ljava_lang_String_);
cb_set_Key_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_V (n_set_Key_Ljava_lang_String_));
return cb_set_Key_Ljava_lang_String_;
}

Expand Down Expand Up @@ -193,7 +193,7 @@ public partial class MyClass {
static Delegate Getget_AbstractCountHandler ()
{
if (cb_get_AbstractCount == null)
cb_get_AbstractCount = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_I) n_get_AbstractCount);
cb_get_AbstractCount = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_I (n_get_AbstractCount));
return cb_get_AbstractCount;
}

Expand All @@ -209,7 +209,7 @@ public partial class MyClass {
static Delegate Getset_AbstractCount_IHandler ()
{
if (cb_set_AbstractCount_I == null)
cb_set_AbstractCount_I = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPI_V) n_set_AbstractCount_I);
cb_set_AbstractCount_I = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPI_V (n_set_AbstractCount_I));
return cb_set_AbstractCount_I;
}

Expand All @@ -235,7 +235,7 @@ public partial class MyClass {
static Delegate GetGetCountForKey_Ljava_lang_String_Handler ()
{
if (cb_GetCountForKey_Ljava_lang_String_ == null)
cb_GetCountForKey_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate ((_JniMarshal_PPL_I) n_GetCountForKey_Ljava_lang_String_);
cb_GetCountForKey_Ljava_lang_String_ = JNINativeWrapper.CreateDelegate (new _JniMarshal_PPL_I (n_GetCountForKey_Ljava_lang_String_));
return cb_GetCountForKey_Ljava_lang_String_;
}

Expand Down Expand Up @@ -269,7 +269,7 @@ public partial class MyClass {
static Delegate GetKeyHandler ()
{
if (cb_Key == null)
cb_Key = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_L) n_Key);
cb_Key = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_L (n_Key));
return cb_Key;
}

Expand Down Expand Up @@ -308,7 +308,7 @@ public partial class MyClass {
static Delegate GetAbstractMethodHandler ()
{
if (cb_AbstractMethod == null)
cb_AbstractMethod = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_V) n_AbstractMethod);
cb_AbstractMethod = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_V (n_AbstractMethod));
return cb_AbstractMethod;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public partial interface IMyInterface : IJavaObject, IJavaPeerable {
private static Delegate GetDoDefaultHandler ()
{
if (cb_DoDefault == null)
cb_DoDefault = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_V) n_DoDefault);
cb_DoDefault = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_V (n_DoDefault));
return cb_DoDefault;
}

Expand Down Expand Up @@ -96,7 +96,7 @@ internal partial class IMyInterfaceInvoker : global::Java.Lang.Object, IMyInterf
static Delegate GetDoDeclarationHandler ()
{
if (cb_DoDeclaration == null)
cb_DoDeclaration = JNINativeWrapper.CreateDelegate ((_JniMarshal_PP_V) n_DoDeclaration);
cb_DoDeclaration = JNINativeWrapper.CreateDelegate (new _JniMarshal_PP_V (n_DoDeclaration));
return cb_DoDeclaration;
}

Expand Down
Loading

0 comments on commit 8e18c90

Please sign in to comment.