[Java.Interop] Add JniMemberInfoLookup #1208
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context: c6c487b
Context: 312fbf4
Context: 2197579
Context: xamarin/xamarin-android#7276
There is a desire to remove the "marshal-ilgen" component from .NET Android, which is responsible for all non-blittable type marshaling within P/Invoke (and related) invocations.
The largest source of such non-blittable parameter marshaling was with string marshaling:
JNIEnv::GetFieldID()
was "wrapped" byjava_interop_jnienv_get_field_id
:which was P/Invoked within
JniEnvironment.g.cs
:and
string
parameter marshaling is not blittable.Turns out™ that this particular usage of non-blittable parameter marshaling was fixed and rendered moot by:
JNIEnv
invocationsThat said, this code path felt slightly less than ideal: the "top-level abstraction" for member lookups is an "encoded member", a string containing the name of the member, a
.
, and the JNI signature of the member, e.g.:The "encoded member" would need to be split on
.
, and with c6c487b the name and signature would be separately passed toMarshal.StringToCoTaskMemUTF8()
, which performs a memory allocation and converts the UTF-16 string to UTF-8.Meanwhile, C# 11 introduced UTF-8 string literals, which allows the compiler to deal with UTF-8 conversion and memory allocation.
Enter `JniMemberInfoLookup``:
JniMemberInfoLookup
removes the need to callMarshal.StringToCoTaskMemUTF8()
entirely, at the cost of a more complicated member invocation:Is It Worth It™? Maybe; see the new
JniFieldLookupTiming.FieldLookupTiming()
test, which allocates a newJniPeerMembers
instance and invokemembers.InstanceFields.GetFieldInfo(string)
andmembers.InstanceFields.GetFieldInfo(JniMemberInfoLookup)
. (A newJniPeerMembers
instance is required becauseGetFieldInfo()
caches the field lookup.) UsingJniMemberInfoLookup
is about 4% faster.I'm not sure if this is actually worth it, especially as this will imply an increase in code size.
TODO:
Update
JniPeerMembers.*.cs
to useJniMemberInfoLookup
, so that e.g. the above_members.InstanceFields.GetBooleanValue()
overload exists.generator
changes to useJniMemberInfoLookup