Skip to content
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

Covariant returns for RuntimeType #45355

Closed
wants to merge 2 commits into from

Conversation

benaadams
Copy link
Member

Unfortunately crashes during crossgen

@Dotnet-GitSync-Bot
Copy link
Collaborator

I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label.

}
return a;
}
}

public static new RuntimeType GetTypeFromHandle(RuntimeTypeHandle handle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these are going to break analysis within IL Linker whenever they're encountered. IL Linker doesn't hardcode runtime implementation details such as these optimizations - we wouldn't want to hardcode it into linker. Linker operates on public APIs only.

E.g. this one is normally an intrinsic, so is e.g. EmptyTypes. This will make it more difficult for IL Linker to statically analyze what's going on in these spots.

Cc @vitek-karas

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 The covariant returns allow a lot of the casts back to RuntimeType to be dropped (haven't applied all the changes in dropping the casts); and also to devirtualized as direct calls as its a sealed type, rather than virtual calls via Type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have any perf numbers for this?

The cast should be pretty cheap because it's an exact match (the cast will trivially succeed in the part of the type check that RyuJIT typically inlines - it succeeds before actually calling into the casting logic).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type checks then might not mean much?

image

Though it does also drop the virtual calls:

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the non-R2R case: https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxNMAfAAgZgARRwQA2cAJnlgEx4DCeA3gLABQe7l+WAjAGx14AsgAoA9sABWcAMYw8ogJSNWHVZQDseYbQWiA3Co4BfVkaA

RyuJIT generates two checks before calling the casting helper - is it a null object, or is it exactly the same type that we're casting to. If yes, it skips calling into runtime completely.

This change is still an improvement, but is it an improvement that would justify likely having to implement & maintain a IL linker feature? E.g. just earlier today I implemented intrinsic recognition of calls to Type.UnderlyingSystemType within linker motivated by the use within CoreLib - after this change, any call to get_UnderlyingSystemType on a RuntimeType would no longer be intrinsically recognized without linker work because this is a callvirt to a different method.

@@ -769,12 +769,12 @@ public sealed override void ReorderArgumentArray(ref object?[] args, object stat

// Return any exact bindings that may exist. (This method is not defined on the
// Binder and is used by RuntimeType.)
public static MethodBase? ExactBinding(MethodBase[] match, Type[] types, ParameterModifier[]? modifiers)
public static RuntimeConstructorInfo? ExactBinding(RuntimeConstructorInfo[] match, Type[] types, ParameterModifier[]? modifiers)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using RuntimeConstructorInfo will make sharing of this code problematic with NativeAOT.

DefaultBinder is a super slow path. An extra casts here won't make difference.

{
return GetFieldCandidates(null, bindingAttr, false).ToArray();
}

public override Type[] GetInterfaces()
public override RuntimeType[] GetInterfaces()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is potential breaking change if the caller mutates the array and tries to store non-RuntimeType types into the array.

Ben Adams has tried to add usage of covariant returns for the
RuntimeType as the overriding return type and it has uncovered an
ordering issue in the SystemDomain::LoadBaseSystemClasses w.r.t.

This change fixes it by shuffling parts of initialization around a bit.
@ViktorHofer
Copy link
Member

// Auto-generated message

69e114c which was merged 12/7 removed the intermediate src/coreclr/src/ folder. This PR needs to be updated as it touches files in that directory which causes conflicts.

To update your commits you can use this bash script: https://gist.github.com/ViktorHofer/6d24f62abdcddb518b4966ead5ef3783. Feel free to use the comment section of the gist to improve the script for others.

Base automatically changed from master to main March 1, 2021 09:07
@jeffhandley
Copy link
Member

Hi @benaadams -- I wanted to see if this was still on your radar. There's some feedback remaining and a change to our folder structure would also need to be accommodated. If you still want to move this forward, we can leave it open; otherwise we could close this PR--either is fine with us; just let us know. Thanks!

@benaadams
Copy link
Member Author

It interesting; but merge conflicts aside, sounds like there might be issues doing for runtime types specifically.

Also will cause additional merge conflicts for #45121; might revisit another time

@benaadams benaadams closed this Mar 22, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Apr 21, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants