Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Implement TypedReference in CoreRT #3000

Merged
merged 8 commits into from
Mar 23, 2017

Conversation

MichalStrehovsky
Copy link
Member

@MichalStrehovsky MichalStrehovsky commented Mar 16, 2017

This is basically three 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

Fixes #367.

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
@MichalStrehovsky
Copy link
Member Author

MichalStrehovsky commented Mar 16, 2017

This turned out to be more work than I thought it would.

Known missing things:

  1. Block byref-like types in places such as Array.CreateInstance, Activator.CreateInstance (the non-generic one) and Type.MakeGenericType. I assume with the building blocks in this PR, @atsushikan can do this later.
  2. Support in Project N. This needs tweaks in NUTC and the binder. I assume @davidwrighton will take care of that. I don't volunteer for binder work if I can help it.
  3. Support in the runtime type loader. @davidwrighton?

@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
Copy link
Member Author

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.)

Copy link
Member

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.

Copy link
Member

@davidwrighton davidwrighton left a 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

  1. ReflectionInvoke of a method that takes a parameter or returns a TypedByreference, ByReference, or any other ByRefLike type should be prohibited

  2. 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.

  3. 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
Copy link
Member

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)
Copy link
Member

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)
Copy link
Member

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)
Copy link
Member

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);
Copy link
Member

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.

Copy link
Member

@davidwrighton davidwrighton left a comment

Choose a reason for hiding this comment

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

Looksgoodtome

@MichalStrehovsky MichalStrehovsky merged commit f4407ca into dotnet:master Mar 23, 2017
@MichalStrehovsky MichalStrehovsky deleted the typedReference branch March 23, 2017 19:28
/// </summary>
internal static class TypedReferenceHelpers
{
public unsafe static RuntimeTypeHandle TypeHandleToRuntimeTypeMaybeNull(RuntimeTypeHandle typeHandle)

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?

Copy link
Member Author

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.

Copy link
Member Author

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.

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.

None yet

5 participants