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