-
Notifications
You must be signed in to change notification settings - Fork 64
Make JniTypeManager faster by optimizing some code #582
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
Conversation
| { | ||
| // If `false`, reflection checks for the presence of the `JniAddNativeMethodRegistrationAttribute` attribute | ||
| // throughout the **entire** application will be skipped. | ||
| public static bool JniAddNativeMethodRegistrationAttributePresent { get; set; } = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This need not exist here. Instead, it should be in JniRuntime.CreationOptions and in JniRuntime.
|
|
||
| static bool FindAndCallRegisterMethod (Type marshalType, JniNativeMethodRegistrationArguments arguments) | ||
| { | ||
| if (!JniTypeManagerOptions.JniAddNativeMethodRegistrationAttributePresent) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would then need to become an instance method, and check Runtime.JniAddNativeMethodRegistrationAttributePresent.
|
Current failed build should be ignorable; it's a SIGSEGV from mono. |
d940181 to
ad4885d
Compare
GetCustomAttribute calls optional in JniTypeManager|
|
||
| internal bool TrackIDs {get; private set;} | ||
| internal bool NewObjectRequired {get; private set;} | ||
| internal CreationOptions Options { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be needed; just add a JniAddNativeMethodRegistrationAttributePresent property, assign it, as is done with JniVersion, InvocationPointer, etc. The approach here will just keep the CreationOptions instance alive ~forever, "wasting" some amount of memory that would otherwise be collectible.
c34fef4 to
63c5c34
Compare
| } | ||
|
|
||
| public JniTypeSignature (string simpleReference, int arrayRank = 0, bool keyword = false) | ||
| public JniTypeSignature (string? simpleReference, int arrayRank = 0, bool keyword = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we allow a null value here? We don't even test what happens when null is provided!
Does it even make sense to allow null here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it's a struct; there's no way to prevent null from here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, that doesn't in turn mean that this constructor needs to support a null parameter, just that it's not possible in general to prevent SimpleReference from being null.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That said, that doesn't in turn mean that this constructor needs to support a null parameter, just that it's not possible in general to prevent SimpleReference from being null.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see just instance when SimpleReference should be allowed to be null - creation of JniTypeSignature.Empty field to use as the default value for variables. As you mentioned on Slack, though, this could be done using a default constructor (possibly private?), though. Could SimpleReference be String.Empty by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could SimpleReference be
String.Emptyby default
No. It's a struct; structs are special, and one way in which they're special is that they always have a default constructor which "zero-initializes" all members, which means that after invoking the default constructor SimpleReference can never be string.Empty; it can only be null.
Which is in part why JniTypeSignature.SimpleReference is of type string? (after enabling nullable-reference-types); there's always a chance it could be null, so all callers need to be careful.
That does not in any way mean or imply that the constructor needs to allow simpleReference to be null. It may be "nice" in that it allows "equivalent construction" between the default constructor and the non-default constructor -- which in itself may be a good thing! -- but it isn't required.
I can't find anything in the Framework Design Guidelines which address this point.
|
|
||
| static bool GetBuiltInTypeArraySignature (Type type, ref JniTypeSignature signature) | ||
| { | ||
| if (type == typeof (JavaPrimitiveArray<Boolean>)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this also be checking against JavaBooleanArray?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't change anything in the .tt generation logic here - the types checked against are the same types we had previously.
| static bool GetBuiltInTypeArraySignature (Type type, ref JniTypeSignature signature) | ||
| { | ||
| if (type == typeof (JavaPrimitiveArray<Boolean>)) { | ||
| signature = GetCachedTypeSignature (ref __BooleanTypePrimitiveArraySignature, "Z", arrayRank: 1, keyword: true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why both __BooleanTypePrimitiveArraySignature and __BooleanTypeArraySignature? They both have the same signature, [Z, and would be Equal to each other. Why not just have the single field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to change the old code semantics, and it kept the two types distinct (maybe because it was all stored in an array) and I always aim to make the minimal set of changes necessary.
63c5c34 to
8c2f7e4
Compare
Optionally do not look for the `JniAddNativeMethodRegistrationAttribute`.
It turns out that this attribute is not commonly present in
Xamarin.Android applications and so all of the calls to
`GetCustomAttribute` failed to find it, incurring unnecessary
performance penalty on the application.
Make the code consult a global flag (in case of Xamarin.Android it is
set on the build time) which tells it whether or not to skip querying
for the above custom attribute. The flag is `true` by default to
maintain backward compatibility.
Optimize the `JniTypeManager.GetTypeSignature` method to not require an
allocation of `Lazy<>` + a number of instances of `KeyValuePair<>` as
well as `JniTypeSignature`. This affects Xamarin.Android startup a
little:
Before:
344 9 199 Java.Interop.JniRuntime/JniTypeManager:GetTypeSignature (System.Type)
After:
82 9 199 Java.Interop.JniRuntime/JniTypeManager:GetTypeSignature (System.Type)
8c2f7e4 to
18f9e78
Compare
...otherwise we get `LV;`, which is wrong, and corresponding unit test failures. See: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3507789&view=ms.vss-test-web.build-test-results-tab&runId=11520990&resultId=100015&paneView=debug
...otherwise we get `LV;`, which is wrong, and corresponding unit test failures. See: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=3507789&view=ms.vss-test-web.build-test-results-tab&runId=11520990&resultId=100015&paneView=debug
Replace the `JniRuntime.JniBuiltinArrayMappings` field and its
associated `Lazy<T>` initializer with new methods
`JniRuntime.GetBuiltInTypeArraySignature()` and
`JniRuntime.GetBuiltInTypeSignature()`, which removes an array
initialization from the `JniRuntime` static constructor and an array
iteration from `JniRuntime.JniTypeManager.GetTypeSignature()`.
Additionally, use `Type.GetTypeCode(Type)` to more quickly map
builtin types such as `string` to `java/lang/String`.
Additionally, add a new
`JniRuntime.CreationOptions.JniAddNativeMethodRegistrationAttributePresent`
property which controls whether or not
`JniRuntime.JniTypeManager.TryRegisterNativeMembers()` attempts to
look for the `[JniAddNativeMethodRegistration]` custom attribute on
methods. This is a seldom used attribute, and if no types in the app
use the attribute, this can save precious startup time by removing
the `method.GetCustomAttribute()` calls.
These changes together improve Xamarin.Android startup time, saving
~262ms:
* Before:
Total(ms) Self(ms) Calls Method name
344 9 199 Java.Interop.JniRuntime/JniTypeManager:GetTypeSignature (System.Type)
* After:
Total(ms) Self(ms) Calls Method name
82 9 199 Java.Interop.JniRuntime/JniTypeManager:GetTypeSignature (System.Type)
Context: dotnet/android#4302 Context: dotnet#582 Java.Interop tests use their own runtime which doesn't know about the results of Xamarin.Android's build process scanning for the presence of the `JniAddNativeMethodRegistration` custom attribute. In addition, Java.Interop's Java type scanner (for typemaps) does not include in its results the types in `Java.Interop-Tests` which derive from `Java.Interop.JavaObject` (which is **functionally** equivalent to Xamarin.Android's `Java.Lang.Object`) and, thus, the scan doesn't notice that the custom attribute mentioned above is used by a few test classes. In effect, two tests fail with a similar exception: Java.Lang.LinkageError : No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <d30c11568ddc48d5aff8f2d4b2eaa867>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions._InvokeConstructor[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00059] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions.FinishGenericCreateInstance[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00029] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.InteropTests.CallVirtualFromConstructorBase..ctor (System.Int32 value) [0x0004e] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.CallVirtualFromConstructorDerived..ctor (System.Int32 value) [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.InvokeVirtualFromConstructorTests.InvokeVirtualFromConstructor () [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <26b1d17e27e54492bd3e4105b16bfc7e>:0 --- End of managed Java.Lang.LinkageError stack trace --- java.lang.UnsatisfiedLinkError: No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(Native Method) at com.xamarin.interop.CallVirtualFromConstructorBase.<init>(Unknown Source:35) at com.xamarin.interop.CallVirtualFromConstructorDerived.<init>(Unknown Source:2) at crc64f295cabbf85394f5.TestSuiteInstrumentation.n_onStart(Native Method) at crc64f295cabbf85394f5.TestSuiteInstrumentation.onStart(Unknown Source:0) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189) Force the tests to always assume the custom attribute is present, thus restoring the default behavior from before Java.Interop PR582
Context: dotnet/android#4302 Context: #582 Java.Interop tests use their own runtime which doesn't know about the results of Xamarin.Android's build process scanning for the presence of the `[JniAddNativeMethodRegistration]` custom attribute. In addition, Java.Interop's Java type scanner (for typemaps) does not include in its results the types in `Java.Interop-Tests` which derive from `Java.Interop.JavaObject` (which is *functionally* equivalent to Xamarin.Android's `Java.Lang.Object`) and, thus, the scan doesn't notice that the custom attribute mentioned above is used by a few test classes. In effect, two tests fail with a similar exception: Java.Lang.LinkageError : No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <d30c11568ddc48d5aff8f2d4b2eaa867>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions._InvokeConstructor[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00059] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions.FinishGenericCreateInstance[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00029] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.InteropTests.CallVirtualFromConstructorBase..ctor (System.Int32 value) [0x0004e] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.CallVirtualFromConstructorDerived..ctor (System.Int32 value) [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.InvokeVirtualFromConstructorTests.InvokeVirtualFromConstructor () [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <26b1d17e27e54492bd3e4105b16bfc7e>:0 --- End of managed Java.Lang.LinkageError stack trace --- java.lang.UnsatisfiedLinkError: No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(Native Method) at com.xamarin.interop.CallVirtualFromConstructorBase.<init>(Unknown Source:35) at com.xamarin.interop.CallVirtualFromConstructorDerived.<init>(Unknown Source:2) at crc64f295cabbf85394f5.TestSuiteInstrumentation.n_onStart(Native Method) at crc64f295cabbf85394f5.TestSuiteInstrumentation.onStart(Unknown Source:0) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189) Force the tests to always assume the custom attribute is present, thus restoring the default behavior from before b33d183.
Context: dotnet/android#4302 Context: #582 Java.Interop tests use their own runtime which doesn't know about the results of Xamarin.Android's build process scanning for the presence of the `[JniAddNativeMethodRegistration]` custom attribute. In addition, Java.Interop's Java type scanner (for typemaps) does not include in its results the types in `Java.Interop-Tests` which derive from `Java.Interop.JavaObject` (which is *functionally* equivalent to Xamarin.Android's `Java.Lang.Object`) and, thus, the scan doesn't notice that the custom attribute mentioned above is used by a few test classes. In effect, two tests fail with a similar exception: Java.Lang.LinkageError : No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <d30c11568ddc48d5aff8f2d4b2eaa867>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions._InvokeConstructor[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00059] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions.FinishGenericCreateInstance[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00029] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.InteropTests.CallVirtualFromConstructorBase..ctor (System.Int32 value) [0x0004e] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.CallVirtualFromConstructorDerived..ctor (System.Int32 value) [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.InvokeVirtualFromConstructorTests.InvokeVirtualFromConstructor () [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <26b1d17e27e54492bd3e4105b16bfc7e>:0 --- End of managed Java.Lang.LinkageError stack trace --- java.lang.UnsatisfiedLinkError: No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(Native Method) at com.xamarin.interop.CallVirtualFromConstructorBase.<init>(Unknown Source:35) at com.xamarin.interop.CallVirtualFromConstructorDerived.<init>(Unknown Source:2) at crc64f295cabbf85394f5.TestSuiteInstrumentation.n_onStart(Native Method) at crc64f295cabbf85394f5.TestSuiteInstrumentation.onStart(Unknown Source:0) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189) Force the tests to always assume the custom attribute is present, thus restoring the default behavior from before b33d183.
Replace the `JniRuntime.JniBuiltinArrayMappings` field and its
associated `Lazy<T>` initializer with new methods
`JniRuntime.GetBuiltInTypeArraySignature()` and
`JniRuntime.GetBuiltInTypeSignature()`, which removes an array
initialization from the `JniRuntime` static constructor and an array
iteration from `JniRuntime.JniTypeManager.GetTypeSignature()`.
Additionally, use `Type.GetTypeCode(Type)` to more quickly map
builtin types such as `string` to `java/lang/String`.
Additionally, add a new
`JniRuntime.CreationOptions.JniAddNativeMethodRegistrationAttributePresent`
property which controls whether or not
`JniRuntime.JniTypeManager.TryRegisterNativeMembers()` attempts to
look for the `[JniAddNativeMethodRegistration]` custom attribute on
methods. This is a seldom used attribute, and if no types in the app
use the attribute, this can save precious startup time by removing
the `method.GetCustomAttribute()` calls.
These changes together improve Xamarin.Android startup time, saving
~262ms:
* Before:
Total(ms) Self(ms) Calls Method name
344 9 199 Java.Interop.JniRuntime/JniTypeManager:GetTypeSignature (System.Type)
* After:
Total(ms) Self(ms) Calls Method name
82 9 199 Java.Interop.JniRuntime/JniTypeManager:GetTypeSignature (System.Type)
Context: dotnet/android#4302 Context: #582 Java.Interop tests use their own runtime which doesn't know about the results of Xamarin.Android's build process scanning for the presence of the `[JniAddNativeMethodRegistration]` custom attribute. In addition, Java.Interop's Java type scanner (for typemaps) does not include in its results the types in `Java.Interop-Tests` which derive from `Java.Interop.JavaObject` (which is *functionally* equivalent to Xamarin.Android's `Java.Lang.Object`) and, thus, the scan doesn't notice that the custom attribute mentioned above is used by a few test classes. In effect, two tests fail with a similar exception: Java.Lang.LinkageError : No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x0008e] in <d30c11568ddc48d5aff8f2d4b2eaa867>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions._InvokeConstructor[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00059] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.Interop.GenericMarshaler.JniPeerInstanceMethodsExtensions.FinishGenericCreateInstance[T] (Java.Interop.JniPeerMembers+JniInstanceMethods peer, System.String constructorSignature, Java.Interop.IJavaPeerable self, T value) [0x00029] in <f6f553d46eb149a29e6542964ef27aaa>:0 at Java.InteropTests.CallVirtualFromConstructorBase..ctor (System.Int32 value) [0x0004e] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.CallVirtualFromConstructorDerived..ctor (System.Int32 value) [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at Java.InteropTests.InvokeVirtualFromConstructorTests.InvokeVirtualFromConstructor () [0x00000] in <d39267c627f54df3bc31406b36effb6c>:0 at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&) at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <26b1d17e27e54492bd3e4105b16bfc7e>:0 --- End of managed Java.Lang.LinkageError stack trace --- java.lang.UnsatisfiedLinkError: No implementation found for void com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(int) (tried Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor and Java_com_xamarin_interop_CallVirtualFromConstructorDerived_calledFromConstructor__I) at com.xamarin.interop.CallVirtualFromConstructorDerived.calledFromConstructor(Native Method) at com.xamarin.interop.CallVirtualFromConstructorBase.<init>(Unknown Source:35) at com.xamarin.interop.CallVirtualFromConstructorDerived.<init>(Unknown Source:2) at crc64f295cabbf85394f5.TestSuiteInstrumentation.n_onStart(Native Method) at crc64f295cabbf85394f5.TestSuiteInstrumentation.onStart(Unknown Source:0) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189) Force the tests to always assume the custom attribute is present, thus restoring the default behavior from before b33d183.
Optionally do not look for the
JniAddNativeMethodRegistrationAttribute.It turns out that this attribute is not commonly present in
Xamarin.Android applications and so all of the calls to
GetCustomAttributefailed to find it, incurring unnecessaryperformance penalty on the application.
Make the code consult a global flag (in case of Xamarin.Android it is
set on the build time) which tells it whether or not to skip querying
for the above custom attribute. The flag is
trueby default tomaintain backward compatibility.
Optimize the
JniTypeManager.GetTypeSignaturemethod to not require anallocation of
Lazy<>+ a number of instances ofKeyValuePair<>aswell as
JniTypeSignature. This affects Xamarin.Android startup alittle: