Under the hood of the CLR Managed Execution
description
Transcript of Under the hood of the CLR Managed Execution
Under the hood of the CLRManaged Execution
Paul CrossPaul CrossSenior .NET Systems EngineerSenior .NET Systems EngineerMicrosoft Ltd.Microsoft Ltd.
Managed ExecutionWhat is the Common Language Runtime?
Responsible for managing the Responsible for managing the execution of code that is targeted execution of code that is targeted towards the .NET platformtowards the .NET platform
Code that requires the CLR at run-time Code that requires the CLR at run-time in order to execute is referred to as in order to execute is referred to as managed codemanaged code
Managed ExecutionWhat is the role of the CLR?
The CLR exists to provide managed The CLR exists to provide managed services to code and typesservices to code and types Services include the class loader, IL, IL-Services include the class loader, IL, IL-
native compilation, profiling, debugging, native compilation, profiling, debugging, exception handling, serialization, exception handling, serialization, security, memory management and security, memory management and garbage collectiongarbage collection
Managed and unmanaged code may Managed and unmanaged code may coexistcoexist
Low management costs until services Low management costs until services are usedare used
Managed ExecutionCLR Architecture
Managed code relies on two DLLsManaged code relies on two DLLs MSCOREE.DLLMSCOREE.DLL
The CLR, or the RuntimeThe CLR, or the Runtime Is an unmanaged DLL that loads Is an unmanaged DLL that loads
managed codemanaged code MSCORLIB.DLLMSCORLIB.DLL
The Base Class Library, or the runtime The Base Class Library, or the runtime librarylibrary
Is a managed DLLIs a managed DLL
Managed ExecutionWhere does Managed Code come from?
Create source code using any Create source code using any programming language that supports programming language that supports the CLRthe CLR
Compile the source code using the Compile the source code using the corresponding compiler resulting in a corresponding compiler resulting in a managed modulemanaged module
Managed ExecutionWhat is a Managed Module?
A managed module is a standard Windows A managed module is a standard Windows PE file that requires the CLR to executePE file that requires the CLR to execute They can be loaded using the LoadLibrary They can be loaded using the LoadLibrary
system callsystem call
What are the constituent parts of a What are the constituent parts of a Managed Module?Managed Module? PE HeaderPE Header CLR HeaderCLR Header MetadataMetadata Intermediate (IL) codeIntermediate (IL) code
Managed ExecutionWhat is a Portable Executable (PE) File?
The Microsoft implementation of The Microsoft implementation of COFF (Common Object File Format)COFF (Common Object File Format)
COFFCOFF 32-bit format for executable and object 32-bit format for executable and object
files that is portable across platformsfiles that is portable across platforms
Derived from Unix specificationDerived from Unix specification Additional headers for compatibility with Additional headers for compatibility with
MS-DOS and 16-bit WindowsMS-DOS and 16-bit Windows
Managed Execution What is a Managed Module? PE HeaderPE Header
Indicates the type of file: GUI, CUI, DLL plus timestampIndicates the type of file: GUI, CUI, DLL plus timestamp For modules containing only IL code, most information is ignored, For modules containing only IL code, most information is ignored,
for native CPU code contains information about that codefor native CPU code contains information about that code CLR HeaderCLR Header
Version of the CLR requiredVersion of the CLR required FlagsFlags MethodDef metadata token of the module’s entry point method (aka Main MethodDef metadata token of the module’s entry point method (aka Main
method)method) Location/size of metadata, resources, strong name, etc..Location/size of metadata, resources, strong name, etc..
MetadataMetadata Basically a set of tablesBasically a set of tables 2 main types of tables:2 main types of tables:
Tables describing defined types and membersTables describing defined types and members Tables describing referenced types and membersTables describing referenced types and members
Intermediate Language (IL) CodeIntermediate Language (IL) Code Code that the compiler produced as it compiled the source codeCode that the compiler produced as it compiled the source code
Creating a Managed Module
Managed ExecutionAssemblies Oops… The CLR doesn’t work with modules, it Oops… The CLR doesn’t work with modules, it
works with works with assembliesassemblies What is an assembly?What is an assembly?
Logical grouping of one or more managed modules or Logical grouping of one or more managed modules or resource files, c.f. modules that are physical constructs resource files, c.f. modules that are physical constructs that exist as byte-arrays, typically in the file systemthat exist as byte-arrays, typically in the file system
Smallest unit or reuse, security, and versioningSmallest unit or reuse, security, and versioning May be single-file or multi-file, primarily to support May be single-file or multi-file, primarily to support
deferred loading or infrequently accessed codedeferred loading or infrequently accessed code Contains a Contains a manifestmanifest
Describes the files that make up the assembly, public Describes the files that make up the assembly, public exported types implemented by those files, resource exported types implemented by those files, resource or data files associated with the assemblyor data files associated with the assembly
Modules that lack an assembly manifest can only be Modules that lack an assembly manifest can only be loaded indirectlyloaded indirectly
Self-describingSelf-describing
Creating an Assembly
Investigating IL
Managed ExecutionExamining a Managed Module
Using dumpbinUsing dumpbin /clrheader/clrheader
Displays information about the .NET headers Displays information about the .NET headers used in any managed program Location, size used in any managed program Location, size of the .NET header and sections in the headerof the .NET header and sections in the header
/all/all Displays all available information except code Displays all available information except code
disassembly. Use /DISASM to display disassembly. Use /DISASM to display disassembly. Use /RAWDATA:NONE with /ALL disassembly. Use /RAWDATA:NONE with /ALL to omit the raw binary details of the fileto omit the raw binary details of the file
Examining a Managed Module
Managed ExecutionCLR Architecture
How can I tell if the .NET Framework How can I tell if the .NET Framework has been installed on the target has been installed on the target machine?machine? Check for residency of MSCorEE.dll in the Check for residency of MSCorEE.dll in the
%windir%\system32 directory%windir%\system32 directory More than one version may be installed. In More than one version may be installed. In
which case checkwhich case check
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policyHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\policy
Managed ExecutionLoading the CLR
EXE assemblies contain some special EXE assemblies contain some special goo in the PE header and .text sectiongoo in the PE header and .text section
Cause the CLR to load and initializeCause the CLR to load and initialize CLR locates the application’s entry CLR locates the application’s entry
point and starts the execution processpoint and starts the execution process
Managed ExecutionLoading the CLR
Managed EXE Address space
PE header
.text section
.idata section
CLR header
IL
Metadata
Managed EXE
MSCorEE.dll
Process’s primary
thread starts
1. MSCorEE examines CLR header to get .entrypoint method’s metadata token.2. MSCorEE examines .entrypoint metadata to get location of IL within the EXE.3. MSCorEE compiles .entrypoint IL to native CPU.4. MSCorEE jumps to .entrypoint native CPU (using primary thread) – the
application runs.
JMP _CorExeMain
DLL: MsCorEE.dllFunction: _CorExeMain
Managed ExecutionLoading the CLR
6-byte stub functions required for:6-byte stub functions required for: Windows 98, 98 SE, Me, NT4 and 2000Windows 98, 98 SE, Me, NT4 and 2000 Specifically for x86 machinesSpecifically for x86 machines
6-byte stub functions not required for:6-byte stub functions not required for: Windows XP, .NET Server FamilyWindows XP, .NET Server Family Loader modified to look for managed Loader modified to look for managed
assembliesassemblies Examines directory entry 14 in the PE Examines directory entry 14 in the PE
file headerfile header
Managed ExecutionJust-In-Time Compilation (JIT)
JIT Compiler
Class Loader
ExecutionEngine
Functional Duties:Functional Duties: Class LoaderClass Loader
Resolves type references and Resolves type references and loads assemblies into memory to loads assemblies into memory to be consumed by the verifier and be consumed by the verifier and JIT CompilerJIT Compiler
JIT CompilerJIT Compiler Runtime component that Runtime component that
compiles the MSIL stream into compiles the MSIL stream into native codenative code
Compares MSIL stream to Compares MSIL stream to metadata and verifies that the metadata and verifies that the code is safe and legal code is safe and legal (Verification)(Verification)
Managed ExecutionJIT Options for Application Developers
.NET provides two JIT compilers and an .NET provides two JIT compilers and an install-time JIT option:install-time JIT option: A “normal” JIT compiler, designed to provide A “normal” JIT compiler, designed to provide
the expected optimization when compiling MSIL the expected optimization when compiling MSIL to native codeto native code The same level of optimization you might expect The same level of optimization you might expect
from a C compilerfrom a C compiler This makes the compilation process take longer This makes the compilation process take longer
than otherwisethan otherwise Ngen.exe, MSIL code is “pre-JIT’ed” or “zapped” Ngen.exe, MSIL code is “pre-JIT’ed” or “zapped”
and the native image is cached for future useand the native image is cached for future use
Managed ExecutionJust-In-Time Compilation (JIT)
IL must be compiled to native code in order IL must be compiled to native code in order to runto run No files with *.il extensions involvedNo files with *.il extensions involved Multiple JIT compilers for differing processor Multiple JIT compilers for differing processor
architecturesarchitectures Code compiled on an “as needed” basisCode compiled on an “as needed” basis Method cached and subsequent calls are not Method cached and subsequent calls are not
recompiledrecompiled Can revert back to a stub using Can revert back to a stub using code pitchingcode pitching
Reduces memory footprintReduces memory footprint
Managed ExecutionCalling a method for the first time
Managed EXE
Shared Sub Main() Console.WriteLine(“Paul”) Console.WriteLine(“Cross”)End Sub
Console
Shared Sub WriteLine()
Shared Sub WriteLine(String)
(remaining members)
Jitter
Jitter
…
MSCorEE.dll
Function Jitter1. In the assembly that implements the type (Console), look up the method (WriteLine)
being called in the metadata.2. From the metadata, get the IL for this method.3. Allocate a block of memory.4. Compile the IL into native code; save the code in the memory allocated in step 3.5. Modify the method’s entry in the Type’s table so that it now points to the memory block
allocated in step 3.6. Jump to the native code contained inside the memory block.
End Function
Native code
Managed ExecutionJIT Features
Platform IndependencePlatform Independence Realized when high-level language Realized when high-level language
compilers convert source code to compilers convert source code to platform agnostic MSIL codeplatform agnostic MSIL code
The application or software component The application or software component is distributed in this formis distributed in this form
JIT compiles to native code either at JIT compiles to native code either at runtime or at install timeruntime or at install time
Managed ExecutionJIT Features
Language InteroperabilityLanguage Interoperability Occurs when different language Occurs when different language
compilers compile to language-agnostic compilers compile to language-agnostic MSIL codeMSIL code
Metadata and the Common Type System Metadata and the Common Type System play a major role in cross-language and play a major role in cross-language and platform independenceplatform independence
Managed ExecutionJIT Features
Runtime Stack ManipulationRuntime Stack Manipulation The JIT Compiler populates important The JIT Compiler populates important
data structures for object tracking and data structures for object tracking and specific stack-frame constructionspecific stack-frame construction
The JIT Compiler can be used to identify The JIT Compiler can be used to identify specific code elements as they are specific code elements as they are consumed, i.e., exception handlers and consumed, i.e., exception handlers and security descriptorssecurity descriptors
Managed ExecutionJIT Optimizations
Small Memory FootprintSmall Memory Footprint JIT compilation takes advantage of the JIT compilation takes advantage of the
possibility that some code may never be possibility that some code may never be usedused
The JIT Compiler compiles methods only The JIT Compiler compiles methods only as neededas needed
Managed ExecutionJIT Optimizations
Contiguous Native Code AlignmentContiguous Native Code Alignment The runtime method is optimized for fast The runtime method is optimized for fast
data accessdata access The execution engine has the option of The execution engine has the option of
aligning native function images in aligning native function images in memorymemory Lends for a smaller footprintLends for a smaller footprint Speeds up CPU access to memory Speeds up CPU access to memory
where code is storedwhere code is stored
Managed ExecutionJIT Compilation must be slow…
The “Nays”:The “Nays”: Unmanaged code is pre-compiled and Unmanaged code is pre-compiled and
can just executecan just execute Managed code requires 2 compilation Managed code requires 2 compilation
phasesphases Compiler produces ILCompiler produces IL IL compiled to native code at runtime, IL compiled to native code at runtime,
requiring more memory to be requiring more memory to be allocated, and additional CPU cyclesallocated, and additional CPU cycles
Managed ExecutionJIT Compilation is actually pretty fast…
The “Ayes”:The “Ayes”: Second compilation stage does hurt Second compilation stage does hurt
performance and allocate dynamic performance and allocate dynamic memorymemory
However…However… This stage is very heavily optimised This stage is very heavily optimised
and will only get betterand will only get better Many people believe that managed Many people believe that managed
applications could actually outperform applications could actually outperform unmanaged applicationsunmanaged applications
Managed ExecutionJIT Compilation is actually pretty fast…
Reasons why this may be the case:Reasons why this may be the case: JIT compiler knows more about the execution JIT compiler knows more about the execution
environment than an unmanaged compiler environment than an unmanaged compiler would knowwould know
JIT compiler can take advantage of instructions JIT compiler can take advantage of instructions offered by the chip that the unmanaged offered by the chip that the unmanaged compiler knows nothing aboutcompiler knows nothing about
JIT compiler could detect that a certain test is JIT compiler could detect that a certain test is always false, and short-circuitalways false, and short-circuit
The CLR could profile the code’s execution and The CLR could profile the code’s execution and recompile the IL on the fly reducing branching, recompile the IL on the fly reducing branching, etc.etc.
Managed ExecutionAlternatives to JIT Compilation
NGen.exeNGen.exe Unmanaged code!Unmanaged code!
Summary
EXEs and DLLs are composed of ILEXEs and DLLs are composed of IL Even though they are PE files…Even though they are PE files…
.NET EXEs will not run on a machine .NET EXEs will not run on a machine unless .NET is installedunless .NET is installed
Without .NET there is no JIT and Without .NET there is no JIT and without JIT there is no native codewithout JIT there is no native code
Without .NET there is no runtime host Without .NET there is no runtime host to launch the native code and no CLR to launch the native code and no CLR in which to run the code, even if the in which to run the code, even if the native code was launchednative code was launched