-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Extend preinitialization arithmetic and string manipulation #105429
Conversation
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
Makes it possible to allocate and preinitialize strings. Extends arithmetic support to handle `nint operator int32` operations Adds xor / not / shr support and extends casting for floating point types
src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/TypePreinit.cs
Outdated
Show resolved
Hide resolved
&& method.Instantiation.Length == 1) | ||
{ | ||
var type = method.Instantiation[0]; | ||
bool result = type.IsGCPointer || (type is DefType { ContainsGCPointers: 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.
in the coreclr's interpreter we do this for IsReferenceOrContainsReferences
:
bool containsGcPtrs = typeArg->ContainsGCPointers();
// Return true for byref-like structs with ref fields (they might not have them)
if (!containsGcPtrs && typeArg->IsByRefLike())
{
containsGcPtrs |= HasByrefFields(typeArg);
}
so have to be careful around byref-like structs (with byref fields)
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 stole that code from here 1e0c243#diff-daf353351989087d61e8a1cb5e9c1434b14f16a5029cd38c8ce0037ed4685fa7L48 was that code wrong then?
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 guess so? it's only recently it became possible with allow ref struct
feature. Unless DefType.ContainsGCPointers
already does what is needed..
Adding the extra opcodes looks reasonable to me. I feel a bit squeamish about the new intrinsics because of their bug potential. This will need a lot more targeted testing. I assume this is only covered because String.Concat hits all of these. We'll want dedicated tests to hit all of these new instructions/instruction variants/intrinsics instead. At some point someone is going to optimize String.Concat codepaths with AVX5000 intrinsics, we'll no longer be able to preinitialize the API and the test will get deleted. We test the targeted IL building blocks instead to ensure coverage of the building blocks. |
correct
via the SmokeTests project? How would you test |
|
&& stringType.Module == stringType.Context.SystemModule | ||
&& parameters[0] is ValueTypeValue strSize) | ||
{ | ||
retVal = new StringInstance(context.GetWellKnownType(WellKnownType.String), new string('\0', strSize.AsInt32())); |
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.
Do we need a limit on the string size that can be allocated here? We do not want to OOM the compiler if somebody happens to create extremely long strings in the static constructors.
This pull request has been automatically marked |
This pull request will now be closed since it had been marked |
:( |
After talking to Fabian on #allow-unsafe-blocks who trying to use preinitialization as const expressions for the purposes of obfuscating string literals, he encountered a few hurdles that were trivial to resolve:
Makes it possible to dynamically allocate and preinitialize those strings.
Extends arithmetic support to handle
nint operator int32
operations (needed for string manip)Adds xor / not / shr support and extends casting for floating point types