Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add API that allows the emitter to indicate presence of localloc #27589

Merged
merged 5 commits into from
Mar 8, 2018

Conversation

tmat
Copy link
Member

@tmat tmat commented Mar 1, 2018

When encoding method body header the encoder needs to decide whether to emit tiny or fat header. A small method that has no locals but contains localloc instruction and has InitLocals set to true should not be encoded with tiny header since tiny header implies InitLocals is false. The presence of localloc instruction needs to be indicated by the caller of the method body encoder similarly to max stack and other info. Hence we need to add an overload that takes an extra bool parameter.

Fixes https://github.com/dotnet/corefx/issues/26910
Implements https://github.com/dotnet/corefx/issues/27611

@tmat
Copy link
Member Author

tmat commented Mar 1, 2018

@nguerrera @VSadov PTAL

@nguerrera
Copy link
Contributor

LGTM. This is technically new API needing review. @terrajobst can we fast track it?

/// <exception cref="ArgumentOutOfRangeException"><paramref name="maxStack"/> is out of range [0, <see cref="ushort.MaxValue"/>].</exception>
/// <exception cref="InvalidOperationException">
/// A label targeted by a branch in the instruction stream has not been marked,
/// or the distance between a branch instruction and the target label is doesn't fit the size of the instruction operand.
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: "is doesn't"

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

@VSadov VSadov left a comment

Choose a reason for hiding this comment

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

.

Copy link
Member

@VSadov VSadov left a comment

Choose a reason for hiding this comment

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

GTM
As discussed offline, the shape of API solves solves our issue.

@ahsonkhan
Copy link
Member

ahsonkhan commented Mar 1, 2018

API changes/additions here. What's the plan?
cc @terrajobst, @karelz, @danmosemsft

@danmoseley
Copy link
Member

@ahsonkhan when API is approved send shiproom brief note with reasoning for the churn.

@karelz
Copy link
Member

karelz commented Mar 1, 2018

I don't see ref changes ... should they be there as well?

Copy link
Member

@agocke agocke left a comment

Choose a reason for hiding this comment

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

This means we'll have to track two bits instead of one in the compiler, but it also means this isn't a breaking change for S.R.M.

@agocke
Copy link
Member

agocke commented Mar 1, 2018

cc @t-camaia

@tmat
Copy link
Member Author

tmat commented Mar 1, 2018

@karelz Created API proposal issue: https://github.com/dotnet/corefx/issues/27611

@tmat
Copy link
Member Author

tmat commented Mar 1, 2018

test Tizen armel Debug Build please

@VSadov
Copy link
Member

VSadov commented Mar 1, 2018

@agocke - we can also always set hasDynamicStackAllocation and just twiddle the LocalsInit in the attributes. - the result is the same.
Or track the presence of stackalloc. We would have that information anyways, just would need to plumb it through.

Yes the API change is additive to not be breaking.

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

I don't see ref changes ... should they be there as well?

Are they not auto-generated? I run build-managed.cmd, it succeeded and don't see any other files changed in the repo.

@ahsonkhan
Copy link
Member

Are they not auto-generated? I run build-managed.cmd, it succeeded and don't see any other files changed in the repo.

Try running msbuild /t:GenerateReferenceSource /p:TargetGroup=netstandard /p:ConfigurationGroup=Release (from src directory of your project - in this case https://github.com/tmat/corefx/tree/27c4627148084a29bb6839e3a39a7d9d05767de6/src/System.Reflection.Metadata/src)

This is after building the repo at the root.

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

@ahsonkhan Thanks. Added another commit with regenerated ref file.

This process is very much broken. My previous PR also added new APIs but I didn't know the ref files need to be manually regenerated. Yet everything passed and it got merged!
The regenerated ref file also contains some other changes that have likely been made previously without regenerating the ref file: df10420

I wonder how many bugs are there currently in CoreFX due to this ref file generation.

@@ -99,9 +99,7 @@ namespace System.Reflection.Metadata
public System.Reflection.Metadata.StringHandle Name { get { throw null; } }
public System.Reflection.Metadata.BlobHandle PublicKey { get { throw null; } }
public System.Version Version { get { throw null; } }
#if !NETSTANDARD11
Copy link
Member

@ahsonkhan ahsonkhan Mar 2, 2018

Choose a reason for hiding this comment

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

You need to sanitize the changes to only include the necessary changes you want (+ formatting cleanup/spacing/etc).

Keep the ifdefs.

@@ -2039,7 +2036,7 @@ public enum PrimitiveTypeCode : byte
}
public readonly partial struct PropertyAccessors
{
private readonly int _dummy;
private readonly object _dummy;
Copy link
Member

Choose a reason for hiding this comment

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

@weshaggard, is this change OK and expected (the _dummy fields going from int to object)?

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 those definitely look suspicious. object is the fallback if we cannot determine all the fields in the struct.

Copy link
Member

Choose a reason for hiding this comment

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

Can you provide some rudimentary guidelines that we can follow to vet these changes ourselves?

@@ -3135,6 +3138,7 @@ public enum Machine : ushort
AM33 = (ushort)467,
Amd64 = (ushort)34404,
Arm = (ushort)448,
Arm64 = (ushort)43620,
Copy link
Member

Choose a reason for hiding this comment

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

@davidwrighton, this was added here - #26243

This is expected, correct?

@weshaggard
Copy link
Member

This process is very much broken. My previous PR also added new APIs but I didn't know the ref files need to be manually regenerated

The process isn't the greatest but it is the best we have. We cannot automatically generate these easily because we have a different surface area based on configuration in a lot of libraries there isn't one definitively implementation we can generate them from.

I wonder how many bugs are there currently in CoreFX due to this ref file generation.

There may be a few but I don't expect there is a lot because most folks try to test or use their new APIs and they do it via the ref assembly and if the APIs aren't present then they cannot use them.

@ahsonkhan
Copy link
Member

ahsonkhan commented Mar 2, 2018

This process is very much broken. My previous PR also added new APIs but I didn't know the ref files need to be manually regenerated. Yet everything passed and it got merged!

If you add tests that exercise the newly added APIs, the build won't pass without the APIs being added to the ref. Only if you have test gaps would this be an issue.

What does the code coverage look like for this assembly?

@ahsonkhan
Copy link
Member

There may be a few but I don't expect there is a lot because most folks try to test or use their new APIs and they do it via the ref assembly and if the APIs aren't present then they cannot use them.

Precisely.

https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj#L144

<!-- Some internal types are needed, so we reference the implementation assembly, rather than the reference assembly. -->

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

There may be a few but I don't expect there is a lot because most folks try to test or use their new APIs and they do it via the ref assembly and if the APIs aren't present then they cannot use them.

The unit tests pass :(

If you add tests that exercise the newly added APIs, the build won't pass without the APIs being added to the ref.

Well, it passed.

@ahsonkhan
Copy link
Member

The unit tests pass :(

I wonder if we can use InternalsVisibleTo instead of referencing the implementation assembly. Would we then be able to reference the ref and circumvent this issue?

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

The process isn't the greatest but it is the best we have.

This is not an acceptable answer.
@Petermarcu

@danmoseley
Copy link
Member

Seems the problem is not that one must manually update the ref, but that by some unknown means the unit tests passed without the ref update. @weshaggard ?

@nguerrera
Copy link
Contributor

@danmosemsft The means has been identified: the tests reference the implementation assembly as they require access to internals.

@nguerrera
Copy link
Contributor

nguerrera commented Mar 2, 2018

I wonder if we can use InternalsVisibleTo instead of referencing the implementation assembly. Would we then be able to reference the ref and circumvent this issue?

@ahsonkhan We are using InternalsVisibleTo. Do you mean put the internals in the reference assembly? Do other assemblies do that? If this closes the test gap, then yes, we should at least do that.

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

Filed an issue to fix the process: https://github.com/dotnet/corefx/issues/27639

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

Unit tests won't validate that the ref assembly is 100% correct. E.g. ref assembly contains private dummy fields. No unit test will validate those.

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

I have somewhat fixed up the ref assembly. Please validate it's correct.

@ahsonkhan
Copy link
Member

I have somewhat fixed up the ref assembly. Please validate it's correct.

The only thing would be to keep the #if !NETSTANDARD11 that were removed. See https://github.com/dotnet/corefx/pull/27589/files#r171741403

@danmoseley
Copy link
Member

What about two test libraries for the same implementation library, one with IVT and the other going only through public API would that help?

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

@danmosemsft. That makes it more complicated, not less. I don't want any more complexity in this already over complicated system.

This would help:

  1. Generate one ref file per configuration and target framework
  2. Generate the file to intermediate directory and do not check it in
  3. Use C# compiler ref assembly feature

Perhaps these are not applicable on all projects in CoreFX that need some magic like System.Runtime but it will work at least for SCI and SRM (and maybe for others).

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

Let's move the ref assembly discussion to https://github.com/dotnet/corefx/issues/27639

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

test OSX x64 Debug Build please

@tmat
Copy link
Member Author

tmat commented Mar 2, 2018

test UWP CoreCLR x64 Debug Build please

@tmat
Copy link
Member Author

tmat commented Mar 5, 2018

test OSX x64 Debug Build please

@tmat
Copy link
Member Author

tmat commented Mar 5, 2018

test UWP CoreCLR x64 Debug Build please

@ahsonkhan
Copy link
Member

The OSX failure is a known issue - https://github.com/dotnet/core-eng/issues/2808

@tmat tmat merged commit 3fc3900 into dotnet:master Mar 8, 2018
@tmat tmat deleted the LocAlloc branch March 8, 2018 18:22
@weshaggard
Copy link
Member

While working on https://github.com/dotnet/corefx/issues/27639 I regenerated the ref for System.Reflection.Metadata and also noticed the dummy fields being changed from int to object and I do think that is a correct update because those structs have ImmutableArray references which contain array references. As part of addressing https://github.com/dotnet/corefx/issues/27639 I will regenerate the ref to fix that.

@karelz karelz added this to the 2.1.0 milestone Mar 10, 2018
@tmat tmat assigned VSadov and tmat and unassigned tmat and VSadov Mar 23, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…net/corefx#27589)

* Add API that allows the emitter to indicate presence of localloc

* Regenerate ref assembly source


Commit migrated from dotnet/corefx@3fc3900
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.

8 participants