Does CLR still loads the assembly in the process even when it has Ngen'd copy of that assembly

424 views Asked by At

I was reading an article from Jeffrey Richter' book CLR via C#. And I found a nice paragraph about the NGen.exe tool.

Many people believe that it might be possible to ship NGen’d files without shipping the files containing the original IL code, thereby keeping their intellectual property a secret. Unfortunately, this is not possible. At run time, the CLR requires access to the assembly’s metadata (for functions such as reflection and serialization); this requires that the assemblies that contain IL and metadata be shipped.

I just wanted to clear few thing.

  1. Does CLR always loads the assembly when the referencing types are there in the assembly.
  2. Does it do verification check on it?
  3. When it comes to compiling the code (JIT compiler), does it look for NGen'd code and load the compiled native CPU instructions from that file, or doesn't load the assembly at all when NGen'd file is already there?
1

There are 1 answers

14
Yuval Itzchakov On

Does CLR always loads the assembly when the referencing types are there in the assembly.

No. The CLR will load the assembly once a method is to be JITTED, and is depended an assembly in order to execute. The JIT will instruct the runtime to load that DLL.

Does it do verification check on it?

Yes, the binder, which is responsible for loading the dll will verify it as a valid assembly via it's metadata in the CLR header (see section below).

When it comes to compiling the code (JIT compiler), does it look for NGen'd code and load the compiled native CPU instructions from that file, or doesn't load the assembly at all when NGen'd file is already there?

Not sure what you mean by "NGENED file already there", but the native binder will look for the native dll as part of the loading process. This article explains the details of loading the assembly to details:

  1. First the standard fusion binder will kick in to find that assembly. It can find it either in:

    • GAC, which means it is strongly named. The way files are placed in GAC ensures that the binder can extract all the required information about the assembly without physically opening the file

    • Find it the APPBASE (E.g. the local folder of program.exe). It will proceed to open the IL file and read the assemblies metadata.

  2. Native binding will proceed only in the default context (more about this in a later post)
  3. The NativeBinder finds the NI file from the NIC. It reads in the NI file details and metadata
  4. Verifies the NI is indeed for that very same IL assembly. For that it goes through a rigorous matching process which includes (but not limited to) full assembly name match (same name, version, public key tokens, culture), time stamp matching (NI has to be newer than IL), MVID (see below)
  5. Also verifies that the NI has been generated for the same CLR under which it is going to be run (exact .NET version, processor type, etc…) .
  6. Also ensures that the NI’s dependencies are also valid. E.g. when the NI was generated it bound against a particular version of mscorlib. If that mscorlib native image is not valid then this NI image is also rejected

Default context:

Default context: This is the context where assembly loaded through implicit assembly references or Assembly.Load(…) call lands