Its very basic question.
JIT compilation is on demand as per MSDN MSIL To Native Code.
Every time when we run the assembly JIT compiler converts MSIL to Native language? Or When we run assembly first time, it converts and store the native language code to somewhere?
Thanks in advance!
The JIT compiler compiles your code when you start the application and stores it in memory.
This code can be cached by ngen.exe (Native Image Generator) and stored in the native image cache. This will be automatically loaded the next time you start the application, and you won't have to JIT the MSIL code a second time.
Ngen.exe creates native images, which are files containing compiled processor-specific machine code, and installs them into the native image cache on the local computer. The runtime can use native images from the cache instead of using the just-in-time (JIT) compiler to compile the original assembly.
The native image cache can be found on a path similar to C:\Windows\assembly\NativeImages_v4.0.30319_64. This path is not accessible through Windows Explorer, so use cmd or a powershell.
Related
I know that Java code is compiled into byte-code, that is executed by the JVM.
What is the case with C# ? I have noticed that applications written in C# have the .exe extension what would suggest they are native machine instructions. but is it really so ?
No.
Like Java, C# is compiled to an intermediary language (called MSIL or CIL).
Unlike Java, the IL is stored in EXE files which have enough actual EXE code to show a dialog box asking users to install .Net.
C# compilation is done in these two steps :
1. Conversion from C# to CIL by the C# compiler
2. Conversion from CIL to instructions that the processor can execute.
A component (just in time) performs this compilation at run time from CIL to machine code
What that .exe is supposed to tell you is that the file is executable. C# is compiled into bytecode, just as java is, but .NET wraps this in a CLR executable.
Look here for a more in depth look at CLR executable http://etutorials.org/Programming/.NET+Framework+Essentials/Chapter+2.+The+Common+Language+Runtime/2.2+CLR+Executables/
c# code is compiled to MSIL. it likes java bytecode. msil will be convert to machine isntrctions at runtime.
C# code is compiled to MSIL, MSIL is taken care by .NET CLR
There is also a project that allows compilation of C# to standalone binary executables: CoreRT
I am trying to get something clarified.
When a .NET console application is run, does mscorlib.dll/mscoree.dll get loaded in the process's virtual address space?
mscorlib.dll and mscoree.dll (CLR) are not managed dlls. Is that correct?
Also, what is a good resource to understand more about how a .NET program is executed?
Yes. You'll always get mscoree.dll loaded, that's the bootstrapper for the default CLR host. It is an unmanaged DLL. Every .NET assembly contains a wee bit of native code, just a jump into that DLL. It does however get loaded by recent Windows versions directly, the OS loader has .NET awareness built-in. You can see it in the Debug + Modules window when you turn on the unmanaged debugging option, Project + Properties, Debug tab. You'll then also see mscorjit.dll, mscorwks.dll and msvcr80.dll, three other chunks of native code that are required to run managed code. Respectively the just-in-time compiler, the CLR and the C-runtime support library. They have different DLL names in .NET 4.
Technically it is possible to not get mscorlib.dll loaded, the compiler has the /nostdlib option to avoid a reference to that assembly. Practically that only works if you provide a substitute, that's how Silverlight gets compiled for example. It is otherwise a mixed-mode assembly with some native code but mostly managed code. There's a separate version of it for the 64-bit framework because of that. You'll also see mscorlib.ni.dll with unmanaged debugging enabled, that's the ngen-ed version of the assembly.
I would recommend to read the Jefrey Richter's book CLR via C#. It provides very clear explanation what is going on under the hood :)
Also yoг may find this question helpful: Why is an assembly .exe file?
.Net Executable is no different than any other PE files. So like every imported dlls in native executable, mscorlib.dll is loaded in the Process virtual space of .net executable.
If it interests you, you can read about PE file format here
whats the relation(if any) of MASM assembly language and ILASM. Is there a one to one conversion? Im trying to incorporate Quantum GIS into a program Im kinda writing as I go along! I have GIS on my computer, I have RedGate Reflector and it nor the Object Browser of Visual Studio 2008 couldnt open one(of several which I dont have a strong clue to how they behave) of the .dlls in Quantum. I used the MASM assembly editor and "opened" the same dll and it spewed something I didnt expect to necessarily understand in the first place. How can I/can I make a conversion of that same "code" to something I can interact with in ILASM and Im assuming consequently in Csharp? Thanks a ton for reading and all the responses to earlier questions...please bear in mind Im relatively new to programming in Csharp, and even fresher to MASM and ILASM.
MASM deals with the x86 instructions and is platform/processor dependent, while ILASM reffers to the .Net CIL (common intermediary language) instructions which are platform/processor independent. Switching from something specific to something more general is hard to achieve, that's why, AFAIK, there is no converter from MASM to ILASM (inverse, there is!)
IL is a platform independent layer of abstraction over native code. Code written on the .NET platform in C#, VB.NET, or other .NET language all compile down to an assembly .EXE/.DLL containing IL. Typically, the first time the IL code is executed the .NET runtime will run it through NGen, which compiles it once again down to native code and stores the output in a temporary location where it is actually executed. This allows .NET platform code to be deployed to any platform supporting that .NET framework, regardless of the processor or architecture of the system.
As you've seen, Reflector is great for viewing the code in an assembly because IL can easily be previewed in C# or VB.NET form. This is because IL is generally a little higher level instructions and also contain a lot of metadata that native code wouldn't normally have, such as class, method, and variable names.
It's also possible to compile a .NET project directly to native code by setting the Visual Studio project platform or by calling Ngen.exe directly on the assembly. Once done, it's really difficult to make sense of the native code.
Ther is no relationship between MASM assembly language and ILASM. I don't see you have any way to convert native code to IL code. IL can be understood by CLR only while the MASM assembly language is about native machine code. CLR turns the IL into native code in runtime
I am running performance profile for a C# application on a virtual machine.
The results shows a huge load of "JIT Compiler". When I dig further, it shows something called "Class Loader" as the only method getting called by JIT compiler.
What should I do to bring "JIT compiler" load down?
JIT is the 'Just In Time' compiler, this essentially compiles your C# into executable code that can work on the current processor.
.Net comes with a utility called NGEN, this creates a native image of your C# code, that doesn't need to be JIT'ted. There are downsides to this however, have a read of this:
http://codeidol.com/csharp/net-framework/Assemblies,-Loading,-and-Deployment/Native-Image-Generation-%28NGen%29/
And finally here's a link to the MS info about NGEN:
http://msdn.microsoft.com/en-us/library/6t9t5wcf%28VS.80%29.aspx
You could try using NGEN to pre-JIT your assemblies to native images. This will lessen Jitting overhead on application load:
http://msdn.microsoft.com/en-us/library/6t9t5wcf(VS.80).aspx
You should run this tool on the machine where your assemblies are i.e. your virtual machine.
Q1) Why is C# initially compiled to IL and then at runtime JIT complied and run on top of a virtual machine(?). Or is it JIT complied to native machine code?
Q2) If the second is true (JIT complied to native machine code), then where is the .NET sandbox the code runs under?
Q3) In addition, why is the code compiled to IL in the first place. Why not simply compile to native machine code all the time? There is a tool from MS from this called ngen but why is that optional?
The IL is JIT'd (JIT = Just In Time) compiled to native machine code as the process runs.
The use of a virtual machine layer allows .NET to behave in a consistent manner across platforms (e.g. an int is always 32 bits regardless of whether you're running on a 32- or 64- bit machine, this is not the case with C++).
JIT compiling allows optimisations to dynamically tailor themselves to the code as it runs (e.g. apply more aggressive optimisations to bits of code that are called frequently, or make use of hardware instructions available on the specific machine like SSE2) which you can't do with a static compiler.
A1) JIT compiles to native machine code
A2) In .net there is no such term as sandbox. There is AppDomains instead. And they runs as part of CLR (i.e. as part of executable process)
A3) NGen drawbacks from Jeffrey Richter:
NGen'd files can get out of sync.
When the CLR loads an NGen'd file, it compares a
number of characteristics about the previously compiled code and the current execution
environment. If any of the characteristics don't match, the NGen'd file cannot be
used, and the normal JIT compiler process is used instead.
Inferior Load-Time Performance (Rebasing/Binding).
Assembly files are standard Windows PE files, and, as such, each contains a preferred base address. Many Windows
developers are familiar with the issues surrounding base addresses and rebasing. When JIT compiling code, these issues aren't a concern because correct memory address references are calculated at run time.
Inferior Execution-Time Performance.
When compiling code, NGen can't make as many
assumptions about the execution environment as the JIT compiler can. This causes
NGen.exe to produce inferior code. For example, NGen won't optimize the use of
certain CPU instructions; it adds indirections for static field access because the actual
address of the static fields isn't known until run time. NGen inserts code to call class
constructors everywhere because it doesn't know the order in which the code will execute
and if a class constructor has already been called.
You can use NGEN to create native versions of your .NET assemblies. Doing this means that the JIT does not have to do this at runtime.
.NET is compiled to IL first and then to native since the JIT was designed to optimize IL code for the current CPU the code is running under.
.NET code is compiled to IL for compatability. Since you can create code using C#, VB.NET, etc then the JIT needs a common instruction set (IL) in order to compile to native code. If the JIT had to be aware of languages, then the JIT would need to be updated when a new .NET language was released.
I'm not sure about the sandbox question, my best guess is that a .NET app runs with 3 application domains. One domain contains the .NET runtimes (mscorlib, system.dll, etc), another domain contains your .NET code, and I can't recall what the other domain's for.
Check out http://my.safaribooksonline.com/9780321584090
1. C# is compiled in to CIL (or IL) because it shares a platform with the rest of the .NET languages (which is why you can write a DLL in C# and use it in VB.NET or F# without hassle). The CLR will then JIT Compile the code into Native Machine Code.
.NET can also be run on multiple platforms (Mono on *NIX and OS X). If C# compiled to native code, this wouldn't be nearly as easy.
2. There is no sandbox.
3. Covered in the answer to #1
A1) This way it's platform agnostic (Windows, Linux, Mac) and it can also use specific optimizations for your current hardware. When it gets JIT compiled it's to machine code.
A2) The whole framework (the .NET framework) is all sandbox so all calls you might make through your app will go through the .NET framework sandbox.
A3) As in answer 1, it allows the .NET binary to work in different platforms and perform specific optimizations in the client machine on the fly.
Compiled .Net code becomes IL which is an intermediate language in the exact same way as that of Javas' object code. Yes it is possible to generate native machine code using the NGen tool. NGen binds the resulting native image to the machine, so copying the ngen'd binary to a different system would not produce expected results. Compiling to intermediate code allows for runtime decisions that can be made that otherwise can't (easily) be made with a staticly-typed language like C++, it also allows the functioning of code on different hardware archetectures because the code then becomes descriptive in the sense that it also describes the intent of what should happen in a bit (eg 32 or 64)-agnostic way, as opposed to machine-specific code that only works on 32-bit systems or 64-bit systems but not both.
Also, NGen is optional because as I said it binds the binary to the system, it can be useful when you need the performance of compiled machine code with the flexibility of a dynamically typed language and you know that the binary won't be moving to a system it's not bound to.