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

Conversation

@danmoseley
Copy link
Member

@danmoseley danmoseley commented Feb 2, 2017

Contributes to https://github.com/dotnet/coreclr/issues/4651

This applies all the changes that BCLRewriter does to our actual code, with the aim of making it possible to remove the rewriting step. I did this mostly with a Roslyn rewriter but some hand edits as well. Not ready for detailed review but perhaps someone can glance and see I'm not on the wrong track.

  • do the delete
  • diff x64 windows debug against regular rewrite output using decompiler and using apireviewer
  • diff unix, x86, and release binaries
  • review the changes, delete empty files
  • ideally, check the tests pass .. although the diff should be enough, this is a big change

@danmoseley
Copy link
Member Author

There are some diffs that I can't avoid, principally the rewriter removes compiler generated default ctor from internal classes, so this is now present (eg., LocalDataStore()). Rewriter also adds [CompilerGenerated] on some private fields. Rewriter also inlines some constants, which I avoided to keep the code clear.

@danmoseley
Copy link
Member Author

@jkotas

internal static class SR
internal static class SR
{
public static string Arg_ArrayZeroError
Copy link
Member

@jkotas jkotas Feb 2, 2017

Choose a reason for hiding this comment

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

This will cause build break on Unix #Resolved


/// <summary>
/// Returns a session mask representing all sessions in which the activity
/// associated with the current thread is allowed through the activity filter.
Copy link
Member

@jkotas jkotas Feb 2, 2017

Choose a reason for hiding this comment

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

Folks would prefer the EventSource and friends to be left intact (the other cleanup was rolled back in these files...) #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

Should I introduce an #if CORECLR for these? Eg WriteEvent(..) are quite large. Don't know how much we care about size.


In reply to: 99062226 [](ancestors = 99062226)

Copy link
Member

Choose a reason for hiding this comment

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

To the extent possible, I'd rather have fewer ifdefs in this code simply because we'd like EventSource to be as close to the same as possible on all platforms. Are there particular methods that you're concerned about? I believe that all of the WriteEvent methods should be available on all platforms and should not get removed by the rewriter. Is this not the case?

/// Represents an I/O handle that is bound to the system thread pool and enables low-level
/// components to receive notifications for asynchronous I/O operations.
/// </summary>
public sealed partial class ThreadPoolBoundHandle : IDisposable
Copy link
Member

@jkotas jkotas Feb 2, 2017

Choose a reason for hiding this comment

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

This should stay as is - this type was moved from corefx, but the redundant copy in corefx was not removed yet. I have pending change to clean it up. #Resolved

/// </summary>
/// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
internal sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
Copy link
Member

@jkotas jkotas Feb 2, 2017

Choose a reason for hiding this comment

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

Same here #Resolved

@jkotas
Copy link
Member

jkotas commented Feb 2, 2017

Looks reasonable to me so far

{
internal const string GlobalizationInterop = "System.Globalization.Native"; // CoreFX wrappers for ICU
// Shims
internal const string SystemNative = "System.Native";
Copy link
Member

@stephentoub stephentoub Feb 2, 2017

Choose a reason for hiding this comment

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

Won't deleting these break the Unix build? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I just hadn't got to that.


In reply to: 99095195 [](ancestors = 99095195)

_string = str;
}

[OnSerializing]
Copy link
Member

@stephentoub stephentoub Feb 2, 2017

Choose a reason for hiding this comment

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

Anything on exposed types like this marked as [OnSerializing], [OnDeserializing], etc. should not be removed, as it's used via reflection as part of serialization/formatting. If it was being removed before, it was a bug and should have been listed in the model.xml to prevent them from being removed. #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

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

Unix only, didn't diff those yet. I"ll revert any.


In reply to: 99095564 [](ancestors = 99095564)

Copy link
Member Author

Choose a reason for hiding this comment

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

Looks like yes it was previously stripping it. I'll open a bug in corefx to add tests for serializing those.


In reply to: 99196301 [](ancestors = 99196301,99095564)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, rewriter was stripping some of them. I found all the ones getting stripped and reverted them, also opened this to add tests https://github.com/dotnet/corefx/issues/15731

/// </summary>
internal static bool IsDirectoryTooLong(string fullPath)
{
return fullPath.Length >= Interop.Sys.MaxPath;
Copy link
Member

@stephentoub stephentoub Feb 2, 2017

Choose a reason for hiding this comment

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

Do we have any goal of keeping files consistent between CoreCLR and CoreFx? Or are these not used in CoreFx either?

Copy link
Member Author

Choose a reason for hiding this comment

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

@JeremyKuhne why do we have a copy of this in PathInternal in CoreFX?

Copy link
Member

Choose a reason for hiding this comment

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

We're trying to remove the pre-emptive max path checks.

Copy link
Member Author

Choose a reason for hiding this comment

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

@JeremyKuhne I interpret that to mean there is a good reason for both, and I can continue to delete what's not used by coreclr.


namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid
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 just delete the whole file instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll delete empty files

using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;

internal sealed class SafeLocalAllocHandle : SafeBuffer {
Copy link
Member

Choose a reason for hiding this comment

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

Ditto


namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeViewOfFileHandle : SafeHandleZeroOrMinusOneIsInvalid
Copy link
Member

Choose a reason for hiding this comment

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

Ditto. Anywhere all of the code is being removed, we should be able to instead just remove the whole file.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I just hadn't done that yet, you're too fast.

}

// A default constructor is needed to satisfy CoreCLR inheritence rules. It should not be called at runtime
protected SafeHandleZeroOrMinusOneIsInvalid()
Copy link
Member

Choose a reason for hiding this comment

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

Why are these being changed from protected to protected internal?

///
/// See http://msdn.microsoft.com/en-us/library/x810d419.aspx
/// </summary>
private int InnerExceptionCount
Copy link
Member

Choose a reason for hiding this comment

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

Removing this will break the DebuggerDisplayAttribute (it should not have been removed by the rewriter). See the above comment.

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, and checked all the other such attributes.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks. This is also something it'd be good to have some tests in CoreFx for. We have them in a few libraries, with tests that look at types we expect to have debugger attributes, and then use some basic parsing and reflection to verify that the expected members exist and can be invoked. But it'd be good to effectively cover all of our types with such attributes; it's so easy to accidentally remove such members, either manually or via automatic tools like this.

//
//This constructor is required for serialization.
//
protected AppDomainUnloadedException(SerializationInfo info, StreamingContext context) : base(info, context) {
Copy link
Member

Choose a reason for hiding this comment

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

I assume that an instance of this exception will never be thrown to user code? If it could be, removing this ctor will break code if that code tries to serialize and deserialize the exception it caught.

Copy link
Member Author

Choose a reason for hiding this comment

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

Brought back as part of bringing back all the serialization.

using System.Security.Util;
using System.Text;
using System.Diagnostics.Contracts;

Copy link
Member

Choose a reason for hiding this comment

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

The whole file can be removed.

}
}
#endif
}
Copy link
Member

Choose a reason for hiding this comment

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

Whole file can be removed

return InnerList.GetEnumerator();
}

protected virtual void OnSet(int index, Object oldValue, Object newValue) {
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 not sure why all of these protecteds are being changed to protected internals. If this is what the rewriter is doing, seems like a bug in the rewriter. protected internal is more accessible than protected, not less, as protected internal is an or, not an and.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't know why either -- I rolled the back.

m_compareInfo = culture.CompareInfo;
}

private Comparer(SerializationInfo info, StreamingContext context) {
Copy link
Member

Choose a reason for hiding this comment

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

Removing this will break deserialization. Do CoreFx tests pass with this change? If so, that's a gap in our tests.

Copy link
Member

Choose a reason for hiding this comment

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

This whole file should be deleted. The shipping public implementation is in corefx. It is just that something is keeping alive in CoreLib.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's used in several places in Array and in some other types so I believe I have to keep it.

I brought back this with the other serialiation stuff.

Copy link
Member

Choose a reason for hiding this comment

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

It is used as internal implementation detail that cannot leak and thus cannot be serialized. It was renamed to LowLevelComparer (with more cruft stripped) in CoreRT. We should get it eventually as we are unifying the CoreCLR and CoreRT impls.

/// <returns>true if the object was added successfully; otherwise, false.</returns>
/// <remarks>For <see cref="ConcurrentQueue{T}"/>, this operation will always add the object to the
/// end of the <see cref="ConcurrentQueue{T}"/>
/// and return true.</remarks>
Copy link
Member

Choose a reason for hiding this comment

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

This should break the build: without these members, the type won't properly implement the interface it claims to implement.

Copy link
Member

Choose a reason for hiding this comment

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

(Oh, I see, the interface was modified as well.)

namespace System.Collections.Concurrent
{

/// <summary>
Copy link
Member

Choose a reason for hiding this comment

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

Delete the whole file


namespace System.Collections.Concurrent
{
/// <summary>
Copy link
Member

Choose a reason for hiding this comment

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

Delete the whole file

}

// Used by the serialization engine.
private Int32EnumComparer(SerializationInfo info, StreamingContext context) { }
Copy link
Member

Choose a reason for hiding this comment

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

These deserialization ctors should not be removed. We have tests for this in CoreFx (I know because I recently added them)... they pass with this change?

Copy link
Member Author

Choose a reason for hiding this comment

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

all back

// To avoid bad behavior you want it to be the case that the increment is ‘large’ even for ‘small’ values (because small
// values tend to happen more in practice). Thus we multiply ‘seed’ by a number that will make these small values
// bigger (and not hurt large values). We picked HashPrime (101) because it was prime, and if ‘hashSize-1’ is not a multiple of HashPrime
// While this works well for uniformly distributed keys, in practice, non-uniformity is common.
Copy link
Member

Choose a reason for hiding this comment

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

Some characters are messed up

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


namespace System.Collections {
using System.Diagnostics;

Copy link
Member

Choose a reason for hiding this comment

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

Delete the whole file

using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Globalization;

Copy link
Member

Choose a reason for hiding this comment

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

Delete the whole file

[DebuggerDisplay("Count = {Count}")]
[System.Runtime.InteropServices.ComVisible(true)]
[Serializable]
public class Stack : ICollection, ICloneable {
Copy link
Member

Choose a reason for hiding this comment

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

Delete the whole file

@danmoseley
Copy link
Member Author

Fixed binary .props file.
All CoreFX tests pass against release x64.

If you get to it first, please squash before commit...

@danmoseley
Copy link
Member Author

@ericstj --

D:\j\workspace\debug_windows---17180f1b\Tools\Packaging.targets(1061,5): error MSB4018: The "GeneratePackageReport" task failed unexpectedly. [D:\j\workspace\debug_windows---17180f1b\src\.nuget\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj]
21:09:19 D:\j\workspace\debug_windows---17180f1b\Tools\Packaging.targets(1061,5): error MSB4018: System.IO.IOException: The process cannot access the file 'D:\j\workspace\debug_windows---17180f1b\bin\Product\Windows_NT.x64.Debug\mscordaccore_amd64_amd64_4.6.25005.00.dll' because it is being used by another process. [D:\j\workspace\debug_windows---17180f1b\src\.nuget\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj]
21:09:19 D:\j\workspace\debug_windows---17180f1b\Tools\Packaging.targets(1061,5): error MSB4018:    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) [D:\j\workspace\debug_windows---17180f1b\src\.nuget\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj]
21:09:19 D:\j\workspace\debug_windows---17180f1b\Tools\Packaging.targets(1061,5): error MSB4018:    at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) [D:\j\workspace\debug_windows---17180f1b\src\.nuget\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj]
21:09:19 D:\j\workspace\debug_windows---17180f1b\Tools\Packaging.targets(1061,5): error MSB4018:    at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) [D:\j\workspace\debug_windows---17180f1b\src\.nuget\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj]
21:09:19 D:\j\workspace\debug_windows---17180f1b\Tools\Packaging.targets(1061,5): error MSB4018:    at Microsoft.DotNet.Build.Tasks.Packaging.VersionUtility.GetAssemblyVersion(String assemblyPath) [D:\j\workspace\debug_windows---17180f1b\src\.nuget\Microsoft.NETCore.Runtime.CoreCLR\Microsoft.NETCore.Runtime.CoreCLR.pkgproj]

@danmoseley
Copy link
Member Author

@dotnet-bot test Windows_NT x64 Debug Build and Test please (as above)

@mattwarren
Copy link

mattwarren commented Feb 9, 2017

@danmosemsft Just a small thing I noticed, when you made the changes to SharedStatics.cs (diff from #9269), it stripped out the public/internal properties/methods, but left the private backing fields behind you can see that they are still there

Should they be removed as well?

@danmoseley
Copy link
Member Author

@mattwarren thanks, did you notice anything else? I can remove those.

@danmoseley danmoseley mentioned this pull request Feb 15, 2017
@mattwarren
Copy link

No sorry, I was only looking at SharedStatics.cs when I noticed the issue.

We're these changes done with a tool and is there a chance that the tool isn't properly stripping out private code that was only used by the public code it removed?

@danmoseley
Copy link
Member Author

I diffed assemblies before and after BCLRewriter then used Roslyn to remove all those types. I did some manual work as the rewriter had bugs (as did my Roslyn code). Then I diffed the API manually including privates. There's enough noise at the level of privates though that I can imagine some thing slipped through. I do'nt plan to do another pass unless there's some big mistake I made.

jorive pushed a commit to guhuro/coreclr that referenced this pull request May 4, 2017
Delete essentially all the code that the BCL rewriter is removing.
Added back some code it shouldn't have been removing, eg., serialization code, debugger visualizers, and some changing of 'protected' to 'protected internal'
@karelz karelz modified the milestone: 2.0.0 Aug 28, 2017
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
Delete essentially all the code that the BCL rewriter is removing.
Added back some code it shouldn't have been removing, eg., serialization code, debugger visualizers, and some changing of 'protected' to 'protected internal'

Commit migrated from dotnet/coreclr@ee5862c
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.