-
Notifications
You must be signed in to change notification settings - Fork 206
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
String marshallers for UTF-16 and UTF-8 #249
String marshallers for UTF-16 and UTF-8 #249
Conversation
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.
Just a few comments around some possible refactoring and maybe using Span in the generated code.
DllImportGenerator/DllImportGenerator/Marshalling/StringMarshaller.Utf8.cs
Show resolved
Hide resolved
DllImportGenerator/DllImportGenerator/Marshalling/StringMarshaller.Utf8.cs
Show resolved
Hide resolved
DllImportGenerator/DllImportGenerator/Marshalling/StringMarshaller.Utf16.cs
Outdated
Show resolved
Hide resolved
// else | ||
// { | ||
// int <byteLenIdentifier> = (<managedIdentifier>.Length + 1) * sizeof(ushort); | ||
// if (<byteLenIdentifier> > <StackAllocBytesThreshold>) |
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.
Maybe we want to abstract out the conditional stackalloc concept to a base class? We already do this twice and arrays will do this as well.
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.
Yep, that is the plan - was going to do it in a subsequent change
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.
Ideally, this would just call dotnet/runtime#25423
DllImportGenerator/DllImportGenerator.IntegrationTests/CharacterTests.cs
Show resolved
Hide resolved
DllImportGenerator/DllImportGenerator/Marshalling/StringMarshaller.Utf16.cs
Outdated
Show resolved
Hide resolved
DllImportGenerator/DllImportGenerator/Marshalling/StringMarshaller.Utf8.cs
Show resolved
Hide resolved
DllImportGenerator/DllImportGenerator/Marshalling/StringMarshaller.Utf8.cs
Show resolved
Hide resolved
@elinor-fung and @jkoritzinsky From now on when a new Thoughts? |
That sounds good to me. |
These marshalers are not performance critical. It is not important to inline the logic for performance reasons for them. Would it be better to build them using the standard struct-based marshallers that wrap the logic? The marshaling logic can then be optimized independently with ease. |
PR feedback
@jkotas Can you elaborate on this? Are we referencing the internal |
I meant the The idea would be to transform |
@jkotas I like this approach for V2 as an extension. For V1, my concern would be where would this and other types live? Pulling this into Does my concern make sense or am I missing something? |
The source generator can paste an internal copy of these marshaler types into each library that needs them for now. I think it is better to do that than to manually inline the logic for each use. I see the inlining of the logic as an important optimization for marshalers that do very little (e.g. just pin). The marshaler type abstraction would be measurably more expensive for those given the current limits of JIT optimizations. The inlining is not worth it for heavy marshalers that allocate memory, copy blocks of memory around, etc. The relative performance overhead should be fairly small for them. In fact, inlining of the more complex logic is likely performance de-optimization overall because of the increased code size. Having the logic for these marshalers in regular C# will make it easy to modify and optimize them. |
I was hoping to avoid adding types the user wasn't aware of - not a big deal if we do though. I think this approach is something we should consider post our first pass on NetCoreApp. I could easily be persuaded if we had some performance tests that could help move the needle here and demonstrate the cost/benefit. We are planning on meeting with the performance team today to talk about guidance for performance tests. Once we understand that guidance, performance test authoring was going to start. I will make the The TL;DR is I want to continue with the current approach and apply it to the @jkotas Is that a fair plan? |
The throughput performance is only one of the factors. Other factors to consider include:
I see the complex marshaling logic factored into a marshaler types as the baseline solution, and the manually inlined code as the extra cost that we need to demonstrate the benefit of.
Fine with me. |
CharSet
orMarshalAs
) forchar
orstring
CharEncoding.Ansi
char
, support forstring
will be added in another changeThere is currently a good amount of duplication between
Utf16StringMarshaller
andUtf8StringMarshaller
. I'm planning on doing some refactoring to pull out common bits when I deal withCharSet.Ansi
andCharSet.Auto
in a subsequent change.cc @AaronRobinsonMSFT @jkoritzinsky
UTF-16:
UTF-8: