<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matt Warren</title>
    <description>The latest articles on DEV Community by Matt Warren (@mattwarren).</description>
    <link>https://dev.to/mattwarren</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3387%2Fd8dd6a81-c2db-43ee-944a-d71613192697.jpg</url>
      <title>DEV Community: Matt Warren</title>
      <link>https://dev.to/mattwarren</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mattwarren"/>
    <language>en</language>
    <item>
      <title>ASCII Art in .NET Code</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Wed, 17 Jul 2019 13:07:18 +0000</pubDate>
      <link>https://dev.to/mattwarren/ascii-art-in-net-code-3kcj</link>
      <guid>https://dev.to/mattwarren/ascii-art-in-net-code-3kcj</guid>
      <description>&lt;p&gt;Who doesn't like a nice bit of 'ASCII Art'? I know I certainly do!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=bwSNyA1Nfz4&amp;amp;t=1477" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2019%2F04%2FASCII%2520Art%2520-%2520Matt%27s%2520CLR.png" alt="ASCII Art - Matt's CLR"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see what &lt;em&gt;Matt's CLR&lt;/em&gt; was all about you can watch the recording of my talk &lt;a href="https://www.youtube.com/watch?v=bwSNyA1Nfz4&amp;amp;t=1477" rel="noopener noreferrer"&gt;'From 'dotnet run' to 'Hello World!''&lt;/a&gt; (from about ~24:30 in)&lt;/p&gt;




&lt;p&gt;So armed with a trusty regex &lt;code&gt;/\*(.*?)\*/|//(.*?)\r?\n|"((\\[^\n]|[^"\n])*)"|@("[^"]*")+&lt;/code&gt;, I set out to find all the &lt;strong&gt;interesting ASCII Art&lt;/strong&gt; used in source code comments in the following &lt;em&gt;.NET related&lt;/em&gt; repositories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/" rel="noopener noreferrer"&gt;dotnet/CoreCLR&lt;/a&gt; - "&lt;em&gt;the runtime for .NET Core. It includes the garbage collector, JIT compiler, primitive data types and low-level classes.&lt;/em&gt;"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mono/mono" rel="noopener noreferrer"&gt;Mono&lt;/a&gt; - "&lt;em&gt;open source ECMA CLI, C# and .NET implementation.&lt;/em&gt;"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/corefx" rel="noopener noreferrer"&gt;dotnet/CoreFX&lt;/a&gt; - "&lt;em&gt;the foundational class libraries for .NET Core. It includes types for collections, file systems, console, JSON, XML, async and many others.&lt;/em&gt;"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/Roslyn" rel="noopener noreferrer"&gt;dotnet/Roslyn&lt;/a&gt; - "&lt;em&gt;provides C# and Visual Basic languages with rich code analysis APIs&lt;/em&gt;"&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/aspnet/AspNetCore" rel="noopener noreferrer"&gt;aspnet/AspNetCore&lt;/a&gt; - "&lt;em&gt;a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.&lt;/em&gt;"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Yes, I shamelessly 'borrowed' this idea from &lt;a href="https://twitter.com/johnregehr/status/1095018518737637376" rel="noopener noreferrer"&gt;John Regehr&lt;/a&gt;, I was motivated to write this because his excellent post &lt;a href="https://blog.regehr.org/archives/1653" rel="noopener noreferrer"&gt;'Explaining Code using ASCII Art'&lt;/a&gt; didn't have any &lt;em&gt;.NET related&lt;/em&gt; code in it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you've come across any interesting examples I've missed out, please let me know!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;p&gt;To make the examples easier to browse, I've split them up into categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Table of Contents&lt;/li&gt;
&lt;li&gt;Dave Cutler&lt;/li&gt;
&lt;li&gt;Syntax Trees&lt;/li&gt;
&lt;li&gt;Timelines&lt;/li&gt;
&lt;li&gt;Logic Tables&lt;/li&gt;
&lt;li&gt;Class Hierarchies&lt;/li&gt;
&lt;li&gt;Component Diagrams&lt;/li&gt;
&lt;li&gt;Algorithms&lt;/li&gt;
&lt;li&gt;Bit Packing&lt;/li&gt;
&lt;li&gt;Data Structures&lt;/li&gt;
&lt;li&gt;State Machines&lt;/li&gt;
&lt;li&gt;RFC's and Specs&lt;/li&gt;
&lt;li&gt;Dates &amp;amp; Times&lt;/li&gt;
&lt;li&gt;Stack Layouts&lt;/li&gt;
&lt;li&gt;The Rest&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Dave Cutler
&lt;/h2&gt;

&lt;p&gt;There's no &lt;em&gt;art&lt;/em&gt; in this one, but it deserves it's own category as it quotes the amazing &lt;a href="https://en.wikipedia.org/wiki/Dave_Cutler" rel="noopener noreferrer"&gt;Dave Cutler&lt;/a&gt; who led the development of Windows NT. Therefore there's no better person to ask a deep, technical question about how &lt;em&gt;Thread Suspension&lt;/em&gt; works on Windows, from &lt;a href="https://github.com/dotnet/coreclr/blob/dc11162e1c36624d3cabb6e0bf6583a94ab2e30c/src/vm/threadsuspend.cpp#L102-L124" rel="noopener noreferrer"&gt;coreclr/src/vm/threadsuspend.cpp&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Message from David Cutler
/*
    After SuspendThread returns, can the suspended thread continue to execute code in user mode?

    [David Cutler] The suspended thread cannot execute any more user code, but it might be currently "running"
    on a logical processor whose other logical processor is currently actually executing another thread.
    In this case the target thread will not suspend until the hardware switches back to executing instructions
    on its logical processor. In this case even the memory barrier would not necessarily work - a better solution
    would be to use interlocked operations on the variable itself.

    After SuspendThread returns, does the store buffer of the CPU for the suspended thread still need to drain?

    Historically, we've assumed that the answer to both questions is No.  But on one 4/8 hyper-threaded machine
    running Win2K3 SP1 build 1421, we've seen two stress failures where SuspendThread returns while writes seem to still be in flight.

    Usually after we suspend a thread, we then call GetThreadContext.  This seems to guarantee consistency.
    But there are places we would like to avoid GetThreadContext, if it's safe and legal.

    [David Cutler] Get context delivers a APC to the target thread and waits on an event that will be set
    when the target thread has delivered its context.

    Chris.
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more info on Dave Cutler, see this excellent interview &lt;a href="https://dave.cheney.net/2018/10/06/internets-of-interest-6-dave-cutler-on-dave-cutler" rel="noopener noreferrer"&gt;'Internets of Interest #6: Dave Cutler on Dave Cutler'&lt;/a&gt; or &lt;a href="https://news.microsoft.com/features/the-engineers-engineer-computer-industry-luminaries-salute-dave-cutlers-five-decade-long-quest-for-quality/" rel="noopener noreferrer"&gt;'The engineer’s engineer: Computer industry luminaries salute Dave Cutler’s five-decade-long quest for quality'&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Syntax Trees
&lt;/h2&gt;

&lt;p&gt;The inner workings of the .NET 'Just-in-Time' (JIT) Compiler have always been a bit of a mystery to me. But, having informative comments like this one from &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/lsra.cpp#L6166-L6196" rel="noopener noreferrer"&gt;coreclr/src/jit/lsra.cpp&lt;/a&gt; go some way to showing what it's doing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// For example, for this tree (numbers are execution order, lower is earlier and higher is later):
//
//                                   +---------+----------+
//                                   |       GT_ADD (3)   |
//                                   +---------+----------+
//                                             |
//                                           /   \
//                                         /       \
//                                       /           \
//                   +-------------------+           +----------------------+
//                   |         x (1)     | "tree"    |         y (2)        |
//                   +-------------------+           +----------------------+
//
// generate this tree:
//
//                                   +---------+----------+
//                                   |       GT_ADD (4)   |
//                                   +---------+----------+
//                                             |
//                                           /   \
//                                         /       \
//                                       /           \
//                   +-------------------+           +----------------------+
//                   |  GT_RELOAD (3)    |           |         y (2)        |
//                   +-------------------+           +----------------------+
//                             |
//                   +-------------------+
//                   |         x (1)     | "tree"
//                   +-------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's also a more in-depth example in &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/morph.cpp#L6170-L6236" rel="noopener noreferrer"&gt;coreclr/src/jit/morph.cpp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also from &lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/VisualBasic/Portable/Semantics/TypeInference/RequiredConversion.vb#L87-L104" rel="noopener noreferrer"&gt;roslyn/src/Compilers/VisualBasic/Portable/Semantics/TypeInference/RequiredConversion.vb&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; '// These restrictions form a partial order composed of three chains: from less strict to more strict, we have:
'//    [reverse chain] [None] &amp;lt; AnyReverse &amp;lt; ReverseReference &amp;lt; Identity
'//    [middle  chain] None &amp;lt; [Any,AnyReverse] &amp;lt; AnyConversionAndReverse &amp;lt; Identity
'//    [forward chain] [None] &amp;lt; Any &amp;lt; ArrayElement &amp;lt; Reference &amp;lt; Identity
'//
'//            =           KEY:
'//         /  |  \           =     Identity
'//        /   |   \         +r     Reference
'//      -r    |    +r       -r     ReverseReference
'//       |  +-any  |       +-any   AnyConversionAndReverse
'//       |   /|\   +arr     +arr   ArrayElement
'//       |  / | \  |        +any   Any
'//      -any  |  +any       -any   AnyReverse
'//         \  |  /           none  None
'//          \ | /
'//           none
'//
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Timelines
&lt;/h2&gt;

&lt;p&gt;This example from &lt;a href="https://github.com/dotnet/coreclr/blob/e277764916cbb740db199132be81701593820bb0/src/vm/comwaithandle.cpp#L129-L156" rel="noopener noreferrer"&gt;coreclr/src/vm/comwaithandle.cpp&lt;/a&gt; was unique! I didn't find another example of ASCII Art used to illustrate time-lines, it's a really novel approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// In case the CLR is paused inbetween a wait, this method calculates how much 
// the wait has to be adjusted to account for the CLR Freeze. Essentially all
// pause duration has to be considered as "time that never existed".
//
// Two cases exists, consider that 10 sec wait is issued 
// Case 1: All pauses happened before the wait completes. Hence just the 
// pause time needs to be added back at the end of wait
// 0           3                   8       10
// |-----------|###################|------&amp;gt;
//                 5-sec pause    
//             ....................&amp;gt;
//                                            Additional 5 sec wait
//                                        |=========================&amp;gt; 
//
// Case 2: Pauses ended after the wait completes. 
// 3 second of wait was left as the pause started at 7 so need to add that back
// 0                           7           10
// |---------------------------|###########&amp;gt;
//                                 5-sec pause   12
//                             ...................&amp;gt;
//                                            Additional 3 sec wait
//                                                |==================&amp;gt; 
//
// Both cases can be expressed in the same calculation
// pauseTime:   sum of all pauses that were triggered after the timer was started
// expDuration: expected duration of the wait (without any pauses) 10 in the example
// actDuration: time when the wait finished. Since the CLR is frozen during pause it's
//              max of timeout or pause-end. In case-1 it's 10, in case-2 it's 12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Logic Tables
&lt;/h2&gt;

&lt;p&gt;A sweet-spot for ASCII Art seems to be tables, there are so many examples. Starting with &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/methodtablebuilder.cpp#L4675-L4686" rel="noopener noreferrer"&gt;coreclr/src/vm/methodtablebuilder.cpp&lt;/a&gt; (bonus points for combining comments and code together!)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//               |        Base type&lt;/span&gt;
&lt;span class="c1"&gt;// Subtype       |        mdPrivateScope  mdPrivate   mdFamANDAssem   mdAssem     mdFamily    mdFamORAssem    mdPublic&lt;/span&gt;
&lt;span class="c1"&gt;// --------------+-------------------------------------------------------------------------------------------------------&lt;/span&gt;
&lt;span class="cm"&gt;/*mdPrivateScope | */&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="cm"&gt;/*mdPrivate      | */&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="cm"&gt;/*mdFamANDAssem  | */&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_SA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="cm"&gt;/*mdAssem        | */&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_SA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_SA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_NO&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="cm"&gt;/*mdFamily       | */&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;e_NO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_NSA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;e_NO&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="cm"&gt;/*mdFamORAssem   | */&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;e_SA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;e_NO&lt;/span&gt;    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="cm"&gt;/*mdPublic       | */&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;e_SM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="n"&gt;e_YES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="n"&gt;e_YES&lt;/span&gt;   &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/importer.cpp#L15265-L15283" rel="noopener noreferrer"&gt;coreclr/src/jit/importer.cpp&lt;/a&gt; which shows how the JIT deals with boxing/un-boxing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
    ----------------------------------------------------------------------
    | \ helper  |                         |                              |
    |   \       |                         |                              |
    |     \     | CORINFO_HELP_UNBOX      | CORINFO_HELP_UNBOX_NULLABLE  |
    |       \   | (which returns a BYREF) | (which returns a STRUCT)     |
    | opcode  \ |                         |                              |
    |---------------------------------------------------------------------
    | UNBOX     | push the BYREF          | spill the STRUCT to a local, |
    |           |                         | push the BYREF to this local |
    |---------------------------------------------------------------------
    | UNBOX_ANY | push a GT_OBJ of        | push the STRUCT              |
    |           | the BYREF               | For Linux when the           |
    |           |                         |  struct is returned in two   |
    |           |                         |  registers create a temp     |
    |           |                         |  which address is passed to  |
    |           |                         |  the unbox_nullable helper.  |
    |---------------------------------------------------------------------
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, there's some other nice examples showing the rules for &lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/CSharp/Portable/Binder/Semantics/Operators/BinaryOperatorEasyOut.cs#L104-L165" rel="noopener noreferrer"&gt;operator overloading&lt;/a&gt; in the C# (Roslyn) Compiler and which .NET data-types &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Convert.cs#L46-L63" rel="noopener noreferrer"&gt;can be converted&lt;/a&gt; via the &lt;code&gt;System.ToXXX()&lt;/code&gt; functions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Class Hierarchies
&lt;/h2&gt;

&lt;p&gt;Of course, most IDE's come with tools that will generate class-hierarchies for you, but it's much nicer to see them in ASCII, from &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/object.h#L28-L55" rel="noopener noreferrer"&gt;coreclr/src/vm/object.h&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; * COM+ Internal Object Model
 *
 *
 * Object              - This is the common base part to all COM+ objects
 *  |                        it contains the MethodTable pointer and the
 *  |                        sync block index, which is at a negative offset
 *  |
 *  +-- code:StringObject       - String objects are specialized objects for string
 *  |                        storage/retrieval for higher performance
 *  |
 *  +-- BaseObjectWithCachedData - Object Plus one object field for caching.
 *  |       |
 *  |       +-  ReflectClassBaseObject    - The base object for the RuntimeType class
 *  |       +-  ReflectMethodObject       - The base object for the RuntimeMethodInfo class
 *  |       +-  ReflectFieldObject        - The base object for the RtFieldInfo class
 *  |
 *  +-- code:ArrayBase          - Base portion of all arrays
 *  |       |
 *  |       +-  I1Array    - Base type arrays
 *  |       |   I2Array
 *  |       |   ...
 *  |       |
 *  |       +-  PtrArray   - Array of OBJECTREFs, different than base arrays because of pObjectClass
 *  |              
 *  +-- code:AssemblyBaseObject - The base object for the class Assembly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's also an &lt;a href="https://github.com/dotnet/coreclr/blob/1f02c30e053b1da4410e20c3b715128e3d1e354a/src/vm/frames.h#L7-L197" rel="noopener noreferrer"&gt;even larger one&lt;/a&gt; that I stumbled across when writing &lt;a href="http://mattwarren.org/2019/01/21/Stackwalking-in-the-.NET-Runtime/" rel="noopener noreferrer"&gt;"Stack Walking" in the .NET Runtime&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Component Diagrams
&lt;/h2&gt;

&lt;p&gt;When you have several different components in a code-base it's always nice to see how they fit together. From &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/codeman.h#L14-L56" rel="noopener noreferrer"&gt;coreclr/src/vm/codeman.h&lt;/a&gt; we can see how the top-level parts of the .NET JIT work together&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                                               ExecutionManager
                                                       |
                           +-----------+---------------+---------------+-----------+--- ...
                           |           |                               |           |
                        CodeType       |                            CodeType       |
                           |           |                               |           |
                           v           v                               v           v
+---------------+      +--------+&amp;lt;---- R    +---------------+      +--------+&amp;lt;---- R
|ICorJitCompiler|&amp;lt;----&amp;gt;|IJitMan |&amp;lt;---- R    |ICorJitCompiler|&amp;lt;----&amp;gt;|IJitMan |&amp;lt;---- R
+---------------+      +--------+&amp;lt;---- R    +---------------+      +--------+&amp;lt;---- R
                           |       x   .                               |       x   .
                           |        \  .                               |        \  .
                           v         \ .                               v         \ .
                       +--------+      R                           +--------+      R
                       |ICodeMan|                                  |ICodeMan|     (RangeSections)
                       +--------+                                  +--------+       
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other notable examples are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/compile.h#L14-L47" rel="noopener noreferrer"&gt;coreclr/src/vm/compile.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/inc/ceegen.h#L47-L92" rel="noopener noreferrer"&gt;coreclr/src/inc/ceegen.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/debug/di/divalue.cpp#L1432-L1451" rel="noopener noreferrer"&gt;coreclr/src/debug/di/divalue.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/ceeload.cpp#L10543-L10578" rel="noopener noreferrer"&gt;coreclr/src/vm/ceeload.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, from &lt;a href="https://github.com/dotnet/coreclr/blob/e6034d903f2608445a3f66e3694f461fad7b8b88/src/vm/ceeload.cpp#L10350-L10385" rel="noopener noreferrer"&gt;coreclr/src/vm/ceeload.cpp&lt;/a&gt; we see the inner-workings of the &lt;a href="https://docs.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator" rel="noopener noreferrer"&gt;Native Image Generator (NGEN)&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        This diagram illustrates the layout of fixups in the ngen image.
        This is the case where function foo2 has a class-restore fixup
        for class C1 in b.dll.

                                  zapBase+curTableVA+rva /         FixupList (see Fixup Encoding below)
                                  m_pFixupBlobs
                                                            +-------------------+
                  pEntry-&amp;gt;VA +--------------------+         |     non-NULL      | foo1
                             |Handles             |         +-------------------+
ZapHeader.ImportTable        |                    |         |     non-NULL      |
                             |                    |         +-------------------+
   +------------+            +--------------------+         |     non-NULL      |
   |a.dll       |            |Class cctors        |&amp;lt;---+    +-------------------+
   |            |            |                    |     \   |         0         |
   |            |     p-&amp;gt;VA/ |                    |&amp;lt;---+ \  +===================+
   |            |      blobs +--------------------+     \ +-------non-NULL      | foo2
   +------------+            |Class restore       |      \  +-------------------+
   |b.dll       |            |                    |       +-------non-NULL      |
   |            |            |                    |         +-------------------+
   |  token_C1  |&amp;lt;--------------blob(=&amp;gt;fixedUp/0) |&amp;lt;--pBlob--------index        |
   |            | \          |                    |         +-------------------+
   |            |  \         +--------------------+         |     non-NULL      |
   |            |   \        |                    |         +-------------------+
   |            |    \       |        .           |         |         0         |
   |            |     \      |        .           |         +===================+
   +------------+      \     |        .           |         |         0         | foo3
                        \    |                    |         +===================+
                         \   +--------------------+         |     non-NULL      | foo4
                          \  |Various fixups that |         +-------------------+
                           \ |need too happen     |         |         0         |
                            \|                    |         +===================+
                             |(CorCompileTokenTable)
                             |                    |
               pEntryEnd-&amp;gt;VA +--------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Algorithms
&lt;/h2&gt;

&lt;p&gt;They say '&lt;em&gt;a picture paints a thousand words&lt;/em&gt;' and that definately applies when describing complex algorithms, from &lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Workspaces/Core/Portable/Utilities/EditDistance.cs#L232-L287" rel="noopener noreferrer"&gt;roslyn/src/Workspaces/Core/Portable/Utilities/EditDistance.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// If we fill out the matrix fully we'll get:
//          
//           s u n d a y &amp;lt;-- source
//      ----------------
//      |∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞
//      |∞ 0 1 2 3 4 5 6
//    s |∞ 1 0 1 2 3 4 5 
//    a |∞ 2 1 1 2 3 3 4 
//    t |∞ 3 2 2 2 3 4 4 
//    u |∞ 4 3 2 3 3 4 5 
//    r |∞ 5 4 3 3 4 4 5 
//    d |∞ 6 5 4 4 3 4 5 
//    a |∞ 7 6 5 5 4 3 4 
//    y |∞ 8 7 6 6 5 4 3 &amp;lt;--
//                     ^
//                     |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, this gem that explains how the DOS wild-card matching works, &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemName.cs#L104-L158" rel="noopener noreferrer"&gt;corefx/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemName.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Matching routine description
// ============================
// (copied from native impl)
//
// This routine compares a Dbcs name and an expression and tells the caller
// if the name is in the language defined by the expression.  The input name
// cannot contain wildcards, while the expression may contain wildcards.
//
// Expression wild cards are evaluated as shown in the nondeterministic
// finite automatons below.  Note that ~* and ~? are DOS_STAR and DOS_QM.
//
//        ~* is DOS_STAR, ~? is DOS_QM, and ~. is DOS_DOT
//
//                                  S
//                               &amp;lt;-----&amp;lt;
//                            X  |     |  e       Y
//        X * Y ==       (0)-----&amp;gt;-(1)-&amp;gt;-----(2)-----(3)
//
//                                 S-.
//                               &amp;lt;-----&amp;lt;
//                            X  |     |  e       Y
//        X ~* Y ==      (0)-----&amp;gt;-(1)-&amp;gt;-----(2)-----(3)
//
//                           X     S     S     Y
//        X ?? Y ==      (0)---(1)---(2)---(3)---(4)
//
//                           X     .        .      Y
//        X ~.~. Y ==    (0)---(1)----(2)------(3)---(4)
//                              |      |________|
//                              |           ^   |
//                              |_______________|
//                                 ^EOF or .^
//
//                           X     S-.     S-.     Y
//        X ~?~? Y ==    (0)---(1)-----(2)-----(3)---(4)
//                              |      |________|
//                              |           ^   |
//                              |_______________|
//                                 ^EOF or .^
//
//    where S is any single character
//          S-. is any single character except the final .
//          e is a null character transition
//          EOF is the end of the name string
//
//   In words:
//
//       * matches 0 or more characters.
//       ? matches exactly 1 character.
//       DOS_STAR matches 0 or more characters until encountering and matching
//           the final . in the name.
//       DOS_QM matches any single character, or upon encountering a period or
//           end of name string, advances the expression to the end of the
//           set of contiguous DOS_QMs.
//       DOS_DOT matches either a . or zero characters beyond name string.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally from &lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Workspaces/Core/Portable/Shared/Collections/IntervalTree%601.Node.cs#L65-L125" rel="noopener noreferrer"&gt;roslyn/src/Workspaces/Core/Portable/Shared/Collections/IntervalTree1.Node.cs&lt;/a&gt; we have per-method comments with samples, this is a great idea!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sample:&lt;/span&gt;
&lt;span class="c1"&gt;//   1            1                  3&lt;/span&gt;
&lt;span class="c1"&gt;//  / \          / \              /     \&lt;/span&gt;
&lt;span class="c1"&gt;// a   2        a   3            1       2&lt;/span&gt;
&lt;span class="c1"&gt;//    / \   =&amp;gt;     / \     =&amp;gt;   / \     / \&lt;/span&gt;
&lt;span class="c1"&gt;//   3   d        b   2        a   b   c   d&lt;/span&gt;
&lt;span class="c1"&gt;//  / \              / \&lt;/span&gt;
&lt;span class="c1"&gt;// b   c            c   d&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="nf"&gt;InnerRightOuterLeftRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IIntervalIntrospector&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;introspector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Sample:&lt;/span&gt;
&lt;span class="c1"&gt;//     1              1              3&lt;/span&gt;
&lt;span class="c1"&gt;//    / \            / \          /     \&lt;/span&gt;
&lt;span class="c1"&gt;//   2   d          3   d        2       1&lt;/span&gt;
&lt;span class="c1"&gt;//  / \     =&amp;gt;     / \     =&amp;gt;   / \     / \&lt;/span&gt;
&lt;span class="c1"&gt;// a   3          2   c        a   b   c   d&lt;/span&gt;
&lt;span class="c1"&gt;//    / \        / \&lt;/span&gt;
&lt;span class="c1"&gt;//   b   c      a   b&lt;/span&gt;
&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="n"&gt;Node&lt;/span&gt; &lt;span class="nf"&gt;InnerLeftOuterRightRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IIntervalIntrospector&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;introspector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Bit Packing
&lt;/h2&gt;

&lt;p&gt;Maybe you can visualise which &lt;em&gt;individual&lt;/em&gt; bits are set given a Hexadecimal value, but I can't, so I'm always grateful for comments like this one from &lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs#L28-L37" rel="noopener noreferrer"&gt;roslyn/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// We current pack everything into two 32-bit ints; layouts for each are given below.

// First int:
//
// | |d|yy|xxxxxxxxxxxxxxxxxxxxxxx|wwwwww|
//
// w = special type.  6 bits.
// x = modifiers.  23 bits.
// y = IsManagedType.  2 bits.
// d = FieldDefinitionsNoted. 1 bit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one from &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Runtime.WindowsRuntime/src/System/Threading/Tasks/TaskToAsyncInfoAdapter.cs#L26-L43" rel="noopener noreferrer"&gt;corefx/src/System.Runtime.WindowsRuntime/src/System/Threading/Tasks/TaskToAsyncInfoAdapter.cs&lt;/a&gt; also does a great job of showing the different bit-flags and how they interact&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ! THIS DIAGRAM ILLUSTRATES THE CONSTANTS BELOW. UPDATE THIS IF UPDATING THE CONSTANTS BELOW!:
//     3         2         1         0
//    10987654321098765432109876543210
//    X...............................   Reserved such that we can use Int32 and not worry about negative-valued state constants
//    ..X.............................   STATEFLAG_COMPLETED_SYNCHRONOUSLY
//    ...X............................   STATEFLAG_MUST_RUN_COMPLETION_HNDL_WHEN_SET
//    ....X...........................   STATEFLAG_COMPLETION_HNDL_NOT_YET_INVOKED
//    ................................   STATE_NOT_INITIALIZED
//    ...............................X   STATE_STARTED
//    ..............................X.   STATE_RUN_TO_COMPLETION
//    .............................X..   STATE_CANCELLATION_REQUESTED
//    ............................X...   STATE_CANCELLATION_COMPLETED
//    ...........................X....   STATE_ERROR
//    ..........................X.....   STATE_CLOSED
//    ..........................XXXXXX   STATEMASK_SELECT_ANY_ASYNC_STATE
//    XXXXXXXXXXXXXXXXXXXXXXXXXX......   STATEMASK_CLEAR_ALL_ASYNC_STATES
//     3         2         1         0
//    10987654321098765432109876543210
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we have some helpful explanations of how different encoding work. Firstly UTF-8 from &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Text/UTF8Encoding.cs#L38-L49" rel="noopener noreferrer"&gt;corefx//src/Common/src/CoreLib/System/Text/UTF8Encoding.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
    bytes   bits    UTF-8 representation
    -----   ----    -----------------------------------
    1        7      0vvvvvvv
    2       11      110vvvvv 10vvvvvv
    3       16      1110vvvv 10vvvvvv 10vvvvvv
    4       21      11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
    -----   ----    -----------------------------------
    Surrogate:
    Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then UTF-32 in &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Text/UTF32Encoding.cs#L26-L35" rel="noopener noreferrer"&gt;corefx/src/Common/src/CoreLib/System/Text/UTF32Encoding.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
    words   bits    UTF-32 representation
    -----   ----    -----------------------------------
    1       16      00000000 00000000 xxxxxxxx xxxxxxxx
    2       21      00000000 000xxxxx hhhhhhll llllllll
    -----   ----    -----------------------------------
    Surrogate:
    Real Unicode value = (HighSurrogate - 0xD800) * 0x400 + (LowSurrogate - 0xDC00) + 0x10000
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Data Structures
&lt;/h2&gt;

&lt;p&gt;This comment from &lt;a href="https://github.com/mono/mono/blob/2019-02/mono/utils/dlmalloc.c#L1509-L1564" rel="noopener noreferrer"&gt;mono/utils/dlmalloc.c&lt;/a&gt; does a great job of showing how chunks of memory are arranaged by &lt;code&gt;malloc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  A chunk that's in use looks like:

   chunk-&amp;gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           | Size of previous chunk (if P = 1)                             |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
         | Size of this chunk                                         1| +-+
   mem-&amp;gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |                                                               |
         +-                                                             -+
         |                                                               |
         +-                                                             -+
         |                                                               :
         +-      size - sizeof(size_t) available payload bytes          -+
         :                                                               |
 chunk-&amp;gt; +-                                                             -+
         |                                                               |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
       | Size of next chunk (may or may not be in use)               | +-+
 mem-&amp;gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    And if it's free, it looks like this:

   chunk-&amp;gt; +-                                                             -+
           | User payload (must be in use, or we would have merged!)       |
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
         | Size of this chunk                                         0| +-+
   mem-&amp;gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         | Next pointer                                                  |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         | Prev pointer                                                  |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         |                                                               :
         +-      size - sizeof(struct chunk) unused bytes               -+
         :                                                               |
 chunk-&amp;gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         | Size of this chunk                                            |
         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
       | Size of next chunk (must be in use, or we would have merged)| +-+
 mem-&amp;gt; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               :
       +- User payload                                                -+
       :                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                                     |0|
                                                                    +-+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, from &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/MemoryExtensions.cs#L1185-L1311" rel="noopener noreferrer"&gt;corefx/src/Common/src/CoreLib/System/MemoryExtensions.cs&lt;/a&gt; we can see how overlapping memory regions are detected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//  Visually, the two sequences are located somewhere in the 32-bit
//  address space as follows:
//
//      [----------------------------------------------)                            normal address space
//      0                                             2³²
//                            [------------------)                                  first sequence
//                            xRef            xRef + xLength
//              [--------------------------)     .                                  second sequence
//              yRef          .         yRef + yLength
//              :             .            .     .
//              :             .            .     .
//                            .            .     .
//                            .            .     .
//                            .            .     .
//                            [----------------------------------------------)      relative address space
//                            0            .     .                          2³²
//                            [------------------)             :                    first sequence
//                            x1           .     x2            :
//                            -------------)                   [-------------       second sequence
//                                         y2                  y1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  State Machines
&lt;/h2&gt;

&lt;p&gt;This comment from &lt;a href="https://github.com/mono/mono/blob/2019-02/mono/benchmark/zipmark.cs#L204-L237" rel="noopener noreferrer"&gt;mono/benchmark/zipmark.cs&lt;/a&gt; gives a great over-view of the implementation of &lt;a href="https://www.ietf.org/rfc/rfc1951.txt" rel="noopener noreferrer"&gt;RFC 1951 - DEFLATE Compressed Data Format Specification&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
 * The Deflater can do the following state transitions:
    *
    * (1) -&amp;gt; INIT_STATE   ----&amp;gt; INIT_FINISHING_STATE ---.
    *        /  | (2)      (5)                         |
    *       /   v          (5)                         |
    *   (3)| SETDICT_STATE ---&amp;gt; SETDICT_FINISHING_STATE |(3)
    *       \   | (3)                 |        ,-------'
    *        |  |                     | (3)   /
    *        v  v          (5)        v      v
    * (1) -&amp;gt; BUSY_STATE   ----&amp;gt; FINISHING_STATE
    *                                | (6)
    *                                v
    *                           FINISHED_STATE
    *    \_____________________________________/
    *          | (7)
    *          v
    *        CLOSED_STATE
    *
    * (1) If we should produce a header we start in INIT_STATE, otherwise
    *     we start in BUSY_STATE.
    * (2) A dictionary may be set only when we are in INIT_STATE, then
    *     we change the state as indicated.
    * (3) Whether a dictionary is set or not, on the first call of deflate
    *     we change to BUSY_STATE.
    * (4) -- intentionally left blank -- :)
    * (5) FINISHING_STATE is entered, when flush() is called to indicate that
    *     there is no more INPUT.  There are also states indicating, that
    *     the header wasn't written yet.
    * (6) FINISHED_STATE is entered, when everything has been flushed to the
    *     internal pending output buffer.
    * (7) At any time (7)
    *
    */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This might be pushing the definition of 'state machine' a bit far, but I wanted to include it because it shows just how complex 'exception handling' can be, from &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/jiteh.cpp#L1935-L1966" rel="noopener noreferrer"&gt;coreclr/src/jit/jiteh.cpp&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// fgNormalizeEH: Enforce the following invariants:
//
//   1. No block is both the first block of a handler and the first block of a try. In IL (and on entry
//      to this function), this can happen if the "try" is more nested than the handler.
//
//      For example, consider:
//
//               try1 ----------------- BB01
//               |                      BB02
//               |--------------------- BB03
//               handler1
//               |----- try2 ---------- BB04
//               |      |               BB05
//               |      handler2 ------ BB06
//               |      |               BB07
//               |      --------------- BB08
//               |--------------------- BB09
//
//      Thus, the start of handler1 and the start of try2 are the same block. We will transform this to:
//
//               try1 ----------------- BB01
//               |                      BB02
//               |--------------------- BB03
//               handler1 ------------- BB10 // empty block
//               |      try2 ---------- BB04
//               |      |               BB05
//               |      handler2 ------ BB06
//               |      |               BB07
//               |      --------------- BB08
//               |--------------------- BB09
//
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  RFC's and Specs
&lt;/h2&gt;

&lt;p&gt;Next up, how the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.2" rel="noopener noreferrer"&gt;Kestrel web-server&lt;/a&gt; handles &lt;a href="https://tools.ietf.org/html/rfc7540" rel="noopener noreferrer"&gt;RFC 7540 - Hypertext Transfer Protocol Version 2 (HTTP/2)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Firstly, from &lt;a href="https://github.com/aspnet/AspNetCore/blob/ab3e0f953e537c71b3ba06966e6db1e88e33bc41/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.cs#L6-L16" rel="noopener noreferrer"&gt;aspnet/AspNetCore/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* https://tools.ietf.org/html/rfc7540#section-4.1
    +-----------------------------------------------+
    |                 Length (24)                   |
    +---------------+---------------+---------------+
    |   Type (8)    |   Flags (8)   |
    +-+-------------+---------------+-------------------------------+
    |R|                 Stream Identifier (31)                      |
    +=+=============================================================+
    |                   Frame Payload (0...)                      ...
    +---------------------------------------------------------------+
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then in &lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Headers.cs#L6-L18" rel="noopener noreferrer"&gt;aspnet/AspNetCore/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Headers.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* https://tools.ietf.org/html/rfc7540#section-6.2
    +---------------+
    |Pad Length? (8)|
    +-+-------------+-----------------------------------------------+
    |E|                 Stream Dependency? (31)                     |
    +-+-------------+-----------------------------------------------+
    |  Weight? (8)  |
    +-+-------------+-----------------------------------------------+
    |                   Header Block Fragment (*)                 ...
    +---------------------------------------------------------------+
    |                           Padding (*)                       ...
    +---------------------------------------------------------------+
*/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are other notable examples in &lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameReader.cs#L15-L25" rel="noopener noreferrer"&gt;aspnet/AspNetCore/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameReader.cs&lt;/a&gt; and &lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs#L145-L158" rel="noopener noreferrer"&gt;aspnet/AspNetCore/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also &lt;a href="https://tools.ietf.org/html/rfc3986" rel="noopener noreferrer"&gt;RFC 3986 - Uniform Resource Identifier (URI)&lt;/a&gt; is discussed in &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/System/Net/IPv4AddressHelper.Common.cs#L105-L113" rel="noopener noreferrer"&gt;corefx/src/Common/src/System/Net/IPv4AddressHelper.Common.cs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, &lt;a href="https://httpwg.org/specs/rfc7541.html" rel="noopener noreferrer"&gt;RFC 7541 - HPACK: Header Compression for HTTP/2&lt;/a&gt;, is covered in &lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecoder.cs#L26-L71" rel="noopener noreferrer"&gt;aspnet/AspNetCore/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecoder.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// http://httpwg.org/specs/rfc7541.html#rfc.section.6.1&lt;/span&gt;
&lt;span class="c1"&gt;//   0   1   2   3   4   5   6   7&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+---+---+---+---+---+---+&lt;/span&gt;
&lt;span class="c1"&gt;// | 1 |        Index (7+)         |&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---------------------------+&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;IndexedHeaderFieldMask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;IndexedHeaderFieldRepresentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1&lt;/span&gt;
&lt;span class="c1"&gt;//   0   1   2   3   4   5   6   7&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+---+---+---+---+---+---+&lt;/span&gt;
&lt;span class="c1"&gt;// | 0 | 1 |      Index (6+)       |&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+-----------------------+&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;LiteralHeaderFieldWithIncrementalIndexingMask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0xc0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;LiteralHeaderFieldWithIncrementalIndexingRepresentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2&lt;/span&gt;
&lt;span class="c1"&gt;//   0   1   2   3   4   5   6   7&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+---+---+---+---+---+---+&lt;/span&gt;
&lt;span class="c1"&gt;// | 0 | 0 | 0 | 0 |  Index (4+)   |&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+-----------------------+&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;LiteralHeaderFieldWithoutIndexingMask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0xf0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;LiteralHeaderFieldWithoutIndexingRepresentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3&lt;/span&gt;
&lt;span class="c1"&gt;//   0   1   2   3   4   5   6   7&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+---+---+---+---+---+---+&lt;/span&gt;
&lt;span class="c1"&gt;// | 0 | 0 | 0 | 1 |  Index (4+)   |&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+-----------------------+&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;LiteralHeaderFieldNeverIndexedMask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0xf0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;LiteralHeaderFieldNeverIndexedRepresentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// http://httpwg.org/specs/rfc7541.html#rfc.section.6.3&lt;/span&gt;
&lt;span class="c1"&gt;//   0   1   2   3   4   5   6   7&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+---+---+---+---+---+---+&lt;/span&gt;
&lt;span class="c1"&gt;// | 0 | 0 | 1 |   Max size (5+)   |&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---------------------------+&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;DynamicTableSizeUpdateMask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0xe0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;DynamicTableSizeUpdateRepresentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// http://httpwg.org/specs/rfc7541.html#rfc.section.5.2&lt;/span&gt;
&lt;span class="c1"&gt;//   0   1   2   3   4   5   6   7&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---+---+---+---+---+---+---+&lt;/span&gt;
&lt;span class="c1"&gt;// | H |    String Length (7+)     |&lt;/span&gt;
&lt;span class="c1"&gt;// +---+---------------------------+&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;HuffmanMask&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0x80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Dates &amp;amp; Times
&lt;/h2&gt;

&lt;p&gt;It is pretty widely accepted that &lt;a href="https://www.reddit.com/r/programming/comments/ln1tg/bad_timing_why_dates_and_times_are_hard/" rel="noopener noreferrer"&gt;dates and times are hard&lt;/a&gt; and that's reflected in the amount of comments explaining different scenarios. For example from &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/TimeZoneInfo.cs#L1273-L1289" rel="noopener noreferrer"&gt;corefx/src/Common/src/CoreLib/System/TimeZoneInfo.cs&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// startTime and endTime represent the period from either the start of DST to the end and
// ***does not include*** the potentially overlapped times
//
//         -=-=-=-=-=- Pacific Standard Time -=-=-=-=-=-=-
//    April 2, 2006                            October 29, 2006
// 2AM            3AM                        1AM              2AM
// |      +1 hr     |                        |       -1 hr      |
// | &amp;lt;invalid time&amp;gt; |                        | &amp;lt;ambiguous time&amp;gt; |
//                  [========== DST ========&amp;gt;)
//
//        -=-=-=-=-=- Some Weird Time Zone -=-=-=-=-=-=-
//    April 2, 2006                          October 29, 2006
// 1AM              2AM                    2AM              3AM
// |      -1 hr       |                      |       +1 hr      |
// | &amp;lt;ambiguous time&amp;gt; |                      |  &amp;lt;invalid time&amp;gt;  |
//                    [======== DST ========&amp;gt;)
//
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, from &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/TimeZoneInfo.Unix.cs#L1244-L1265" rel="noopener noreferrer"&gt;corefx/src/Common/src/CoreLib/System/TimeZoneInfo.Unix.cs&lt;/a&gt; we see some details on how 'leap-years' are handled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// should be n Julian day format which we don't support. 
// 
// This specifies the Julian day, with n between 0 and 365. February 29 is counted in leap years.
//
// n would be a relative number from the begining of the year. which should handle if the 
// the year is a leap year or not.
// 
// In leap year, n would be counted as:
// 
// 0                30 31              59 60              90      335            365
// |-------Jan--------|-------Feb--------|-------Mar--------|....|-------Dec--------|
//
// while in non leap year we'll have 
// 
// 0                30 31              58 59              89      334            364
// |-------Jan--------|-------Feb--------|-------Mar--------|....|-------Dec--------|
//
// 
// For example if n is specified as 60, this means in leap year the rule will start at Mar 1,
// while in non leap year the rule will start at Mar 2.
// 
// If we need to support n format, we'll have to have a floating adjustment rule support this case.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, this comment from &lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Runtime/tests/System/TimeZoneInfoTests.cs#L1512-L1524" rel="noopener noreferrer"&gt;corefx/src/System.Runtime/tests/System/TimeZoneInfoTests.cs&lt;/a&gt; discusses invalid and ambiguous times that are covered in tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//    March 26, 2006                            October 29, 2006
// 2AM            3AM                        2AM              3AM
// |      +1 hr     |                        |       -1 hr      |
// | &amp;lt;invalid time&amp;gt; |                        | &amp;lt;ambiguous time&amp;gt; |
//                  *========== DST ========&amp;gt;*

//
// * 00:59:59 Sunday March 26, 2006 in Universal converts to
//   01:59:59 Sunday March 26, 2006 in Europe/Amsterdam (NO DST)
//
// * 01:00:00 Sunday March 26, 2006 in Universal converts to
//   03:00:00 Sunday March 26, 2006 in Europe/Amsterdam (DST)
//
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Stack Layouts
&lt;/h2&gt;

&lt;p&gt;To finish off, I wanted to look at 'stack layouts' because they seem to be a favourite of the .NET/Mono Runtime Engineers, there's sooo many examples!&lt;/p&gt;

&lt;p&gt;First-up, &lt;code&gt;x68&lt;/code&gt; from &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/lclvars.cpp#L4309-L4374" rel="noopener noreferrer"&gt;coreclr/src/jit/lclvars.cpp&lt;/a&gt; (you can also see the &lt;a href="https://github.com/dotnet/coreclr/blob/e277764916cbb740db199132be81701593820bb0/src/jit/lclvars.cpp#L3574-L3658" rel="noopener noreferrer"&gt;x64&lt;/a&gt;, &lt;a href="https://github.com/dotnet/coreclr/blob/e277764916cbb740db199132be81701593820bb0/src/jit/lclvars.cpp#L3660-L3744" rel="noopener noreferrer"&gt;ARM&lt;/a&gt; and &lt;a href="https://github.com/dotnet/coreclr/blob/e277764916cbb740db199132be81701593820bb0/src/jit/lclvars.cpp#L3746-L3835" rel="noopener noreferrer"&gt;ARM64&lt;/a&gt; versions).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; *  The frame is laid out as follows for x86:
 *
 *              ESP frames                
 *
 *      |                       |         
 *      |-----------------------|         
 *      |       incoming        |         
 *      |       arguments       |         
 *      |-----------------------| &amp;lt;---- Virtual '0'         
 *      |    return address     |         
 *      +=======================+
 *      |Callee saved registers |         
 *      |-----------------------|         
 *      |       Temps           |         
 *      |-----------------------|         
 *      |       Variables       |         
 *      |-----------------------| &amp;lt;---- Ambient ESP
 *      |   Arguments for the   |         
 *      ~    next function      ~ 
 *      |                       |         
 *      |       |               |         
 *      |       | Stack grows   |         
 *              | downward                
 *              V                         
 *
 *
 *              EBP frames
 *
 *      |                       |
 *      |-----------------------|
 *      |       incoming        |
 *      |       arguments       |
 *      |-----------------------| &amp;lt;---- Virtual '0'         
 *      |    return address     |         
 *      +=======================+
 *      |    incoming EBP       |
 *      |-----------------------| &amp;lt;---- EBP
 *      |Callee saved registers |         
 *      |-----------------------|         
 *      |   security object     |
 *      |-----------------------|
 *      |     ParamTypeArg      |
 *      |-----------------------|
 *      |  Last-executed-filter |
 *      |-----------------------|
 *      |                       |
 *      ~      Shadow SPs       ~
 *      |                       |
 *      |-----------------------|
 *      |                       |
 *      ~      Variables        ~
 *      |                       |
 *      ~-----------------------|
 *      |       Temps           |
 *      |-----------------------|
 *      |       localloc        |
 *      |-----------------------| &amp;lt;---- Ambient ESP
 *      |   Arguments for the   |
 *      |    next function      ~
 *      |                       |
 *      |       |               |
 *      |       | Stack grows   |
 *              | downward
 *              V
 *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not to be left out, Mono has some nice examples covering &lt;a href="https://github.com/mono/mono/blob/2019-02/mono/mini/mini-mips.c#L4682-L4705" rel="noopener noreferrer"&gt;MIPS&lt;/a&gt; (below), &lt;a href="https://github.com/mono/mono/blob/2019-02/mono/mini/mini-ppc.c#L4677-L4692" rel="noopener noreferrer"&gt;PPC&lt;/a&gt; and &lt;a href="https://github.com/mono/mono/blob/2019-02/mono/mini/mini-arm.c#L6137-L6149" rel="noopener noreferrer"&gt;ARM&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
 * Stack frame layout:
 * 
 *   ------------------- sp + cfg-&amp;gt;stack_usage + cfg-&amp;gt;param_area
 *      param area      incoming
 *   ------------------- sp + cfg-&amp;gt;stack_usage + MIPS_STACK_PARAM_OFFSET
 *      a0-a3           incoming
 *   ------------------- sp + cfg-&amp;gt;stack_usage
 *  ra
 *   ------------------- sp + cfg-&amp;gt;stack_usage-4
 *      spilled regs
 *   ------------------- sp + 
 *      MonoLMF structure   optional
 *   ------------------- sp + cfg-&amp;gt;arch.lmf_offset
 *      saved registers     s0-s8
 *   ------------------- sp + cfg-&amp;gt;arch.iregs_offset
 *      locals
 *   ------------------- sp + cfg-&amp;gt;param_area
 *      param area      outgoing
 *   ------------------- sp + MIPS_STACK_PARAM_OFFSET
 *      a0-a3           outgoing
 *   ------------------- sp
 *      red zone
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, there's another example &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/dllimportcallback.cpp#L254-L293" rel="noopener noreferrer"&gt;covering &lt;code&gt;[DLLImport]&lt;/code&gt; callbacks&lt;/a&gt; and one more &lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/codegenarm64.cpp#L791-L873" rel="noopener noreferrer"&gt;involving funclet frames in ARM64&lt;/a&gt;, I told you there were lots!!&lt;/p&gt;




&lt;h2&gt;
  
  
  The Rest
&lt;/h2&gt;

&lt;p&gt;If you aren't sick of 'ASCII Art' by now, here's a few more examples for you to look at!!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CoreCLR

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.2/src/vm/arm/stubs.cpp#L1934-L1966" rel="noopener noreferrer"&gt;coreclr/stubs.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/inlinetracking.h#L191-L203" rel="noopener noreferrer"&gt;coreclr/inlinetracking.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/inlinetracking.h#L248-L260" rel="noopener noreferrer"&gt;coreclr/inlinetracking.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/comcallablewrapper.h#L105-L131" rel="noopener noreferrer"&gt;coreclr/comcallablewrapper.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/vm/comcallablewrapper.cpp#L1986-L2012" rel="noopener noreferrer"&gt;coreclr/comcallablewrapper.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/4e2d07b5f592627530ee5645fd94325f17ee9487/src/System.Private.CoreLib/shared/System/Runtime/InteropServices/SafeHandle.cs#L36-L46" rel="noopener noreferrer"&gt;coreclr/SafeHandle.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/gc/gcpriv.h#L375-L398" rel="noopener noreferrer"&gt;coreclr/gcpriv.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/compiler.hpp#L2081-L2104" rel="noopener noreferrer"&gt;coreclr/compiler.hpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/optimizer.cpp#L1004-L1019" rel="noopener noreferrer"&gt;coreclr/optimizer.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/9d3f264b9ef8b4715017ec615dcb6f9d57e607cc/src/jit/codegencommon.cpp#L4858-L4911" rel="noopener noreferrer"&gt;coreclr/codegencommon.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/c4dca1072d15bdda64c754ad1ea474b1580fa554/src/jit/morph.cpp#L1768-L1785" rel="noopener noreferrer"&gt;coreclr/morph.cpp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Roslyn

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/Test/Resources/Core/MetadataTests/Invalid/Signatures/SignatureCycle2.il#L3-L20" rel="noopener noreferrer"&gt;roslyn/SignatureCycle2.il&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs#L1017-L1022" rel="noopener noreferrer"&gt;roslyn/SourceMemberContainerSymbol.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/Core/CodeAnalysisTest/RealParserTests.cs#L529-L551" rel="noopener noreferrer"&gt;roslyn/RealParserTests.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/Visual-Studio-2017-Version-15.9/src/Compilers/CSharp/Portable/Compilation/CSharpSemanticModel.cs#L2718-L2759" rel="noopener noreferrer"&gt;roslyn/CSharpSemanticModel.cs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;CoreFX

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Decimal.DecCalc.cs#L1433-L1453" rel="noopener noreferrer"&gt;corefx/Decimal.DecCalc.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Number.Grisu3.cs#L964-L991" rel="noopener noreferrer"&gt;corefx/Number.Grisu3.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Buffers/Binary/Reader.cs#L89-L107" rel="noopener noreferrer"&gt;corefx/Reader.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Globalization/Calendar.cs#L371-L400" rel="noopener noreferrer"&gt;corefx/Calendar.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/System/Collections/Generic/LargeArrayBuilder.SpeedOpt.cs#L196-L203" rel="noopener noreferrer"&gt;corefx/LargeArrayBuilder.SpeedOpt.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/Common/src/CoreLib/System/Runtime/Intrinsics/Vector128.cs#L610-L625" rel="noopener noreferrer"&gt;corefx/Vector128.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Collections/src/System/Collections/Generic/SortedSet.cs#L18-L26" rel="noopener noreferrer"&gt;corefx/SortedSet.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Data.Common/src/System/Data/RbTree.cs#L75-L81" rel="noopener noreferrer"&gt;corefx/RbTree.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Numerics.Vectors/src/System/Numerics/Matrix4x4.cs#L818-L842" rel="noopener noreferrer"&gt;corefx/Matrix4x4.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobBuilder.cs#L396-L410" rel="noopener noreferrer"&gt;corefx/BlobBuilder.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/corefx/blob/4b9fff5c022269c7dbb000bd14c10be27400beb2/src/System.Runtime.Extensions/src/System/IO/BufferedStream.cs#L909-L918" rel="noopener noreferrer"&gt;corefx/BufferedStream.cs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;AspNetCore

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Data.cs#L6-L14" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.Data.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Ping.cs#L6-L12" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.Ping.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.GoAway.cs#L6-L14" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.GoAway.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Priority.cs#L6-L12" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.Priority.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Settings.cs#L6-L13" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.Settings.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.RstStream.cs#L6-L10" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.RstStream.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.Continuation.cs#L6-L10" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.Continuation.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Frame.WindowUpdate.cs#L6-L10" rel="noopener noreferrer"&gt;AspNetCore/Http2Frame.WindowUpdate.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/HPackDecoder.cs#L26-L71" rel="noopener noreferrer"&gt;AspNetCore/HPackDecoder.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Components/Components/test/RenderTreeBuilderTest.cs#L188-L203" rel="noopener noreferrer"&gt;AspNetCore/RenderTreeBuilderTest.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aspnet/AspNetCore/blob/9f1a978230cdd161998815c425bfd2d25e8436b6/src/Servers/Kestrel/test/FunctionalTests/MaxRequestBufferSizeTests.cs#L25-L45" rel="noopener noreferrer"&gt;AspNetCore/MaxRequestBufferSizeTests.cs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Mono

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/mono/mono/blob/2019-02/mono/sgen/sgen-qsort.c#L46-L53" rel="noopener noreferrer"&gt;mono/sgen/sgen-qsort.c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

</description>
      <category>art</category>
      <category>ascii</category>
      <category>net</category>
    </item>
    <item>
      <title>How does .NET JIT a method? (also featuring 'Tiered Compilation')</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Sat, 16 Dec 2017 09:40:57 +0000</pubDate>
      <link>https://dev.to/mattwarren/how-does-net-jit-a-method-also-featuring-tiered-compilation-4if</link>
      <guid>https://dev.to/mattwarren/how-does-net-jit-a-method-also-featuring-tiered-compilation-4if</guid>
      <description>&lt;p&gt;The .NET runtime (CLR) has predominantly used a just-in-time (JIT) compiler to convert your executable into machine code (leaving aside &lt;a href="https://github.com/dotnet/corert/" rel="noopener noreferrer"&gt;ahead-of-time (AOT) scenarios&lt;/a&gt; for the time being), as the &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/managed-execution-process" rel="noopener noreferrer"&gt;official Microsoft docs say&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At execution time, &lt;strong&gt;a just-in-time (JIT) compiler translates the MSIL into native code&lt;/strong&gt;. During this compilation, code must pass a verification process that examines the MSIL and metadata to find out whether the code can be determined to be type safe.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;But how does that process actually work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same docs &lt;a href="https://docs.microsoft.com/en-us/dotnet/standard/managed-execution-process" rel="noopener noreferrer"&gt;give us a bit more info&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JIT compilation takes into account the possibility that some code might never be called during execution. Instead of using time and memory to convert all the MSIL in a PE file to native code, it converts the MSIL as needed during execution and stores the resulting native code in memory so that it is accessible for subsequent calls in the context of that process. The loader &lt;strong&gt;creates and attaches a stub to each method&lt;/strong&gt; in a type when the type is loaded and initialized. When a method is called for the first time, &lt;strong&gt;the stub passes control to the JIT compiler&lt;/strong&gt;, which converts the MSIL for that method into native code and &lt;strong&gt;modifies the stub to point directly to the generated native code&lt;/strong&gt;. Therefore, subsequent calls to the JIT-compiled method go directly to the native code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Simple really!!&lt;/strong&gt; However if you want to know more, the rest of this post will explore this process in detail.&lt;/p&gt;

&lt;p&gt;In addition, we will look at a &lt;strong&gt;new feature that is making its way into the Core CLR&lt;/strong&gt;, called '&lt;strong&gt;Tiered Compilation&lt;/strong&gt;'. This is a big change for the CLR, up till now .NET methods have only been JIT compiled once, on their first usage. Tiered compilation is looking to change that, allowing methods to be re-compiled into a more optimised version much like &lt;a href="http://www.oracle.com/technetwork/java/whitepaper-135217.html" rel="noopener noreferrer"&gt;the Java Hotspot compiler&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;But before we look at future plans, &lt;strong&gt;how does the current CLR allow the JIT to transform a method from IL to native code&lt;/strong&gt;? Well, they say 'a pictures speaks a thousand words'&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Before the method is JITed&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F01%2520-%2520Before%2520JITing.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F01%2520-%2520Before%2520JITing.svg" alt="Step 1 - Before JITing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;After the method has been JITed&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F02%2520-%2520After%2520JITing%2520-%2520Normal.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F02%2520-%2520After%2520JITing%2520-%2520Normal.svg" alt="Step 2 - After JITing - Normal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main things to note are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CLR has put in a 'precode' and 'stub' to divert the initial method call to the &lt;code&gt;PreStubWorker()&lt;/code&gt; method (which ultimately calls the JIT). These are hand-written assembly code fragments consisting of only a few instructions.&lt;/li&gt;
&lt;li&gt;Once the method had been JITed into 'native code', a stable entry point it created. For the rest of the life-time of the method the CLR guarantees that this won't change, so the rest of the run-time can depend on it remaining stable.&lt;/li&gt;
&lt;li&gt;The 'temporary entry point' doesn't go away, it's still available because there may be other methods that are expecting to call it. However the associated 'precode fixup' has been re-written or 'back patched' to point to the newly created 'native code' instead of &lt;code&gt;PreStubWorker()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The CLR doesn't change the address of the &lt;code&gt;call&lt;/code&gt; instruction in the method that called the method being JITted, it only changes the address inside the 'precode'. But because all method calls in the CLR go via a precode, the 2nd time the newly JITed method is called, the call will end up at the 'native code'. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For reference, the 'stable entry point' is the same memory location as the &lt;code&gt;IntPtr&lt;/code&gt; that is returned when you call the &lt;a href="https://msdn.microsoft.com/en-us/library/system.runtimemethodhandle.getfunctionpointer%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396" rel="noopener noreferrer"&gt;RuntimeMethodHandle.GetFunctionPointer() method&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to see this process in action for yourself, you can either re-compile the CoreCLR source and add the relevant debug information as I did &lt;strong&gt;or&lt;/strong&gt; just use WinDbg and follow the steps &lt;a href="https://blogs.msdn.microsoft.com/abhinaba/2014/09/29/net-just-in-time-compilation-and-warming-up-your-system/" rel="noopener noreferrer"&gt;in this excellent blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the different parts of the Core CLR source code that are involved are listed below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/inc/jithelpers.h#L295-L299" rel="noopener noreferrer"&gt;JIT Helpers for 'PrecodeFixupThunk'&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/i386/asmhelpers.asm#L888-L907" rel="noopener noreferrer"&gt;PrecodeFixupThunk (i386 assembly)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/i386/asmhelpers.asm#L1739-L1769" rel="noopener noreferrer"&gt;ThePreStub (i386 assembly)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/prestub.cpp#L1027-L1140" rel="noopener noreferrer"&gt;PreStubWorker(..)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/prestub.cpp#L1178-L1707" rel="noopener noreferrer"&gt;MethodDesc::DoPrestub(..)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/prestub.cpp#L67-L193" rel="noopener noreferrer"&gt;MethodDesc::DoBackpatch(..)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/method.cpp#L5170-L5189" rel="noopener noreferrer"&gt;MethodDesc::SetStableEntryPointInterlocked(..)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; this post isn't going to look at how the JIT itself works, if you are interested in that take a look as this &lt;a href="https://github.com/CarolEidt/coreclr/blob/master/Documentation/botr/ryujit-tutorial.md#ryujit-high-level-overview" rel="noopener noreferrer"&gt;excellent overview&lt;/a&gt; written by one of the main developers.&lt;/p&gt;




&lt;h3&gt;
  
  
  JIT and Execution Engine (EE) Interaction
&lt;/h3&gt;

&lt;p&gt;The make all this work the JIT and the EE have to work together, to get an idea of what is involved, take a look at this comment describing the &lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/inc/corinfo.h#L1426-L1514" rel="noopener noreferrer"&gt;rules that determine which type of precode the JIT can use&lt;/a&gt;. All this info is stored in the EE as it's the only place that has the full knowledge of what a method does, so the JIT has to ask which mode to work in.&lt;/p&gt;

&lt;p&gt;In addition, the JIT has to ask the EE what the address of a functions entry point is, this is done via the following methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/jitinterface.cpp#L8872-L8923" rel="noopener noreferrer"&gt;CEEInfo::getFunctionEntryPoint(..)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Then calls &lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/method.cpp#L2218-L2324" rel="noopener noreferrer"&gt;MethodDesc::TryGetMultiCallableAddrOfCode(..)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/jitinterface.cpp#L8925-L8955" rel="noopener noreferrer"&gt;CEEInfo::getFunctionFixedEntryPoint(..)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Then calls &lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/method.cpp#L2187-L2209" rel="noopener noreferrer"&gt;MethodDesc::GetMultiCallableAddrOfCode(..)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Precode and Stubs
&lt;/h3&gt;

&lt;p&gt;There are different types or 'precode' available, 'FIXUP', 'REMOTING' or 'STUB', you can see the rules for which one is used in &lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/method.cpp#L5747-L5773" rel="noopener noreferrer"&gt;MethodDesc::GetPrecodeType()&lt;/a&gt;. In addition, because they are such a low-level mechanism, they are implemented differently across CPU architectures, from a &lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/method.hpp#L2023-L2035" rel="noopener noreferrer"&gt;comment in the code&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There two implementation options for temporary entrypoints:&lt;/p&gt;

&lt;p&gt;(1) Compact entrypoints. They provide as dense entrypoints as possible, but can't be patched to point to the final code. The call to unjitted method is indirect call via slot.&lt;/p&gt;

&lt;p&gt;(2) Precodes. The precode will be patched to point to the final code eventually, thus the temporary entrypoint can be embedded in the code. &lt;br&gt;
The call to unjitted method is direct call to direct jump.&lt;/p&gt;

&lt;p&gt;We use (1) for x86 and (2) for 64-bit to get the best performance on each platform. For ARM (1) is used.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's also a whole lot more information about 'precode' available &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/method-descriptor.md#precode" rel="noopener noreferrer"&gt;in the BOTR&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally, it turns out that you can't go very far into the internals of the CLR without coming across 'stubs' (or 'trampolines', 'thunks', etc), for instance they're used in&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/01/25/How-do-.NET-delegates-work/#creation-of-the-delegate-invoke-method" rel="noopener noreferrer"&gt;Delegates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md#stubs" rel="noopener noreferrer"&gt;Virtual Method (Interface) Dispatch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/jump-stubs.md" rel="noopener noreferrer"&gt;Jump Stubs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/Documentation/botr/clr-abi.md#generics" rel="noopener noreferrer"&gt;Shared Generics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/release/2.0.0/src/vm/stubmgr.cpp#L1360-L1388" rel="noopener noreferrer"&gt;Dll Import callbacks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and probably some more I've missed!&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tiered Compilation
&lt;/h2&gt;

&lt;p&gt;Before we go any further I want to point out that &lt;strong&gt;Tiered Compilation&lt;/strong&gt; is very much work-in-progress. As an indication, to get it working you currently have to set an environment variable called &lt;code&gt;COMPLUS_EXPERIMENTAL_TieredCompilation&lt;/code&gt;. It appears that the current work is focussed on the infrastructure to make it possible (i.e. CLR changes), then I assume that there has to be a fair amount of testing and performance analysis before it's enabled by default.&lt;/p&gt;

&lt;p&gt;If you want to learn about the goals of the feature and how it fits into the wider process of 'code versioning', I recommend reading the &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/code-versioning.md" rel="noopener noreferrer"&gt;excellent design docs&lt;/a&gt;, including the &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/code-versioning.md#future-roadmap-possibilities" rel="noopener noreferrer"&gt;future roadmap possibilities&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To give an indications of what has been involved so far, there has been work going on in the:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debugger&lt;/strong&gt; (e.g. &lt;a href="https://github.com/dotnet/coreclr/issues/14427" rel="noopener noreferrer"&gt;Breakpoints aren't hit if tiered jitting recompiled the method before the debugger was attached&lt;/a&gt; and &lt;a href="https://github.com/dotnet/coreclr/issues/14423" rel="noopener noreferrer"&gt;Source line breakpoints stop working when tiered jitting replaces the code&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profiling APIs&lt;/strong&gt; - e.g. &lt;a href="https://github.com/dotnet/coreclr/issues/12610" rel="noopener noreferrer"&gt;Tiered jitting: Implement additional profiler APIs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnostics&lt;/strong&gt; - (all tracked via &lt;a href="https://github.com/dotnet/coreclr/issues/12612" rel="noopener noreferrer"&gt;Tiered jitting: Design/Implement appropriate diagnostics&lt;/a&gt;, e.g. &lt;a href="https://github.com/dotnet/coreclr/issues/14947" rel="noopener noreferrer"&gt;Tiered Jitting: Fix IL to native mapping for ETW&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interpreter&lt;/strong&gt; - &lt;a href="http://mattwarren.org/2017/03/30/The-.NET-IL-Interpreter/" rel="noopener noreferrer"&gt;yes the CLR has a built-in Interpreter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/search?utf8=%E2%9C%93&amp;amp;q=tiered+compilation&amp;amp;type=" rel="noopener noreferrer"&gt;Many other places&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to follow along you can &lt;a href="https://github.com/dotnet/coreclr/search?q=tiered+compilation&amp;amp;type=Issues&amp;amp;utf8=%E2%9C%93" rel="noopener noreferrer"&gt;take a look at the related issues/PRs&lt;/a&gt;, here are the main ones to get you started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/pull/10478" rel="noopener noreferrer"&gt;Tiered Compilation step 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/pull/12193" rel="noopener noreferrer"&gt;WIP - Tiered Jitting Part Deux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/pulls?q=is%3Apr+author%3Anoahfalk" rel="noopener noreferrer"&gt;All PRs by Noah Falk&lt;/a&gt; (main Microsoft Developer working on the feature)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also some nice background information available in &lt;a href="https://github.com/dotnet/coreclr/issues/4331" rel="noopener noreferrer"&gt;Introduce a tiered JIT&lt;/a&gt; and if you want to understand how it will eventually makes use of changes in the JIT ('MinOpts'), take a look at &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/performance/JitOptimizerTodoAssessment.md#low-tier-back-off" rel="noopener noreferrer"&gt;Low Tier Back-Off&lt;/a&gt; and &lt;a href="https://github.com/dotnet/coreclr/pull/15046" rel="noopener noreferrer"&gt;JIT: enable aggressive inline policy for Tier1&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  History - ReJIT
&lt;/h3&gt;

&lt;p&gt;As an quick historical aside, you have previously been able to get the CLR to &lt;a href="https://blogs.msdn.microsoft.com/davbr/2011/10/12/rejit-a-how-to-guide/" rel="noopener noreferrer"&gt;re-JIT a method for you&lt;/a&gt;, but it only worked with the &lt;a href="https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/profiling-overview#profiling_api" rel="noopener noreferrer"&gt;Profiling APIs&lt;/a&gt;, which meant you had to write some C/C++ COM code to make it happen! In addition ReJIT only allowed the method to be re-compiled at the same level, so it wouldn't ever produce more optimised code. It was mostly meant to help &lt;a href="https://blogs.msdn.microsoft.com/davbr/2011/10/10/rejit-limitations-in-net-4-5/" rel="noopener noreferrer"&gt;monitoring or profiling tools&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Finally, how does it work, again lets look at some diagrams. Firstly, as a recap, lets take a look at how things ends up once a method had been JITed, with &lt;strong&gt;tiered compilation turned off&lt;/strong&gt; (the same diagram as above):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F02%2520-%2520After%2520JITing%2520-%2520Normal.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F02%2520-%2520After%2520JITing%2520-%2520Normal.svg" alt="Step 2 - After JITing - Normal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, as a comparison, here's what the same stage looks like with &lt;strong&gt;tiered compilation enabled&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F03%2520-%2520After%2520JITing%2520-%2520Tiered%2520Compilation.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F03%2520-%2520After%2520JITing%2520-%2520Tiered%2520Compilation.svg" alt="Step 3 - After JITing - Tiered Compilation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The main difference is that tiered compilation has forced the method call to go through another level of indirection, the 'pre stub'. This is to make it possible to count the number of times the method is called, then once it has hit the threshold (&lt;a href="https://github.com/dotnet/coreclr/blob/5d91c4d2cc8fe60bad20cdfdf2e5f239bc024061/src/vm/tieredcompilation.cpp#L84" rel="noopener noreferrer"&gt;currently 30&lt;/a&gt;), the 'pre stub' is re-written to point to the 'optimised native code' instead:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F04%2520-%2520After%2520Tiered%2520Compilation%2520Optimisation.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.mattwarren.org%2Fimages%2F2017%2F12%2F04%2520-%2520After%2520Tiered%2520Compilation%2520Optimisation.svg" alt="Step 4 - 04 - After Tiered Compilation Optimisation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the original 'native code' is still available, so if needed the changes can be reverted and the method call can go back to the unoptimised version.&lt;/p&gt;




&lt;h3&gt;
  
  
  Using a counter
&lt;/h3&gt;

&lt;p&gt;We can see a bit more details about the counter in this comments from &lt;a href="https://github.com/dotnet/coreclr/blob/5d91c4d2cc8fe60bad20cdfdf2e5f239bc024061/src/vm/prestub.cpp#L1702-L1715" rel="noopener noreferrer"&gt;prestub.cpp&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    /***************************   CALL COUNTER    ***********************/
    // If we are counting calls for tiered compilation, leave the prestub
    // in place so that we can continue intercepting method invocations.
    // When the TieredCompilationManager has received enough call notifications
    // for this method only then do we back-patch it.
    BOOL fCanBackpatchPrestub = TRUE;
#ifdef FEATURE_TIERED_COMPILATION
    BOOL fEligibleForTieredCompilation = IsEligibleForTieredCompilation();
    if (fEligibleForTieredCompilation)
    {
        CallCounter * pCallCounter = GetCallCounter();
        fCanBackpatchPrestub = pCallCounter-&amp;gt;OnMethodCalled(this);
    }
#endif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In essence the 'stub' calls back into the &lt;a href="https://github.com/dotnet/coreclr/blob/5d91c4d2cc8fe60bad20cdfdf2e5f239bc024061/src/vm/tieredcompilation.cpp" rel="noopener noreferrer"&gt;TieredCompilationManager&lt;/a&gt; until the 'tiered compilation' is triggered, once that happens the 'stub' is 'back-patched' to stop it being called any more.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why not 'Interpreted'?
&lt;/h3&gt;

&lt;p&gt;If you're wondering why tiered compilation doesn't have an interpreted mode, you're not alone, I asked the &lt;a href="https://github.com/dotnet/coreclr/pull/10478#issuecomment-289394905" rel="noopener noreferrer"&gt;same question&lt;/a&gt; (for more info see &lt;a href="http://mattwarren.org/2017/03/30/The-.NET-IL-Interpreter/" rel="noopener noreferrer"&gt;my previous post on the .NET Interpreter&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;And the &lt;a href="https://github.com/dotnet/coreclr/pull/10478#issuecomment-289412414" rel="noopener noreferrer"&gt;answer I got was&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;There's already an Interpreter available, or is it not considered suitable for production code?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Its a fine question, but you guessed correctly - the interpreter is not in good enough shape to run production code as-is. There are also some significant issues if you want debugging and profiling tools to work (which we do). Given enough time and effort it is all solvable, it just isn't the easiest place to start.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How different is the overhead between non-optimised and optimised JITting?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On my machine non-optimized jitting used about ~65% of the time that optimized jitting took for similar IL input sizes, but of course I expect results will vary by workload and hardware. Getting this first step checked in should make it easier to collect better measurements.&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;But that's from a few months ago, maybe &lt;a href="http://www.mono-project.com/news/2017/11/13/mono-interpreter/" rel="noopener noreferrer"&gt;Mono's New .NET Interpreter&lt;/a&gt; will change things, &lt;a href="https://twitter.com/matthewwarren/status/930397571478183937" rel="noopener noreferrer"&gt;who knows&lt;/a&gt;?&lt;/p&gt;




&lt;h3&gt;
  
  
  Why not LLVM?
&lt;/h3&gt;

&lt;p&gt;Finally, why aren't they using a LLVM to compile the code, from &lt;a href="https://github.com/dotnet/coreclr/issues/4331#issuecomment-313179155" rel="noopener noreferrer"&gt;Introduce a tiered JIT (comment)&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There were (and likely still are) &lt;strong&gt;significant differences in the LLVM support needed for the CLR versus what is needed for Java&lt;/strong&gt;, both in GC and in EH, and in the restrictions one must place on the optimizer. To cite just one example: the CLRs GC currently cannot tolerate managed pointers that point off the end of objects. Java handles this via a base/derived paired reporting mechanism. We'd either need to plumb support for this kind of paired reporting into the CLR or restrict LLVM's optimizer passes to never create these kinds of pointers. On top of that, the LLILC jit was slow and we weren't sure ultimately what kind of code quality it might produce.&lt;/p&gt;

&lt;p&gt;So, figuring out how LLILC might fit into a potential multi-tier approach that did not yet exist seemed (and still seems) premature. &lt;strong&gt;The idea for &lt;br&gt;
now is to get tiering into the framework and use RyuJit for the second-tier jit&lt;/strong&gt;. As we learn more, we may discover there is indeed room for higher tier jits, or, at least, understand better what else we need to do before such things make sense.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is more background info in &lt;a href="https://github.com/dotnet/coreclr/issues/4331" rel="noopener noreferrer"&gt;Introduce a tiered JIT&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;One of my favourite side-effects of Microsoft making .NET Open Source and developing out in the open is that we can follow along with work-in-progress features. It's great being able to download the latest code, try them out and see how they work under-the-hood, yay for OSS!!&lt;/p&gt;

</description>
      <category>clr</category>
      <category>net</category>
      <category>internals</category>
      <category>jitcompiler</category>
    </item>
    <item>
      <title>Exploring the BBC micro:bit software stack and OS</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Thu, 30 Nov 2017 10:19:09 +0000</pubDate>
      <link>https://dev.to/mattwarren/exploring-the-bbc-microbit-software-stack-and-os-b11</link>
      <guid>https://dev.to/mattwarren/exploring-the-bbc-microbit-software-stack-and-os-b11</guid>
      <description>&lt;p&gt;This post &lt;a href="http://mattwarren.org/2017/11/28/Exploring-the-BBC-microbit-Software-Stack/" rel="noopener noreferrer"&gt;first appeared on my blog&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;If you grew up in the UK and went to school during the 1980's or 1990's there's a good chance that this picture brings back fond memories:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.classicacorn.freeuk.com%2F8bit_focus%2Flogo%2Flogo_8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.classicacorn.freeuk.com%2F8bit_focus%2Flogo%2Flogo_8.jpg" alt="BBC Micro and a Turtle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(image courtesy of &lt;a href="http://www.classicacorn.freeuk.com/" rel="noopener noreferrer"&gt;Classic Acorn&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;I'd imagine that for a large amount of computer programmers (currently in their 30's) the BBC Micro was their first experience of programming. If this applies to you and you want a trip down memory lane, have a read of &lt;a href="https://www.geeksaresexy.net/2009/10/22/remembering-the-bbc-micro/" rel="noopener noreferrer"&gt;Remembering: The BBC Micro&lt;/a&gt; and &lt;a href="https://www.retro-kit.co.uk/page.cfm/content/The-BBC-Micro-in-Education/" rel="noopener noreferrer"&gt;The BBC Micro in my education&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Programming the classic &lt;a href="https://angrytechnician.wordpress.com/2009/07/23/relic/" rel="noopener noreferrer"&gt;Turtle&lt;/a&gt; was done in &lt;a href="http://www.walkingrandomly.com/?p=13" rel="noopener noreferrer"&gt;Logo&lt;/a&gt;, with code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FORWARD 100
LEFT 90
FORWARD 100
LEFT 90
FORWARD 100
LEFT 90
FORWARD 100
LEFT 90
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, once you knew what you were doing, you would re-write it like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REPEAT 4 [FORWARD 100 LEFT 90]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  BBC micro:bit
&lt;/h2&gt;

&lt;p&gt;The original Micro was launched as an education tool, as part of the &lt;a href="http://www.swansea.ac.uk/library/archive-and-research-collections/hocc/computersandsoftware/earlyhomecomputers/bbcmicro/" rel="noopener noreferrer"&gt;BBC’s Computer Literacy Project&lt;/a&gt; and by most accounts was a big success. As a follow-up, in March 2016 the &lt;a href="http://www.bbc.co.uk/mediacentre/latestnews/2016/bbc-micro-bit-schools-launch" rel="noopener noreferrer"&gt;micro:bit was launched&lt;/a&gt; as part of the BBC's 'Make it Digital' initiative and 1 million devices were given out to schools and libraries in the UK to 'help develop a new generation of digital pioneers' (i.e. get them into programming!)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aside&lt;/strong&gt;: I love the difference in branding across 30 years, '&lt;em&gt;BBC Micro&lt;/em&gt;' became '&lt;em&gt;BBC micro:bit&lt;/em&gt;' (you must include the colon) and '&lt;em&gt;Computer Literacy Project&lt;/em&gt;' changed to the '&lt;em&gt;Make it Digital Initiative&lt;/em&gt;'.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.bbc.co.uk/mediacentre/mediapacks/microbit/specs" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FBBC%2520microbit%2520hardware%2520specification.jpg" alt="BBC microbit hardware specification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few weeks ago I walked into my local library, &lt;a href="http://microbit.org/en/2017-10-23-libraries/" rel="noopener noreferrer"&gt;picked up a nice starter kit&lt;/a&gt; and then spent a fun few hours watching my son play around with it (I'm worried about how quickly he picked up the basics of programming, I think I might be out of a job in a few years time!!) &lt;/p&gt;

&lt;p&gt;However once he'd gone to bed it was all mine! The result of my 'playing around' is this post, in it I will be exploring the &lt;strong&gt;software stack&lt;/strong&gt; that makes up the micro:bit, what's in it, what it does and how it all fits together. &lt;/p&gt;

&lt;p&gt;If you want to learn about how to program the micro:bit, its hardware or anything else, take a look at this &lt;a href="https://github.com/carlosperate/awesome-microbit" rel="noopener noreferrer"&gt;excellent list of resources&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Slightly off-topic, but if you enjoy reading &lt;strong&gt;source code&lt;/strong&gt; you might like these other posts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/02/07/The-68-things-the-CLR-does-before-executing-a-single-line-of-your-code/?recommended=1" rel="noopener noreferrer"&gt;The 68 things the CLR does before executing a single line of your code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/03/23/Hitchhikers-Guide-to-the-CoreCLR-Source-Code/?recommended=1" rel="noopener noreferrer"&gt;A Hitchhikers Guide to the CoreCLR Source Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/10/19/DotNetAnywhere-an-Alternative-.NET-Runtime/?recommended=1" rel="noopener noreferrer"&gt;DotNetAnywhere: An Alternative .NET Runtime&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  BBC micro:bit Software Stack
&lt;/h1&gt;

&lt;p&gt;If we take a &lt;em&gt;high-level&lt;/em&gt; view at the stack, it divides up into 3 discrete &lt;strong&gt;software&lt;/strong&gt; components that all sit on top of the &lt;strong&gt;hardware&lt;/strong&gt; itself:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FBBC%2520Microbit%2520Software%2520Stack.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FBBC%2520Microbit%2520Software%2520Stack.png" alt="BBC Microbit Software Stack.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you would like to build this stack for yourself take a look at the &lt;a href="https://lancaster-university.github.io/microbit-docs/offline-toolchains" rel="noopener noreferrer"&gt;Building with Yotta guide&lt;/a&gt;. I also found this post describing &lt;a href="https://hackernoon.com/the-first-video-game-on-the-bbc-micro-bit-probably-4175fab44da8" rel="noopener noreferrer"&gt;The First Video Game on the BBC micro:bit [probably]&lt;/a&gt; very helpful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Runtimes
&lt;/h2&gt;

&lt;p&gt;There are several high-level &lt;em&gt;runtimes&lt;/em&gt; available, these are useful because they let you write code in a language other than C/C++ or even create programs by &lt;a href="https://www.microbit.co.uk/blocks/editor" rel="noopener noreferrer"&gt;dragging &lt;em&gt;blocks&lt;/em&gt; around on a screen&lt;/a&gt;. The main ones that I've come across are below (see &lt;a href="https://github.com/carlosperate/awesome-microbit#programming" rel="noopener noreferrer"&gt;'Programming'&lt;/a&gt; for a full list):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; via &lt;a href="https://github.com/bbcmicrobit/micropython/" rel="noopener noreferrer"&gt;MicroPython&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript&lt;/strong&gt; with &lt;a href="https://github.com/Microsoft/pxt-microbit" rel="noopener noreferrer"&gt;Microsoft Programming Experience Toolkit (PXT)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;well actually it's &lt;a href="https://makecode.com/language" rel="noopener noreferrer"&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/a&gt;, which is good, we wouldn't want to rot the brains of impressionable young children with the &lt;a href="https://www.destroyallsoftware.com/talks/wat" rel="noopener noreferrer"&gt;horrors of Javascript - Wat!!&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;They both work in a similar way, the users code (Python or TypeScript) is bundled up along with the C/C++ code of the runtime itself and then the entire binary (hex) file is deployed to the micro:bit. When the device starts up, the runtime then looks for the users code at a known location in memory and starts interpreting it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt; It turns out that I was wrong about the Microsoft PXT, it actually &lt;a href="https://makecode.com/language#static-compilation-vs-a-dynamic-vm" rel="noopener noreferrer"&gt;compiles your TypeScript program to native code&lt;/a&gt;, very cool! Interestingly, they did it that way because:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compared to a typical dynamic JavaScript engine, PXT compiles code statically, giving rise to significant time and space performance improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;user programs are compiled directly to machine code, and are never in any byte-code form that needs to be interpreted; this results in much faster execution than a typical JS interpreter&lt;/li&gt;
&lt;li&gt;there is no RAM overhead for user-code - all code sits in flash; in a dynamic VM there are usually some data-structures representing code&lt;/li&gt;
&lt;li&gt;due to lack of boxing for small integers and static class layout the memory consumption for objects is around half the one you get in a dynamic VM (not counting the user-code structures mentioned above)&lt;/li&gt;
&lt;li&gt;while there is some runtime support code in PXT, it’s typically around 100KB smaller than a dynamic VM, bringing down flash consumption and leaving more space for user code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The execution time, RAM and flash consumption of PXT code is as a rule of thumb 2x of compiled C code, making it competitive to write drivers and other user-space libraries.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Memory Layout
&lt;/h2&gt;

&lt;p&gt;Just before we go onto the other parts of the software stack I want to take a deeper look at the memory layout. This is important because memory is so constrained on the micro:bit, there is &lt;em&gt;only&lt;/em&gt; 16KB of RAM. To put that into perspective, we'll use the calculation from this StackOverflow question &lt;a href="https://stackoverflow.com/questions/5999821/how-many-bytes-of-memory-is-a-tweet/5999852#5999852" rel="noopener noreferrer"&gt;How many bytes of memory is a tweet?&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Twitter uses UTF-8 encoded messages. UTF-8 code points can be up to six four octets long, making the maximum message size &lt;strong&gt;140 x 4 = 560 8-bit bytes&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we re-calculate for the newer, longer tweets &lt;strong&gt;280 x 4 = 1,120 bytes&lt;/strong&gt;. So we could only fit &lt;strong&gt;10 tweets&lt;/strong&gt; into the available RAM on the micro:bit (it turns out that only ~11K out of the total 16K is available for general use). Which is why it's worth using a &lt;a href="https://github.com/lancaster-university/microbit-dal/issues/323" rel="noopener noreferrer"&gt;custom version of atoi() to save 350 bytes of RAM&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;The memory layout is specified by the linker at compile-time using &lt;a href="https://github.com/lancaster-university/microbit-targets/blob/master/bbc-microbit-classic-gcc-nosd/ld/NRF51822.ld#L6" rel="noopener noreferrer"&gt;NRF51822.ld&lt;/a&gt;, there is a &lt;a href="http://mattwarren.org/data/2017/11/microbit-samples.map" rel="noopener noreferrer"&gt;sample output available&lt;/a&gt; if you want to take a look. Because it's done at compile-time you run into build errors such as &lt;a href="https://github.com/bbcmicrobit/micropython/issues/363" rel="noopener noreferrer"&gt;"region RAM overflowed with stack"&lt;/a&gt; if you configure it incorrectly.&lt;/p&gt;

&lt;p&gt;The table below shows the memory layout from the 'no SD' version of a 'Hello World' app, i.e. with the maximum amount of RAM available as the Bluetooth (BLE) Soft-Device (SD) support has been removed. By comparison with BLE enabled, you instantly have &lt;a href="https://github.com/lancaster-university/microbit-targets/blob/master/bbc-microbit-classic-gcc/ld/NRF51822.ld#L6" rel="noopener noreferrer"&gt;8K less RAM available&lt;/a&gt;, so things start to get tight!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Start Address&lt;/th&gt;
&lt;th&gt;End Address&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Percentage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.data&lt;/td&gt;
&lt;td&gt;0x20000000&lt;/td&gt;
&lt;td&gt;0x20000098&lt;/td&gt;
&lt;td&gt;152 bytes&lt;/td&gt;
&lt;td&gt;0.93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.bss&lt;/td&gt;
&lt;td&gt;0x20000098&lt;/td&gt;
&lt;td&gt;0x20000338&lt;/td&gt;
&lt;td&gt;672 bytes&lt;/td&gt;
&lt;td&gt;4.10%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heap (mbed)&lt;/td&gt;
&lt;td&gt;0x20000338&lt;/td&gt;
&lt;td&gt;0x20000b38&lt;/td&gt;
&lt;td&gt;2,048 bytes&lt;/td&gt;
&lt;td&gt;12.50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Empty&lt;/td&gt;
&lt;td&gt;0x20000b38&lt;/td&gt;
&lt;td&gt;0x20003800&lt;/td&gt;
&lt;td&gt;11,464 bytes&lt;/td&gt;
&lt;td&gt;69.97%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stack&lt;/td&gt;
&lt;td&gt;0x20003800&lt;/td&gt;
&lt;td&gt;0x20004000&lt;/td&gt;
&lt;td&gt;2,048 bytes&lt;/td&gt;
&lt;td&gt;12.50%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For more info on the column names see the Wikipedia pages for &lt;a href="https://en.wikipedia.org/wiki/Data_segment" rel="noopener noreferrer"&gt;.data&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/.bss" rel="noopener noreferrer"&gt;.bss&lt;/a&gt; as well as &lt;a href="https://mcuoneclipse.com/2013/04/14/text-data-and-bss-code-and-data-size-explained/" rel="noopener noreferrer"&gt;text, data and bss: Code and Data Size Explained&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a comparison there is a nice image of the micro:bit RAM Layout &lt;a href="https://hackernoon.com/the-first-video-game-on-the-bbc-micro-bit-probably-4175fab44da8#5fea" rel="noopener noreferrer"&gt;in this article&lt;/a&gt;. It shows what things look like when running MicroPython and you can clearly see the main Python heap in the centre &lt;a href="https://github.com/bbcmicrobit/micropython/blob/master/source/microbit/mprun.c#L95-L104" rel="noopener noreferrer"&gt;taking up all the remaining space&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://github.com/lancaster-university/microbit-dal" rel="noopener noreferrer"&gt;microbit-dal&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Sitting in the stack below the high-level runtime is the &lt;em&gt;device abstraction layer&lt;/em&gt; (DAL), created at &lt;a href="https://github.com/lancaster-university" rel="noopener noreferrer"&gt;Lancaster University&lt;/a&gt; in the UK, it's made up of 4 main components: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/lancaster-university/microbit-dal/tree/master/source/core" rel="noopener noreferrer"&gt;&lt;strong&gt;core&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;High-level components, such as &lt;code&gt;Device&lt;/code&gt;, &lt;code&gt;Font&lt;/code&gt;, &lt;code&gt;HeapAllocator&lt;/code&gt;, &lt;code&gt;Listener&lt;/code&gt; and &lt;code&gt;Fiber&lt;/code&gt;, often implemented on-top of 1 or more &lt;code&gt;driver&lt;/code&gt; classes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/lancaster-university/microbit-dal/tree/master/source/types" rel="noopener noreferrer"&gt;&lt;strong&gt;types&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Helper types such as &lt;code&gt;ManagedString&lt;/code&gt;, &lt;code&gt;Image&lt;/code&gt;, &lt;code&gt;Event&lt;/code&gt; and &lt;code&gt;PacketBuffer&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/lancaster-university/microbit-dal/tree/master/source/drivers" rel="noopener noreferrer"&gt;&lt;strong&gt;drivers&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;For control of a specific hardware component, such as &lt;code&gt;Accelerometer&lt;/code&gt;, &lt;code&gt;Button&lt;/code&gt;, &lt;code&gt;Compass&lt;/code&gt;, &lt;code&gt;Display&lt;/code&gt;, &lt;code&gt;Flash&lt;/code&gt;, &lt;code&gt;IO&lt;/code&gt;, &lt;code&gt;Serial&lt;/code&gt; and &lt;code&gt;Pin&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/lancaster-university/microbit-dal/tree/master/source/bluetooth" rel="noopener noreferrer"&gt;&lt;strong&gt;bluetooth&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;All the code for the &lt;a href="https://www.kitronik.co.uk/blog/bbc-microbit-bluetooth-low-energy/" rel="noopener noreferrer"&gt;Bluetooth Low Energy&lt;/a&gt; (BLE) stack that is &lt;a href="https://lancaster-university.github.io/microbit-docs/ble/profile/" rel="noopener noreferrer"&gt;shipped with the micro:bit&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/lancaster-university/microbit-dal/tree/master/source/asm" rel="noopener noreferrer"&gt;&lt;strong&gt;asm&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Just 4 functions are implemented in assembly, they are &lt;code&gt;swap_context&lt;/code&gt;, &lt;code&gt;save_context&lt;/code&gt;, &lt;code&gt;save_register_context&lt;/code&gt; and &lt;code&gt;restore_register_context&lt;/code&gt;. As the names suggest, they handle the 'context switching' necessary to make the &lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFiber.cpp" rel="noopener noreferrer"&gt;MicroBit Fiber scheduler&lt;/a&gt; work&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The image below shows the distribution of 'Lines of Code' (LOC), as you can see the majority of the code is in the &lt;code&gt;drivers&lt;/code&gt; and &lt;code&gt;bluetooth&lt;/code&gt; components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgw513llkug4x9twjhh8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgw513llkug4x9twjhh8y.png" alt="LOC Metrics Pie - microbit-dal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to providing nice helper classes for working with the underlying devices, the DAL provides the &lt;code&gt;Fiber&lt;/code&gt; abstraction to allows asynchronous functions to work. This is useful because you can asynchronously display text on the LED display and your code won't block whilst it's &lt;em&gt;scrolling&lt;/em&gt; across the screen. In addition the &lt;code&gt;Fiber&lt;/code&gt; class is used to handle the interrupts that signal when the buttons on the micro:bit are pushed. This comment from the code clearly lays out what the &lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFiber.cpp" rel="noopener noreferrer"&gt;Fiber scheduler&lt;/a&gt; does:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This lightweight, &lt;strong&gt;non-preemptive scheduler&lt;/strong&gt; provides a &lt;strong&gt;simple threading mechanism&lt;/strong&gt; for two main purposes:&lt;/p&gt;

&lt;p&gt;1) To provide a clean abstraction for application languages to use when building async behaviour (callbacks).&lt;br&gt;
 2) To provide ISR decoupling for EventModel events generated in an ISR context.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally the high-level classes &lt;a href="https://github.com/lancaster-university/microbit/blob/master/source/MicroBit.cpp" rel="noopener noreferrer"&gt;MicroBit.cpp&lt;/a&gt; and &lt;a href="https://github.com/lancaster-university/microbit/blob/master/inc/MicroBit.h" rel="noopener noreferrer"&gt;MicroBit.h&lt;/a&gt; are housed in the &lt;a href="https://github.com/lancaster-university/microbit" rel="noopener noreferrer"&gt;microbit repository&lt;/a&gt;. These classes define the API of the MicroBit runtime and setup the default configuration, as shown in the &lt;code&gt;Constructor&lt;/code&gt; of &lt;code&gt;MicroBit.cpp&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
  * Constructor.
  *
  * Create a representation of a MicroBit device, which includes member variables
  * that represent various device drivers used to control aspects of the micro:bit.
  */&lt;/span&gt;
&lt;span class="n"&gt;MicroBit&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;MicroBit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;serial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;USBTX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;USBRX&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;resetButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_PIN_BUTTON_RESET&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;i2c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;I2C_SDA0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;I2C_SCL0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;messageBus&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;buttonA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_PIN_BUTTON_A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MICROBIT_ID_BUTTON_A&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;buttonB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_PIN_BUTTON_B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MICROBIT_ID_BUTTON_B&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;buttonAB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_BUTTON_A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_BUTTON_B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MICROBIT_ID_BUTTON_AB&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;accelerometer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i2c&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;compass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i2c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accelerometer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;compassCalibrator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;compass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accelerometer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;thermometer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;MICROBIT_ID_IO_P3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;MICROBIT_ID_IO_P6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;MICROBIT_ID_IO_P9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;MICROBIT_ID_IO_P12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;MICROBIT_ID_IO_P15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;MICROBIT_ID_IO_P19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;MICROBIT_ID_IO_P20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;bleManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;radio&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;ble&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a href="https://github.com/lancaster-university/mbed-classic" rel="noopener noreferrer"&gt;mbed-classic&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The software at the bottom of the stack is making use of the &lt;a href="https://github.com/ARMmbed/mbed-os" rel="noopener noreferrer"&gt;ARM mbed OS&lt;/a&gt; which is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;.. an open-source embedded operating system designed for the "things" in the Internet of Things (IoT). mbed OS includes the features you need to develop a connected product using an ARM Cortex-M microcontroller.&lt;/p&gt;

&lt;p&gt;mbed OS provides a platform that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security foundations.&lt;/li&gt;
&lt;li&gt;Cloud management services.&lt;/li&gt;
&lt;li&gt;Drivers for sensors, I/O devices and connectivity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;mbed OS is modular, configurable software that you can customize it to your device and to reduce memory requirements by excluding unused software.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can see this from the layout of it's source, it's based around &lt;code&gt;common&lt;/code&gt; components, which can be combined with a &lt;code&gt;hal&lt;/code&gt; (Hardware Abstraction Layers) and a &lt;code&gt;target&lt;/code&gt; specific to the hardware you are running on.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/tree/master/api" rel="noopener noreferrer"&gt;&lt;strong&gt;api&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/tree/master/common" rel="noopener noreferrer"&gt;&lt;strong&gt;common&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/tree/master/hal" rel="noopener noreferrer"&gt;&lt;strong&gt;hal&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/tree/master/targets" rel="noopener noreferrer"&gt;&lt;strong&gt;targets&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More specifically the micro:bit uses the &lt;code&gt;yotta target bbc-microbit-classic-gcc&lt;/code&gt;, but it can also use &lt;a href="https://github.com/lancaster-university/microbit-targets" rel="noopener noreferrer"&gt;others targets as needed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For reference, here are the files from the &lt;code&gt;common&lt;/code&gt; section of &lt;code&gt;mbed&lt;/code&gt; that are used by the &lt;code&gt;micro:bit-dal&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/board.c" rel="noopener noreferrer"&gt;board.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/error.c" rel="noopener noreferrer"&gt;error.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/FileBase.cpp" rel="noopener noreferrer"&gt;FileBase.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/FilePath.cpp" rel="noopener noreferrer"&gt;FilePath.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/FileSystemLike.cpp" rel="noopener noreferrer"&gt;FileSystemLike.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/gpio.c" rel="noopener noreferrer"&gt;gpio.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/I2C.cpp" rel="noopener noreferrer"&gt;I2C.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/InterruptIn.cpp" rel="noopener noreferrer"&gt;InterruptIn.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/pinmap_common.c" rel="noopener noreferrer"&gt;pinmap_common.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/RawSerial.cpp" rel="noopener noreferrer"&gt;RawSerial.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/SerialBase.cpp" rel="noopener noreferrer"&gt;SerialBase.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/Ticker.cpp" rel="noopener noreferrer"&gt;Ticker.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/ticker_api.c" rel="noopener noreferrer"&gt;ticker_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/Timeout.cpp" rel="noopener noreferrer"&gt;Timeout.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/Timer.cpp" rel="noopener noreferrer"&gt;Timer.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/TimerEvent.cpp" rel="noopener noreferrer"&gt;TimerEvent.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/us_ticker_api.c" rel="noopener noreferrer"&gt;us_ticker_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/common/wait_api.c" rel="noopener noreferrer"&gt;wait_api.c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here are the hardware specific files, targeting the &lt;code&gt;NORDIC - MCU NRF51822&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.c" rel="noopener noreferrer"&gt;analogin_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/gpio_api.c" rel="noopener noreferrer"&gt;gpio_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/gpio_irq_api.c" rel="noopener noreferrer"&gt;gpio_irq_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/i2c_api.c" rel="noopener noreferrer"&gt;i2c_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/pinmap.c" rel="noopener noreferrer"&gt;pinmap.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/port_api.c" rel="noopener noreferrer"&gt;port_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/pwmout_api.c" rel="noopener noreferrer"&gt;pwmout_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_ARM_STD/sys.cpp" rel="noopener noreferrer"&gt;retarget.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/serial_api.c" rel="noopener noreferrer"&gt;serial_api.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.S" rel="noopener noreferrer"&gt;startup_NRF51822.S&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/system_nrf51.c" rel="noopener noreferrer"&gt;system_nrf51.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/twi_master.c" rel="noopener noreferrer"&gt;twi_master.c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/us_ticker.c" rel="noopener noreferrer"&gt;us_ticker.c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  End-to-end (or top-to-bottom)
&lt;/h2&gt;

&lt;p&gt;Finally, lets look a few examples of how the different components within the stack are used in specific scenarios&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing to the Display
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/lancaster-university/microbit-dal" rel="noopener noreferrer"&gt;&lt;strong&gt;microbit-dal&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitDisplay.cpp" rel="noopener noreferrer"&gt;MicroBitDisplay.cpp&lt;/a&gt;, handles scrolling, asynchronous updates and other high-level tasks, before handing off to:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/core/MicroBitFont.cpp" rel="noopener noreferrer"&gt;MicroBitFont.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/types/MicroBitImage.cpp" rel="noopener noreferrer"&gt;MicroBitImage.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/inc/drivers/MicroBitMatrixMaps.h" rel="noopener noreferrer"&gt;MicroBitMatrixMaps.h&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/lancaster-university/mbed-classic" rel="noopener noreferrer"&gt;&lt;strong&gt;mbed-classic&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;void port_write(port_t *obj, int value)&lt;/code&gt; in &lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/port_api.c" rel="noopener noreferrer"&gt;port_api.c&lt;/a&gt; ('NORDIC NRF51822' version), via a call to &lt;code&gt;void write(int value)&lt;/code&gt; in &lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/api/PortOut.h" rel="noopener noreferrer"&gt;PortOut.h&lt;/a&gt;, using info from &lt;a href="https://github.com/lancaster-university/mbed-classic/blob/master/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/TARGET_NRF51_MICROBIT/PinNames.h" rel="noopener noreferrer"&gt;PinNames.h&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Storing files on the Flash memory
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/lancaster-university/microbit-dal" rel="noopener noreferrer"&gt;&lt;strong&gt;microbit-dal&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Provides the high-level abstractions, such as:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitFileSystem.cpp" rel="noopener noreferrer"&gt;FileSystem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitFile.cpp" rel="noopener noreferrer"&gt;File&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitFlash.cpp" rel="noopener noreferrer"&gt;Flash&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/lancaster-university/mbed-classic" rel="noopener noreferrer"&gt;&lt;strong&gt;mbed-classic&lt;/strong&gt;&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Allows low-level control of the hardware, such as writing to the flash itself either directly or via the SoftDevice (SD) layer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;In addition, this comment from &lt;a href="https://github.com/lancaster-university/microbit-dal/blob/master/source/drivers/MicroBitStorage.h" rel="noopener noreferrer"&gt;MicroBitStorage.h&lt;/a&gt; gives a nice overview of how the file system is implemented on-top of the raw flash storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* The first 8 bytes are reserved for the KeyValueStore struct which gives core
* information such as the number of KeyValuePairs in the store, and whether the
* store has been initialised.
*
* After the KeyValueStore struct, KeyValuePairs are arranged contiguously until
* the end of the block used as persistent storage.
*
* |-------8-------|--------48-------|-----|---------48--------|
* | KeyValueStore | KeyValuePair[0] | ... | KeyValuePair[N-1] |
* |---------------|-----------------|-----|-------------------|
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;All-in-all the micro:bit is a very nice piece of kit and hopefully will achieve its goal 'to help develop a new generation of digital pioneers'. However, it also has a really nice software stack, one that is easy to understand and find your way around.&lt;/p&gt;




&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;I've got nothing to add that isn't already included in this &lt;a href="https://github.com/carlosperate/awesome-microbit" rel="noopener noreferrer"&gt;excellent, comprehensive list of resources&lt;/a&gt;, thanks &lt;a href="https://twitter.com/carlosperate" rel="noopener noreferrer"&gt;Carlos&lt;/a&gt; for putting it together!!&lt;/p&gt;

</description>
      <category>technology</category>
      <category>iot</category>
      <category>embeddedsystems</category>
    </item>
    <item>
      <title>Best technology-related, non-fiction books</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Mon, 27 Nov 2017 14:15:33 +0000</pubDate>
      <link>https://dev.to/mattwarren/best-technology-related-non-fiction-books-54n</link>
      <guid>https://dev.to/mattwarren/best-technology-related-non-fiction-books-54n</guid>
      <description>&lt;p&gt;It appears that most developers &lt;a href="https://dev.to/ben/books-appear-to-still-be-popular-in-software-development-d85"&gt;really like reading books&lt;/a&gt;, but this is a specific ask.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are the best, technology-related, non-fiction books you've ever read?
&lt;/h3&gt;

&lt;p&gt;To get things started, here's my &lt;strong&gt;Top 5&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Soul of A New Machine&lt;/strong&gt; by Tracy Kidder&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Where Wizards Stay Up Late: The Origins of the Internet&lt;/strong&gt; by Katie Hafner and Matthew Lyon&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Cuckoo's Egg&lt;/strong&gt; by Cliff Stoll&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Show Stopper! The Breakneck Race to Create Windows NT and the Next Generation at Microsoft&lt;/strong&gt; by G. Pascal Zachary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Masters Of Doom: How two guys created an empire and transformed pop culture&lt;/strong&gt; by David Kushner&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What are your favourites?
&lt;/h3&gt;

</description>
      <category>books</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Punishment Driven Development?</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Fri, 17 Nov 2017 15:34:44 +0000</pubDate>
      <link>https://dev.to/mattwarren/punishment-driven-development-33e</link>
      <guid>https://dev.to/mattwarren/punishment-driven-development-33e</guid>
      <description>&lt;p&gt;In a previous job I developed 'Industrial Monitoring Systems', otherwise known as a &lt;strong&gt;PC&lt;/strong&gt;, a &lt;strong&gt;Camera&lt;/strong&gt; and &lt;strong&gt;Image Processing Software&lt;/strong&gt; to analyse products moving down a production line.&lt;/p&gt;

&lt;p&gt;If everything was fine the keg of cider, pizza box or carrot would be sent out to a shop, otherwise it would be diverted to the reject pile! The systems looked something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--scQe8ANE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7co3xjbss6l0wrhy5iy9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--scQe8ANE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/7co3xjbss6l0wrhy5iy9.gif" alt="Key Inspection System"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;But why &lt;strong&gt;Punishment Driven Development&lt;/strong&gt;, well because when my software stopped working the entire production line would grind to a halt and some poor '&lt;em&gt;volunteer&lt;/em&gt;' would have to stand there and inspect the parts manually, clicking a &lt;em&gt;red&lt;/em&gt; or a &lt;em&gt;green&lt;/em&gt; button for each one.&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;Fun fact&lt;/strong&gt;: I was once told that &lt;strong&gt;allegedly&lt;/strong&gt; some factory workers would mess with the PC until it broke, hitting the same key 100 times in a row, endlessly restarting it, etc, etc. They did this because whilst the production line was down, they got to go on an extended tea-break 😊)&lt;/p&gt;

&lt;p&gt;Needless to say, if things went wrong the 'Head of Production' would soon be on the phone and because they had a support contract, it was my job to answer it and fix the problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;During the 5 years that I worked this job, I discovered the following&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Most industrial systems are located far away from the office where there is a phone and internet access&lt;/li&gt;
&lt;li&gt;People don't like being repeatedly asked '&lt;em&gt;can you just try this&lt;/em&gt;?' if each time it involves a 10 minute walk&lt;/li&gt;
&lt;li&gt;All sorts of things can go wrong with software running on a PC mounted to the side of a production line, inside a noisy, dirty factory&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If the problem can't be solved over the phone, someone (me), has to drive to the factory and stay till it's fixed&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Not surprisingly it is the last lesson that caused me the most problems!! Turns out, most factories are in the middle-of-nowhere. In addition, you have limited access to the machine you're fixing and there's no chance you'll get a nice comfy desk and a chair to sit on.&lt;/p&gt;

&lt;p&gt;However, it also forced me to implement &lt;strong&gt;reliable&lt;/strong&gt; and &lt;strong&gt;useful&lt;/strong&gt; diagnostics in my software and make it easy to extract them from the PC. Also I made it possible for the software to update itself from the contents of a USB stick, so no more evenings in a factory for me!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All in all I learnt:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Having useful diagnostics &lt;strong&gt;doesn't happen by accident&lt;/strong&gt;, you have to design it into your product&lt;/li&gt;
&lt;li&gt;Spending time thinking about &lt;strong&gt;what information to log&lt;/strong&gt; pays off (I always assumed that one day I'd be relying on it)&lt;/li&gt;
&lt;li&gt;Be &lt;strong&gt;nice to the person using your software&lt;/strong&gt;, so that when you visit their factory, they'll want to help you out&lt;/li&gt;
&lt;li&gt;Having a &lt;strong&gt;motivation to make your software better&lt;/strong&gt; really helps, hence &lt;strong&gt;Punishment Driven Development&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Otherwise you end up being &lt;a href="https://en.wikipedia.org/wiki/Send_to_Coventry"&gt;sent to Coventry&lt;/a&gt; (literally in my case!!)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What about you, do you have a similar story?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you ever learnt a valuable lesson about software development, due to an external motivation?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>A DoS Attack against the C# Compiler</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Thu, 09 Nov 2017 10:20:16 +0000</pubDate>
      <link>https://dev.to/mattwarren/a-dos-attack-against-the-c-compiler-35c</link>
      <guid>https://dev.to/mattwarren/a-dos-attack-against-the-c-compiler-35c</guid>
      <description>&lt;p&gt;This post first appeared &lt;a href="http://mattwarren.org/2017/11/08/A-DoS-Attack-against-the-C-Compiler/" rel="noopener noreferrer"&gt;on my blog&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Generics in C# are certainly very useful and I find it amazing that &lt;a href="https://blogs.msdn.microsoft.com/dsyme/2011/03/15/netc-generics-history-some-photos-from-feb-1999/" rel="noopener noreferrer"&gt;we almost didn't get them&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What would the cost of inaction have been? What would the cost of failure have been? No generics in C# 2.0? No LINQ in C# 3.0? No TPL in C# 4.0? No Async in C# 5.0? No F#? Ultimately, an erasure model of generics would have been adopted, as for Java, since the CLR team would never have pursued a in-the-VM generics design without external help.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So a big thanks is due to &lt;a href="https://www.microsoft.com/en-us/research/people/dsyme/" rel="noopener noreferrer"&gt;Don Syme&lt;/a&gt; and the rest of the team at Microsoft Research in Cambridge!&lt;/p&gt;

&lt;p&gt;But as well as being useful, I also find some usages of generics mind-bending, for instance I'm still not sure what this code &lt;em&gt;actually&lt;/em&gt; means or how to explain it in words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blah&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Blah&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As always, reading an Eric Lippert post &lt;a href="https://blogs.msdn.microsoft.com/ericlippert/2011/02/03/curiouser-and-curiouser/" rel="noopener noreferrer"&gt;helps a lot&lt;/a&gt;, but even he recommends against using this specific 'circular' pattern.&lt;/p&gt;




&lt;p&gt;Recently I spoke at the &lt;a href="https://www.corestart.cz/" rel="noopener noreferrer"&gt;CORESTART 2.0&lt;/a&gt; conference in Prague, giving a talk on &lt;a href="https://www.corestart.cz/#page-speeches" rel="noopener noreferrer"&gt;'Microsoft and Open-Source – A 'Brave New World'&lt;/a&gt;. Whilst I was there I met the very knowledgeable &lt;a href="https://twitter.com/cincura_net" rel="noopener noreferrer"&gt;Jiri Cincura&lt;/a&gt;, who blogs at &lt;a href="https://www.tabsoverspaces.com/" rel="noopener noreferrer"&gt;tabs â†¹ over â£ â£ â£ spaces&lt;/a&gt;. He was giving a great talk on 'C# 7.1 and 7.2 features', but also shared with me an excellent code snippet that he called 'Crazy Class':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Inner&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;He said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;this is the class that takes crazy amount of time to compile. You can add more &lt;code&gt;Inner.Inner.Inner...&lt;/code&gt; to make it even longer (and also generic parameters).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After a big of digging around I found that someone else had noticed this, see the StackOverflow question &lt;a href="https://stackoverflow.com/questions/14177225/why-does-field-declaration-with-duplicated-nested-type-in-generic-class-results/14178014" rel="noopener noreferrer"&gt;Why does field declaration with duplicated nested type in generic class results in huge source code increase?&lt;/a&gt; Helpfully the 'accepted answer' explains what is going on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you combine these two, the way you have done, something interesting happens. The type &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner&lt;/code&gt; is not the same type as &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner.Inner&lt;/code&gt;. &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner&lt;/code&gt; is a subclass of &lt;code&gt;Outer&amp;lt;Outer&amp;lt;T&amp;gt;.Inner&amp;gt;&lt;/code&gt; while &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner.Inner&lt;/code&gt; is a subclass of &lt;code&gt;Outer&amp;lt;Outer&amp;lt;Outer&amp;lt;T&amp;gt;.Inner&amp;gt;.Inner&amp;gt;&lt;/code&gt;, which we established before as being different from &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner&lt;/code&gt;. So &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner.Inner&lt;/code&gt; and &lt;code&gt;Outer&amp;lt;T&amp;gt;.Inner&lt;/code&gt; &lt;strong&gt;are referring to different types&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When generating IL, the compiler always uses fully qualified names for types. You have cleverly found a way to refer to types with names whose lengths that grow at &lt;strong&gt;exponential rates&lt;/strong&gt;. That is why as you increase the generic arity of &lt;code&gt;Outer&lt;/code&gt; or add additional levels &lt;code&gt;.Y&lt;/code&gt; to the field &lt;code&gt;field&lt;/code&gt; in &lt;code&gt;Inner&lt;/code&gt; the output IL size and compile time grow so quickly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Clear? Good!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You probably have to be Jon Skeet, Eric Lippert or a member of the &lt;a href="https://github.com/dotnet/csharplang/blob/057c1fde486803b9e7d33df70dcb84fefa6c89b1/meetings/2015/LDM-2015-01-21.md#design-team" rel="noopener noreferrer"&gt;C# Language Design Team&lt;/a&gt; (yay, 'Matt Warren') to really understand what's going on here, but that doesn't stop the rest of us having fun with the code!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I can't think of any reason why you'd actually want to write code like this, so please don't!! (or at least if you do, don't blame me!!)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a simple idea of what's actually happening, lets take this code (with only 2 'Levels'):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Inner&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 'decompiled' version actually looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Inner&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                            &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wow, no wonder things go wrong quickly!!&lt;/p&gt;




&lt;h3&gt;
  
  
  Exponential Growth
&lt;/h3&gt;

&lt;p&gt;Firstly let's check the claim of &lt;strong&gt;exponential growth&lt;/strong&gt;, if you don't remember your &lt;a href="https://en.wikipedia.org/wiki/Big_O_notation" rel="noopener noreferrer"&gt;Big O notation&lt;/a&gt; you can also think of this as &lt;code&gt;O(very, very bad)&lt;/code&gt;!!&lt;/p&gt;

&lt;p&gt;To test this out, I'm going to compile the code above, but vary the 'level' each time by adding a new &lt;code&gt;.Inner&lt;/code&gt;, so 'Level 5' looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;'Level 6' like this, and so on&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Inner&lt;/span&gt; &lt;span class="n"&gt;inner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We then get the following results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Compile Time (secs)&lt;/th&gt;
&lt;th&gt;Working set (KB)&lt;/th&gt;
&lt;th&gt;Binary Size (Bytes)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;1.15&lt;/td&gt;
&lt;td&gt;54,288&lt;/td&gt;
&lt;td&gt;135,680&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;1.22&lt;/td&gt;
&lt;td&gt;59,500&lt;/td&gt;
&lt;td&gt;788,992&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;70,728&lt;/td&gt;
&lt;td&gt;4,707,840&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;6.43&lt;/td&gt;
&lt;td&gt;121,852&lt;/td&gt;
&lt;td&gt;28,222,464&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;33.23&lt;/td&gt;
&lt;td&gt;405,472&lt;/td&gt;
&lt;td&gt;169,310,208&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;202.10&lt;/td&gt;
&lt;td&gt;2,141,272&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;CRASH&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If we look at these results in graphical form, it's very obvious what's going on&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/11/Crazy%20Class%20-%20Compile%20Time.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FCrazy%2520Class%2520-%2520Compile%2520Time.png" alt="Crazy Class - Compile Time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/11/Crazy%20Class%20-%20Working%20Set.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FCrazy%2520Class%2520-%2520Working%2520Set.png" alt="Crazy Class - Working Set"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/11/Crazy%20Class%20-%20Binary%20Size.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FCrazy%2520Class%2520-%2520Binary%2520Size.png" alt="Crazy Class - Binary Size"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(the dotted lines are a 'best fit' trend-line and they are exponential)&lt;/p&gt;

&lt;p&gt;If I compile the code with &lt;code&gt;dotnet build&lt;/code&gt; (version 2.0.0), things go really wrong at 'Level 10' and the compiler throws an error (&lt;a href="https://gist.github.com/mattwarren/d6fd747792cf1e98cba4679bf1398041" rel="noopener noreferrer"&gt;full stack trace&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ArgumentOutOfRangeException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Specified&lt;/span&gt; &lt;span class="n"&gt;argument&lt;/span&gt; &lt;span class="n"&gt;was&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which looks similar to &lt;a href="https://github.com/Microsoft/visualfsharp/issues/3866" rel="noopener noreferrer"&gt;Internal compiler error when creating Portable PDB files #3866&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However your mileage may vary, when I ran the code in Visual Studio 2015 it threw an &lt;code&gt;OutOfMemoryException&lt;/code&gt; instead and then promptly restarted itself!! I assume this is because &lt;a href="https://blogs.msdn.microsoft.com/ricom/2009/06/10/visual-studio-why-is-there-no-64-bit-version-yet/" rel="noopener noreferrer"&gt;VS is a 32-bit application&lt;/a&gt; and it runs out of memory before it can go really wrong!&lt;/p&gt;




&lt;h3&gt;
  
  
  Profiling the Compiler
&lt;/h3&gt;

&lt;p&gt;Finally, I want to look at just where the compiler is spending all it's time. From the results above we saw that it was taking &lt;strong&gt;over 3 minutes&lt;/strong&gt; to compile a simple program, with a peak memory usage of &lt;strong&gt;2.14 GB&lt;/strong&gt;, so what was it actually doing??&lt;/p&gt;

&lt;p&gt;Well clearly there's lots of &lt;code&gt;Types&lt;/code&gt; involved and the Compiler seems happy for you to write this code, so I guess it needs to figure it all out. Once it's done that, it then needs to write all this &lt;code&gt;Type&lt;/code&gt; metadata out to a .dll or .exe, which can be &lt;strong&gt;100's of MB&lt;/strong&gt; in size.&lt;/p&gt;

&lt;p&gt;At a high-level the profiling summary produce by VS looks like this (click for full-size image):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/11/Profiling%20Report.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FProfiling%2520Report.png" alt="Profiling Report"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However if we take a bit of a close look, we can see the 'hot-path' is inside the &lt;code&gt;SerializeTypeReference(..)&lt;/code&gt; method in &lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs#L3788-L3810" rel="noopener noreferrer"&gt;Compilers/Core/Portable/PEWriter/MetadataWriter.cs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/11/Profiling%20-%20Hot%20Path.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F11%2FProfiling%2520-%2520Hot%2520Path.png" alt="Profiling - Hot Path"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;I'm a bit torn about this, it is clearly an 'abuse' of generics!!&lt;/p&gt;

&lt;p&gt;In some ways I think that it &lt;strong&gt;shouldn't&lt;/strong&gt; be fixed, it seems better that the compiler encourages you to &lt;strong&gt;not&lt;/strong&gt; write code like this, rather than making is possible!!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So if it takes 3 mins to compile your code, allocates 2GB of memory and then crashes, take that as a warning!!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>opensource</category>
      <category>roslyn</category>
    </item>
    <item>
      <title>DotNetAnywhere: An Alternative .NET Runtime</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Fri, 20 Oct 2017 11:27:01 +0000</pubDate>
      <link>https://dev.to/mattwarren/dotnetanywhere-an-alternative-net-runtime-726</link>
      <guid>https://dev.to/mattwarren/dotnetanywhere-an-alternative-net-runtime-726</guid>
      <description>

&lt;p&gt;&lt;em&gt;This post originally &lt;a href="http://mattwarren.org/2017/10/19/DotNetAnywhere-an-Alternative-.NET-Runtime/"&gt;appeared on my blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Recently I was listening to the excellent &lt;a href="https://www.dotnetrocks.com/"&gt;DotNetRocks podcast&lt;/a&gt; and they had &lt;a href="https://twitter.com/stevensanderson"&gt;Steven Sanderson&lt;/a&gt; (of &lt;a href="http://knockoutjs.com/"&gt;Knockout.js fame&lt;/a&gt;) talking about &lt;a href="https://www.dotnetrocks.com/?show=1455"&gt;'WebAssembly and Blazor'&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In case you haven't heard about it, &lt;a href="https://github.com/SteveSanderson/Blazor"&gt;Blazor&lt;/a&gt; is an attempt to bring .NET to the browser, using the magic of &lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly"&gt;WebAssembly&lt;/a&gt;. If you want more info, Scott Hanselmen has done a &lt;a href="https://www.hanselman.com/blog/NETAndWebAssemblyIsThisTheFutureOfTheFrontend.aspx"&gt;nice write-up of the various .NET/WebAssembly projects&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, as much as the mention of WebAssembly was pretty cool, what interested me even more how Blazor was using &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere"&gt;DotNetAnywhere&lt;/a&gt; as the underlying .NET runtime. This post will look at what DotNetAnywhere is, what you can do with it and how it compares to the full .NET framework.&lt;/p&gt;




&lt;h1&gt;
  
  
  DotNetAnywhere
&lt;/h1&gt;

&lt;p&gt;Firstly it's worth pointing out that DotNetAnywhere (DNA) is designed to be a fully compliant .NET runtime, which means that it can run .NET dlls/exes that have been compiled to run against the full framework. On top of that (at least in theory) it &lt;strong&gt;supports&lt;/strong&gt; all the following &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere#supported-net-runtime-features"&gt;.NET runtime features&lt;/a&gt;, which is a pretty impressive list!&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Generics&lt;/li&gt;
&lt;li&gt;Garbage collection and finalization&lt;/li&gt;
&lt;li&gt;Weak references&lt;/li&gt;
&lt;li&gt;Full exception handling - try/catch/finally&lt;/li&gt;
&lt;li&gt;PInvoke&lt;/li&gt;
&lt;li&gt;Interfaces&lt;/li&gt;
&lt;li&gt;Delegates&lt;/li&gt;
&lt;li&gt;Events&lt;/li&gt;
&lt;li&gt;Nullable types&lt;/li&gt;
&lt;li&gt;Single-dimensional arrays&lt;/li&gt;
&lt;li&gt;Multi-threading&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;In addition there is some &lt;strong&gt;partial support&lt;/strong&gt; for &lt;a href="https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/reflection"&gt;Reflection&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Very limited read-only reflection

&lt;ul&gt;
&lt;li&gt;typeof(), .GetType(), Type.Name, Type.Namespace, Type.IsEnum(), &amp;lt;object&amp;gt;.ToString() only&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, there are a few features that are currently &lt;strong&gt;unsupported&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Attributes&lt;/li&gt;
&lt;li&gt;Most reflection&lt;/li&gt;
&lt;li&gt;Multi-dimensional arrays&lt;/li&gt;
&lt;li&gt;Unsafe code&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/issues?q=is%3Aissue+is%3Aclosed"&gt;various bugs or missing functionality&lt;/a&gt; that might prevent your code running under DotNetAnywhere, however several of these have been &lt;a href="https://github.com/SteveSanderson/Blazor/pulls?utf8=%E2%9C%93&amp;amp;q=is%3Apr"&gt;fixed since Blazor came along&lt;/a&gt;, so it's worth checking against the Blazor version of DotNetAnywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;At this point in time the original DotNetAnywhere repo is &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere#this-project-is-inactive-no-issues-or-prs-will-be-dealt-with"&gt;no longer active&lt;/a&gt; (the last sustained activity was in Jan 2012), so it seems that any future development or bugs fixes will likely happen in the Blazor repo. If you have ever fixed something in DotNetAnywhere, consider sending a P.R there, to help the effort.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; In addition there are other forks with various bug fixes and enhancements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ncave/dotnet-js"&gt;https://github.com/ncave/dotnet-js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/memsom/dna"&gt;https://github.com/memsom/dna&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Source Code Layout
&lt;/h2&gt;

&lt;p&gt;What I find most impressive about the DotNetAnywhere runtime is that it was &lt;strong&gt;developed by one person&lt;/strong&gt; and is &lt;strong&gt;less that 40,000 lines of code&lt;/strong&gt;!! For a comparison the .NET framework Garbage Collector is &lt;a href="https://github.com/dotnet/coreclr/blob/master/src/gc/gc.cpp"&gt;almost 37,000 lines on it's own&lt;/a&gt; (more info available in my previous post &lt;a href="http://mattwarren.org/2017/03/23/Hitchhikers-Guide-to-the-CoreCLR-Source-Code/#overall-stats"&gt;A Hitchhikers Guide to the CoreCLR Source Code&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This makes DotNetAnywhere an ideal learning resource!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Firstly, lets take a look at the Top-10 largest source files, to see where the complexity is:  &lt;/p&gt;

&lt;h3&gt;
  
  
  Native Code - &lt;strong&gt;17,710&lt;/strong&gt; lines in total
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;LOC&lt;/th&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;3,164&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/JIT_Execute.c"&gt;JIT_Execute.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,778&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/JIT.c"&gt;JIT.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,109&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/PInvoke_CaseCode.h"&gt;PInvoke_CaseCode.h&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;630&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/Heap.c"&gt;Heap.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;618&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/MetaData.c"&gt;MetaData.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;563&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/MetaDataTables.h"&gt;MetaDataTables.h&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;517&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/Type.c"&gt;Type.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;491&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/MetaData_Fill.c"&gt;MetaData_Fill.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;467&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/MetaData_Search.c"&gt;MetaData_Search.c&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;452&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/tree/master/dna/JIT_OpCodes.h"&gt;JIT_OpCodes.h&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Managed Code - &lt;strong&gt;28,783&lt;/strong&gt; lines in total
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;LOC&lt;/th&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2393&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System.Globalization/CalendricalCalculations.cs"&gt;corlib/System.Globalization/CalendricalCalculations.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2314&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System/NumberFormatter.cs"&gt;corlib/System/NumberFormatter.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1582&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/System.Drawing/System.Drawing/Pens.cs"&gt;System.Drawing/System.Drawing/Pens.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1443&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/System.Drawing/System.Drawing/Brushes.cs"&gt;System.Drawing/System.Drawing/Brushes.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1405&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/System.Core/System.Linq/Enumerable.cs"&gt;System.Core/System.Linq/Enumerable.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;745&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System/DateTime.cs"&gt;corlib/System/DateTime.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;693&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System.IO/Path.cs"&gt;corlib/System.IO/Path.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;632&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System.Collections.Generic/Dictionary.cs"&gt;corlib/System.Collections.Generic/Dictionary.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;598&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System/String.cs"&gt;corlib/System/String.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;467&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System.Text/StringBuilder.cs"&gt;corlib/System.Text/StringBuilder.cs&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Main areas of functionality
&lt;/h2&gt;

&lt;p&gt;Next, lets look at the key components in DotNetAnywhere as this gives us a really good idea about what you need to implement a .NET compatible runtime. Along the way, we will also see how they differ from the implementation found in Microsoft's .NET Framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading .NET dlls
&lt;/h3&gt;

&lt;p&gt;The first thing DotNetAnywhere has to do is read/understand/parse the .NET &lt;em&gt;Metadata and Code&lt;/em&gt; that's contained in a .dll/.exe. This all takes place in &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/MetaData.c"&gt;MetaData.c&lt;/a&gt;, primarily within the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/MetaData.c#L302-L484"&gt;LoadSingleTable(..)&lt;/a&gt; function. By adding some debugging code, I was able to get a  summary of all the different types of &lt;em&gt;Metadata&lt;/em&gt; that are read in from a typical .NET dll, it's quite an interesting list: &lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MetaData contains     1 Assemblies (MD_TABLE_ASSEMBLY)
MetaData contains     1 Assembly References (MD_TABLE_ASSEMBLYREF)
MetaData contains     0 Module References (MD_TABLE_MODULEREF)

MetaData contains    40 Type References (MD_TABLE_TYPEREF)
MetaData contains    13 Type Definitions (MD_TABLE_TYPEDEF)
MetaData contains    14 Type Specifications (MD_TABLE_TYPESPEC)
MetaData contains     5 Nested Classes (MD_TABLE_NESTEDCLASS)

MetaData contains    11 Field Definitions (MD_TABLE_FIELDDEF)
MetaData contains     0 Field RVA's (MD_TABLE_FIELDRVA)
MetaData contains     2 Propeties (MD_TABLE_PROPERTY)
MetaData contains    59 Member References (MD_TABLE_MEMBERREF)
MetaData contains     2 Constants (MD_TABLE_CONSTANT)

MetaData contains    35 Method Definitions (MD_TABLE_METHODDEF)
MetaData contains     5 Method Specifications (MD_TABLE_METHODSPEC)
MetaData contains     4 Method Semantics (MD_TABLE_PROPERTY)
MetaData contains     0 Method Implementations (MD_TABLE_METHODIMPL)
MetaData contains    22 Parameters (MD_TABLE_PARAM)

MetaData contains     2 Interface Implementations (MD_TABLE_INTERFACEIMPL)
MetaData contains     0 Implementation Maps? (MD_TABLE_IMPLMAP)

MetaData contains     2 Generic Parameters (MD_TABLE_GENERICPARAM)
MetaData contains     1 Generic Parameter Constraints (MD_TABLE_GENERICPARAMCONSTRAINT)

MetaData contains    22 Custom Attributes (MD_TABLE_CUSTOMATTRIBUTE)
MetaData contains     0 Security Info Items? (MD_TABLE_DECLSECURITY)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For more information on the &lt;em&gt;Metadata&lt;/em&gt; see &lt;a href="https://iobservable.net/blog/2013/05/12/introduction-to-clr-metadata/"&gt;Introduction to CLR metadata&lt;/a&gt;, &lt;a href="https://www.red-gate.com/simple-talk/blogs/anatomy-of-a-net-assembly-pe-headers/"&gt;Anatomy of a .NET Assembly – PE Headers&lt;/a&gt; and the &lt;a href="https://www.visualstudio.com/license-terms/ecma-c-common-language-infrastructure-standards/"&gt;ECMA specification itself&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Executing .NET IL
&lt;/h3&gt;

&lt;p&gt;Another large piece of functionality within DotNetAnywhere is the 'Just-in-Time' Compiler (JIT), i.e. the code that is responsible for executing the IL, this takes place initially in &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/JIT_Execute.c"&gt;JIT_Execute.c&lt;/a&gt; and then &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/JIT.c"&gt;JIT.c&lt;/a&gt;. The main 'execution loop' is in the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/JIT.c#L232-L1606"&gt;JITit(..) function&lt;/a&gt; which contains an impressive 1,374 lines of code and over 200 &lt;code&gt;case&lt;/code&gt; statements within a single &lt;code&gt;switch&lt;/code&gt;!!&lt;/p&gt;

&lt;p&gt;Taking a higher level view, the overall process that it goes through looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/10/NET%20IL%20-%20DNA%20JIT%20Op-Codes.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EMQbPqu1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/10/NET%2520IL%2520-%2520DNA%2520JIT%2520Op-Codes.png" alt="NET IL -&amp;gt; DNA JIT Op-Codes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where the .NET IL Op-Codes (&lt;code&gt;CIL_XXX&lt;/code&gt;) are defined in &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/CIL_OpCodes.h"&gt;CIL_OpCodes.h&lt;/a&gt; and the DotNetAnywhere JIT Op-Codes (&lt;code&gt;JIT_XXX&lt;/code&gt;) are defined in &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/JIT_OpCodes.h"&gt;JIT_OpCodes.h&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interesting enough, the JIT is the only place in DotNetAnywhere that &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/JIT_Execute.c#L184-L204"&gt;uses assembly code&lt;/a&gt; and even then it's only for &lt;code&gt;win32&lt;/code&gt;. It is used to allow a 'jump' or a &lt;code&gt;goto&lt;/code&gt; to labels in the C source code, so as IL instructions are executed it never actually leaves the &lt;code&gt;JITit(..)&lt;/code&gt; function, control is just moved around without having to make a full method call.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifdef __GNUC__
&lt;/span&gt;
&lt;span class="cp"&gt;#define GET_LABEL(var, label) var = &amp;amp;&amp;amp;label
&lt;/span&gt;
&lt;span class="cp"&gt;#define GO_NEXT() goto **(void**)(pCurOp++)
&lt;/span&gt;
&lt;span class="cp"&gt;#else
#ifdef WIN32
&lt;/span&gt;
&lt;span class="cp"&gt;#define GET_LABEL(var, label) \
    { __asm mov edi, label \
    __asm mov var, edi }
&lt;/span&gt;
&lt;span class="cp"&gt;#define GO_NEXT() \
    { __asm mov edi, pCurOp \
    __asm add edi, 4 \
    __asm mov pCurOp, edi \
    __asm jmp DWORD PTR [edi - 4] }
&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Differences with the .NET Framework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the full .NET framework all IL code is turned into machine code by the &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/ryujit-tutorial.md"&gt;Just-in-Time Compiler (JIT)&lt;/a&gt; before being executed by the CPU.&lt;/p&gt;

&lt;p&gt;However as we've already seen, DotNetAnywhere 'interprets' the IL, instruction-by-instruction and even through it's done in a file called &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/JIT.c"&gt;JIT.c&lt;/a&gt; &lt;strong&gt;no machine code&lt;/strong&gt; is emitted, so the naming seems strange!?&lt;/p&gt;

&lt;p&gt;Maybe it's just a difference of perspective, but it's not clear to me at what point you move from 'interpreting' code to 'JITting' it, even after reading the following links I'm not sure!! (can someone enlighten me?)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/2426091/what-are-the-differences-between-a-just-in-time-compiler-and-an-interpreter"&gt;What are the differences between a Just-in-Time-Compiler and an Interpreter?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://softwareengineering.stackexchange.com/questions/246094/understanding-the-differences-traditional-interpreter-jit-compiler-jit-interp"&gt;Understanding the differences: traditional interpreter, JIT compiler, JIT interpreter and AOT compiler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/3718024/jit-vs-interpreters"&gt;JIT vs Interpreters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.quora.com/Why-do-we-call-it-JIT-compiler-and-not-JIT-interpreter-to-refer-to-the-thing-that-converts-the-Java-bytecode-to-the-machine-code"&gt;Why do we call it "JIT compiler" and not "JIT interpreter" to refer to the thing that converts the Java bytecode to the machine code?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/underst_jit.html"&gt;Understanding JIT Compilation and Optimizations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Garbage Collector
&lt;/h3&gt;

&lt;p&gt;All the code for the DotNetAnywhere Garbage Collector (GC) is contained in &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/Heap.c"&gt;Heap.c&lt;/a&gt; and is a very readable 600 lines of code. To give you an overview of what it does, here is the list of functions that it exposes:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_Init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_SetRoots&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tHeapRoots&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pHeapRoots&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pRoots&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;sizeInBytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_UnmarkFinalizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;heapPtr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_GarbageCollect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;Heap_NumCollections&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;Heap_GetTotalMemory&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;Heap_Alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tMD_TypeDef&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pTypeDef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;Heap_AllocType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tMD_TypeDef&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pTypeDef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_MakeUndeletable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;heapEntry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_MakeDeletable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;heapEntry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;tMD_TypeDef&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Heap_GetType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;heapEntry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;Heap_Box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tMD_TypeDef&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PTR&lt;/span&gt; &lt;span class="n"&gt;pMem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;Heap_Clone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;Heap_SyncTryEnter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;Heap_SyncExit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;Heap_SetWeakRefTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;weakRef&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Heap_GetWeakRefAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Heap_RemovedWeakRefTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HEAP_PTR&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Differences with the .NET Framework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;However, like the JIT/Interpreter, the GC has some fundamental differences when compared to the .NET Framework&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Conservative Garbage Collection&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Firstly DotNetAnywhere implements what is knows as a &lt;a href="https://stackoverflow.com/questions/7629446/conservative-garbage-collector"&gt;&lt;em&gt;Conservative&lt;/em&gt; GC&lt;/a&gt;. In simple terms this means that is does not know (for sure) which areas of memory are actually references/pointers to objects and which are just a random number (that looks like a memory address). In the Microsoft .NET Framework the JIT calculates this information and stores it in the &lt;a href="https://github.com/dotnet/coreclr/blob/master/src/inc/gcinfo.h"&gt;GCInfo structure&lt;/a&gt; so the GC can make use of it. But DotNetAnywhere doesn't do this.&lt;/p&gt;

&lt;p&gt;Instead, during the &lt;code&gt;Mark&lt;/code&gt; phase the GC &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/Heap.c#L278-L345"&gt;gets all the available 'roots'&lt;/a&gt;, but it will consider all memory addresses within an object as 'potential' references (hence it is '&lt;em&gt;conservative&lt;/em&gt;'). It then has to lookup each possible reference, to see if it really points to an 'object reference'. It does this by keeping track of all memory/heap references in a &lt;a href="http://www.eternallyconfuzzled.com/tuts/datastructures/jsw_tut_andersson.aspx"&gt;balanced binary search tree&lt;/a&gt; (ordered by memory address), which looks something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/10/Binary%20Tree%20with%20Pointers%20into%20the%20Heap.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E5KNFZvp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/10/Binary%2520Tree%2520with%2520Pointers%2520into%2520the%2520Heap.png" alt="Binary Tree with Pointers into the Heap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this means that all objects references have to be stored in the binary tree when they are allocated, which adds some overhead to allocation. In addition extra memory is needed, 20 bytes per heap entry. We can see this by looking at the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/Heap.c#L58-L83"&gt;&lt;code&gt;tHeapEntry&lt;/code&gt; data structure&lt;/a&gt; (all pointers are 4 bytes, &lt;code&gt;U8&lt;/code&gt; = 1 byte and &lt;code&gt;padding&lt;/code&gt; is ignored), &lt;code&gt;tHeapEntry *pLink[2]&lt;/code&gt; is the extra data that is needed just to enable the binary tree lookup. &lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;tHeapEntry_&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Left/right links in the heap binary tree&lt;/span&gt;
    &lt;span class="n"&gt;tHeapEntry&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pLink&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="c1"&gt;// The 'level' of this node. Leaf nodes have lowest level&lt;/span&gt;
    &lt;span class="n"&gt;U8&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Used to mark that this node is still in use.&lt;/span&gt;
    &lt;span class="c1"&gt;// If this is set to 0xff, then this heap entry is undeletable.&lt;/span&gt;
    &lt;span class="n"&gt;U8&lt;/span&gt; &lt;span class="n"&gt;marked&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Set to 1 if the Finalizer needs to be run.&lt;/span&gt;
    &lt;span class="c1"&gt;// Set to 2 if this has been added to the Finalizer queue&lt;/span&gt;
    &lt;span class="c1"&gt;// Set to 0 when the Finalizer has been run (or there is no Finalizer in the first place)&lt;/span&gt;
    &lt;span class="c1"&gt;// Only set on types that have a Finalizer&lt;/span&gt;
    &lt;span class="n"&gt;U8&lt;/span&gt; &lt;span class="n"&gt;needToFinalize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// unused&lt;/span&gt;
    &lt;span class="n"&gt;U8&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// The type in this heap entry&lt;/span&gt;
    &lt;span class="n"&gt;tMD_TypeDef&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pTypeDef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Used for locking sync, and tracking WeakReference that point to this object&lt;/span&gt;
    &lt;span class="n"&gt;tSync&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pSync&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// The user memory&lt;/span&gt;
    &lt;span class="n"&gt;U8&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But why does DotNetAnywhere work like this? Fortunately &lt;a href="https://github.com/chrisdunelm"&gt;Chris Bacon&lt;/a&gt; the author of DotNetAnywhere &lt;a href="https://github.com/SteveSanderson/Blazor/pull/7#discussion_r136719427"&gt;explains&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mind you, the whole heap code really needs a rewrite to reduce per-object memory overhead, and to remove the need for the binary tree of allocations. Not really thinking of a generational GC, that would probably add to much code. This was something I vaguely intended to do, but never got around to.&lt;br&gt;
&lt;strong&gt;The current heap code was just the simplest thing to get GC working quickly.&lt;/strong&gt; The very initial implementation did no GC at all. It was beautifully fast, but ran out of memory rather too quickly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For more info on 'Conservative' and 'Precise' GCs see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Tracing_garbage_collection#Precise_vs._conservative_and_internal_pointers"&gt;Precise vs. conservative and internal pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/5096088/how-does-the-net-clr-distinguish-between-managed-from-unmanaged-pointers/5096824#5096824"&gt;How does the .NET CLR distinguish between Managed from Unmanaged Pointers?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;GC only does 'Mark-Sweep', it doesn't Compact&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Another area in which the GC behaviour differs is that it doesn't do any &lt;strong&gt;Compaction&lt;/strong&gt; of memory after it's cleaned up, as Steve Sanderson found out when &lt;a href="https://github.com/SteveSanderson/Blazor/blob/master/src/Blazor.Runtime/Interop/ManagedGCHandle.cs#L40-L43"&gt;working on Blazor&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;.. During server-side execution we don't actually need to pin anything, because there's no interop outside .NET. During client-side execution, everything is (in effect) pinned regardless, &lt;strong&gt;because DNA's GC only does mark-sweep - it doesn't have any compaction phase&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In addition, when an object is allocated DotNetAnywhere just makes a call to &lt;a href="http://www.cplusplus.com/reference/cstdlib/malloc/"&gt;malloc()&lt;/a&gt;, see the code that does this is in the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/Heap.c#L468"&gt;Heap_Alloc(..) function&lt;/a&gt;. So there is no concept of &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/garbage-collection.md#physical-representation-of-the-managed-heap"&gt;'Generations' or 'Segments'&lt;/a&gt; that you have in the .NET Framework GC, i.e. no 'Gen 0', 'Gen 1', or 'Large Object Heap'. &lt;/p&gt;




&lt;h3&gt;
  
  
  Threading Model
&lt;/h3&gt;

&lt;p&gt;Finally, lets take a look at the threading model, which is fundamentally different from the one found in the .NET Framework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Differences with the .NET Framework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Whilst DotNetAnywhere will happily create new threads and execute them for you, it's only providing the illusion of true multi-threading. In reality it only runs on &lt;strong&gt;one thread&lt;/strong&gt;, but &lt;strong&gt;context switches&lt;/strong&gt; between the different threads that your program creates:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/10/Thread%20Usage%20Explanation.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zLWV090B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/10/Thread%2520Usage%2520Explanation.png" alt="Thread Usage Explanation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see this in action in the code below, (from the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/Thread.c#L112-L236"&gt;Thread_Execute() function&lt;/a&gt;), note the call to &lt;code&gt;JIT_Execute(..)&lt;/code&gt; with &lt;code&gt;numInst&lt;/code&gt; set to &lt;code&gt;100&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;minSleepTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xffffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;I32&lt;/span&gt; &lt;span class="n"&gt;threadExitValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JIT_Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;....&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;An interesting side-effect is that the threading code in the DotNetAnywhere &lt;code&gt;corlib&lt;/code&gt; implementation is really simple. For instance the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/dna/System.Threading.Interlocked.c#L26-L37"&gt;internal implementation&lt;/a&gt; of the &lt;a href="https://github.com/chrisdunelm/DotNetAnywhere/blob/master/corlib/System.Threading/Interlocked.cs#L28"&gt;&lt;code&gt;Interlocked.CompareExchange()&lt;/code&gt; function&lt;/a&gt; looks like the following, note the lack of synchronisation that you would normally expect:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;tAsyncCall&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;System_Threading_Interlocked_CompareExchange_Int32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;PTR&lt;/span&gt; &lt;span class="n"&gt;pThis_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PTR&lt;/span&gt; &lt;span class="n"&gt;pParams&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PTR&lt;/span&gt; &lt;span class="n"&gt;pReturnValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pLoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INTERNALCALL_PARAM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;U32&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INTERNALCALL_PARAM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;U32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;U32&lt;/span&gt; &lt;span class="n"&gt;comparand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INTERNALCALL_PARAM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;U32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;U32&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;pReturnValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pLoc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pLoc&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;comparand&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pLoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h2&gt;
  
  
  Benchmarks
&lt;/h2&gt;

&lt;p&gt;As a simple test, I ran some benchmarks from &lt;a href="http://benchmarksgame.alioth.debian.org/u64q/binarytrees.html"&gt;The Computer Language Benchmarks Game - binary-trees&lt;/a&gt;, using the &lt;a href="http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&amp;amp;lang=csharpcore&amp;amp;id=1"&gt;simplest C# version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: DotNetAnywhere was designed to run on low-memory devices, so it was not meant to have the same performance as the full .NET Framework. Please bear that in mind when looking at the results!!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  .NET Framework, 4.6.1 - 0.36 seconds
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoked=TestApp.exe 15
stretch tree of depth 16         check: 131071
32768    trees of depth 4        check: 1015808
8192     trees of depth 6        check: 1040384
2048     trees of depth 8        check: 1046528
512      trees of depth 10       check: 1048064
128      trees of depth 12       check: 1048448
32       trees of depth 14       check: 1048544
long lived tree of depth 15      check: 65535

Exit code      : 0
Elapsed time   : 0.36
Kernel time    : 0.06 (17.2%)
User time      : 0.16 (43.1%)
page fault #   : 6604
Working set    : 25720 KB
Paged pool     : 187 KB
Non-paged pool : 24 KB
Page file size : 31160 KB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  DotNetAnywhere - 54.39 seconds
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Invoked=dna TestApp.exe 15
stretch tree of depth 16         check: 131071
32768    trees of depth 4        check: 1015808
8192     trees of depth 6        check: 1040384
2048     trees of depth 8        check: 1046528
512      trees of depth 10       check: 1048064
128      trees of depth 12       check: 1048448
32       trees of depth 14       check: 1048544
long lived tree of depth 15      check: 65535

Total execution time = 54288.33 ms
Total GC time = 36857.03 ms
Exit code      : 0
Elapsed time   : 54.39
Kernel time    : 0.02 (0.0%)
User time      : 54.15 (99.6%)
page fault #   : 5699
Working set    : 15548 KB
Paged pool     : 105 KB
Non-paged pool : 8 KB
Page file size : 13144 KB
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So clearly DotNetAnywhere doesn't work as fast in this benchmark (0.36 seconds v 54 seconds). However if we look at other benchmarks from the same site, it performs a lot better. It seems that DotNetAnywhere has a significant overhead when allocating objects (a &lt;code&gt;class&lt;/code&gt;), which is less obvious when using &lt;code&gt;structs&lt;/code&gt;. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;
&lt;a href="http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&amp;amp;lang=csharpcore&amp;amp;id=1"&gt;Benchmark 1&lt;/a&gt; (using &lt;code&gt;classes&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;
&lt;a href="http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&amp;amp;lang=csharpcore&amp;amp;id=2"&gt;Benchmark 2&lt;/a&gt; (using &lt;code&gt;structs&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Elapsed Time (secs)&lt;/td&gt;
&lt;td&gt;3.1&lt;/td&gt;
&lt;td&gt;2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GC Collections&lt;/td&gt;
&lt;td&gt;96&lt;/td&gt;
&lt;td&gt;67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total GC time (msecs)&lt;/td&gt;
&lt;td&gt;983.59&lt;/td&gt;
&lt;td&gt;439.73&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;strong&gt;Finally, I really want to thank &lt;a href="https://github.com/chrisdunelm"&gt;Chris Bacon&lt;/a&gt;, DotNetAnywhere is a great code base and gives a fantastic insight into what needs to happen for a .NET runtime to work.&lt;/strong&gt;&lt;/p&gt;


</description>
      <category>net</category>
      <category>clr</category>
      <category>internals</category>
    </item>
    <item>
      <title>Analysing C# code on GitHub with BigQuery</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Fri, 13 Oct 2017 08:50:12 +0000</pubDate>
      <link>https://dev.to/mattwarren/analysing-c-code-on-github-with-bigquery-c8d</link>
      <guid>https://dev.to/mattwarren/analysing-c-code-on-github-with-bigquery-c8d</guid>
      <description>&lt;p&gt;Just over a year ago Google made all the &lt;a href="https://medium.com/google-cloud/github-on-bigquery-analyze-all-the-code-b3576fd2b150"&gt;open source code on GitHub available for querying&lt;/a&gt; within BigQuery and as if that wasn't enough &lt;a href="https://cloud.google.com/blog/big-data/2017/01/how-to-run-a-terabyte-of-google-bigquery-queries-each-month-without-a-credit-card"&gt;you can run a terabyte of queries each month for free&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;So in this post I am going to be looking at all the &lt;strong&gt;C#&lt;/strong&gt; source code on GitHub and what we can find out from it. Handily a smaller, C# only, dataset has been made available (in BigQuery you are charged per byte read), called &lt;a href="https://bigquery.cloud.google.com/table/fh-bigquery:github_extracts.contents_net_cs"&gt;fh-bigquery:github_extracts.contents_net_cs&lt;/a&gt; and has&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;5,885,933&lt;/strong&gt; unique '.cs' files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;792,166,632&lt;/strong&gt; lines of code (LOC)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;37.17 GB&lt;/strong&gt; (37,174,783,891 bytes) of data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which is a pretty comprehensive set of C# source code!&lt;/p&gt;




&lt;p&gt;The rest of this post will &lt;em&gt;attempt&lt;/em&gt; to answer the following questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tabs or Spaces?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;regions&lt;/code&gt;: 'should be banned' or 'okay in some cases'?&lt;/li&gt;
&lt;li&gt;'K&amp;amp;R' or 'Allman', where do C# devs like to put their braces?&lt;/li&gt;
&lt;li&gt;Do C# developers like writing functional code?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then moving onto some less controversial C# topics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which &lt;code&gt;using&lt;/code&gt; statements are most widely used?&lt;/li&gt;
&lt;li&gt;What NuGet packages are most often included in a .NET project&lt;/li&gt;
&lt;li&gt;How many lines of code (LOC) are in a typical C# file?&lt;/li&gt;
&lt;li&gt;What is the most widely thrown &lt;code&gt;Exception&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;'async/await all the things' or not?&lt;/li&gt;
&lt;li&gt;Do C# developers like using the &lt;code&gt;var&lt;/code&gt; keyword?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before we end up looking at repositories, not just individual C# files:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is the most popular repository with C# code in it?&lt;/li&gt;
&lt;li&gt;Just how many files should you have in a repository?&lt;/li&gt;
&lt;li&gt;What are the most popular C# &lt;code&gt;class&lt;/code&gt; names?&lt;/li&gt;
&lt;li&gt;'Foo.cs', 'Program.cs' or something else, what's the most common file name?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want to try the queries for yourself (or find my mistakes), all of them are available in &lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752"&gt;this gist&lt;/a&gt;. There's a good chance that my regular expressions miss out some edge-cases, after all &lt;a href="https://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/"&gt;Regular Expressions: Now You Have Two Problems&lt;/a&gt;!!&lt;/p&gt;




&lt;h3&gt;
  
  
  Tabs or Spaces?
&lt;/h3&gt;

&lt;p&gt;In the entire data-set there are 5,885,933 files, but here we only include ones that have more than 10 lines starting with a tab or a space&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tabs&lt;/th&gt;
&lt;th&gt;Tabs %&lt;/th&gt;
&lt;th&gt;Spaces&lt;/th&gt;
&lt;th&gt;Spaces %&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;799,055&lt;/td&gt;
&lt;td&gt;17.15%&lt;/td&gt;
&lt;td&gt;3,859,528&lt;/td&gt;
&lt;td&gt;82.85%&lt;/td&gt;
&lt;td&gt;4,658,583&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Clearly, C# developers (on GitHub) prefer &lt;strong&gt;Spaces&lt;/strong&gt; over &lt;strong&gt;Tabs&lt;/strong&gt;, let the endless debates continue!! (I think &lt;em&gt;some&lt;/em&gt; of this can be explained by the fact that Visual Studio &lt;a href="https://blogs.msdn.microsoft.com/zainnab/2010/09/08/insert-spaces-vs-keep-tabs/"&gt;uses 'spaces' by default&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;If you want to see how C# compares to other programming languages, take a look at &lt;a href="https://medium.com/@hoffa/400-000-github-repositories-1-billion-files-14-terabytes-of-code-spaces-or-tabs-7cfe0b5dd7fd"&gt;400,000 GitHub repositories, 1 billion files, 14 terabytes of code: Spaces or Tabs?&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;regions&lt;/code&gt;: 'should be banned' or 'okay in some cases'?
&lt;/h3&gt;

&lt;p&gt;It turns out that there are an impressive &lt;strong&gt;712,498&lt;/strong&gt; C# files (out of 5.8 million) that contain at least one &lt;code&gt;#region&lt;/code&gt; statement (&lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752#regions"&gt;query used&lt;/a&gt;), that's just over 12%. (I'm hoping that a lot of those files have been auto-generated by a tool!)&lt;/p&gt;

&lt;h3&gt;
  
  
  'K&amp;amp;R' or 'Allman', where do C# devs like to put their braces?
&lt;/h3&gt;

&lt;p&gt;C# developers overwhelmingly prefer putting an opening brace &lt;code&gt;{&lt;/code&gt; on it's own line (&lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752#brace_placement"&gt;query used&lt;/a&gt;)&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;separate line&lt;/th&gt;
&lt;th&gt;same line&lt;/th&gt;
&lt;th&gt;same line (initializer)&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;total (with brace)&lt;/th&gt;
&lt;th&gt;total (all code)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;81,306,320 (67%)&lt;/td&gt;
&lt;td&gt;40,044,603 (33%)&lt;/td&gt;
&lt;td&gt;3,631,947 (2.99%)&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;121,350,923 (15.32%)&lt;/td&gt;
&lt;td&gt;792,166,632&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;('same line initializers' include code like &lt;code&gt;new { Name = "", .. }&lt;/code&gt;, &lt;code&gt;new [] { 1, 2, 3.. }&lt;/code&gt;) &lt;/p&gt;

&lt;h3&gt;
  
  
  Do C# developers like writing functional code?
&lt;/h3&gt;

&lt;p&gt;This is slightly unscientific, but I wanted to see how widely the &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/lambda-operator"&gt;Lambda Operator&lt;/a&gt; &lt;code&gt;=&amp;gt;&lt;/code&gt; is used in C# code (&lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752#lambdas"&gt;query&lt;/a&gt;). Yes, I know, if you want to write functional code on .NET you really should use F#, but C# has become more 'functional' over the years and I wanted to see how much code was taking advantage of that.&lt;/p&gt;

&lt;p&gt;Here's the raw percentiles:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Percentile&lt;/th&gt;
&lt;th&gt;% of lines using lambdas&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;0.51&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;25&lt;/td&gt;
&lt;td&gt;1.14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;2.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;75&lt;/td&gt;
&lt;td&gt;5.26&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;90&lt;/td&gt;
&lt;td&gt;9.95&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;95&lt;/td&gt;
&lt;td&gt;14.29&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;28.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So we can say that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50% of all the C# code on GitHub uses &lt;code&gt;=&amp;gt;&lt;/code&gt; on 2.44% (or less) of their lines.&lt;/li&gt;
&lt;li&gt;10% of all C# files have lambdas on almost 1 in 10 of their lines&lt;/li&gt;
&lt;li&gt;5% use &lt;code&gt;=&amp;gt;&lt;/code&gt; on 1 in 7 lines (14.29%)&lt;/li&gt;
&lt;li&gt;1% of files have lambdas on over 1 in 3 lines (28%) of their lines of code, that's pretty impressive!&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Which &lt;code&gt;using&lt;/code&gt; statements are most widely used?
&lt;/h3&gt;

&lt;p&gt;Now on to some a bit more substantial, what are the most widely used &lt;code&gt;using&lt;/code&gt; statements in C# code?&lt;/p&gt;

&lt;p&gt;The top 10 looks like this (the &lt;a href="https://gist.github.com/mattwarren/be5df65729b0188d31463e3f143ba886"&gt;full results are available&lt;/a&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;using statement&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;using System.Collections.Generic;&lt;/td&gt;
&lt;td&gt;1,780,646&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System;&lt;/td&gt;
&lt;td&gt;1,477,019&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Linq;&lt;/td&gt;
&lt;td&gt;1,319,830&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Text;&lt;/td&gt;
&lt;td&gt;902,165&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Threading.Tasks;&lt;/td&gt;
&lt;td&gt;628,195&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Runtime.InteropServices;&lt;/td&gt;
&lt;td&gt;431,867&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.IO;&lt;/td&gt;
&lt;td&gt;407,848&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Runtime.CompilerServices;&lt;/td&gt;
&lt;td&gt;338,686&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Collections;&lt;/td&gt;
&lt;td&gt;289,867&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Reflection;&lt;/td&gt;
&lt;td&gt;218,369&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;However, &lt;a href="https://twitter.com/davkean/status/917523113587257344"&gt;as was pointed out&lt;/a&gt;, the top 5 are included by default when you add a new file in Visual Studio and many people wouldn't remove them. The same applies to 'System.Runtime.InteropServices' and 'System.Runtime.CompilerServices' which are include in 'AssemblyInfo.cs` by default.&lt;/p&gt;

&lt;p&gt;So if we adjust the list to take account of this, the top 10 looks like so:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;using statement&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;using System.IO;&lt;/td&gt;
&lt;td&gt;407,848&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Collections;&lt;/td&gt;
&lt;td&gt;289,867&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Reflection;&lt;/td&gt;
&lt;td&gt;218,369&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Diagnostics;&lt;/td&gt;
&lt;td&gt;201,341&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Threading;&lt;/td&gt;
&lt;td&gt;179,168&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.ComponentModel;&lt;/td&gt;
&lt;td&gt;160,681&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Web;&lt;/td&gt;
&lt;td&gt;160,323&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Windows.Forms;&lt;/td&gt;
&lt;td&gt;137,003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Globalization;&lt;/td&gt;
&lt;td&gt;132,113&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Drawing;&lt;/td&gt;
&lt;td&gt;127,033&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally, an interesting list is the top 10 using statements that aren't &lt;code&gt;System&lt;/code&gt;, &lt;code&gt;Microsoft&lt;/code&gt; or &lt;code&gt;Windows&lt;/code&gt; namespaces:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;using statement&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;using NUnit.Framework;&lt;/td&gt;
&lt;td&gt;119,463&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using UnityEngine;&lt;/td&gt;
&lt;td&gt;117,673&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using Xunit;&lt;/td&gt;
&lt;td&gt;99,099&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using System.Web.Mvc;&lt;/td&gt;
&lt;td&gt;87,622&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using Newtonsoft.Json;&lt;/td&gt;
&lt;td&gt;81,675&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using Newtonsoft.Json.Linq;&lt;/td&gt;
&lt;td&gt;29,416&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using Moq;&lt;/td&gt;
&lt;td&gt;23,546&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using UnityEngine.UI;&lt;/td&gt;
&lt;td&gt;20,355&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using UnityEditor;&lt;/td&gt;
&lt;td&gt;19,937&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;using Amazon.Runtime;&lt;/td&gt;
&lt;td&gt;18,941&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What NuGet packages are most often included in a .NET project?
&lt;/h3&gt;

&lt;p&gt;It turns out that there is also a separate dataset containing all the 'packages.config' files on GitHub, it's called &lt;a href="https://bigquery.cloud.google.com/table/fh-bigquery:github_extracts.contents_net_packages_config"&gt;contents_net_packages_config&lt;/a&gt; and has 104,808 entries. By querying this we can see that &lt;a href="https://www.newtonsoft.com/json"&gt;Json.Net&lt;/a&gt; is the clear winner!!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;package&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Newtonsoft.Json&lt;/td&gt;
&lt;td&gt;45,055&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.Web.Infrastructure&lt;/td&gt;
&lt;td&gt;16,022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.Razor&lt;/td&gt;
&lt;td&gt;15,109&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.WebPages&lt;/td&gt;
&lt;td&gt;14,495&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.Mvc&lt;/td&gt;
&lt;td&gt;14,236&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EntityFramework&lt;/td&gt;
&lt;td&gt;14,191&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.WebApi.Client&lt;/td&gt;
&lt;td&gt;13,480&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.WebApi.Core&lt;/td&gt;
&lt;td&gt;12,210&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.Net.Http&lt;/td&gt;
&lt;td&gt;11,625&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;jQuery&lt;/td&gt;
&lt;td&gt;10,646&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.Bcl.Build&lt;/td&gt;
&lt;td&gt;10,641&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.Bcl&lt;/td&gt;
&lt;td&gt;10,349&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NUnit&lt;/td&gt;
&lt;td&gt;10,341&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Owin&lt;/td&gt;
&lt;td&gt;9,681&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.Owin&lt;/td&gt;
&lt;td&gt;9,202&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.WebApi.WebHost&lt;/td&gt;
&lt;td&gt;9,007&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebGrease&lt;/td&gt;
&lt;td&gt;8,743&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.Web.Optimization&lt;/td&gt;
&lt;td&gt;8,721&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft.AspNet.WebApi&lt;/td&gt;
&lt;td&gt;8,179&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  How many lines of code (LOC) are in a typical C# file?
&lt;/h3&gt;

&lt;p&gt;Are C# developers prone to creating huge files that go one for 1000's of lines? Well some are but fortunately it's the minority of us!!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/10/Percentiles%20of%20lines%20of%20code%20per%20file.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M10pUGsf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/10/Percentiles%2520of%2520lines%2520of%2520code%2520per%2520file.png" alt="Percentiles of lines of code per file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the Y-axis is 'lines of code' and is logarithmic, the &lt;a href="https://gist.github.com/mattwarren/c810abe0c1ea152b60632c5987161aa4"&gt;raw data is available&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Oh dear, Uncle Bob isn't going to be happy, whilst 96% of the files have 509 LOC of less, the other 4% don't!! From &lt;a href="http://amzn.to/2yezlZH"&gt;Clean Code&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/10/Uncle%20Bob%20-%20Clean%20Code%20-%20Number%20of%20lines%20of%20code%20in%20a%20file.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TrZGKNYI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/10/Uncle%2520Bob%2520-%2520Clean%2520Code%2520-%2520Number%2520of%2520lines%2520of%2520code%2520in%2520a%2520file.png" alt="Uncle Bob - Clean Code - Number of lines of code in a file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And in case you're wondering, here's the Top 10 longest C# files!!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Lines&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MarMot/Input/test.marmot.cs&lt;/td&gt;
&lt;td&gt;92663&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;src/CodenameGenerator/WordRepos/LastNamesRepository.cs&lt;/td&gt;
&lt;td&gt;88810&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cs_inputtest/cs_02_7000.cs&lt;/td&gt;
&lt;td&gt;63004&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cs_inputtest/cs_02_6000.cs&lt;/td&gt;
&lt;td&gt;54004&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;src/ML NET20/Utility/UserName.cs&lt;/td&gt;
&lt;td&gt;52014&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MWBS/Dictionary/DefaultWordDictionary.cs&lt;/td&gt;
&lt;td&gt;48912&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sources/Accord.Math/Matrix/Matrix.Comparisons1.Generated.cs&lt;/td&gt;
&lt;td&gt;48407&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UrduProofReader/UrduLibs/Utils.cs&lt;/td&gt;
&lt;td&gt;48255&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cs_inputtest/cs_02_5000.cs&lt;/td&gt;
&lt;td&gt;45004&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;css/style.cs&lt;/td&gt;
&lt;td&gt;44366&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What is the most widely thrown &lt;code&gt;Exception&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;There's a few interesting results in &lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752#most-popular-execeptions"&gt;this query&lt;/a&gt;, for instance who knew that so many &lt;code&gt;ApplicationExceptions&lt;/code&gt; were thrown and &lt;code&gt;NotSupportedException&lt;/code&gt; being so high up the list is a bit worrying!!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exception&lt;/th&gt;
&lt;th&gt;count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;throw new ArgumentNullException&lt;/td&gt;
&lt;td&gt;699,526&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new ArgumentException&lt;/td&gt;
&lt;td&gt;361,616&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new NotImplementedException&lt;/td&gt;
&lt;td&gt;340,361&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new InvalidOperationException&lt;/td&gt;
&lt;td&gt;260,792&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new ArgumentOutOfRangeException&lt;/td&gt;
&lt;td&gt;160,640&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new NotSupportedException&lt;/td&gt;
&lt;td&gt;110,019&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new HttpResponseException&lt;/td&gt;
&lt;td&gt;74,498&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new ValidationException&lt;/td&gt;
&lt;td&gt;35,615&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new ObjectDisposedException&lt;/td&gt;
&lt;td&gt;31,129&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new ApplicationException&lt;/td&gt;
&lt;td&gt;30,849&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new UnauthorizedException&lt;/td&gt;
&lt;td&gt;21,133&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new FormatException&lt;/td&gt;
&lt;td&gt;19,510&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new SerializationException&lt;/td&gt;
&lt;td&gt;17,884&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new IOException&lt;/td&gt;
&lt;td&gt;15,779&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new IndexOutOfRangeException&lt;/td&gt;
&lt;td&gt;14,778&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new NullReferenceException&lt;/td&gt;
&lt;td&gt;12,372&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new InvalidDataException&lt;/td&gt;
&lt;td&gt;12,260&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new ApiException&lt;/td&gt;
&lt;td&gt;11,660&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;throw new InvalidCastException&lt;/td&gt;
&lt;td&gt;10,510&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  'async/await all the things' or not?
&lt;/h3&gt;

&lt;p&gt;The addition of the &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; keywords to the C# language makes writing &lt;a href="https://docs.microsoft.com/en-us/dotnet/csharp/async"&gt;asynchronous code much easier&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;` csharp&lt;br&gt;
public async Task GetDotNetCountAsync()&lt;br&gt;
{&lt;br&gt;
    // Suspends GetDotNetCountAsync() to allow the caller (the web server)&lt;br&gt;
    // to accept another request, rather than blocking on this one.&lt;br&gt;
    var html = await _httpClient.DownloadStringAsync("&lt;a href="http://dotnetfoundation.org%22"&gt;http://dotnetfoundation.org"&lt;/a&gt;);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return Regex.Matches(html, ".NET").Count;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;But how much is it used? Using the query below:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;SQL&lt;br&gt;
SELECT Count(*) count&lt;br&gt;
FROM&lt;br&gt;
  [fh-bigquery:github_extracts.contents_net_cs]&lt;br&gt;
WHERE&lt;br&gt;
  REGEXP_MATCH(content, r'\sasync\s|\sawait\s')&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I found that there are &lt;strong&gt;218,643&lt;/strong&gt; files (out of 5,885,933) that have at least one usage of &lt;code&gt;async&lt;/code&gt; or &lt;code&gt;await&lt;/code&gt; in them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do C# developers like using the &lt;code&gt;var&lt;/code&gt; keyword?
&lt;/h3&gt;

&lt;p&gt;Less that they use &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;, there are &lt;strong&gt;130,590&lt;/strong&gt; files that have at least one usage of the &lt;code&gt;var&lt;/code&gt; keyword &lt;/p&gt;




&lt;h3&gt;
  
  
  Just how many files should you have in a repository?
&lt;/h3&gt;

&lt;p&gt;90% of the repositories (that have any C# files) have 95 files or less. 95% have 170 files or less and 99% have 535 files or less.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mattwarren.org/images/2017/10/Number%20of%20Files%20per%20Repository.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4tYNqZUp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/10/Number%2520of%2520Files%2520per%2520Repository.png" alt="Number of C# Files per Repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(again the Y-axis (# files) is logarithmic)&lt;/p&gt;

&lt;p&gt;The top 10 largest repositories, by number of C# files are shown below:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Repository&lt;/th&gt;
&lt;th&gt;# Files&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/xen2/mcs"&gt;https://github.com/xen2/mcs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;23389&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/mater06/LEGOChimaOnlineReloaded"&gt;https://github.com/mater06/LEGOChimaOnlineReloaded&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;14241&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/Microsoft/referencesource"&gt;https://github.com/Microsoft/referencesource&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;13051&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/dotnet/corefx"&gt;https://github.com/dotnet/corefx&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;10652&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/apo-j/Projects_Working"&gt;https://github.com/apo-j/Projects_Working&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;10185&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/Microsoft/CodeContracts"&gt;https://github.com/Microsoft/CodeContracts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;9338&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/drazenzadravec/nequeo"&gt;https://github.com/drazenzadravec/nequeo&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;8060&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/ClearCanvas/ClearCanvas"&gt;https://github.com/ClearCanvas/ClearCanvas&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;7946&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/mwilliamson-firefly/aws-sdk-net"&gt;https://github.com/mwilliamson-firefly/aws-sdk-net&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;7860&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/151706061/MacroMedicalSystem"&gt;https://github.com/151706061/MacroMedicalSystem&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;7765&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What is the most popular repository with C# code in it?
&lt;/h3&gt;

&lt;p&gt;This time we are going to look at the most popular repositories (based on GitHub 'stars') that contain at least 50 C# files (&lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752#most_popular_c_repos"&gt;query used&lt;/a&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;repo&lt;/th&gt;
&lt;th&gt;stars&lt;/th&gt;
&lt;th&gt;files&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/grpc/grpc"&gt;https://github.com/grpc/grpc&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;11075&lt;/td&gt;
&lt;td&gt;237&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/dotnet/coreclr"&gt;https://github.com/dotnet/coreclr&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;8576&lt;/td&gt;
&lt;td&gt;6503&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/dotnet/roslyn"&gt;https://github.com/dotnet/roslyn&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;8422&lt;/td&gt;
&lt;td&gt;6351&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/facebook/yoga"&gt;https://github.com/facebook/yoga&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;8046&lt;/td&gt;
&lt;td&gt;73&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/bazelbuild/bazel"&gt;https://github.com/bazelbuild/bazel&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;7123&lt;/td&gt;
&lt;td&gt;132&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/dotnet/corefx"&gt;https://github.com/dotnet/corefx&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;7115&lt;/td&gt;
&lt;td&gt;10652&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/SeleniumHQ/selenium"&gt;https://github.com/SeleniumHQ/selenium&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;7024&lt;/td&gt;
&lt;td&gt;512&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/Microsoft/WinObjC"&gt;https://github.com/Microsoft/WinObjC&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;6184&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/qianlifeng/Wox"&gt;https://github.com/qianlifeng/Wox&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5674&lt;/td&gt;
&lt;td&gt;207&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/Wox-launcher/Wox"&gt;https://github.com/Wox-launcher/Wox&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5674&lt;/td&gt;
&lt;td&gt;142&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/ShareX/ShareX"&gt;https://github.com/ShareX/ShareX&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5336&lt;/td&gt;
&lt;td&gt;766&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/Microsoft/Windows-universal-samples"&gt;https://github.com/Microsoft/Windows-universal-samples&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;5130&lt;/td&gt;
&lt;td&gt;1501&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/NancyFx/Nancy"&gt;https://github.com/NancyFx/Nancy&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;3701&lt;/td&gt;
&lt;td&gt;957&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/chocolatey/choco"&gt;https://github.com/chocolatey/choco&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;3432&lt;/td&gt;
&lt;td&gt;248&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/JamesNK/Newtonsoft.Json"&gt;https://github.com/JamesNK/Newtonsoft.Json&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;3340&lt;/td&gt;
&lt;td&gt;650&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Interesting that the top spot is a Google Repository! (the C# files in it are sample code for using the GRPC library from .NET) &lt;/p&gt;

&lt;h3&gt;
  
  
  What are the most popular C# &lt;code&gt;class&lt;/code&gt; names?
&lt;/h3&gt;

&lt;p&gt;Assuming that I got the &lt;a href="https://gist.github.com/mattwarren/42100ffe488bce5d48be22b59124b752#class_names"&gt;regex correct&lt;/a&gt;, the most popular C# &lt;code&gt;class&lt;/code&gt; names are the following:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class name&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;class C&lt;/td&gt;
&lt;td&gt;182480&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class Program&lt;/td&gt;
&lt;td&gt;163462&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class Test&lt;/td&gt;
&lt;td&gt;50593&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class Settings&lt;/td&gt;
&lt;td&gt;40841&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class Resources&lt;/td&gt;
&lt;td&gt;39345&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class A&lt;/td&gt;
&lt;td&gt;34687&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class App&lt;/td&gt;
&lt;td&gt;28462&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class B&lt;/td&gt;
&lt;td&gt;24246&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class Startup&lt;/td&gt;
&lt;td&gt;18238&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;class Foo&lt;/td&gt;
&lt;td&gt;15198&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Yay for &lt;code&gt;Foo&lt;/code&gt;, just sneaking into the Top 10!! &lt;/p&gt;

&lt;h3&gt;
  
  
  'Foo.cs', 'Program.cs' or something else, what's the most common file name?
&lt;/h3&gt;

&lt;p&gt;Finally lets look at the different &lt;code&gt;class&lt;/code&gt; names used, as with the &lt;code&gt;using&lt;/code&gt; statement they are dominated by the default ones used in the Visual Studio templates:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AssemblyInfo.cs&lt;/td&gt;
&lt;td&gt;386822&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Program.cs&lt;/td&gt;
&lt;td&gt;105280&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resources.Designer.cs&lt;/td&gt;
&lt;td&gt;40881&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Settings.Designer.cs&lt;/td&gt;
&lt;td&gt;35392&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App.xaml.cs&lt;/td&gt;
&lt;td&gt;21928&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global.asax.cs&lt;/td&gt;
&lt;td&gt;16133&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Startup.cs&lt;/td&gt;
&lt;td&gt;14564&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HomeController.cs&lt;/td&gt;
&lt;td&gt;13574&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RouteConfig.cs&lt;/td&gt;
&lt;td&gt;11278&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MainWindow.xaml.cs&lt;/td&gt;
&lt;td&gt;11169&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  More Information
&lt;/h2&gt;

&lt;p&gt;As always, if you've read this far your present is yet more blog posts to read, enjoy!!&lt;/p&gt;

&lt;h3&gt;
  
  
  How BigQuery Works (only put in at the end of the blog post)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/big-data/2016/01/bigquery-under-the-hood"&gt;BigQuery under the hood&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/big-data/2016/04/inside-capacitor-bigquerys-next-generation-columnar-storage-format"&gt;Inside Capacitor, BigQuery’s next-generation columnar storage format&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/big-data/2016/08/in-memory-query-execution-in-google-bigquery"&gt;In-memory query execution in Google BigQuery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/big-data/2017/07/counting-uniques-faster-in-bigquery-with-hyperloglog"&gt;Counting uniques faster in BigQuery with HyperLogLog++&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/big-data/2017/10/separation-of-compute-and-state-in-google-bigquery-and-cloud-dataflow-and-why-it-matters"&gt;Separation of compute and state in Google BigQuery and Cloud Dataflow (and why it matters)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gcppodcast.com/post/episode-94-big-query-under-the-hood-with-tino-tereshko-and-jordan-tigani/"&gt;#94 BigQuery Under the Hood with Tino Tereshko and Jordan Tigani&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.atscale.com/bi-benchmarks-with-google-bigquery"&gt;TECH TALK: BI Performance Benchmarks with Google BigQuery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  BigQuery analysis of other Programming Languages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/google-cloud/analyzing-go-code-with-bigquery-485c70c3b451"&gt;Analyzing Go code with BigQuery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@sAbakumoff/using-bigquery-github-data-to-rank-npm-repositories-ecf8947a1182"&gt;Using BigQuery GitHub data to rank npm repositories&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@sAbakumoff/using-bigquery-github-data-to-find-out-open-source-software-development-trends-e288a2ca3e6b"&gt;Using BigQuery GitHub data to find out open source software development trends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cloud.google.com/blog/big-data/2016/09/using-bigquery-to-analyze-php-on-github"&gt;Using BigQuery to Analyze PHP on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://labs.steren.fr/2017/08/17/extracting-all-go-regular-expressions-found-on-github/"&gt;Extracting all Go regular expressions found on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kozikow.com/2016/06/05/more-advanced-github-code-search/"&gt;More advanced github code search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kozikow.com/2016/07/01/top-angular-directives-on-github/"&gt;Top angular directives on github, including custom directives&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.takipi.com/779236-java-logging-statements-1313-github-repositories-error-warn-or-fatal/"&gt;779,236 Java Logging Statements, 1,313 GitHub Repositories: ERROR, WARN or FATAL?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/bigquery/"&gt;/r/BigQuery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>c</category>
    </item>
    <item>
      <title>'Lowering' in the C# Compiler (and what happens when you misuse it)</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Fri, 26 May 2017 15:29:59 +0000</pubDate>
      <link>https://dev.to/mattwarren/lowering-in-the-c-compiler-and-what-happens-when-you-misuse-it</link>
      <guid>https://dev.to/mattwarren/lowering-in-the-c-compiler-and-what-happens-when-you-misuse-it</guid>
      <description>

&lt;p&gt;Turns out that what I'd always thought of as "&lt;em&gt;Compiler magic&lt;/em&gt;" or "&lt;em&gt;Syntactic sugar&lt;/em&gt;" is actually known by the technical term '&lt;em&gt;Lowering&lt;/em&gt;' and the C# compiler (a.k.a &lt;a href="https://github.com/dotnet/roslyn"&gt;Roslyn&lt;/a&gt;) uses it extensively.&lt;/p&gt;

&lt;p&gt;But what is it? Well this quote from &lt;a href="http://www.drdobbs.com/architecture-and-design/so-you-want-to-write-your-own-language/240165488?pgno=2"&gt;So You Want To Write Your Own Language?&lt;/a&gt; gives us some idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lowering&lt;/strong&gt;&lt;br&gt;
One semantic technique that is obvious in hindsight (but took Andrei Alexandrescu to point out to me) is called "lowering." It consists of, internally, rewriting more complex semantic constructs in terms of simpler ones. For example, while loops and foreach loops can be rewritten in terms of for loops. Then, the rest of the code only has to deal with for loops. This turned out to uncover a couple of latent bugs in how while loops were implemented in D, and so was a nice win. It's also used to rewrite scope guard statements in terms of try-finally statements, etc. Every case where this can be found in the semantic processing will be win for the implementation.&lt;/p&gt;

&lt;p&gt;-- by &lt;a href="https://en.wikipedia.org/wiki/Walter_Bright"&gt;Walter Bright&lt;/a&gt; (author of the D programming language)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But if you're still not sure what it means, have a read of Eric Lippert's post on the subject, &lt;a href="https://ericlippert.com/2014/04/28/lowering-in-language-design-part-one/"&gt;Lowering in language design&lt;/a&gt;, which contains this quote:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A common technique along the way though is to have the compiler “lower from high-level language features to low-level language features in the &lt;em&gt;same language&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;As an aside, if you like reading about the &lt;strong&gt;Roslyn compiler source&lt;/strong&gt; you may like these other posts that I've written:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="%7B%7B%20base%20%7D%7D/2016/10/26/How-does-the-fixed-keyword-work/?recommended=1"&gt;How does the 'fixed' keyword work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="%7B%7B%20base%20%7D%7D/2014/06/05/roslyn-code-base-performance-lessons-part-1/?recommended=1"&gt;Roslyn code base - performance lessons (part 1)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="%7B%7B%20base%20%7D%7D/2014/06/10/roslyn-code-base-performance-lessons-part-2/?recommended=1"&gt;Roslyn code base - performance lessons (part 2)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What does 'Lowering' look like?
&lt;/h2&gt;

&lt;p&gt;The C# compiler has used lowering for a while, one of the oldest or most recognised examples is when this code:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;M&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;is turned into this&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CompilerGenerated&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;__current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;l__initialThreadId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="n"&gt;__this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;__3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;__current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Current&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;get&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;__current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;d__0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;l__initialThreadId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;IDisposable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MoveNext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__2&lt;/span&gt;&lt;span class="p"&gt;++;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__2&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;__3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;s__2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;__current&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="n"&gt;__3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotSupportedException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;IEnumerator&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__0&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;l__initialThreadId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentManagedThreadId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;__state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;d__0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="n"&gt;__this&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="n"&gt;__this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DebuggerHidden&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;IEnumerator&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnumerator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;IteratorStateMachine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__0&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;M&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;d__0&lt;/span&gt; &lt;span class="n"&gt;expr_07&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;d__0&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;expr_07&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="n"&gt;__this&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;expr_07&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yikes, I'm glad we don't have to write that code ourselves!! There's an entire state-machine in there, built to allow our original code to be halted/resumed each time round the loop (at the 'yield' statement).&lt;/p&gt;




&lt;h2&gt;
  
  
  The C# compiler and 'Lowering'
&lt;/h2&gt;

&lt;p&gt;But it turns out that the Roslyn compiler does &lt;em&gt;a lot&lt;/em&gt; more 'lowering' than you might think. If you take a look at the code under &lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/CSharp/Portable/Lowering"&gt;'/src/Compilers/CSharp/Portable/Lowering'&lt;/a&gt; (VB.NET &lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/VisualBasic/Portable/Lowering"&gt;equivalent here&lt;/a&gt;), you see the following folders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter"&gt;AsyncRewriter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter"&gt;IteratorRewriter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/CSharp/Portable/Lowering/LambdaRewriter"&gt;LambdaRewriter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter"&gt;StateMachineRewriter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which correspond to some C# language features you might be familar with, such as 'lambdas', i.e. &lt;code&gt;x =&amp;gt; x.Name &amp;gt; 5&lt;/code&gt;, 'iterators' used by &lt;code&gt;yield&lt;/code&gt; (above) and the &lt;code&gt;async&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;However if we look at bit deeper, under the &lt;a href="https://github.com/dotnet/roslyn/tree/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter"&gt;'LocalRewriter' folder&lt;/a&gt; we can see lots more scenarios that we might never have considered 'lowering', such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_DelegateCreationExpression.cs"&gt;Delegate creation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_Event.cs"&gt;Events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_FixedStatement.cs"&gt;'fixed' keyword&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ForEachStatement.cs"&gt;ForEach loops&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsOperator.cs"&gt;'Is' operator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_LockStatement.cs"&gt;'lock' statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_NullCoalescingOperator.cs"&gt;'?.' a.k.a the null-coalescing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StackAlloc.cs"&gt;'stackalloc' keyword&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_StringConcat.cs"&gt;'String.Concat()'&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_SwitchStatement.cs"&gt;'switch' statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_ThrowStatement.cs"&gt;'throw' expression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UsingStatement.cs"&gt;'using' statement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;even a &lt;a href="https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_WhileStatement.cs"&gt;'while' loop&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So a big thank-you is due to all the past and present C# language developers and designers, they did all this work for us. Imagine that C# didn't have all these high-level features, we'd be stuck writing them by hand. &lt;/p&gt;

&lt;p&gt;It would be like writing &lt;strong&gt;Java&lt;/strong&gt; :-)&lt;/p&gt;




&lt;h2&gt;
  
  
  What happens when you misuse it
&lt;/h2&gt;

&lt;p&gt;But of course the real fun part is 'misusing' or outright 'abusing' the compiler. So I set up a little &lt;a href="https://twitter.com/matthewwarren/status/867753577346985984"&gt;twitter competition&lt;/a&gt; just how much 'lowering' could we get the compiler to do for us (i.e the highest ratio of 'input' lines of code to 'output' lines).&lt;/p&gt;

&lt;p&gt;It had the following rules (see &lt;a href="https://gist.github.com/mattwarren/3c7cfaa245effc0a318b87f1ee5dc153"&gt;this gist&lt;/a&gt; for more info):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can have as many lines as you want within method &lt;code&gt;M()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;No single line can be longer than 100 chars&lt;/li&gt;
&lt;li&gt;To get your score, divide the '# of expanded lines' by the '# of original line(s)'

&lt;ol&gt;
&lt;li&gt;Based on the default &lt;strong&gt;output&lt;/strong&gt; formatting of &lt;a href="https://sharplab.io/#b:master/f:r/"&gt;https://sharplab.io&lt;/a&gt;, no re-formatting allowed!!&lt;/li&gt;
&lt;li&gt;But you can format the &lt;strong&gt;intput&lt;/strong&gt; however you want, i.e. make use of the full 100 chars&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;Must compile with no warnings on &lt;a href="https://sharplab.io/#b:master/f:r/"&gt;&lt;/a&gt;&lt;a href="https://sharplab.io"&gt;https://sharplab.io&lt;/a&gt; (allows C# 7 features)

&lt;ol&gt;
&lt;li&gt;But doesn't have to do anything sensible when run&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;You cannot modify the code that is already there, i.e. &lt;code&gt;public class C {}&lt;/code&gt; and &lt;code&gt;public void M()&lt;/code&gt;

&lt;ol&gt;
&lt;li&gt;Cannot just add &lt;code&gt;async&lt;/code&gt; to &lt;code&gt;public void M()&lt;/code&gt;, that's too easy!!&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;You can add new &lt;code&gt;using ...&lt;/code&gt; declarations, these do not count towards the line count&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For instance with the following code (interactive version available on &lt;a href="https://sharplab.io/#b:master/f:r/K4Zwlgdg5gBAygTxAFwKYFsDcBYAUAB2ACMAbMAYxnJIEMQQYBhGAbzxg5kNIpgDcA9mAAmMALIAKAJSt2neQDFgEcgB4UAJ0hQAfDDQoYAXhjTjegESkaACws5c8gL54nQA"&gt;sharplab.io&lt;/a&gt;):&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;M&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"blah"&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This counts as &lt;strong&gt;1&lt;/strong&gt; line of original code (only code inside method &lt;code&gt;M()&lt;/code&gt; is counted)&lt;/p&gt;

&lt;p&gt;This expands to &lt;strong&gt;23&lt;/strong&gt; lines (again only lines of code inside the braces (&lt;code&gt;{&lt;/code&gt;, &lt;code&gt;}&lt;/code&gt;) of &lt;code&gt;class C&lt;/code&gt; are counted. &lt;/p&gt;

&lt;p&gt;Giving a &lt;strong&gt;total score&lt;/strong&gt; of &lt;strong&gt;23&lt;/strong&gt; (23 / 1)&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;CompilerGenerated&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Serializable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;c&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;__0_0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Note: this type is marked as 'beforefieldinit'.&lt;/span&gt;
            &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;b__0_0&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"blah"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;M&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;__0_0&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;__0_0&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="m"&gt;9.&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;b__0_0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;p&gt;The first place entry was the following entry from &lt;a href="https://gist.github.com/mattwarren/3c7cfaa245effc0a318b87f1ee5dc153#gistcomment-2106237"&gt;Schabse Laks&lt;/a&gt;, which contains 9 lines-of-code inside the &lt;code&gt;M()&lt;/code&gt; method:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Linq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Collections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;M&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;()());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;this expands to an impressive &lt;strong&gt;7964&lt;/strong&gt; lines of code (yep you read that right!!) for a score of &lt;strong&gt;885&lt;/strong&gt; (7964 / 9). The main trick he figured out was that adding more lines to the input increased the score, i.e is scales superlinearly. Although it you &lt;a href="https://twitter.com/Schabse/status/867809080714313729"&gt;take things too far&lt;/a&gt; the compiler bails out with a pretty impressive error message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;error CS8078: An expression is too long or complex to compile&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here's the Top 6 top results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Submitter&lt;/th&gt;
&lt;th&gt;Entry&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://twitter.com/Schabse"&gt;Schabse Laks&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://twitter.com/Schabse/status/867808817655840768"&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;885&lt;/strong&gt; (7964 / 9)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://twitter.com/a_tessenr"&gt;Andrey Dyatlov&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://twitter.com/a_tessenr/status/867776073735454721"&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;778&lt;/strong&gt; (778 / 1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://twitter.com/alrz_h"&gt;alrz&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://twitter.com/alrz_h/status/867780509627273216"&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;755&lt;/strong&gt; (755 / 1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://twitter.com/andygocke"&gt;Andy Gocke&lt;/a&gt; *&lt;/td&gt;
&lt;td&gt;&lt;a href="https://twitter.com/andygocke/status/867773813907312640"&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;633&lt;/strong&gt; (633 / 1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;a href="https://twitter.com/jaredpar"&gt;Jared Parsons&lt;/a&gt; *&lt;/td&gt;
&lt;td&gt;&lt;a href="https://twitter.com/jaredpar/status/867772979698049024"&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;461&lt;/strong&gt; (461 / 1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://twitter.com/jon_cham"&gt;Jonathan Chambers&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://twitter.com/jon_cham/status/867759359803228162"&gt;link&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;384&lt;/strong&gt; (384 / 1)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;*&lt;/code&gt; = member of the Roslyn compiler team (they're not disqualified, but maybe they should have some kind of handicap applied to 'even out' the playing field?)&lt;/p&gt;

&lt;h3&gt;
  
  
  Honourable mentions
&lt;/h3&gt;

&lt;p&gt;However there were some other entries that whilst they didn't make it into the Top 6, are still worth a mention due to the ingenuity involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uncovering a &lt;a href="https://twitter.com/a_tessenr/status/867765123745710080"&gt;complier bug&lt;/a&gt;, kudos to &lt;a href="https://twitter.com/a_tessenr"&gt;@a_tessenr&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/roslyn/issues/19778"&gt;GitHub bug report&lt;/a&gt; and &lt;a href="https://github.com/dotnet/roslyn/pull/19784/files"&gt;fix in the compiler&lt;/a&gt; that was done within a few hours!!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Hitting an &lt;a href="https://twitter.com/Schabse/status/867809080714313729"&gt;internal compiler limit&lt;/a&gt;, nice work by &lt;a href="https://twitter.com/Schabse"&gt;@Schabse&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The most &lt;a href="https://twitter.com/NickPalladinos/status/867764488958857216"&gt;elegant attempt&lt;/a&gt; featuring a &lt;code&gt;Y combinator&lt;/code&gt; by &lt;a href="https://twitter.com/NickPalladinos"&gt;@NickPalladinos&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://twitter.com/AdamSpeight2008/status/867800480478515200"&gt;Using VB.NET&lt;/a&gt; (hint: it didn't end well!!), but still a valiant attempt by &lt;a href="https://twitter.com/AdamSpeight2008"&gt;@AdamSpeight2008&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The most &lt;a href="https://twitter.com/leppie/status/867861870241226753"&gt;astheticially pleasing&lt;/a&gt; entry by &lt;a href="https://twitter.com/leppie"&gt;@leppie&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The post &lt;a href="http://mattwarren.org/2017/01/25/How-do-.NET-delegates-work/"&gt;'Lowering' in the C# Compiler (and what happens when you misuse it)&lt;/a&gt; appeared first on my blog &lt;a href="http://mattwarren.org"&gt;mattwarren.org&lt;/a&gt;&lt;/p&gt;


</description>
      <category>c</category>
      <category>opensource</category>
      <category>roslyn</category>
    </item>
    <item>
      <title>Arrays and the Common Language Runtime - a Very Special Relationship</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Fri, 19 May 2017 21:12:58 +0000</pubDate>
      <link>https://dev.to/mattwarren/arrays-and-the-clr---a-very-special-relationship</link>
      <guid>https://dev.to/mattwarren/arrays-and-the-clr---a-very-special-relationship</guid>
      <description>

&lt;p&gt;A while ago I wrote about the 'special relationship' that &lt;a href="http://mattwarren.org/2016/05/31/Strings-and-the-CLR-a-Special-Relationship/"&gt;exists between Strings and the CLR&lt;/a&gt;, well it turns out that Arrays and the CLR have an even deeper one, the type of closeness where you &lt;em&gt;hold hands on your first meeting&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.telegraph.co.uk/news/2017/01/27/theresa-may-donald-trump-prove-opposites-can-attract-uk-us-leaders/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HPk1rtO4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/05/Donald-Trump-Theresa-May.jpg" alt="Donald Trump and  Theresa May"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;As an aside, if you like reading about &lt;strong&gt;CLR internals&lt;/strong&gt; you may find these other posts interesting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/04/13/The-CLR-Thread-Pool-Thread-Injection-Algorithm/?devto-recommended=1"&gt;The CLR Thread Pool 'Thread Injection' Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/02/07/The-68-things-the-CLR-does-before-executing-a-single-line-of-your-code/?devto-recommended=1"&gt;The 68 things the CLR does before executing a single line of your code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2017/01/25/How-do-.NET-delegates-work/?devto-recommended=1"&gt;How do .NET delegates work?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2016/12/14/Why-is-Reflection-slow/?devto-recommended=1"&gt;Why is reflection slow?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mattwarren.org/2016/10/26/How-does-the-fixed-keyword-work/?devto-recommended=1"&gt;How does the 'fixed' keyword work?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Fundamental to the Common Language Runtime (CLR)
&lt;/h2&gt;

&lt;p&gt;Arrays are such a fundamental part of the CLR that they are included in the &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/dotnet-standards.md"&gt;ECMA specification&lt;/a&gt;, to make it clear that the &lt;em&gt;runtime&lt;/em&gt; has to implement them:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tic1ys-K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/05/Single-Dimensions%2520Arrays%2520%28Vectors%29%2520in%2520the%2520ECMA%2520Spec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tic1ys-K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/05/Single-Dimensions%2520Arrays%2520%28Vectors%29%2520in%2520the%2520ECMA%2520Spec.png" alt="Single-Dimensions Arrays (Vectors) in the ECMA Spec"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition, there are several &lt;a href="https://en.wikipedia.org/wiki/List_of_CIL_instructions"&gt;IL (Intermediate Language) instructions&lt;/a&gt; that specifically deal with arrays: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;newarr &amp;lt;etype&amp;gt;

&lt;ul&gt;
&lt;li&gt;Create a new array with elements of type etype.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;ldelem.ref

&lt;ul&gt;
&lt;li&gt;Load the element at index onto the top of the stack as an O. The type of the O is the same as the element type of the array pushed on the CIL stack.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;stelem &amp;lt;typeTok&amp;gt;

&lt;ul&gt;
&lt;li&gt;Replace array element at index with the value on the stack (also &lt;code&gt;stelem.i&lt;/code&gt;, &lt;code&gt;stelem.i1&lt;/code&gt;, &lt;code&gt;stelem.i2&lt;/code&gt;, &lt;code&gt;stelem.r4&lt;/code&gt; etc)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;ldlen

&lt;ul&gt;
&lt;li&gt;Push the length (of type native unsigned int) of array on the stack.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes sense because arrays are the building blocks of so many other data types, you want them to be available, well defined and efficient in a modern high-level language like C#. Without arrays you can't have lists, dictionaries, queues, stacks, trees, etc, they're all built on-top of arrays which provided low-level access to contiguous pieces of memory in a type-safe way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Memory and Type Safety
&lt;/h3&gt;

&lt;p&gt;This &lt;em&gt;memory&lt;/em&gt; and &lt;em&gt;type-safety&lt;/em&gt; is important because without it .NET couldn't be described as a 'managed runtime' and you'd be left having to deal with the types of issues you get when your are writing code in a more low-level language.&lt;/p&gt;

&lt;p&gt;More specifically, the CLR provide the following protections when you are using arrays (from the section on &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/intro-to-clr.md#memory-and-type-safety"&gt;Memory and Type Safety&lt;/a&gt; in the BOTR 'Intro to the CLR' page):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While a GC is necessary to ensure memory safety, it is not sufficient. The GC will not prevent the program from &lt;strong&gt;indexing off the end of an array&lt;/strong&gt; or accessing a field off the end of an object (possible if you compute the field's address using a base and offset computation). &lt;strong&gt;However, if we do prevent these cases, then we can indeed make it impossible for a programmer to create memory-unsafe programs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While the common intermediate language (CIL) does have operators that can fetch and set arbitrary memory (and thus violate memory safety), it also has the &lt;strong&gt;following memory-safe operators&lt;/strong&gt; and the CLR strongly encourages their use in most programming:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Field-fetch operators (LDFLD, STFLD, LDFLDA) that fetch (read), set and take the address of a field by name.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Array-fetch operators (LDELEM, STELEM, LDELEMA)&lt;/strong&gt; that fetch, set and take the address of an array element by index. &lt;strong&gt;All arrays include a tag specifying their length&lt;/strong&gt;. This facilitates an automatic bounds check before each access.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, from the section on &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/intro-to-clr.md#verifiable-code---enforcing-memory-and-type-safety"&gt;Verifiable Code - Enforcing Memory and Type Safety&lt;/a&gt; in the same BOTR page&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In practice, the number of run-time checks needed is actually very small. They include the following operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Casting a pointer to a base type to be a pointer to a derived type (the opposite direction can be checked statically)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Array bounds checks&lt;/strong&gt; (just as we saw for memory safety)&lt;/li&gt;
&lt;li&gt;Assigning an element in an &lt;strong&gt;array of pointers to a new (pointer) value&lt;/strong&gt;. This particular check is only required because &lt;strong&gt;CLR arrays have liberal casting rules&lt;/strong&gt; (more on that later...)&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;However you don't get this protection for free, there's a cost to pay:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that the need to do these checks places requirements on the runtime. In particular:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All memory in the GC heap must be tagged with its type (so the casting operator can be implemented). This type information must be available at runtime, and it must be rich enough to determine if casts are valid (e.g., the runtime needs to know the inheritance hierarchy). In fact, the first field in every object on the GC heap points to a runtime data structure that represents its type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All arrays must also have their size&lt;/strong&gt; (for bounds checking).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arrays must have complete type information&lt;/strong&gt; about their element type.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Implementation Details
&lt;/h2&gt;

&lt;p&gt;It turns out that large parts of the internal implementation of arrays is best described as &lt;em&gt;magic&lt;/em&gt;, this Stack Overflow &lt;a href="http://stackoverflow.com/questions/19914523/mystery-behind-system-array#comment29631862_19914523"&gt;comment from Marc Gravell sums it up nicely&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Arrays are basically voodoo. Because they pre-date generics, yet must allow on-the-fly type-creation (even in .NET 1.0), they are implemented using tricks, hacks, and sleight of hand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yep that's right, arrays were parametrised (i.e. generic) before generics even existed. That means you could create arrays such as &lt;code&gt;int[]&lt;/code&gt; and &lt;code&gt;string[]&lt;/code&gt;, long before you were able to write &lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt; or &lt;code&gt;List&amp;lt;string&amp;gt;&lt;/code&gt;, which only became possible in .NET 2.0.&lt;/p&gt;

&lt;h3&gt;
  
  
  Special helper classes
&lt;/h3&gt;

&lt;p&gt;All this &lt;em&gt;magic&lt;/em&gt; or &lt;em&gt;sleight of hand&lt;/em&gt; is made possible by 2 things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CLR breaking all the usual type-safety rules&lt;/li&gt;
&lt;li&gt;A special array helper class called &lt;code&gt;SZArrayHelper&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But first the why, why were all these tricks needed? From &lt;a href="https://blogs.msdn.microsoft.com/bclteam/2004/11/19/net-arrays-ilistt-generic-algorithms-and-what-about-stl-brian-grunkemeyer/"&gt;.NET Arrays, IList&amp;lt;T&amp;gt;, Generic Algorithms, and what about STL?&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we were designing our generic collections classes, one of the things that bothered me was how to write a generic algorithm that would work on both arrays and collections.  To drive generic programming, of course we must make arrays and generic collections as seamless as possible.  It felt that there should be a simple solution to this problem &lt;strong&gt;that meant you shouldn’t have to write the same code twice, once taking an IList&amp;lt;T&amp;gt; and again taking a T[]&lt;/strong&gt;.  The solution that dawned on me was that arrays needed to implement our generic IList.  We made arrays in V1 implement the non-generic IList, which was rather simple due to the lack of strong typing with IList and our base class for all arrays (System.Array). &lt;strong&gt;What we needed was to do the same thing in a strongly typed way for IList&amp;lt;T&amp;gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it was only done for the common case, i.e. 'single dimensional' arrays:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There were some restrictions here though – &lt;strong&gt;we didn’t want to support multidimensional arrays since IList&amp;lt;T&amp;gt; only provides single dimensional accesses&lt;/strong&gt;.  Also, arrays with non-zero lower bounds are rather strange, and probably wouldn’t mesh well with IList&amp;lt;T&amp;gt;, where most people may iterate from 0 to the return from the Count property on that IList.  So, &lt;strong&gt;instead of making System.Array implement IList&amp;lt;T&amp;gt;, we made T[] implement IList&amp;lt;T&amp;gt;&lt;/strong&gt;.  Here, T[] means a single dimensional array with 0 as its lower bound (often called an SZArray internally, but I think Brad wanted to promote the term 'vector' publically at one point in time), and the element type is T. So Int32[] implements IList&amp;lt;Int32&amp;gt;, and String[] implements IList&amp;lt;String&amp;gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, this comment from the &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/array.cpp#L1369-L1428"&gt;array source code&lt;/a&gt; sheds some further light on the reasons:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//----------------------------------------------------------------------------------
// Calls to (IList&amp;lt;T&amp;gt;)(array).Meth are actually implemented by SZArrayHelper.Meth&amp;lt;T&amp;gt;
// This workaround exists for two reasons:
//
//    - For working set reasons, we don't want insert these methods in the array 
//      hierachy in the normal way.
//    - For platform and devtime reasons, we still want to use the C# compiler to 
//      generate the method bodies.
//
// (Though it's questionable whether any devtime was saved.)
//
// ....
//----------------------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So it was done for &lt;em&gt;convenience&lt;/em&gt; and &lt;em&gt;efficiently&lt;/em&gt;, as they didn't want every instance of &lt;code&gt;System.Array&lt;/code&gt; to carry around all the code for the &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt; implementations.&lt;/p&gt;

&lt;p&gt;This mapping takes places via a call to &lt;a href="https://github.com/dotnet/coreclr/blob/a9b25d4aa22a1f4ad5f323f6c826e318f5a720fe/src/vm/methodtable.cpp#L6870-L6873"&gt;GetActualImplementationForArrayGenericIListOrIReadOnlyListMethod(..)&lt;/a&gt;, which wins the prize for the best method name in the CoreCLR source!! It's responsible for wiring up the corresponding method from the &lt;a href="https://github.com/dotnet/coreclr/blob/68f72dd2587c3365a9fe74d1991f93612c3bc62a/src/mscorlib/src/System/Array.cs#L2595-L2778"&gt;SZArrayHelper&lt;/a&gt; class, i.e. &lt;code&gt;IList&amp;lt;T&amp;gt;.Count&lt;/code&gt; -&amp;gt; &lt;code&gt;SZArrayHelper.Count&amp;lt;T&amp;gt;&lt;/code&gt; or if the method is part of the &lt;code&gt;IEnumerator&amp;lt;T&amp;gt;&lt;/code&gt; interface, the &lt;a href="https://github.com/dotnet/coreclr/blob/68f72dd2587c3365a9fe74d1991f93612c3bc62a/src/mscorlib/src/System/Array.cs#L2718-L2776"&gt;SZGenericArrayEnumerator&amp;lt;T&amp;gt;&lt;/a&gt; is used.&lt;/p&gt;

&lt;p&gt;But this has the potential to cause security holes, as it breaks the normal C# type system guarantees, specifically regarding the &lt;code&gt;this&lt;/code&gt; pointer. To illustrate the problem, here's the source code of the &lt;a href="https://github.com/dotnet/coreclr/blob/68f72dd2587c3365a9fe74d1991f93612c3bc62a/src/mscorlib/src/System/Array.cs#L2627-L2633"&gt;&lt;code&gt;Count&lt;/code&gt; property&lt;/a&gt;, note the call to &lt;code&gt;JitHelpers.UnsafeCast&amp;lt;T[]&amp;gt;&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;internal&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;get_Count&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//! Warning: "this" is an array, not an SZArrayHelper. See comments above&lt;/span&gt;
    &lt;span class="c1"&gt;//! or you may introduce a security hole!&lt;/span&gt;
    &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;_this&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JitHelpers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnsafeCast&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;]&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Yikes, it has to remap &lt;code&gt;this&lt;/code&gt; to be able to call &lt;code&gt;Length&lt;/code&gt; on the correct object!!&lt;/p&gt;

&lt;p&gt;And just in case those comments aren't enough, there is a very strongly worded comment &lt;a href="https://github.com/dotnet/coreclr/blob/68f72dd2587c3365a9fe74d1991f93612c3bc62a/src/mscorlib/src/System/Array.cs#L2572-L2594"&gt;at the top of the class&lt;/a&gt; that further spells out the risks!!&lt;/p&gt;

&lt;p&gt;Generally all this magic is hidden from you, but occasionally it leaks out. For instance if you run the code below, &lt;code&gt;SZArrayHelper&lt;/code&gt; will show up in the &lt;code&gt;StackTrace&lt;/code&gt; and &lt;code&gt;TargetSite&lt;/code&gt; of properties of the &lt;code&gt;NotSupportedException&lt;/code&gt;:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;someInts&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;someInts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Throws NotSupportedException 'Collection is read-only'&lt;/span&gt;
    &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;         
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NotSupportedException&lt;/span&gt; &lt;span class="n"&gt;nsEx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;              
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{0} - {1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nsEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TargetSite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeclaringType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nsEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TargetSite&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nsEx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StackTrace&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Removing Bounds Checks
&lt;/h3&gt;

&lt;p&gt;The runtime also provides support for arrays in more conventional ways, the first of which is related to performance. Array bounds checks are all well and good when providing &lt;em&gt;memory-safety&lt;/em&gt;, but they have a cost, so where possible the JIT removes any checks that it knows are redundant. &lt;/p&gt;

&lt;p&gt;It does this by calculating the &lt;em&gt;range&lt;/em&gt; of values that a &lt;code&gt;for&lt;/code&gt; loop access and compares those to the actual length of the array. If it determines that there is &lt;em&gt;never&lt;/em&gt; an attempt to access an item outside the permissible bounds of the array, the run-time checks are then removed.&lt;/p&gt;

&lt;p&gt;For more information, the links below take you to the areas of the JIT source code that deal with this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/ec80b02b61839af453ce297faf4ce074edeee9da/src/jit/compiler.cpp#L4524-L4525"&gt;JIT trying to remove range checks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/27b2300f790793733e501497203316ccad390e2b/src/jit/rangecheck.cpp#L201-L303"&gt;RangeCheck::OptimizeRangeCheck(..)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;In turn calls &lt;a href="https://github.com/dotnet/coreclr/blob/27b2300f790793733e501497203316ccad390e2b/src/jit/rangecheck.cpp#L1261-L1290"&gt;RangeCheck::GetRange(..)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Also call &lt;a href="https://github.com/dotnet/coreclr/blob/c06fb332e7bb77a55bda724a56b33d6094a0a042/src/jit/optimizer.cpp#L7255-L7322"&gt;Compiler::optRemoveRangeCheck(..)&lt;/a&gt; to actually remove the range-check&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Really informative source code comment &lt;a href="https://github.com/dotnet/coreclr/blob/master/src/jit/rangecheck.h#L5-L58"&gt;explaining the range check removal logic&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you are really keen, take a look at &lt;a href="https://gist.github.com/mattwarren/a72cdb3ae427957af10635153d79555b#gistcomment-2075030"&gt;this gist&lt;/a&gt; that I put together to explore the scenarios where bounds checks are 'removed' and 'not removed'.&lt;/p&gt;

&lt;h3&gt;
  
  
  Allocating an array
&lt;/h3&gt;

&lt;p&gt;Another task that the runtime helps with is allocating arrays, using hand-written assembly code so the methods are as optimised as possible, see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/0ec02d7375a1aa96206fd755b02e553e075ac3ae/src/vm/i386/jitinterfacex86.cpp#L885-L1109"&gt;JIT_TrialAlloc::GenAllocArray(..)&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/0ec02d7375a1aa96206fd755b02e553e075ac3ae/src/vm/i386/jitinterfacex86.cpp#L1082-L1104"&gt;Patching in the assembly code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Run-time treats arrays differently
&lt;/h3&gt;

&lt;p&gt;Finally, because arrays are so intertwined with the CLR, there are lots of places in which they are dealt with as a &lt;em&gt;special-case&lt;/em&gt;. For instance &lt;a href="https://github.com/dotnet/coreclr/search?l=C%2B%2B&amp;amp;q=path%3A%2Fsrc+IsArray%28%29&amp;amp;type=&amp;amp;utf8=%E2%9C%93"&gt;a search for 'IsArray()'&lt;/a&gt; in the CoreCLR source returns over 60 hits, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The method table for an array is built differently

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/a9b25d4aa22a1f4ad5f323f6c826e318f5a720fe/src/vm/classcompat.cpp#L543-L608"&gt;MethodTableBuilder::BuildInteropVTableForArray(..)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;When you call &lt;code&gt;ToString()&lt;/code&gt; on an array, you get special formatting, i.e. 'System.Int32[]' or 'MyClass[,]' 

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/typestring.cpp#L903-L937"&gt;TypeString::AppendType(..)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;So yes, it's fair to say that arrays and the CLR have a &lt;strong&gt;Very Special Relationship&lt;/strong&gt; &lt;/p&gt;




&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;p&gt;As always, here are some more links for your enjoyment!!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ljw1004/csharpspec/blob/gh-pages/arrays.md"&gt;CSharp Specification for Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti?fid=459323&amp;amp;fr=26#20"&gt;.NET Type Internals - From a Microsoft CLR Perspective - ARRAYS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web.archive.org/web/20081203124917/http://msdn.microsoft.com/msdnmag/issues/06/11/CLRInsideOut/"&gt;CLR INSIDE OUT - Investigating Memory Issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.abhisheksur.com/2011/06/internals-of-array.html"&gt;Internals of Array&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.abhisheksur.com/2011/09/internals-of-net-objects-and-use-of-sos.html"&gt;Internals of .NET Objects and Use of SOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://windowsdebugging.wordpress.com/2012/04/07/memorylayoutofarrays/"&gt;Memory layout of .NET Arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://windowsdebugging.wordpress.com/2012/04/24/memorylayoutofarraysx64/"&gt;Memory Layout of .NET Arrays (x64)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/468832/why-are-multi-dimensional-arrays-in-net-slower-than-normal-arrays"&gt;Why are multi-dimensional arrays in .NET slower than normal arrays?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/11163297/how-do-arrays-in-c-sharp-partially-implement-ilistt/11164210#11164210"&gt;How do arrays in C# partially implement IList&amp;lt;T&amp;gt;?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/33632073/purpose-of-typedependencyattributesystem-szarrayhelper-for-ilistt-ienumer/33632407#33632407"&gt;Purpose of TypeDependencyAttribute(“System.SZArrayHelper”) for IList&amp;lt;T&amp;gt;, IEnumerable&amp;lt;T&amp;gt; and ICollection&amp;lt;T&amp;gt;?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/15341882/what-kind-of-class-does-yield-return-return/15341925#15341925"&gt;What kind of class does 'yield return' return&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&amp;amp;namespace=System&amp;amp;type=SZArrayHelper"&gt;SZArrayHelper implemented in Shared Source CLI (SSCLI)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Array source code references
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Array.cs"&gt;Array.cs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/master/src/vm/array.cpp"&gt;array.cpp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/master/src/vm/array.h"&gt;array.h&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The post &lt;a href="http://mattwarren.org/2017/05/08/Arrays-and-the-CLR-a-Very-Special-Relationship/"&gt;Arrays and the Common Language Runtime - a Very Special Relationship&lt;/a&gt; appeared first on my blog &lt;a href="http://mattwarren.org"&gt;mattwarren.org&lt;/a&gt;&lt;/p&gt;


</description>
      <category>clr</category>
      <category>net</category>
      <category>arrays</category>
    </item>
    <item>
      <title>The .NET IL (bytecode) Interpreter</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Fri, 07 Apr 2017 09:09:34 +0000</pubDate>
      <link>https://dev.to/mattwarren/the-net-il-bytecode-interpreter</link>
      <guid>https://dev.to/mattwarren/the-net-il-bytecode-interpreter</guid>
      <description>

&lt;p&gt;Whilst writing a &lt;a href="http://mattwarren.org/2017/03/23/Hitchhikers-Guide-to-the-CoreCLR-Source-Code/"&gt;previous blog post&lt;/a&gt; I stumbled across the .NET Interpreter, tucked away in the source code. Although, if I'd made even the smallest amount of effort to look for it, I'd have easily found it via the &lt;a href="https://github.com/dotnet/coreclr/find/master"&gt;&lt;em&gt;GitHub 'magic' file search&lt;/em&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xhd0I5bS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/03/GitHub%2520file%2520search%2520for%2520%27Interpreter%27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xhd0I5bS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://mattwarren.org/images/2017/03/GitHub%2520file%2520search%2520for%2520%27Interpreter%27.png" alt="GitHub file search for 'Interpreter'"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage Scenarios
&lt;/h3&gt;

&lt;p&gt;Before we look at how to use it and what it does, it's worth pointing out that the Interpreter is not really meant for production code. As far as I can tell, its main purpose is to allow you to get the CLR up and running on a new CPU architecture. Without the interpreter you wouldn't be able to test &lt;em&gt;any&lt;/em&gt; C# code until you had a fully functioning JIT that could emit machine code for you. For instance see &lt;a href="https://github.com/dotnet/coreclr/pull/8594"&gt;'[ARM32/Linux] Initial bring up of FEATURE_INTERPRETER'&lt;/a&gt; and &lt;a href="https://github.com/dotnet/coreclr/commit/8c4e60054ddb42298f3eebaf20c970d665474ae3"&gt;'[aarch64] Enable the interpreter on linux as well&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also it doesn't have a few key features, most notable debugging support, that is you can't debug through C# code that has been interpreted, although you can of course debug the interpreter itself. From &lt;a href="https://github.com/dotnet/coreclr/pull/10478"&gt;'Tiered Compilation step 1'&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;.... - the interpreter is not in good enough shape to run production code as-is. There are also some significant issues if you want debugging and profiling tools to work (which we do).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can see an example of this in &lt;a href="https://github.com/dotnet/coreclr/issues/34"&gt;'Interpreter: volatile ldobj appears to have incorrect semantics?'&lt;/a&gt; (thanks to &lt;a href="https://www.reddit.com/r/programming/comments/62hcde/the_c_interpreter/dfn3ycc/"&gt;alexrp&lt;/a&gt; for telling me about this issue). There is also a fair amount of &lt;code&gt;TODO&lt;/code&gt; &lt;a href="https://gist.github.com/mattwarren/a7e567c3aacd1c85da86206ea729c66f"&gt;comments in the code&lt;/a&gt;, although I haven't verified what (if any) specific C# code breaks due to the missing functionality.&lt;/p&gt;

&lt;p&gt;However, I think another really useful scenario for the Interpreter is to help you learn about the inner workings of the CLR. It's &lt;em&gt;only&lt;/em&gt; 8,000 lines long, but it's all in one file and most significantly it's written in C++. The code that the CLR/JIT uses when compiling &lt;em&gt;for real&lt;/em&gt; is in multiple several files (the JIT on it's own is over 200,000 L.O.C, spread across 100's of files) and there are large amounts hand-written written in &lt;a href="https://github.com/dotnet/coreclr/tree/master/src/vm/amd64"&gt;raw assembly&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In theory the Interpreter should work in the same way as the &lt;em&gt;full&lt;/em&gt; runtime, albeit not as optimised. This means that it much simpler and those of us who aren't CLR and/or assembly experts can have a chance of working out what's going on! &lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling the Interpreter
&lt;/h2&gt;

&lt;p&gt;The Interpreter is disabled by default, so you have to &lt;a href="https://github.com/dotnet/coreclr/tree/master/Documentation#build-coreclr-from-source"&gt;build the CoreCLR from source&lt;/a&gt; to make it work (it used to be the &lt;a href="https://github.com/dotnet/coreclr/commit/8a47eafa69614589eb86bbdf0c2c36aa690c1b15"&gt;fallback for ARM64&lt;/a&gt; but that's no longer the case), here's the diff of the changes you need to make:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;--- a/src/inc/switches.h
&lt;/span&gt;&lt;span class="gi"&gt;+++ b/src/inc/switches.h
&lt;/span&gt;&lt;span class="gu"&gt;@@ -233,5 +233,8 @@
&lt;/span&gt; #define FEATURE_STACK_SAMPLING
 #endif // defined (ALLOW_SXS_JIT)

&lt;span class="gi"&gt;+// Let's test the .NET Interpreter!!
+#define FEATURE_INTERPRETER
+
&lt;/span&gt; #endif // !defined(CROSSGEN_COMPILE)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You also need to enable some environment variables, the ones that I used are in the table below. For the full list, take a look at &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/project-docs/clr-configuration-knobs.md"&gt;Host Configuration Knobs&lt;/a&gt; and search for 'Interpreter'.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Interpret&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Selectively uses the interpreter to execute the specified methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;InterpreterDoLoopMethods&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;If set, don't check for loops, start by interpreting &lt;em&gt;all&lt;/em&gt; methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;InterpreterPrintPostMortem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prints summary information about the execution to the console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DumpInterpreterStubs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prints all interpreter stubs that are created to the console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TraceInterpreterEntries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logs entries to interpreted methods to the console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TraceInterpreterIL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logs individual instructions of interpreted methods to the console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TraceInterpreterVerbose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logs interpreter progress with detailed messages to the console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TraceInterpreterJITTransition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Logs when the interpreter determines a method should be JITted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To test out the Interpreter, I will be using the code below:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Completed {0,10:N0} iterations"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Performed {0:N0} iterations, max);
&lt;/span&gt;    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Took {0:N0} msecs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ElapsedMilliseconds&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;which on my machine, gives the following results for &lt;code&gt;100,000&lt;/code&gt; iterations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Run&lt;/th&gt;
&lt;th&gt;Compiled (msecs)&lt;/th&gt;
&lt;th&gt;Interpreted (msecs)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;4,393&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;4,089&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;4,416&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So yeah, you don't want to be using the interpreter for any performance sensitive code!!&lt;/p&gt;

&lt;h3&gt;
  
  
  Diagnostic Output
&lt;/h3&gt;

&lt;p&gt;In addition, a diagnostic output is produced. Note, this is from a single iteration of the loop, otherwise it becomes to verbose to read.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="nl"&gt;Generating interpretation stub (# 1 = 0x1, hash = 0x91b7d02e) for ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main.&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;.cctor&lt;/span&gt;
&lt;span class="nl"&gt;Entering method #1 (= 0x1)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ConsoleApplication.Program:Main(class).&lt;/span&gt;
 &lt;span class="nl"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
         0:      class: 0x0000000002C50568 &lt;span class="o"&gt;(&lt;/span&gt;System.String[]&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...]

&lt;span class="nl"&gt;START 1, ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;
     0: nop
   &lt;span class="nl"&gt;0x1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;.cctor&lt;/span&gt;
&lt;span class="nl"&gt;Skipping DomainBoundILStubClass&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;IL_STUB_PInvoke&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;StartNew&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;.ctor&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Reset&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Start&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;GetTimestamp&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
   &lt;span class="nl"&gt;0x6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stloc.0&lt;/span&gt;
      loc0   :      class: 0x0000000002C50580 &lt;span class="o"&gt;(&lt;/span&gt;ConsoleApplication.Stopwatch&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...]
      loc1   :        int: 0
      loc2   :       bool: &lt;span class="nb"&gt;false&lt;/span&gt;
   &lt;span class="nl"&gt;0x7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldc.i4.1&lt;/span&gt;
   &lt;span class="nl"&gt;0x8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stloc.1&lt;/span&gt;
      loc0   :      class: 0x0000000002C50580 &lt;span class="o"&gt;(&lt;/span&gt;ConsoleApplication.Stopwatch&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...]
      loc1   :        int: 1
      loc2   :       bool: &lt;span class="nb"&gt;false&lt;/span&gt;
   &lt;span class="nl"&gt;0x9&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;br.s&lt;/span&gt;
  &lt;span class="nl"&gt;0x27&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.1&lt;/span&gt;
  &lt;span class="nl"&gt;0x28&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldc.i4.2&lt;/span&gt;
  &lt;span class="nl"&gt;0x29&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;clt&lt;/span&gt;
  &lt;span class="nl"&gt;0x2b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stloc.2&lt;/span&gt;
      loc0   :      class: 0x0000000002C50580 &lt;span class="o"&gt;(&lt;/span&gt;ConsoleApplication.Stopwatch&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...]
      loc1   :        int: 1
      loc2   :       bool: &lt;span class="nb"&gt;true&lt;/span&gt;
  &lt;span class="nl"&gt;0x2c&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.2&lt;/span&gt;
  &lt;span class="nl"&gt;0x2d&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;brtrue.s&lt;/span&gt;
   &lt;span class="nl"&gt;0xb&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nop&lt;/span&gt;
   &lt;span class="nl"&gt;0xc&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldstr&lt;/span&gt;
  &lt;span class="nl"&gt;0x11&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.1&lt;/span&gt;
  &lt;span class="nl"&gt;0x12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;box&lt;/span&gt;
  &lt;span class="nl"&gt;0x17&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
  &lt;span class="nl"&gt;0x1c&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="err"&gt;Completed&lt;/span&gt;          &lt;span class="err"&gt;1&lt;/span&gt; &lt;span class="err"&gt;iterations&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
  &lt;span class="nl"&gt;0x21&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nop&lt;/span&gt;
  &lt;span class="nl"&gt;0x22&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nop&lt;/span&gt;
  &lt;span class="nl"&gt;0x23&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.1&lt;/span&gt;
  &lt;span class="nl"&gt;0x24&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldc.i4.1&lt;/span&gt;
  &lt;span class="nl"&gt;0x25&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;
  &lt;span class="nl"&gt;0x26&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stloc.1&lt;/span&gt;
      loc0   :      class: 0x0000000002C50580 &lt;span class="o"&gt;(&lt;/span&gt;ConsoleApplication.Stopwatch&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...]
      loc1   :        int: 2
      loc2   :       bool: &lt;span class="nb"&gt;true&lt;/span&gt;
  &lt;span class="nl"&gt;0x27&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.1&lt;/span&gt;
  &lt;span class="nl"&gt;0x28&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldc.i4.2&lt;/span&gt;
  &lt;span class="nl"&gt;0x29&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;clt&lt;/span&gt;
  &lt;span class="nl"&gt;0x2b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;stloc.2&lt;/span&gt;
      loc0   :      class: 0x0000000002C50580 &lt;span class="o"&gt;(&lt;/span&gt;ConsoleApplication.Stopwatch&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;...]
      loc1   :        int: 2
      loc2   :       bool: &lt;span class="nb"&gt;false&lt;/span&gt;
  &lt;span class="nl"&gt;0x2c&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.2&lt;/span&gt;
  &lt;span class="nl"&gt;0x2d&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;brtrue.s&lt;/span&gt;
  &lt;span class="nl"&gt;0x2f&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.0&lt;/span&gt;
  &lt;span class="nl"&gt;0x30&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;callvirt&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Stop&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
  &lt;span class="nl"&gt;0x35&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nop&lt;/span&gt;
  &lt;span class="nl"&gt;0x36&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldstr&lt;/span&gt;
  &lt;span class="nl"&gt;0x3b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ldloc.0&lt;/span&gt;
  &lt;span class="nl"&gt;0x3c&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;callvirt&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;get_ElapsedMilliseconds&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;GetElapsedDateTimeTicks&lt;/span&gt;
&lt;span class="nl"&gt;Skipping ConsoleApplication.Stopwatch&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;GetRawElapsedTicks&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
  &lt;span class="nl"&gt;0x41&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;box&lt;/span&gt;
  &lt;span class="nl"&gt;0x46&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
  &lt;span class="nl"&gt;0x4b&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;
&lt;span class="err"&gt;Took&lt;/span&gt; &lt;span class="err"&gt;33&lt;/span&gt; &lt;span class="err"&gt;msecs&lt;/span&gt;
  &lt;span class="nl"&gt;Returning to method ConsoleApplication.Program&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nf"&gt;Main(class)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nf"&gt; stub num 1.&lt;/span&gt;
  &lt;span class="nl"&gt;0x50&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;nop&lt;/span&gt;
  &lt;span class="nl"&gt;0x51&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So you can clearly see the interpreter in action, executing the individual IL instructions and showing the current values of any local variables as it goes along. Then, once the entire program has run, you also get some nice summary statistics (this time from a full-run, with &lt;code&gt;100,000&lt;/code&gt; iterations):&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IL instruction profiling:

Instructions (24000085 total, 20000083 1-byte):
Instruction  |   execs   |       % |   cum %
-------------------------------------------
     ldloc.1 |   3000011 |  12.50% |  12.50%
         ceq |   3000001 |  12.50% |  25.00%
    ldc.i4.0 |   3000001 |  12.50% |  37.50%
         nop |   2000013 |   8.33% |  45.83%
     stloc.2 |   2000001 |   8.33% |  54.17%
      ldc.i4 |   2000001 |   8.33% |  62.50%
    brtrue.s |   2000001 |   8.33% |  70.83%
     ldloc.2 |   2000001 |   8.33% |  79.17%
    ldc.i4.1 |   1000001 |   4.17% |  83.33%
         cgt |   1000001 |   4.17% |  87.50%
     stloc.1 |   1000001 |   4.17% |  91.67%
         rem |   1000000 |   4.17% |  95.83%
         add |   1000000 |   4.17% | 100.00%
        call |        23 |   0.00% | 100.00%
       ldstr |        11 |   0.00% | 100.00%
         box |        11 |   0.00% | 100.00%
     ldloc.0 |         2 |   0.00% | 100.00%
    callvirt |         2 |   0.00% | 100.00%
        br.s |         1 |   0.00% | 100.00%
     stloc.0 |         1 |   0.00% | 100.00%
         ret |         1 |   0.00% | 100.00%                                        
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h2&gt;
  
  
  Main sections of the Interpreter code
&lt;/h2&gt;

&lt;p&gt;Now we've seen it in action, let's take a look at the code within the Interpreter and see &lt;strong&gt;how&lt;/strong&gt; it works&lt;/p&gt;

&lt;h3&gt;
  
  
  Top-level dispatcher
&lt;/h3&gt;

&lt;p&gt;At the heart of the Interpreter is a &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L2073-L3261"&gt;giant switch statement&lt;/a&gt; (in &lt;code&gt;Interpreter::ExecuteMethod(..)&lt;/code&gt;), that is almost 1,200 lines long! In it you'll find &lt;em&gt;lots&lt;/em&gt; of code like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;m_ILCodePtr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CEE_NOP&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;m_ILCodePtr&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CEE_BREAK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="c1"&gt;// TODO: interact with the debugger?&lt;/span&gt;
    &lt;span class="n"&gt;m_ILCodePtr&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CEE_LDARG_0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;LdArg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CEE_LDARG_1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;LdArg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In total, there are 199 &lt;code&gt;case&lt;/code&gt; statements, corresponding to all the available CLR &lt;a href="https://en.wikipedia.org/wiki/List_of_CIL_instructions"&gt;Intermediate Language (IL) op-codes&lt;/a&gt;, in all their different combinations, for instance &lt;code&gt;CEE_LDC_??&lt;/code&gt;, i.e. &lt;code&gt;CEE_LDC_I4&lt;/code&gt;, &lt;code&gt;CEE_LDC_I8&lt;/code&gt;, &lt;code&gt;CEE_LDC_R4&lt;/code&gt; and &lt;code&gt;CEE_LDC_R8&lt;/code&gt;. The large majority of the &lt;code&gt;case&lt;/code&gt; statements just call out to another function that does the actual work, although there are some exceptions, &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L2268-L2391"&gt;such as &lt;code&gt;CEE_RET&lt;/code&gt;&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Method calls
&lt;/h3&gt;

&lt;p&gt;The other task that takes up lots of code in the interpreter is handling method calls, over 2,500 L.O.C in total! This is spread across several methods, each doing a particular part of the work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L8965-L10027"&gt;void Interpreter::DoCallWork(..)&lt;/a&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CALL&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.call%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Calls the method indicated by the passed method descriptor&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CALLVIRT&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.callvirt%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Calls a late-bound method on an object, pushing the return value onto the evaluation stack.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; Also via &lt;code&gt;Interpreter::NewObj()&lt;/code&gt;, i.e the &lt;code&gt;NEWOBJ&lt;/code&gt; IL op-code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L10032-L10427"&gt;void Interpreter::CallI()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CALLI&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.calli%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Calls the method indicated on the evaluation stack (as a pointer to an entry point) with arguments described by a calling convention&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L660-L1600"&gt;CorJitResult Interpreter::GenerateInterpreterStub(..)&lt;/a&gt; 

&lt;ul&gt;
&lt;li&gt;The external entry point, i.e. the &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/jitinterface.cpp#L11969-L12012"&gt;JIT inserts a stub to this method&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Also called via &lt;code&gt;Interpreter::InterpretMethodBody(..)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Actually emits &lt;strong&gt;assembly code&lt;/strong&gt;!!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L195-L424"&gt;void InterpreterMethodInfo::InitArgInfo(..)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Called via &lt;code&gt;Interpreter::GenerateInterpreterStub(..)&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, this work involves &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md"&gt;dynamically generating stubs&lt;/a&gt; and ensuring that method arguments are in the right registers (hence the assembly code). It handles virtual methods, static and instance calls, delegates, intrinsics and probably a few other scenarios as well! In addition, if the method being called needs to be interpreted, it also has to make sure that happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating objects and arrays
&lt;/h3&gt;

&lt;p&gt;The interpreter needs to handle some of the key functionality of a runtime, that is creating and initialising objects. To do this it has to call into the GC, before finally calling the constructor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L5833-L6012"&gt;void Interpreter::NewObj()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NEWOBJ&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.newobj%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Creates a new object or a new instance of a value type, pushing an object reference (type O) onto the evaluation stack&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L6015-L6085"&gt;void Interpreter::NewArr()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NEWARR&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.newarr%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Pushes an object reference to a new zero-based, one-dimensional array whose elements are of a specific type onto the evaluation stack&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L5761-L5811"&gt;void Interpreter::InitObj()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;INITOBJ&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.initobj%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Initializes each field of the value type at a specified address to a null reference or a 0 of the appropriate primitive type&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Boxing and Unboxing
&lt;/h3&gt;

&lt;p&gt;Another large chuck of code is dedicated to boxing/unboxing, that is converting 'value types' (&lt;code&gt;structs&lt;/code&gt;) into &lt;code&gt;object&lt;/code&gt; references when needed. The .NET IL provides specific op-codes to handle this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L8497-L8562"&gt;void Interpreter::Box()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;BOX&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.box%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Converts a value type to an object reference (type O)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L8602-L8693"&gt;void Interpreter::Unbox()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UNBOX&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.unbox%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Converts the boxed representation of a value type to its unboxed form&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L8747-L8871"&gt;void Interpreter::UnboxAny()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UNBOX_ANY&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.unbox_any%28v=vs.110%29.aspx?f=255&amp;amp;MSPPError=-2147217396"&gt;Converts the boxed representation of a type specified in the instruction to its unboxed form&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Loading and Storing data
&lt;/h3&gt;

&lt;p&gt;That is, reading/writing fields in an object or elements in an array:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L7533-L7690"&gt;void Interpreter::StFld()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;STFLD&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.stfld(v=vs.110).aspx"&gt;Replaces the value stored in the field of an object reference or pointer with a new value&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L8246-L8385"&gt;void Interpreter::StElem()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;STELEM&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.stelem(v=vs.110).aspx"&gt;Replaces the array element at a given index with the value on the evaluation stack, whose type is specified in the instruction&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L7248-L7477"&gt;void Interpreter::LdFld(FieldDesc* fldIn)&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LDFLD&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldfld(v=vs.110).aspx"&gt;Finds the value of a field in the object whose reference is currently on the evaluation stack&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L8120-L8243"&gt;void Interpreter::LdElem()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LDELEM&lt;/code&gt; &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldelem(v=vs.110).aspx"&gt;Loads the element at a specified array index onto the top of the evaluation stack as the type specified in the instruction&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other Specific IL Op Codes
&lt;/h3&gt;

&lt;p&gt;There is also a significant amount of code (over 1,000 lines) that just deals with low-level operations, that is 'comparisions', 'branching' and 'basic arithmetic':&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L6714-L7127"&gt;INT32 Interpreter::CompareOpRes(..)&lt;/a&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CEQ&lt;/code&gt;, &lt;code&gt;CGT&lt;/code&gt;, &lt;code&gt;CGT_UN&lt;/code&gt;, &lt;code&gt;CLT&lt;/code&gt; &amp;amp; &lt;code&gt;CLT_UN&lt;/code&gt; called via &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L6694-L6710"&gt;Interpreter::CompareOp()&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;BEQ&lt;/code&gt;, &lt;code&gt;BGE&lt;/code&gt;, &lt;code&gt;BGT&lt;/code&gt;, &lt;code&gt;BLE&lt;/code&gt;, &lt;code&gt;BLT&lt;/code&gt;, &lt;code&gt;BNE_UN&lt;/code&gt;, &lt;code&gt;BGE_UN&lt;/code&gt;, &lt;code&gt;BGT_UN&lt;/code&gt;, &lt;code&gt;BLE_UN&lt;/code&gt;, &lt;code&gt;BLT_UN&lt;/code&gt; called via &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L7199-L7245"&gt;Interpreter::BrOnComparison()&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L4353-L4608"&gt;void Interpreter::BinaryArithOp()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ADD&lt;/code&gt;, &lt;code&gt;SUB&lt;/code&gt;, &lt;code&gt;MUL&lt;/code&gt;, &lt;code&gt;DIV&lt;/code&gt; and &lt;code&gt;REM&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;in turn calls &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.hpp#L266-L313"&gt;Interpreter::BinaryArithOpWork(..)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L4612-L4823"&gt;void Interpreter::BinaryArithOvfOp()&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ADD_OVF&lt;/code&gt;, &lt;code&gt;ADD_OVF_UN&lt;/code&gt;, &lt;code&gt;MUL_OVF&lt;/code&gt;, &lt;code&gt;MUL_OVF_UN&lt;/code&gt;, &lt;code&gt;SUB_OVF&lt;/code&gt;, &lt;code&gt;SUB_OVF_UN&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;in turn calls &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L4825-L4866"&gt;Interpreter::BinaryArithOvfOpWork(..)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Working with the Garbage Collector (GC)
&lt;/h3&gt;

&lt;p&gt;In addition, the interpreter has to provide the GC with the information it needs. This happens when the GC calls &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L3667-L3762"&gt;Interpreter::GCScanRoots(..)&lt;/a&gt;, with additional work talking place in &lt;a href="https://github.com/dotnet/coreclr/blob/48e244855c98c6f280c986d0981238f403a49ff3/src/vm/interpreter.cpp#L3765-L3795"&gt;Interpreter::GCScanRootAtLoc(..)&lt;/a&gt;. Very simply the interpreter has to let the GC know about any 'root' objects that are currently 'live'. This includes static variables and any local variables in the function that is currently executing.&lt;/p&gt;

&lt;p&gt;When the interpreter locates a 'root' object, it notifies the GC via a callback (&lt;code&gt;pf(..)&lt;/code&gt;):&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Interpreter&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GCScanRootAtLoc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InterpreterType&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;promote_func&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ScanContext&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;pinningRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToCorInfoType&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CORINFO_TYPE_CLASS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;CORINFO_TYPE_STRING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;DWORD&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pinningRef&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;GC_CALL_PINNED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pf&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Integration with the Virtual Machine (VM)
&lt;/h2&gt;

&lt;p&gt;Finally, whilst the Interpreter is fairly self-contained, there are times where it needs to work with the rest of the runtime&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Run-time is responsible for &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/ceemain.cpp#L816-L818"&gt;starting&lt;/a&gt; and &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/ceemain.cpp#L1824-L1826"&gt;stopping&lt;/a&gt; the interpreter&lt;/li&gt;
&lt;li&gt;The JIT &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/jitinterface.cpp#L11969-L12012"&gt;wires up interpreter stubs&lt;/a&gt; or uses them as a fall-back if JIT compilation fails. In addition the JIT 'pre-stubs' allow for interpreted methods &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/prestub.cpp#L255-L655"&gt;when calling the JIT itself&lt;/a&gt; and when &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/prestub.cpp#L1146-L1633"&gt;the 'pre-stub' is executed&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Stack-walking &lt;a href="https://github.com/dotnet/coreclr/blob/master/src/vm/stackwalk.cpp#L80-L158"&gt;takes account of interpreter frames&lt;/a&gt;, by utilising &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/frames.cpp#L1030-L1049"&gt;InterpreterFrame data structures&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;When looking up the &lt;code&gt;MethodDesc&lt;/code&gt; for a given code address, the &lt;a href="https://github.com/dotnet/coreclr/blob/1c4fda612e8a4f0d48346c477d058fa3fddf514e/src/vm/methodtable.cpp#L7524-L7535"&gt;interpreter stubs are accounted for&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The post &lt;a href="http://mattwarren.org/2017/03/30/The-.NET-IL-Interpreter/"&gt;'The .NET IL (bytecode) Interpreter'&lt;/a&gt; appeared first on my blog &lt;a href="http://www.mattwarren.org"&gt;mattwarren.org&lt;/a&gt;&lt;/p&gt;


</description>
      <category>net</category>
      <category>clr</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How do .NET delegates work?</title>
      <dc:creator>Matt Warren</dc:creator>
      <pubDate>Tue, 07 Mar 2017 15:28:24 +0000</pubDate>
      <link>https://dev.to/mattwarren/how-do-net-delegates-work</link>
      <guid>https://dev.to/mattwarren/how-do-net-delegates-work</guid>
      <description>&lt;p&gt;Delegates are a fundamental part of the .NET runtime and whilst you rarely create them directly, they are there &lt;em&gt;under-the-hood&lt;/em&gt; every time you use a lambda in LINQ (&lt;code&gt;=&amp;gt;&lt;/code&gt;) or a &lt;code&gt;Func&amp;lt;T&amp;gt;&lt;/code&gt;/&lt;code&gt;Action&amp;lt;T&amp;gt;&lt;/code&gt; to &lt;a href="https://blogs.msdn.microsoft.com/madst/2007/01/23/is-c-becoming-a-functional-language/" rel="noopener noreferrer"&gt;make your code more functional&lt;/a&gt;. But how do they actually work and what's going in the CLR when you use them?&lt;/p&gt;




&lt;h3&gt;
  
  
  IL of delegates and/or lambdas
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;delegate&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SimpleDelegate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DelegateTest&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// create an instance of the class&lt;/span&gt;
            &lt;span class="n"&gt;DelegateTest&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DelegateTest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"My instance"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;// create a delegate&lt;/span&gt;
            &lt;span class="n"&gt;SimpleDelegate&lt;/span&gt; &lt;span class="n"&gt;d1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SimpleDelegate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InstanceMethod&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// call 'InstanceMethod' via the delegate (compiler turns this into 'd1.Invoke(5)')&lt;/span&gt;
            &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// returns "My instance: 5"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;InstanceMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{0}: {1}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you were to take a look at the IL of the &lt;code&gt;SimpleDelegate&lt;/code&gt; class, the &lt;code&gt;ctor&lt;/code&gt; and &lt;code&gt;Invoke&lt;/code&gt; methods look like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MethodImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MethodCodeType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MethodCodeType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;SimpleDelegate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;@object&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntPtr&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;MethodImpl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MethodCodeType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MethodCodeType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It turns out that this behaviour is manadated by the spec, from &lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf" rel="noopener noreferrer"&gt;ECMA 335 Standard - Common Language Infrastructure (CLI)&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1ax1i5f2y3x71.cloudfront.net%2Fitems%2F173L2w0x1l2l082P1O1e%2FScreen%2520Shot%25202017-03-06%2520at%252011.28.14%2520AM.png%3FX-CloudApp-Visitor-Id%3D2119651" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd1ax1i5f2y3x71.cloudfront.net%2Fitems%2F173L2w0x1l2l082P1O1e%2FScreen%2520Shot%25202017-03-06%2520at%252011.28.14%2520AM.png%3FX-CloudApp-Visitor-Id%3D2119651"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So the internal implementation of a delegate, the part responsible for calling a method, is created by the runtime. This is because there needs to be complete control over those methods, delegates are a fundamental part of the CLR, any security issues, performance overhead or other inefficiencies would be a big problem.&lt;/p&gt;

&lt;p&gt;Methods that are created in this way are technically know as &lt;code&gt;EEImpl&lt;/code&gt; methods, from the â€˜Book of the Runtime' (BOTR) section â€˜&lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/Documentation/botr/method-descriptor.md#kinds-of-methoddescs" rel="noopener noreferrer"&gt;Method Descriptor - Kinds of MethodDescs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;EEImpl&lt;/strong&gt; Delegate methods whose implementation is provided by the runtime (Invoke, BeginInvoke, EndInvoke). See &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/Documentation/project-docs/dotnet-standards.md" rel="noopener noreferrer"&gt;ECMA 335 Partition II - Delegates&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's also more information available in these two excellent articles &lt;a href="https://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti?fid=459323&amp;amp;fr=26#16" rel="noopener noreferrer"&gt;.NET Type Internals - From a Microsoft CLR Perspective&lt;/a&gt; (section on â€˜Delegates') and &lt;a href="https://www.codeproject.com/Articles/26936/Understanding-NET-Delegates-and-Events-By-Practice#Internal" rel="noopener noreferrer"&gt;Understanding .NET Delegates and Events, By Practice&lt;/a&gt; (section on â€˜Internal Delegates Representation')&lt;/p&gt;




&lt;h2&gt;
  
  
  How the runtime creates delegates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inlining of delegate ctors
&lt;/h3&gt;

&lt;p&gt;So we've seen that the runtime has responsibility for creating the bodies of delegate methods, but how is this done. It starts by wiring up the delegate constructor (ctor), as per the BOTR page on &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/method-descriptor.md" rel="noopener noreferrer"&gt;â€˜method descriptors'&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;FCall&lt;/strong&gt; Internal methods implemented in unmanaged code. These are methods marked with MethodImplAttribute(MethodImplOptions.InternalCall) attribute, &lt;strong&gt;delegate constructors&lt;/strong&gt; and tlbimp constructors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At runtime this happens when the JIT compiles a method that contains IL code for creating a delegate. In &lt;a href="https://github.com/dotnet/coreclr/blob/0d04afc8f5919edcbb371c1e0c4f832f76aed09f/src/jit/flowgraph.cpp#L7031-L7167" rel="noopener noreferrer"&gt;Compiler::fgOptimizeDelegateConstructor(..)&lt;/a&gt;, the JIT firstly obtains a reference to the &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/comdelegate.cpp#L3609" rel="noopener noreferrer"&gt;correct delegate ctor&lt;/a&gt;, which in the simple case is &lt;code&gt;CtorOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk)&lt;/code&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/01a9eaaa14fc3de8f11eafa6155af8ce4e44e9e9/src/mscorlib/src/System/MulticastDelegate.cs#L622-L627" rel="noopener noreferrer"&gt;(link to C# code)&lt;/a&gt;, before finally wiring up the &lt;code&gt;ctor&lt;/code&gt;, &lt;a href="https://github.com/dotnet/coreclr/blob/0d04afc8f5919edcbb371c1e0c4f832f76aed09f/src/jit/importer.cpp#L7366" rel="noopener noreferrer"&gt;inlining it if possible&lt;/a&gt; for maximum performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creation of the delegate Invoke() method
&lt;/h3&gt;

&lt;p&gt;But what's more interesting is the process that happens when creating the &lt;code&gt;Invoke()&lt;/code&gt; method, using a technique involving â€˜stubs' of code (raw-assembly) that know how to locate the information about the target method and can jump control to it. These â€˜stubs' are actually used in a wide-variety of scenarios, for instance during &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md#stubs" rel="noopener noreferrer"&gt;Virtual Method Dispatch&lt;/a&gt; and also &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/method-descriptor.md#precode" rel="noopener noreferrer"&gt;by the JITter&lt;/a&gt; (when a method is first called it hits a â€˜pre-code stub' that causes the method to be JITted, the â€˜stub' is then replaced by a call to the JITted â€˜native code').&lt;/p&gt;

&lt;p&gt;In the particular case of delegates, these stubs are referred to as â€˜shuffle thunks'. This is because part of the work they have to do is â€˜shuffle' the arguments that are passed into the &lt;code&gt;Invoke()&lt;/code&gt; method, so that are in the correct place (stack/register) by the time the â€˜target' method is called.&lt;/p&gt;

&lt;p&gt;To understand what's going on, it's helpful to look at the following diagram taken from the BOTR page on &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/method-descriptor.md#precode" rel="noopener noreferrer"&gt;Method Descriptors and Precode stubs&lt;/a&gt;. The â€˜shuffle thunks' we are discussing are a particular case of a â€˜stub' and sit in the corresponding box in the diagram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F01%2FFigure%25203%2520The%2520most%2520complex%2520case%2520of%2520Precode%2C%2520Stub%2520and%2520Native%2520Code.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fmattwarren.org%2Fimages%2F2017%2F01%2FFigure%25203%2520The%2520most%2520complex%2520case%2520of%2520Precode%2C%2520Stub%2520and%2520Native%2520Code.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How â€˜shuffle thunks' are set-up
&lt;/h3&gt;

&lt;p&gt;So let's look at the code flow for the delegate we created in the sample at the beginning of this post, specifically an â€˜open' delegate, calling an instance method (if you are wondering about the difference between open and closed delegates, have a read of &lt;a href="http://blog.slaks.net/2011/06/open-delegates-vs-closed-delegates.html" rel="noopener noreferrer"&gt;â€˜Open Delegates vs. Closed Delegates'&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;We start off in the &lt;code&gt;impImportCall()&lt;/code&gt; method, deep inside the .NET JIT, triggered when a &lt;a href="https://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.call(v=vs.110).aspx" rel="noopener noreferrer"&gt;â€˜call' op-code&lt;/a&gt; for a delegate is encountered, it then goes through the following functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/0d04afc8f5919edcbb371c1e0c4f832f76aed09f/src/jit/importer.cpp#L7348-L7353" rel="noopener noreferrer"&gt;Compiler::impImportCall(..)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/0d04afc8f5919edcbb371c1e0c4f832f76aed09f/src/jit/flowgraph.cpp#L7031-L7167" rel="noopener noreferrer"&gt;Compiler::fgOptimizeDelegateConstructor(..)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/comdelegate.cpp#L3440-L3691" rel="noopener noreferrer"&gt;COMDelegate::GetDelegateCtor(..)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/c5abe8c5a3d74b8417378e03f560fd54799c17f2/src/vm/comdelegate.cpp#L584-L632" rel="noopener noreferrer"&gt;COMDelegate::SetupShuffleThunk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/stubcache.cpp#L70-L165" rel="noopener noreferrer"&gt;StubCacheBase::Canonicalize(..)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/dotnet/coreclr/blob/c5abe8c5a3d74b8417378e03f560fd54799c17f2/src/vm/comdelegate.cpp#L473-L483" rel="noopener noreferrer"&gt;ShuffleThunkCache::CompileStub()&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; EmitShuffleThunk (specific assembly code for different CPU architectures)

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/arm/stubs.cpp#L1534-L1716" rel="noopener noreferrer"&gt;arm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/arm64/stubs.cpp#L1634-L1676" rel="noopener noreferrer"&gt;arm64&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/375948e39cf1a946b3d8048ca51cd4e548f94648/src/vm/i386/stublinkerx86.cpp#L3989-L4240" rel="noopener noreferrer"&gt;i386&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below is the code from the &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/arm64/stubs.cpp#L1634-L1676" rel="noopener noreferrer"&gt;arm64 version&lt;/a&gt; (chosen because it's the shortest one of the three!). You can see that it emits assembly code to fetch the real target address from &lt;code&gt;MethodPtrAux&lt;/code&gt;, loops through the method arguments and puts them in the correct register (i.e. â€˜shuffles' them into place) and finally emits a tail-call jump to the target method associated with the delegate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;
    &lt;span class="n"&gt;VOID&lt;/span&gt; &lt;span class="n"&gt;StubLinkerCPU&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;EmitShuffleThunk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ShuffleEntry&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pShuffleEntryArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// On entry x0 holds the delegate instance. Look up the real target address stored in the MethodPtrAux&lt;/span&gt;
      &lt;span class="c1"&gt;// field and save it in x9\. Tailcall to the target method after re-arranging the arguments&lt;/span&gt;
      &lt;span class="c1"&gt;// ldr x9, [x0, #offsetof(DelegateObject, _methodPtrAux)]&lt;/span&gt;
      &lt;span class="n"&gt;EmitLoadStoreRegImm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eLOAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;DelegateObject&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetOffsetOfMethodPtrAux&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="c1"&gt;//add x11, x0, DelegateObject::GetOffsetOfMethodPtrAux() - load the indirection cell into x11 used by ResolveWorkerAsmStub&lt;/span&gt;
      &lt;span class="n"&gt;EmitAddImm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;DelegateObject&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetOffsetOfMethodPtrAux&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pEntry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pShuffleEntryArray&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SENTINEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;REGMASK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// If source is present in register then destination must also be a register&lt;/span&gt;
          &lt;span class="n"&gt;_ASSERTE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dstofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;REGMASK&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

          &lt;span class="n"&gt;EmitMovReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dstofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OFSMASK&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OFSMASK&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dstofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;REGMASK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// source must be on the stack&lt;/span&gt;
          &lt;span class="n"&gt;_ASSERTE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;REGMASK&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

          &lt;span class="n"&gt;EmitLoadStoreRegImm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eLOAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dstofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OFSMASK&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;RegSp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// source must be on the stack&lt;/span&gt;
          &lt;span class="n"&gt;_ASSERTE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;REGMASK&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

          &lt;span class="c1"&gt;// dest must be on the stack&lt;/span&gt;
          &lt;span class="n"&gt;_ASSERTE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dstofs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ShuffleEntry&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;REGMASK&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

          &lt;span class="n"&gt;EmitLoadStoreRegImm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eLOAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;RegSp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;srcofs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
          &lt;span class="n"&gt;EmitLoadStoreRegImm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eSTORE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;RegSp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pEntry&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dstofs&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;// Tailcall to target&lt;/span&gt;
      &lt;span class="c1"&gt;// br x9&lt;/span&gt;
      &lt;span class="n"&gt;EmitJumpRegister&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IntReg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Other functions that call &lt;code&gt;SetupShuffleThunk(..)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The other places in code that also emit these â€˜shuffle thunks' are listed below. They are used in the various scenarios where a delegate is explicitly created, e.g. via `Delegate.CreateDelegate(..).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/7200e78258623eb889a46aa7a90818046bd1957d/src/vm/comdelegate.cpp#L881-L1099" rel="noopener noreferrer"&gt;COMDelegate::BindToMethod(..)&lt;/a&gt; - actual &lt;a href="https://github.com/dotnet/coreclr/blob/7200e78258623eb889a46aa7a90818046bd1957d/src/vm/comdelegate.cpp#L1019" rel="noopener noreferrer"&gt;call to &lt;code&gt;SetupShuffleThunk(..)&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/7200e78258623eb889a46aa7a90818046bd1957d/src/vm/comdelegate.cpp#L1938-L2174" rel="noopener noreferrer"&gt;COMDelegate::DelegateConstruct(..)&lt;/a&gt; (ECall impl) - actual &lt;a href="https://github.com/dotnet/coreclr/blob/7200e78258623eb889a46aa7a90818046bd1957d/src/vm/comdelegate.cpp#L2052" rel="noopener noreferrer"&gt;call to &lt;code&gt;SetupShuffleThunk(..)&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/7200e78258623eb889a46aa7a90818046bd1957d/src/vm/comdelegate.cpp#L3440-L3691" rel="noopener noreferrer"&gt;COMDelegate::GetDelegateCtor(..)&lt;/a&gt; - actual &lt;a href="https://github.com/dotnet/coreclr/blob/7200e78258623eb889a46aa7a90818046bd1957d/src/vm/comdelegate.cpp#L3618" rel="noopener noreferrer"&gt;call to &lt;code&gt;SetupShuffleThunk(..)&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Different types of delegates
&lt;/h2&gt;

&lt;p&gt;Now that we've looked at how one type of delegate works (#2 â€˜Instance open non-virt' in the table below), it will be helpful to see the other different types that the runtime deals with. From the very informative &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/comdelegate.cpp#L3547-L3567" rel="noopener noreferrer"&gt;&lt;strong&gt;DELEGATE KINDS TABLE&lt;/strong&gt;&lt;/a&gt; in the CLR source:&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;

&lt;thead&gt;

&lt;tr&gt;

&lt;th&gt;#&lt;/th&gt;

&lt;th&gt;delegate type&lt;/th&gt;

&lt;th&gt;_target&lt;/th&gt;

&lt;th&gt;_methodPtr&lt;/th&gt;

&lt;th&gt;_methodPtrAux&lt;/th&gt;

&lt;/tr&gt;

&lt;/thead&gt;

&lt;tbody&gt;

&lt;tr&gt;

&lt;td&gt;1&lt;/td&gt;

&lt;td&gt;Instance closed&lt;/td&gt;

&lt;td&gt;â€˜this' ptr&lt;/td&gt;

&lt;td&gt;target method&lt;/td&gt;

&lt;td&gt;null&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;2&lt;/td&gt;

&lt;td&gt;&lt;strong&gt;Instance open non-virt&lt;/strong&gt;&lt;/td&gt;

&lt;td&gt;&lt;strong&gt;delegate&lt;/strong&gt;&lt;/td&gt;

&lt;td&gt;&lt;strong&gt;shuffle thunk&lt;/strong&gt;&lt;/td&gt;

&lt;td&gt;&lt;strong&gt;target method&lt;/strong&gt;&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;3&lt;/td&gt;

&lt;td&gt;Instance open virtual&lt;/td&gt;

&lt;td&gt;delegate&lt;/td&gt;

&lt;td&gt;Virtual-stub dispatch&lt;/td&gt;

&lt;td&gt;method id&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;4&lt;/td&gt;

&lt;td&gt;Static closed&lt;/td&gt;

&lt;td&gt;first arg&lt;/td&gt;

&lt;td&gt;target method&lt;/td&gt;

&lt;td&gt;null&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;5&lt;/td&gt;

&lt;td&gt;Static closed (special sig)&lt;/td&gt;

&lt;td&gt;delegate&lt;/td&gt;

&lt;td&gt;specialSig thunk&lt;/td&gt;

&lt;td&gt;target method&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;6&lt;/td&gt;

&lt;td&gt;Static opened&lt;/td&gt;

&lt;td&gt;delegate&lt;/td&gt;

&lt;td&gt;shuffle thunk&lt;/td&gt;

&lt;td&gt;target method&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;7&lt;/td&gt;

&lt;td&gt;Secure&lt;/td&gt;

&lt;td&gt;delegate&lt;/td&gt;

&lt;td&gt;call thunk&lt;/td&gt;

&lt;td&gt;MethodDesc (frame)&lt;/td&gt;

&lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The columns map to the &lt;a href="https://github.com/dotnet/coreclr/blob/b1f5c6acca00ca471818237d698baca317851b1f/src/mscorlib/src/System/Delegate.cs#L23-L38" rel="noopener noreferrer"&gt;internal fields of a delegate&lt;/a&gt; (from &lt;code&gt;System.Delegate&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;So we've (deliberately) looked at the simple case, but the more complex scenarios all work along similar lines, just using different and more stubs/thunks as needed e.g. â€˜virtual-stub dispatch' or â€˜call thunk'.&lt;/p&gt;




&lt;h2&gt;
  
  
  Delegates are special!!
&lt;/h2&gt;

&lt;p&gt;As well as being responsible for creating delegates, the runtime also treats delegate specially, to enforce security and/or type-safety. You can see how this is implemented in the links below&lt;/p&gt;

&lt;p&gt;In MethodTableBuilder.cpp:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/methodtablebuilder.cpp#L3341-L3352" rel="noopener noreferrer"&gt;For delegates we don't allow any non-runtime implemented bodies for any of the four special methods&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/methodtablebuilder.cpp#L6316-L6336" rel="noopener noreferrer"&gt;It is not allowed for EnC (edit-and-continue) to replace one of the runtime builtin methods&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/methodtablebuilder.cpp#L6706-L6719" rel="noopener noreferrer"&gt;Don't allow overrides for any of the four special runtime implemented delegate methods&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In ClassCompat.cpp:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/classcompat.cpp#L2749-L2792" rel="noopener noreferrer"&gt;currently the only runtime implemented functions are delegate instance methods&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/classcompat.cpp#L2869-L2880" rel="noopener noreferrer"&gt;For delegates we don't allow any non-runtime implemented bodies for any of the four special methods&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Discuss this post in &lt;a href="https://www.reddit.com/r/programming/comments/5q2w1t/how_do_net_delegates_work/" rel="noopener noreferrer"&gt;/r/programming&lt;/a&gt; and &lt;a href="https://www.reddit.com/r/csharp/comments/5q3ges/how_do_net_delegates_work/" rel="noopener noreferrer"&gt;/r/csharp&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Other links:
&lt;/h2&gt;

&lt;p&gt;If you've read this far, good job!!&lt;/p&gt;

&lt;p&gt;As a reward, below are some extra links that cover more than you could possibly want to know about delegates!!&lt;/p&gt;

&lt;h3&gt;
  
  
  General Info:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="http://stackoverflow.com/questions/299703/delegate-keyword-vs-lambda-notation" rel="noopener noreferrer"&gt;delegate keyword vs. lambda notation - Stack Overflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://stackoverflow.com/questions/73227/what-is-the-difference-between-lambdas-and-delegates-in-the-net-framework" rel="noopener noreferrer"&gt;What is the difference between lambdas and delegates in the .NET Framework?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://news.ycombinator.com/item?id=13198805" rel="noopener noreferrer"&gt;Why can't the jit inline the generated code?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/issues/6737" rel="noopener noreferrer"&gt;Inline literal delegates passed to functions&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://csharpindepth.com/Articles/Chapter2/Events.aspx" rel="noopener noreferrer"&gt;Delegates and Events&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://blog.slaks.net/2011/06/open-delegates-vs-closed-delegates.html" rel="noopener noreferrer"&gt;Open Delegates vs. Closed Delegates&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://www.philosophicalgeek.com/2014/07/25/using-windbg-to-answer-implementation-questions-for-yourself-can-a-delegate-invocation-be-inlined/" rel="noopener noreferrer"&gt;Using Windbg to answer implementation questions for yourself (Can a Delegate Invocation be Inlined?)&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/issues/8819" rel="noopener noreferrer"&gt;[Question] Can Virtual Stub Dispatch be “inlined”?&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/virtual-stub-dispatch.md" rel="noopener noreferrer"&gt;BOTR - Virtual Stub Dispatch&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internal Delegate Info
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="http://blog.monstuff.com/archives/000038.html" rel="noopener noreferrer"&gt;C# Delegates strike back Â· Curiosity is bliss&lt;/a&gt; (mostly from a Mono P.O.V)&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://stackoverflow.com/questions/7136615/open-delegate-for-generic-interface-method" rel="noopener noreferrer"&gt;Open delegate for generic interface method&lt;/a&gt; (Bug in the CLR)&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/issues/5275" rel="noopener noreferrer"&gt;[ARM/Linux] ARM-softfp delegate code generation issue&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/virtualcallstub.h#L122-L134" rel="noopener noreferrer"&gt;On x86 are four possible kinds of callsites when you take into account all features&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/virtualcallstub.h#L179-L222" rel="noopener noreferrer"&gt;VirtualCallStubManager is the heart of the stub dispatch logic. See the book of the runtime entry&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/vm/virtualcallstub.h#L912-L948" rel="noopener noreferrer"&gt;StubDispatchNotes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://syslog.ravelin.com/anatomy-of-a-function-call-in-go-f6fc81b80ecc" rel="noopener noreferrer"&gt;Anatomy of a function call in Go&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Debugging delegates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="http://geekswithblogs.net/akraus1/archive/2012/05/20/149699.aspx" rel="noopener noreferrer"&gt;Useful .NET Delegate Internals&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/fremag/MemoScope.Net/wiki/Delegate-Targets" rel="noopener noreferrer"&gt;Delegate Targets from MemoScope.Net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/fremag/MemoScope.Net/blob/master/MemoScope/Modules/Delegates/DelegatesAnalysis.cs" rel="noopener noreferrer"&gt;DelegatesAnalysis.cs from MemoScope.Net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://github.com/Microsoft/clrmd/issues/35" rel="noopener noreferrer"&gt;Getting the method name of a Delegate instance&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://stackoverflow.com/questions/3668642/get-method-name-from-delegate-with-windbg" rel="noopener noreferrer"&gt;Get method name from delegate with WinDbg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://julmar.com/blog/debugging/sos-finding-the-method-bound-to-an-eventhandler-with-windbg/" rel="noopener noreferrer"&gt;SOS: finding the method bound to an EventHandler with WinDbg.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://blogs.msdn.microsoft.com/abhinaba/2014/09/29/net-just-in-time-compilation-and-warming-up-your-system/" rel="noopener noreferrer"&gt;.NET Just in Time Compilation and Warming up Your System&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;






&lt;p&gt;The post &lt;a href="http://mattwarren.org/2017/05/25/Lowering-in-the-C-Compiler/" rel="noopener noreferrer"&gt;How do .NET delegates work?&lt;/a&gt; appeared first on my blog &lt;a href="http://mattwarren.org" rel="noopener noreferrer"&gt;mattwarren.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>net</category>
      <category>clr</category>
    </item>
  </channel>
</rss>
