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

Finish support for rank 1 mdarrays#3610

Merged
MichalStrehovsky merged 3 commits intodotnet:masterfrom
MichalStrehovsky:rank1array
May 15, 2017
Merged

Finish support for rank 1 mdarrays#3610
MichalStrehovsky merged 3 commits intodotnet:masterfrom
MichalStrehovsky:rank1array

Conversation

@MichalStrehovsky
Copy link
Member

Three parts:

  1. Update casting logic to allow casting SzArray to rank 1 MdArray (but
    not the other way around)
  2. Update MdArray rank 1 methods to be able to operate on SzArrays
  3. Update array creation path to emulate the behavior where allocating
    rank 1 MdArray with 0 lower bounds actually gives you an SzArray

Third bullet point makes this the most annoying, because we can't
reliably support newobj instance void int32[0...]::.ctor(int32)
without hitting the type loader. I was also considering adding an
optional field on Rank 1 MdArrays that lets you get to the SzArray's
EEType from it. It might be better.

Fixes #3331.

Three parts:

1. Update casting logic to allow casting SzArray to rank 1 MdArray (but
not the other way around)
2. Update MdArray rank 1 methods to be able to operate on SzArrays
3. Update array creation path to emulate the behavior where allocating
rank 1 MdArray with 0 lower bounds actually gives you an SzArray

Third bullet point makes this the most annoying, because we can't
reliably support `newobj instance void int32[0...]::.ctor(int32)`
without hitting the type loader. I was also considering adding an
optional field on Rank 1 MdArrays that lets you get to the SzArray's
EEType from it. It might be better.
@ghost
Copy link

ghost commented May 15, 2017

Wow, I had no idea that MdArray-1=>SzArray horsetrade was so deeply embedded into the runtime.

Since you've put that logic into RuntimeAugments.NewMultiDimArray(), you can get rid of these checks:

https://github.com/dotnet/corert/blob/master/src/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs#L68

https://github.com/dotnet/corert/blob/master/src/System.Private.CoreLib/src/System/Array.CoreRT.cs#L184

@MichalStrehovsky
Copy link
Member Author

Since you've put that logic into RuntimeAugments.NewMultiDimArray(), you can get rid of these checks

Checks removed.

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

Is it going to need a follow up change in ProjectN, or is it just going to work there?

@MichalStrehovsky
Copy link
Member Author

MichalStrehovsky commented May 15, 2017

@davidwrighton PTAL

Now that I've slept on it, I thinking that the way to deal with newobj instance void int32[0...]::.ctor(int32) should be either one of these:

  1. Have codegen lower this into the appropriate constructor call. We would revert my change to Internal/Runtime/CompilerHelpers/ArrayHelpers.cs and replace it with an assert that if rank is 1, lower bounds are non-zero. Codegen is already aware of this weirdness because it needs to special case rank 1 arrays with 0 lower bounds in RuntimeHelpers.InitializeArray expansion to prevent a heap corruption that would result from assuming a normal mdarray got allocated by the ctor call.
  2. Add an optional field to rank 1 array EEType that points to the appropriate SzArray so that we can get to it relatively quickly.

My preference is 1.

@MichalStrehovsky
Copy link
Member Author

Is it going to need a follow up change in ProjectN

If we want newobj instance void int32[0...]::.ctor(int32) to work, it will be some NUTC work. Project N will still benefit from the type loader being able to dynamically load these now (which is what the original bug in CoreFX was about). The newobj path is not reachable from C#, but the dynamic load one is.

I can file a bug if you think we should support this, but we'll get a reminder about this when NUTC starts running against the CoreCLR test assets. I checked in a test for this a month ago or so.

@davidwrighton
Copy link
Member

System.Private.Reflection.Execution/src/Internal/Reflection/Execution/TypeLoader/TypeCast.cs is missing the changes needed for this change. (In fact it appears to be missing array rank checks entirely).

@MichalStrehovsky
Copy link
Member Author

MichalStrehovsky commented May 15, 2017

System.Private.Reflection.Execution/src/Internal/Reflection/Execution/TypeLoader/TypeCast.cs is missing the changes needed for this change

The method in TypeCast.cs where I had to do the change in Runtime.Base is not mirrored in that TypeCast.cs, so no changes are needed. The various IsArray/GetArrayRank checks are suspect, but it's a separate issue (it will lead to e.g. incorrectly considering Foo[] and Foo[*] identical type). Proper fix for that only became possible very recently (reflection didn't use to have a way to tell between rank 1 MdArray and SzArray). I'll open a separate issue/pull request.

I have also validated that the (yet another) copy of casting logic in System.Reflection.Runtime.General.Assignability already handles this case correctly.

@MichalStrehovsky MichalStrehovsky merged commit 9aa607b into dotnet:master May 15, 2017
@MichalStrehovsky MichalStrehovsky deleted the rank1array branch May 15, 2017 20:06
MichalStrehovsky added a commit to MichalStrehovsky/corert that referenced this pull request May 19, 2017
* Make calling Rank 1 MdArray ctor more reliable. This is not a great
fix (great fix would be one of the two options I enumerated in dotnet#3610),
but at least makes the problem go away. It's unlikely anyone is going to
use this anyway.
* Fix exception types we throw.
MichalStrehovsky added a commit that referenced this pull request May 19, 2017
* Make calling Rank 1 MdArray ctor more reliable. This is not a great
fix (great fix would be one of the two options I enumerated in #3610),
but at least makes the problem go away. It's unlikely anyone is going to
use this anyway.
* Fix exception types we throw.
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.

4 participants