JIT Compilation - Microsoft Azure â€؛ slides...آ  JIT Performance Counters - % Time in Jit % elapsed

  • View

  • Download

Embed Size (px)

Text of JIT Compilation - Microsoft Azure â€؛ slides...آ  JIT Performance Counters - % Time in Jit %...

  • JIT Compilation

  • Module Overview

    JIT Compilation

    Native vs. Managed Compilation

    Managed Execution Phases

    Assembly Loading & Initialization

    JIT Compilation

    JIT Optimizations

    What’s new in NGEN 4.0?

    When to use NGEN?


  • Running Code

    Behavior in Windows 2000

    - Legacy entry point mscoree!CorExeMain gets used

    Behavior in Windows XP

    - The operating system loader checks for managed modules by examining a bit

    in the common object file format (COFF) header - The bit being set denotes a managed module

    - If the loader detects managed modules, it loads mscoree.dll, and

    clr!CorValidateImage and clr!CorImageUnloading notify the loader when the

    managed module images are loaded and unloaded

    clr!CorValidateImage performs the following:

    - Ensures that the code is valid managed code

    - Changes the entry point in the image to an entry point in the runtime

    On 64-bit Windows, _CorValidateImage modifies the image that is in

    memory by transforming it from PE32 to PE32+


  • Native compile vs Managed compile

    Simplified view of native code compilation

    .CPP or .C file

    containing C or C++


    Compile .OBJ File (Machine


    .EXE or .DLL File

    (Machine language) Link

    Native Code

    Type describing inform ation



    inform ation


  • Native compile vs Managed compile

    Simplified view of managed code compilation

    .CS File containing C#

    code Compile

    Assembly(.EXE or

    .DLL) containing MSIL

    and Metadata

    Machine Language

    generated in memory

    at runtime by JIT



    Managed Code


  • .NET Source code

    IL and Metadata

    Managed Execution Phases

    Native Code

    Compile Time

    Run Time

    Phase .NET Source code

    IL and Metadata

    IL and Metadata

    Native CodeJIT (CLR)



  • JIT Compilation

    What does JIT do?

    Checks if function is called 1st time

    - JIT compiles IL code to native code if true

    Stores native code in memory

    Updates MethodDescriptor field

    - Reference updated to point to memory location of native code


  • Execute the native code


    First call?

    CILJit::compileMethod (x86)

    PreJit::compileMethod (x64)

    [verifies and compiles the IL]

    Native code, GCInfo, EH


    Store native code in memory Store the address in


    Execute the native code

    Y e


    Retrieve address of native

    code from MethodDesc


    Managed Execution

    JIT Compilation


  • MethodDescriptor

    Contains implementation of a managed method

    Generated as part of the class loading procedure

    Initially points to IL Code

    Can be determined during debugging

    - !SOS.DumpMD

    0:004> !dumpmd 009969a8 Method Name: MyApp.MainForm.menu_Click(System.Object, System.EventArgs)

    Class: 00cd5c0c

    MethodTable: 00996ad4

    mdToken: 0600028d

    Module: 00992c3c

    IsJitted: no

    CodeAddr: ffffffff Transparency: Critical


  • Process starts and

    loads the .NET


    MSCoreEE.dll is loaded

    Process Main thread starts executing

    by calling _CorExeMain

    Initializes CLR

    Reads MetaData tables

    Build InMemory representation

    ClassLoader is called

    JIT compile the Main method

    Execute Main

    MethodTable &


    Managed Execution

    Assembly Loading and Initialization


  • Anatomy of a managed non-value instance

    (very schematic)




    “Hot” metadata





    MethodTable EEClass


    Loader Heap

    Pointer to


    •JItted code

    •“IL” stub


    GC Heap

    Field layout


    * == Pointer 11

  • !DumpClass & DumpMT


  • JIT Optimizations


    Types of Optimization:

    - JIT Inlining

    - JIT Tail Calls


  • JIT Optimizations

    Tail Calls

    When the last thing a function does is call another function

    - Calls without Optimization:

    - With Optimization:

    - will use the same stack space as the caller.

    - improve data locality, memory usage,

    and cache usage.

    static public void Main() {

    Helper(); }

    static public void Helper() {

    One(); Two(); Three();


    static public void Three() {

    ... }

    Call One() Call Two() Call Three()

    Call One() Call Two() Jump Three()


  • JIT Optimizations

    Tail Calls

    Tail Call Feature set different between X86 and X64

    - Can lead to e.g. Stack Overflow Exception on X86 Debug but works fine on

    X64 ( where x86 stack just enough in release with tail call, but overflows

    without optimization)

    No Tail Calls possible if:

    - Caller doesn't return immediately after the call

    - Stack arguments between caller and callee are incompatible in a way that

    would require shifting things around in the caller's frame before the callee

    could execute

    - Caller and callee return different types

    - We inline the call instead (inlining is way better than tail calling, and opens the

    door to many more optimizations)

    - Security issues

    - The debugger / profiler turned off JIT optimizations

    - Full list see: .NET 2.0 Tail limits and .NET 4.0 Tail Limits


    http://blogs.msdn.com/b/davbr/archive/2007/06/20/tail-call-jit-conditions.aspx http://blogs.msdn.com/b/davbr/archive/2007/06/20/tail-call-jit-conditions.aspx http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx

  • JIT Optimizations – Inlining

    Without inlining

    With inlining

    class Test { static int And(int i1, int i2) { return i1 & i2; } static int i; static public void Main() { i = And(i, 0); } }

    class Test { static int i; static public void Main() { i = 0 // xor edx,edx } }


  • JIT Optimizations – Inlining

    Without Inlining:Main()

    mov ecx,dword ptr ds:[183368h] ; setup first argument (i) xor edx,edx ; setup second argument (0) call dword ptr ds:[183818h] (Inline.Program+Test.And(Int32, Int32), mdToken: 06000002) ; Call And(…) mov dword ptr [ebp-4],eax ; save return value mov eax,dword ptr [ebp-4] ; assign result to static mov dword ptr ds:[00283368h],eax ; assign result to static

    ret ; return

    And(Int32, Int32)

    mov eax,dword ptr [ebp-4] ; move arg 1 to eax and eax,dword ptr [ebp-8] ; Add argument 2 to eax (return register)

    ret ; return to caller


  • JIT Optimizations – Inlining

    With Inlining

    - And(.,.) is inlined now

    - No add reg,reg - because not needed (argument is 0)

    MethodDesc Table Entry MethodDesc JIT Name 53dda7e0 53bb4934 PreJIT System.Object.ToString() 53dde2e0 53bb493c PreJIT System.Object.Equals(System.Object) 53dde1f0 53bb495c PreJIT System.Object.GetHashCode() 53e61600 53bb4970 PreJIT System.Object.Finalize() 001dc019 001d3828 NONE Inline.Program+Test..ctor() 001dc011 001d3810 NONE Inline.Program+Test.And(Int32, Int32) 00270070 001d381c JIT Inline.Program+Test.Main()

    Main() xor edx,edx ; generate final result mov dword ptr ds:[1D3368h],edx ; move result to static ret ; return


  • Demo: JIT Compilation

    !dumpmt –md

    bp cmdStartJit_Click

  • JIT Optimizations

    Additional Config

    Instruct CLR not to optimize the code (during jit)

    without recompiling the dll:

    - Use an ini file (and symbols)

    • MyDll.ini: [.NET Framework Debugging Control]

    GenerateTrackingInfo=1 (per default on up from .NET 2.0)


    • (useable for GAC as well)

    Instruct CLR to ignore (optimized) Ngen Image

    - Use Environment variable: set COMPLUS_ZapDisable=1


  • JIT Performance Counters - % Time in Jit

    % elapsed time in JIT compilation since JIT started

    Updated at the end of every JIT compilation phase.

    A JIT compilation phase occurs when a method and its

    dependencies are compiled.

    A value > 5% can indicate a problem

    - Is Ngen an option?

    • http://msdn.microsoft.com/en-us/magazine/cc163610.aspx

    - Do you use multiple AppDomains?

    • loading assemblies as domain neutral can help

    - Minimize the classes and assemblies within code path

    • Use code coverage to determine these components.

    - See .NET Framework Usage Performance Ru