Description
C#9 allows specifying the System.Runtime.CompilerServices.SkipLocalsInitAttribute custom attribute on methods (and other things) for performance reasons:
Finally, you can add the System.Runtime.CompilerServices.SkipLocalsInitAttribute to instruct the compiler not to emit the
localsinit
flag. This flag instructs the CLR to zero-initialize all local variables. Thelocalsinit
flag has been the default behavior for C# since 1.0. However, the extra zero-initialization may have measurable performance impact in some scenarios. In particular, when you usestackalloc
. In those cases, you can add the SkipLocalsInitAttribute.
Our generated binding code does use stackalloc
, e.g. https://github.com/xamarin/java.interop/blob/b0d170c1002e5481564c0afc78afd6dbf3d40e66/tests/generator-Tests/expected.ji/Adapters/Xamarin.Test.AdapterView.cs#L117-L129
We should consider updating generator
output to place [SkipLocalsInit]
on such methods, e.g.
[Register ("setAdapter", "(Lxamarin/test/Adapter;)V", "GetSetAdapter_Lxamarin_test_Adapter_Handler")]
[SkipLocalsInit]
set {
const string __id = "setAdapter.(Lxamarin/test/Adapter;)V";
IntPtr native_value = JNIEnv.ToLocalJniHandle (value);
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (native_value);
_members.InstanceMethods.InvokeAbstractVoidMethod (__id, this, __args);
} finally {
JNIEnv.DeleteLocalRef (native_value);
global::System.GC.KeepAlive (value);
}
}
Problems
The SkipLocalsInitAttribute
is added in .NET 5, which places it into a similar "bucket" as SupportedOSPlatformAttribute
(da12df4, a33084b), which we had to disable in 00862ad.
We likely can't emit SkipLocalsInitAttribute
until we can emit SupportedOSPlatformAttribute
.