Skip to content

Instantly share code, notes, and snippets.

@lucasmeijer
Last active April 6, 2016 14:27
Show Gist options
  • Save lucasmeijer/9de952d508cd9b737518 to your computer and use it in GitHub Desktop.
Save lucasmeijer/9de952d508cd9b737518 to your computer and use it in GitHub Desktop.
What is up and down in CoreFX, CoreCLR world.
I've been trying to understand how all moving parts of CoreFX, CoreCLR & ReferenceSource, especially related to
mscorlib. These are my notes / conclusions. If you have more information, or see something that is wrong, please
let me know!
the CoreCLR repo, has an embedded mscorlib inside of it. When diffing this against the referencesource mscorlib,
it looks like it forked at some point, and has received some minor cleanups. most occuring changes:
- change license header
- remove [ResourceExposure] and [ResourceConsumption] attributes.
- some modest improvements. (files like Task.cs, Thread.cs, AppDomain.cs, are files with relatively high amount of changes)
- cleanup. if referencesource code had #if DOTNETCORE, that define has been removed in the coreclr one, as it is now always true.
- all filenames have been camelcased.
but by and large, these corlibs are pretty much the same.
What it looks like is that the intention is to move many of the types that are in corlib today, into seperate assemblies.
You can see this intention in the CoreFX framework, where it actually has a System.Reflection.dll assembly, but today
that only has typeforwarders to mscorlib. It is my interpetation that this is to futureproof a future where these types
can move to System.Reflection.dll, without breaking user code. (I cannot actually find these typeforwarders in the corefx
repo, but if you inspect a build of corefx, and use ILSpy to look in the asssembly, the typeforwarders are there. maybe
some other tool makes them, not sure).
There are also some parts of BCL that CoreFX seems to implement itself, without typeforwarding to the "legacy" mscorlib.
Example of this is System.IO.File here: https://github.com/dotnet/corefx/blob/master/src/System.IO.FileSystem/src/System/IO/File.cs
This is a bit akward, because System.IO.File is also in the legacy mscorlib, but it looks like that code is read, and could
probably be removed, or maybe it needs to be kept around to make syncing with some internal microsoft full .net sourcetree
easy or something. Apparently there is a tool called BclRewriter.exe (not (yet) opensource), which the CoreCLR build
procress downloads over nuget. On my build it doesn't run, but on kangaroo's build, it apparently makes internal all the
types inside mscorlib that you should no longer be using directly. (like the System.Reflection ones, that you should be
using through the System.Reflection.dll port forwarders)
An important realization is that unlike the Mono BCL, the CoreFX BCL is not platform agnostic. CoreFX wants to stop using
icalls for everything, and start using pinvoke. This leads to the implementation of File.Delete being done with a pinvoke
to a windows native library:
https://github.com/dotnet/corefx/blob/master/src/Common/src/Interop/Windows/mincore/Interop.DeleteFile.cs (pinvokes into: api-ms-win-core-console-l1-1-0.dll.
note to self: we should check what windows-backward-compatibility story is on these native libraries. do they work on win7? winxp?)
So System.IO.dll compiled for windows, always pinvokes into a windows lib. If you want to run it on mac, you need a
different System.IO.dll compiled for mac, that pinvokes into an osx/posix lib. For System.IO.File, an osx/unix
implementation already lives in the corefx repo, but we need to realize that we need to ship seperate BCLs (or at leats
a subset) per platform. Also note that the work of the "cross os porting" of these libraries is shared between all
Runtimes that decide to support CoreFX. As long as the runtime supports PInvoke, which Mono, IL2CPP and CoreCLR do,
System.IO.dll only needs to be ported to platformX once.
Does CoreFX BCL strip/treeshake better than Mono or referencesource BCL? I have been hoping that it would.
(int.ToString() pulling in ThaiBuddistCalendar is not something I hear game devs request a lot :) ). I have not tried
yet, but since the CoreFX corlib at least today seems almost identical to referencesource, I see no reason to believe that
a HelloWorld app, gets smaller after stripping/treeshaking than it did on a referencesource BCL.
@joncham
Copy link

joncham commented Jul 17, 2015

@terrajobst

For the libraries, we'd rather leverage NuGet to select the appropriate
implementation. I think the implementation of System.IO would use source
sharing, #if, and partial classes, so that we can isolate the OS specific
pieces into a small set. We blieve this makes us more agile. So yes, we
believe that P/Invokes and source sharing is the way to go there.

Does that mean have platform specific (or OS API specific, i.e. POSIX/Win32) versions of each assembly needing native resources?

@terrajobst
Copy link

You don't really need to ship multi-BCLs if you embrace nuget. Basically you'd only ship multiple mscorlib's, and then nuget all the packages that the build requires.

Correct. You do, however, need the runtime library (e.g. mscorlib) to support a certain set of contracts which is done via type forwarding, i.e. something needs to type forward System.Runtime!System.String to mscorlib!System.String. Those type forwarders could be shipped by the runtime or in the derived packages (I'm not up to speed where we currently ship those with NuGet v3).

@terrajobst
Copy link

@joncham

Does that mean have platform specific (or OS API specific, i.e. POSIX/Win32) versions of each assembly needing native resources?

Pretty much. In the past, we only had to support multiple architectures (x86, x64, ARM). Now our native resources would be multiplied by platforms. A binary-based ecosystem using native code is much harder than MSIL which is why we'll probably rethink some of our native dependencies. For example, System.IO.Compression uses a native implementation of deflate called zlib. We didn't do it for speed but mostly because zlib provides a superior compression quality and porting it to managed code would have required more work than simply P/Invoking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment