-
Notifications
You must be signed in to change notification settings - Fork 510
Implement TypedReference in CoreRT #3000
Implement TypedReference in CoreRT #3000
Conversation
This is basically two things: 1. `ByReference<T>` support 2. General support infra in the type system for Byref-like types (to be reused for e.g. `Span<T>`). 3. TypedReference
This turned out to be more work than I thought it would. Known missing things:
@davidwrighton @jkotas Can you please do the "where did Michal forget to handle/block the new things" exercise? |
{ | ||
get | ||
{ | ||
// TODO: should we key this off of the fact that there's an instance 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.
(This could also be an algorithm.)
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.
Yes it should. ByRefLike should be set to true for Span, ByReference, any generic structure that has a Span or ByReference in it.
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 change is missing handling of the runtime impacts and ByRefLike virality
-
ReflectionInvoke of a method that takes a parameter or returns a TypedByreference, ByReference, or any other ByRefLike type should be prohibited
-
Dynamic type loader should be updated to properly set the ByRefLike flag in generated EETypes based on the template. The pattern to follow is to either make the type system api work in the runtime scenario, or to add a bool property to TypeBuilderState which does the right thing.
-
ByRefLike is viral, if a type is ByRefLike, then a type with an instance field of such a type is also ByRefLike.
{ | ||
get | ||
{ | ||
// TODO: should we key this off of the fact that there's an instance 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.
Yes it should. ByRefLike should be set to true for Span, ByReference, any generic structure that has a Span or ByReference in it.
if (fieldType.IsValueType && !fieldType.IsPrimitive) | ||
{ | ||
DefType fieldDefType = (DefType)fieldType; | ||
if (fieldDefType.IsByRefLike || fieldDefType.IsByReferenceOfT) |
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.
ByReference<T>
should have IsByRefLike set, so this should be just if (fieldDefType.IsByRefLike)
// ByRef=like instance fields on reference types are not allowed. | ||
if (fieldType.IsValueType && !type.IsValueType) | ||
{ | ||
if (((DefType)fieldType).IsByRefLike || fieldType.IsByReferenceOfT) |
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.
IsByReferenceOfT check should not be needed.
@@ -223,6 +241,12 @@ public override bool ComputeContainsGCPointers(DefType type) | |||
{ | |||
bool someFieldContainsPointers = false; | |||
|
|||
if (type.IsValueType) |
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.
IsGCPointer returns false for ByReference<T>
, so this not quite self-consistent.
FWIW, the CoreCLR implementation does not treat ByReference<T>
as GCPointer. The only place where it really matters is the fast path on getClassGClayout - it checks for IsByRefLike to take the slow path there.
{ | ||
ComputeIsByRefLike(); | ||
} | ||
return _fieldLayoutFlags.HasFlags(FieldLayoutFlags.IsByRefLike); |
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.
BTW: I expect that the ref-like types will be eventually identified by attribute, and so ComputeIsByRefLike will be just a check of the attribute; not a property of the field layout.
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.
Looksgoodtome
/// </summary> | ||
internal static class TypedReferenceHelpers | ||
{ | ||
public unsafe static RuntimeTypeHandle TypeHandleToRuntimeTypeMaybeNull(RuntimeTypeHandle typeHandle) |
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.
@MichalStrehovsky What does this function do exactly? Is it a compiler intrinsic?
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.
It's what we give to RyuJIT as CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPE_MAYBENULL
.
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.
You don't have to worry about it because this is something RyuJIT needs as part of compiling refanytype
IL instruction. The UTC team showed little to no enthusiasm about implementing that so what we'll have to do on Project N is update DR (or GateKeeper) to mark all methods that have this (and related instructions) as unsupported IL and bail.
This is basically three things:
ByReference<T>
supportreused for e.g.
Span<T>
).Fixes #367.