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

Extract portable/managed code from Array for sharing with Mono and CoreCLR#3201

Merged
MichalStrehovsky merged 2 commits intodotnet:masterfrom
marek-safar:array
Apr 6, 2017
Merged

Extract portable/managed code from Array for sharing with Mono and CoreCLR#3201
MichalStrehovsky merged 2 commits intodotnet:masterfrom
marek-safar:array

Conversation

@marek-safar
Copy link
Contributor

Includes few missing GetLowerBound calls from CoreCLR version

@marek-safar marek-safar force-pushed the array branch 2 times, most recently from 477dc78 to 1884826 Compare April 4, 2017 11:54
@ghost
Copy link

ghost commented Apr 4, 2017

In keeping with our filenaming conventions (https://github.com/dotnet/corert/blob/master/src/System.Private.CoreLib/shared/README.md), please rename...

Array.Portable.cs => Array.cs
Array.cs => Array.CoreRT.cs

Thanks!

@ghost
Copy link

ghost commented Apr 4, 2017

Array.Initialize() is not functioning on CoreRt and is inherently unportable. It should stay in the non-portable partition.

// Project N port note: On the desktop, this api is a nop unless the array element type is a value type with
// an explicit nullary constructor. Such a type cannot be expressed in C# so Project N does not support this.
// The ILC toolchain fails the build if it encounters such a type.
return;
Copy link
Member

Choose a reason for hiding this comment

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

This won't be sharable once CoreRT implements the right semantics.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to CoreRT version

int endIndex = startIndex + count;

// See comment above Array.GetComparerForReferenceTypesOnly for details
EqualityComparer<T> comparer = GetComparerForReferenceTypesOnly<T>();
Copy link
Member

Choose a reason for hiding this comment

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

Places that call GetComparerForReferenceTypesOnly rely on deep compiler magic that is not even portable between our two CoreRT compilers right now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to CoreRT version

Copy link
Member

Choose a reason for hiding this comment

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

There are still places in Array.cs left that call into this.

Array.CopyImplReferenceArrayToValueTypeArray(objItems, index, items, index, length, reliable: false);
}
#else
Object[] objKeys = keys as Object[];
Copy link
Member

Choose a reason for hiding this comment

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

This is going to break us on the TFS side because Project N (the AOT compiler for Universal Windows Apps) doesn't define CORERT.

Copy link
Member

@jkotas jkotas Apr 4, 2017

Choose a reason for hiding this comment

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

That something we should fix.

  • CORERT - defined in both TFS side and GitHub side
  • PROJECTN - defined in TFS only

For now, any ifdefs need to be #if CORERT || PROJECTN.

Copy link
Member

Choose a reason for hiding this comment

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

Or even better - move anything with ifdefs to the non-portable part.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to CoreRT part

{
if (_index < 0) throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
if (_index >= _endIndex) throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
return _array.GetValueWithFlattenedIndex_NoErrorCheck(_index);
Copy link
Member

Choose a reason for hiding this comment

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

ArrayEnumerator differs from CoreCLR at this place (we avoid a bunch of checks this way), but it makes the enumerator rather non-portable (see my pending change to it in #3192).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should not matter as GetValueWithFlattenedIndex_NoErrorCheck is in implementation specific part

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, but as the name suggest, it doesn't do error checking, which means it doesn't check if the element type is an unmanaged pointer. If I get my #3192 signed off before you do your pull request, it won't be portable...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

CoreRT limitation ?

You can't call get_Current on the enumerator of e.g. int*[]. I would think Mono blocks this too (CLR does). Pointer types cannot be boxed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved it to CoreRT part

@ghost
Copy link

ghost commented Apr 4, 2017

You should probably compare each method with the CoreCLR version before putting in in the shared part. Even if the code compiles and runs, you may lose optimizations that CoreRT wasn't able to take advantage of (in particular, around the sorting and searching apis where CoreRT was hobbled by the inability to create generic instantiations on the fly with assurance of success.)

There's also the "throw" vs. ThrowHelper issue (another optimization thing on CoreCLR.)

@marek-safar
Copy link
Contributor Author

@atsushikan files renamed

I'll leave it to CoreCLR folks to decide what to do with ThrowHelper optimization

@jkotas
Copy link
Member

jkotas commented Apr 4, 2017

decide what to do with ThrowHelper optimization

We should deal with that separately from this PR - once we actually move it to the shared partition.

@MichalStrehovsky
Copy link
Member

I can't comment on the diff because this is unchanged, but

private static bool StructOnlyEquals<T>(T left, T right)

Is the same kind of deep compiler magic as GetComparerForReferenceTypesOnly that should not be portable (neither any of the references to it).

It also seems like we don't need ComparerAsComparerT in the common code.

@marek-safar marek-safar force-pushed the array branch 2 times, most recently from 2c6262c to 90fe366 Compare April 4, 2017 17:54
@MichalStrehovsky
Copy link
Member

If you make your change a rename Array.cs -> Array.CoreRT.cs followed by starting a new Array.cs from scratch, it should merge clean with the pull request I just merged. The interesting parts (and majority of the code) is in Array.CoreRT.cs so that's where I would want to see uninterrupted history anyway.

@marek-safar marek-safar force-pushed the array branch 2 times, most recently from 99f5538 to efdb06e Compare April 4, 2017 18:36
@marek-safar marek-safar force-pushed the array branch 2 times, most recently from 666ebb7 to 241f8bd Compare April 4, 2017 19:07
@marek-safar
Copy link
Contributor Author

@MichalStrehovsky Done. Although I could move the new common bits to shared and avoid the rename altogether

@MichalStrehovsky
Copy link
Member

@marek-safar The private static bool StructOnlyEquals<T>(T left, T right) is still in Array.cs, but should be in Array.CoreRT.cs.

I'm not sure if it's worth having Empty<T>() in the common subset. I've been thinking about potentially optimizing this so that it doesn't force existence of a bunch of data structures per each "T", and can be inlined by RyuJIT. There's no interesting logic in that method.

I don't know what the policy is for moves to /shared/ (do we need to follow more cleanup rules?). I'm not opposed to it, but I've been detached from those efforts. @jkotas?

Other than that, looks good! Thanks!

@jkotas
Copy link
Member

jkotas commented Apr 6, 2017

I don't know what the policy is for moves to shared

The best way to do it is to do similar refactoring in both CoreCLR and CoreRT, so that the file being moved is same or pretty close in both. Then move the file to shared in one repo, wait for the automatic PR to get generated in the other repo and amend it with a commit to delete the unshared copy of the file in other repo.

I do not think it makes sense to move Array.cs to shared as part of this PR.

…oreCLR

Includes few missing GetLowerBound calls from CoreCLR version
@marek-safar
Copy link
Contributor Author

@MichalStrehovsky moved both to CoreRT version

@MichalStrehovsky
Copy link
Member

@dotnet-bot test OSX Release

@MichalStrehovsky MichalStrehovsky merged commit 1fc9809 into dotnet:master Apr 6, 2017
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