Skip to content

[generator] Use GC.KeepAlive for reference type method parameters. #725

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

Merged
merged 1 commit into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}

Expand All @@ -46,6 +47,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}

Expand All @@ -65,6 +67,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}

Expand All @@ -84,6 +87,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}
}
Expand Down Expand Up @@ -65,6 +66,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}
}
Expand Down Expand Up @@ -94,6 +96,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}
}
Expand Down Expand Up @@ -123,6 +126,7 @@ public partial class MyClass {
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ static void n_SetAdapter_Lxamarin_test_SpinnerAdapter_ (IntPtr jnienv, IntPtr na
__args [0] = new JniArgumentValue ((value == null) ? IntPtr.Zero : ((global::Java.Lang.Object) value).Handle);
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (value);
}
}
}
Expand Down Expand Up @@ -137,6 +138,7 @@ public AbsSpinnerInvoker (IntPtr handle, JniHandleOwnership transfer) : base (ha
_members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_value);
global::System.GC.KeepAlive (value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ public AdapterViewInvoker (IntPtr handle, JniHandleOwnership transfer) : base (h
_members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_value);
global::System.GC.KeepAlive (value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public unsafe SpannableString (global::Java.Lang.ICharSequence source) : base (I
_members.InstanceMethods.FinishCreateInstance (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_source);
global::System.GC.KeepAlive (source);
}
}

Expand All @@ -74,6 +75,7 @@ public unsafe SpannableString (string source) : base (IntPtr.Zero, JniHandleOwne
_members.InstanceMethods.FinishCreateInstance (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_source);
global::System.GC.KeepAlive (source);
}
}

Expand Down Expand Up @@ -106,6 +108,7 @@ static int n_GetSpanFlags_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this
var __rm = _members.InstanceMethods.InvokeVirtualInt32Method (__id, this, __args);
return (global::Android.Text.SpanTypes) __rm;
} finally {
global::System.GC.KeepAlive (what);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static int n_GetSpanFlags_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this
var __rm = _members.InstanceMethods.InvokeVirtualInt32Method (__id, this, __args);
return (global::Android.Text.SpanTypes) __rm;
} finally {
global::System.GC.KeepAlive (p0);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ public virtual unsafe void SetOnClickListener (global::Android.Views.View.IOnCli
__args [0] = new JniArgumentValue ((l == null) ? IntPtr.Zero : ((global::Java.Lang.Object) l).Handle);
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (l);
}
}

Expand Down Expand Up @@ -211,6 +212,7 @@ public virtual unsafe void SetOn123Listener (global::Android.Views.View.IOnClick
__args [0] = new JniArgumentValue ((l == null) ? IntPtr.Zero : ((global::Java.Lang.Object) l).Handle);
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (l);
}
}

Expand Down Expand Up @@ -243,6 +245,7 @@ public virtual unsafe void AddTouchables (global::System.Collections.Generic.ILi
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_views);
global::System.GC.KeepAlive (views);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public unsafe void SetOnEventListener (global::Com.Google.Android.Exoplayer.Drm.
__args [0] = new JniArgumentValue ((p0 == null) ? IntPtr.Zero : ((global::Java.Lang.Object) p0).Handle);
_members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (p0);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ public unsafe InstanceInner (global::Xamarin.Test.NotificationCompatBase __self)
SetHandle (__r.Handle, JniHandleOwnership.TransferLocalRef);
_members.InstanceMethods.FinishCreateInstance (__id, this, __args);
} finally {
global::System.GC.KeepAlive (__self);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public unsafe SomeObject (global::Java.Lang.Class c) : base (IntPtr.Zero, JniHan
SetHandle (__r.Handle, JniHandleOwnership.TransferLocalRef);
_members.InstanceMethods.FinishCreateInstance (__id, this, __args);
} finally {
global::System.GC.KeepAlive (c);
}
}

Expand Down Expand Up @@ -114,6 +115,8 @@ static int n_Handle_Ljava_lang_Object_Ljava_lang_Throwable_ (IntPtr jnienv, IntP
var __rm = _members.InstanceMethods.InvokeVirtualInt32Method (__id, this, __args);
return __rm;
} finally {
global::System.GC.KeepAlive (o);
global::System.GC.KeepAlive (t);
}
}

Expand Down Expand Up @@ -260,6 +263,7 @@ public virtual unsafe void VoidMethodWithParams (string astring, int anint, glob
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_astring);
global::System.GC.KeepAlive (anObject);
}
}

Expand Down Expand Up @@ -323,6 +327,7 @@ public virtual unsafe void ArrayListTest (global::System.Collections.Generic.ILi
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_p0);
global::System.GC.KeepAlive (p0);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ public override unsafe int SomeInteger {
__args [0] = new JniArgumentValue ((value == null) ? IntPtr.Zero : ((global::Java.Lang.Object) value).Handle);
_members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public virtual unsafe void SetA (global::Java.Lang.Object adapter)
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_adapter);
global::System.GC.KeepAlive (adapter);
}
}

Expand Down Expand Up @@ -98,6 +99,7 @@ public virtual unsafe void ListTest (global::System.Collections.Generic.IList<gl
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_p0);
global::System.GC.KeepAlive (p0);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public static unsafe void SetSomeObject (global::Java.Lang.Object newvalue)
__args [0] = new JniArgumentValue ((newvalue == null) ? IntPtr.Zero : ((global::Java.Lang.Object) newvalue).Handle);
_members.StaticMethods.InvokeVoidMethod (__id, __args);
} finally {
global::System.GC.KeepAlive (newvalue);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public unsafe FilterOutputStream (global::System.IO.Stream @out) : base (IntPtr.
_members.InstanceMethods.FinishCreateInstance (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native__out);
global::System.GC.KeepAlive (@out);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ public virtual unsafe int Read (byte[] buffer)
JNIEnv.CopyArray (native_buffer, buffer);
JNIEnv.DeleteLocalRef (native_buffer);
}
global::System.GC.KeepAlive (buffer);
}
}

Expand Down Expand Up @@ -262,6 +263,7 @@ public virtual unsafe int Read (byte[] buffer, int byteOffset, int byteCount)
JNIEnv.CopyArray (native_buffer, buffer);
JNIEnv.DeleteLocalRef (native_buffer);
}
global::System.GC.KeepAlive (buffer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ public virtual unsafe void Write (byte[] buffer)
JNIEnv.CopyArray (native_buffer, buffer);
JNIEnv.DeleteLocalRef (native_buffer);
}
global::System.GC.KeepAlive (buffer);
}
}

Expand Down Expand Up @@ -180,6 +181,7 @@ public virtual unsafe void Write (byte[] buffer, int offset, int count)
JNIEnv.CopyArray (native_buffer, buffer);
JNIEnv.DeleteLocalRef (native_buffer);
}
global::System.GC.KeepAlive (buffer);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public virtual unsafe void SetObject (byte[] value)
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ static void n_SetObject_Ljava_lang_Object_ (IntPtr jnienv, IntPtr native__this,
__args [0] = new JniArgumentValue ((value == null) ? IntPtr.Zero : ((global::Java.Lang.Object) value).Handle);
_members.InstanceMethods.InvokeVirtualVoidMethod (__id, this, __args);
} finally {
global::System.GC.KeepAlive (value);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public virtual unsafe void SetObject (string[] value)
JNIEnv.CopyArray (native_value, value);
JNIEnv.DeleteLocalRef (native_value);
}
global::System.GC.KeepAlive (value);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public override unsafe int GetSpanFlags (global::Java.Lang.Object tag)
var __rm = _members.InstanceMethods.InvokeAbstractInt32Method (__id, this, __args);
return __rm;
} finally {
global::System.GC.KeepAlive (tag);
}
}

Expand All @@ -203,6 +204,7 @@ public override unsafe void Append (global::Java.Lang.ICharSequence value)
_members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_value);
global::System.GC.KeepAlive (value);
}
}

Expand All @@ -219,6 +221,7 @@ public override unsafe void Append (global::Java.Lang.ICharSequence value)
return global::Java.Lang.Object.GetObject<Java.Lang.ICharSequence> (__rm.Handle, JniHandleOwnership.TransferLocalRef);
} finally {
JNIEnv.DeleteLocalRef (native_value);
global::System.GC.KeepAlive (value);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public unsafe int CompareTo (global::Java.Lang.Object o)
return __rm;
} finally {
JNIEnv.DeleteLocalRef (native_o);
global::System.GC.KeepAlive (o);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,32 @@ public bool Validate (CodeGenerationOptions opt, GenericParameterDefinitionList
return true;
}

public bool ShouldGenerateKeepAlive ()
{
if (Symbol.IsEnum)
return false;

return Type switch {
"bool" => false,
"sbyte" => false,
"char" => false,
"double" => false,
"float" => false,
"int" => false,
"long" => false,
"short" => false,
"uint" => false,
"ushort" => false,
"ulong" => false,
"byte" => false,
"ubyte" => false, // Not a C# type, but we will see it from Kotlin unsigned types support
"string" => false,
"java.lang.String" => false,
"Android.Graphics.Color" => false,
_ => true
};
}

public ISymbol Symbol => sym;
}
}
4 changes: 4 additions & 0 deletions tools/generator/SourceWriters/BoundConstructor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ protected override void WriteBody (CodeWriter writer)
var call_cleanup = constructor.Parameters.GetCallCleanup (opt);
foreach (string cleanup in call_cleanup)
writer.WriteLine (cleanup);

foreach (var p in constructor.Parameters.Where (para => para.ShouldGenerateKeepAlive ()))
writer.WriteLine ($"global::System.GC.KeepAlive ({opt.GetSafeIdentifier (p.Name)});");

writer.Unindent ();

writer.WriteLine ("}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ public static void AddMethodBody (List<string> body, Method method, CodeGenerati
foreach (string cleanup in method.Parameters.GetCallCleanup (opt))
body.Add ("\t" + cleanup);

foreach (var p in method.Parameters.Where (para => para.ShouldGenerateKeepAlive ()))
body.Add ($"\tglobal::System.GC.KeepAlive ({opt.GetSafeIdentifier (p.Name)});");

body.Add ("}");
}

Expand Down