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

Mark applicable structs as readonly #14789

Merged
merged 1 commit into from Nov 3, 2017

Conversation

stephentoub
Copy link
Member

@stephentoub stephentoub commented Nov 1, 2017

In a few known "why wasn't this annotated" cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Contributes to https://github.com/dotnet/corefx/issues/24900

cc: @jaredpar, @VSadov, @jkotas

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.

We should make sure that the corefx contract consistency check start verifying the readonly annotations (if they are not doing it already). The contracts have to stay in sync with the implementation.

@@ -11,7 +11,7 @@ namespace System.Diagnostics.Tracing
/// <summary>
/// TraceLogging: Empty struct indicating no payload data.
/// </summary>
internal struct EmptyStruct
internal readonly struct EmptyStruct
Copy link
Member

Choose a reason for hiding this comment

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

@brianrob Are you ok with marking these as readonly - will it cause issues with source sharing?

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 is also in the same boat as the other "empty" structs below. I'm fine keeping the changes for these and fine getting rid of them.

@@ -10,7 +10,7 @@
namespace System
{
// This class represents the void return type
public struct Void
public readonly struct Void
Copy link
Member

@jkotas jkotas Nov 1, 2017

Choose a reason for hiding this comment

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

You can mark this readonly, but it has zero value here - just adds extra bytes to the binary. The marking on this type looks a bit odd to me.

I am wondering what the rule should be: mark structs as read only because of it makes senses (it would be my preference), or just because of we can?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I went back and forth on that. There are a few types like this in a PR I'm about to put up in corefx as well. I could go either way.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps mark like public /* readonly */ struct Void so it's clear it was intentionally skipped.

Copy link
Member Author

Choose a reason for hiding this comment

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

Perhaps mark like public /* readonly */ struct Void so it's clear it was intentionally skipped.

Ok, I'll do that for internal types and leave public types annotated. Seems like a reasonable place to land.

EDIT: Actually, I'll just remove them from these no-member types. We can always add them later if desired.

@@ -19,7 +19,7 @@ internal static class PaddingHelpers

/// <summary>Padding structure used to minimize false sharing</summary>
[StructLayout(LayoutKind.Explicit, Size = PaddingHelpers.CACHE_LINE_SIZE - sizeof(int))]
internal struct PaddingFor32
internal readonly struct PaddingFor32
Copy link
Member

Choose a reason for hiding this comment

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

Same here.

@@ -53,7 +53,7 @@ namespace System
[StructLayout(LayoutKind.Auto)]
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public partial struct DateTime : IComparable, IFormattable, IConvertible, IComparable<DateTime>, IEquatable<DateTime>, ISerializable
public readonly partial struct DateTime : IComparable, IFormattable, IConvertible, IComparable<DateTime>, IEquatable<DateTime>, ISerializable
Copy link
Member

Choose a reason for hiding this comment

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

I see that you were not able to mark DateTimeOffset because of its internal implementation detail around binary serialization. It is pretty unfortunate. I am wondering whether the DateTimeOffset case would warrant using the Unsafe helper to cast away the readonly-liness, so that DateTimeOffset can be marked as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Exactly. I started looking at fixing it, but decided to keep this PR just focused on the easy cases where implementation changes weren't necessary. There are probably also additional structs that could be made readonly if their fields were appropriately annotated; I only looked at / fixed a few in that category (e.g. DateTime, Nullable), but didn't do a full sweep looking for others; that can be done subsequently, either piecemeal or with an analyzer.

Copy link
Member

Choose a reason for hiding this comment

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

DateTimeOffset #19552

@jkotas
Copy link
Member

jkotas commented Nov 1, 2017

KeyValuePair is a good candidate to annotate.

@jkotas
Copy link
Member

jkotas commented Nov 1, 2017

@dotnet-bot test Windows_NT x64 corefx_baseline

@stephentoub
Copy link
Member Author

We should make sure that the corefx contract consistency check start verifying the readonly annotations (if they are not doing it already). The contracts have to stay in sync with the implementation.

I don't believe they do yet. And in my corefx change, I went through and manually propagated the visible changes to the refs.
cc: @weshaggard, @ericstj

KeyValuePair is a good candidate to annotate.

Another case where the fields aren't currently annotated as readonly, so I didn't pick it up. I'll fix that one here, but others can be done subsequently.

In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.
@stephentoub
Copy link
Member Author

@dotnet-bot test Windows_NT x64 full_opt ryujit CoreCLR Perf Tests Correctness please
@dotnet-bot test Windows_NT x86 full_opt ryujit CoreCLR Perf Tests Correctness please

@stephentoub
Copy link
Member Author

@jkotas, should these CoreCLR Perf Tests Correctness legs be working? The details links just come back as 404s.

@weshaggard
Copy link
Member

I don't believe they do yet. And in my corefx change, I went through and manually propagated the visible changes to the refs.

I don't think we are currently. It should be easy enough to add for anyone that wants to verify it. The code lives in Microsoft.Cci.Extensions in Buildtools.

@jkotas
Copy link
Member

jkotas commented Nov 2, 2017

@adiaaida I see you have pending PR to change perf related legs. Are the perf test correctness failures known issue?

@jkotas
Copy link
Member

jkotas commented Nov 2, 2017

It should be easy enough to add for anyone that wants to verify it. The code lives in Microsoft.Cci.Extensions in Buildtools.

We need tracking issue for this at least. It needs to be done before we ship 2.1 to ensure consistency.

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.

LGTM

@michellemcdaniel
Copy link

I can't see the failure because I removed the jobs with my last change. I'll re-run the Perf Build and Test runs, which should tell us if this change will break the perf testing.

@dotnet-bot test Perf Build and Test please

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.

LGTM
Nice change!!!

@stephentoub
Copy link
Member Author

@adiaaida, how long is that perf build and test leg expected to take? It's been running for almost 5 hours. Similarly in the PR at #14836.

@jkotas
Copy link
Member

jkotas commented Nov 3, 2017

We should not block on the Perf Build and Test

@jkotas jkotas merged commit 278c8f3 into dotnet:master Nov 3, 2017
dotnet-bot pushed a commit to dotnet/corefx that referenced this pull request Nov 3, 2017
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
@jkotas
Copy link
Member

jkotas commented Nov 3, 2017

It should be easy enough to add for anyone that wants to verify it. The code lives in Microsoft.Cci.Extensions in Buildtools.

We need tracking issue for this at least. It needs to be done before we ship 2.1 to ensure consistency.

Opened https://github.com/dotnet/corefx/issues/25039 on this

stephentoub added a commit to dotnet/corefx that referenced this pull request Nov 3, 2017
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
@stephentoub stephentoub deleted the readonly_structs branch November 3, 2017 13:51
nategraf pushed a commit to nategraf/coreclr that referenced this pull request Nov 7, 2017
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.
dotnet-bot pushed a commit to dotnet/corert that referenced this pull request Nov 8, 2017
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
jkotas pushed a commit to dotnet/corert that referenced this pull request Nov 8, 2017
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
jkotas pushed a commit to dotnet/corert that referenced this pull request Nov 9, 2017
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
@@ -47,10 +47,10 @@ internal static string PairToString(object key, object value)
// and IReadOnlyDictionary<TKey, TValue>.
[Serializable]
[System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public struct KeyValuePair<TKey, TValue>
public readonly struct KeyValuePair<TKey, TValue>
Copy link
Member

Choose a reason for hiding this comment

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

I'm working on the APICompat checks work but I'm not sure if this a compatible change. @jkotas @stephentoub is this an API compatible change?

Copy link
Member

Choose a reason for hiding this comment

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

Marking struct as readonly should be compatible change. The other direction (removing readonly on a struct) is not a compatible change.

cc @VSadov

Copy link
Member

Choose a reason for hiding this comment

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

Yes this is a compatible change.

dotnet-bot pushed a commit to dotnet/corefx that referenced this pull request Jan 13, 2018
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
dotnet-bot pushed a commit to dotnet/corefx that referenced this pull request Jan 13, 2018
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
safern pushed a commit to dotnet/corefx that referenced this pull request Jan 16, 2018
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
safern pushed a commit to dotnet/corefx that referenced this pull request Jan 16, 2018
In a few cases (e.g. nullable), I added readonly to fields in order to allow readonly on the type.

Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
8 participants