Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use native-sized integers to avoid overhead for 32-bit platforms #3603

Merged
merged 7 commits into from
Nov 27, 2020

Conversation

kpreisser
Copy link
Contributor

@kpreisser kpreisser commented Jul 19, 2020

Proposed changes

  • Resolve TODOs in the TaskDialog code by using native-sized integers (nint/nuint) where applicable, to reduce overhead for 32-bit platforms and to avoid having to use the unsafe keyword.
  • In class PARAM, cast IntPtr to nint instead of long where applicable.

Customer Impact

  • None

Regression?

  • No

Risk

Test methodology

  • Testing the changed code running as x86 and x64 with various inputs, including values where an overflow could happen, to make sure it behaves the same as the previous code.
  • Added tests for PARAM.

Test environment(s)

.NET SDK (reflecting any global.json):
Version: 6.0.100-alpha.1.20472.11
Commit: e55929c5a5

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18363
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\6.0.100-alpha.1.20472.11\

Host (useful for support):
Version: 6.0.0-alpha.1.20468.7
Commit: a820ca1c4f

.NET SDKs installed:
5.0.100-rc.1.20452.10 [C:\Program Files\dotnet\sdk]
6.0.100-alpha.1.20472.11 [C:\Program Files\dotnet\sdk]

Microsoft Reviewers: Open in CodeFlow

@kpreisser kpreisser requested a review from a team as a code owner July 19, 2020 13:58
@ghost ghost assigned kpreisser Jul 19, 2020
@kpreisser kpreisser changed the title Use pointer-sized integers to avoid overhead for 32-bit platforms Use native-sized integers to avoid overhead for 32-bit platforms Jul 19, 2020
@kpreisser
Copy link
Contributor Author

kpreisser commented Jul 19, 2020

It seems the build uses an older C# compiler (pre-16.7) that doesn't yet support the native-sized integers feature.

@kpreisser kpreisser marked this pull request as draft July 19, 2020 17:24
@JeremyKuhne JeremyKuhne added the ⛔ blocked Blocked by external dependencies label Jul 22, 2020
@kpreisser
Copy link
Contributor Author

#3959 updated the SDK to 5.0.100-rc.1, so this builds successfully now.

@kpreisser kpreisser marked this pull request as ready for review September 23, 2020 19:11
@codecov
Copy link

codecov bot commented Sep 23, 2020

Codecov Report

Merging #3603 (ae690c7) into master (36f3feb) will not change coverage.
The diff coverage is n/a.

@@              Coverage Diff              @@
##              master       #3603   +/-   ##
=============================================
  Coverage   97.96958%   97.96958%           
=============================================
  Files            499         499           
  Lines         259010      259010           
  Branches        4569        4569           
=============================================
  Hits          253751      253751           
  Misses          4457        4457           
  Partials         802         802           
Flag Coverage Δ
Debug 97.96958% <ø> (ø)
production 100.00000% <ø> (ø)
test 97.96958% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

@RussKie RussKie removed the ⛔ blocked Blocked by external dependencies label Sep 23, 2020
@RussKie
Copy link
Member

RussKie commented Sep 23, 2020

We'll review this, once we over the release hump.

@RussKie RussKie added the enhancement Product code improvement that does NOT require public API changes/additions label Sep 23, 2020
@RussKie RussKie added this to the 6.0 Preview1 milestone Sep 24, 2020
@RussKie RussKie added the waiting-review This item is waiting on review by one or more members of team label Sep 24, 2020
@RussKie
Copy link
Member

RussKie commented Oct 8, 2020

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

// Convert the int to an uint before converting it to a pointer type,
// which ensures the high dword being zero for 64-bit pointers.
// This corresponds to the logic of the MAKELPARAM/MAKEWPARAM/MAKELRESULT
// macros.
// TODO: Use nint (with 'unchecked') instead of void* when it is available.
=> (IntPtr)(void*)unchecked((uint)ToInt(low, high));
=> unchecked((nint)(nuint)(uint)ToInt(low, high));
Copy link
Member

Choose a reason for hiding this comment

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

I believe the following should be sufficient:

Suggested change
=> unchecked((nint)(nuint)(uint)ToInt(low, high));
=> unchecked((nint)(uint)ToInt(low, high));

Due to converting from uint to nint, C# will just emit a conv.u which is a zero extension: https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxASwDYB8ACAmARgFgAoHAZgAJ9KBhSgb1MpeqoEkA7GABRgUoBZAgAo03SgDcIGAK5wAlI2atVOAOyVZnAMYALODoDWcACYiRncTAWXZ12/e4LpcxQG4VLAL5fKfikouXn4hPDEJV3klJhJVNU1tfUMTc0sHEScbKI8/XxJvIA

Copy link
Contributor

@weltkante weltkante Oct 9, 2020

Choose a reason for hiding this comment

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

@tannergooding well, its not readable, you don't know whether (nint)(uint) means uint -> int -> nint or uint -> nuint -> nint - see discussion above - and in fact for constants Roslyn was not doing zero-extension for a while.

Copy link
Member

Choose a reason for hiding this comment

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

It should be no different, logically, from doing a cast of uint to int (if a 32-bit process) or uint to long (if a 64-bit process), I don't think you would write (long)(ulong)(uint)value or (int)(uint)(uint)value so I (personally) wouldn't expect to see (nint)(nuint)(uint)value here either.

and in fact for constants Roslyn was not doing zero-extension for a while.

AFAIK, all these cases have been fixed. There were a few edge cases in the initial preview, and all of those that were made known have been fixed.
Going through a few cases, I didn't see any issues with constants when comparing nint/nuint to int/uint in RC2 (I did not check if they had all made it into RC1).

Copy link
Contributor

@weltkante weltkante Oct 9, 2020

Choose a reason for hiding this comment

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

My point is that its not readable because the operation does two things at a time and conceptually is ambigous, changing signed-ness and size of the number, and different programming languages spec differently what happens. C# has (apparently) specced it to zero extend, i.e. first widen then change sign. This is not obvious when reading a (nint)(uint) cast in source, it could just as well first change sign then widen, sign-extending in the process.

@tannergooding
Copy link
Member

LGTM.

@RussKie RussKie added 📭 waiting-author-feedback The team requires more information from the author and removed waiting-review This item is waiting on review by one or more members of team labels Oct 9, 2020
@ghost ghost removed the 📭 waiting-author-feedback The team requires more information from the author label Oct 18, 2020
@RussKie RussKie merged commit afd350e into dotnet:master Nov 27, 2020
@RussKie
Copy link
Member

RussKie commented Nov 27, 2020

Thank you all

@kpreisser kpreisser deleted the usePointerSizedIntegers branch November 27, 2020 07:39
@ghost ghost locked as resolved and limited conversation to collaborators Jan 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Product code improvement that does NOT require public API changes/additions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants