Saturday, September 25, 2010

compiler optimization switch


There are two C# compiler switches that impact code optimization: /optimize and /debug.

On disabing optimize switch (/optimize-), the unoptimized IL code produced by the compiler contains many no-operation (NOP) instructions and also branches that jump to the next line of code. On debugging in IDE, the extra instructions make code easier to debug by allowing breakpoints to be set on control flow instructions. On enabling the switch (/optimize+), compiler will remove these NOP and branch instructions

On enabling debug switch (+/full/pdbonly), the compiler produces a Program Database (PDB) file which helps the debugger find local variables and map the IL instructions to source code. /debug:full switch tells the JIT compiler that you intend to debug the assembly, and the JIT compiler will track what native code came from each IL instruction. This allows you to use the just-in-time debugger feature of Visual Studio to connect a debugger to an already-running process and debug the code easily.

By default, Debug version has /optimize- and /debug:full switches. But Release configuration has /optimize+ and /debug:pdbonly switches specified.

Recently, one of my collegue KarthickAlagar generated the big impact in prod launch. Hats off for his Release mode analysis!

Saturday, September 18, 2010

Contents of .NET Managed Module


There are 4 components in a .NET Managed Module. They are listed as:

1. PE32(Portable Executable 32 bit) or PE32+ header
2. CLR (Common Language Runtime) header
3. Metadata (Data about data)
4. IL(Intermediate Language) Code

PE file header is similar to the Common Object File Format (COFF) header. If the header uses the PE32 format, the file can run on a 32-bit or 64-bit version of Windows. If the header uses the PE32+ format, the file requires a 64-bit version of Windows to run. This header also indicates the type of file: GUI, CUI, or DLL, and contains a timestamp indicating when the file was built.

CLR header contains the version of the CLR required, the MethodDef metadata token of the managed module’s entry point Main method, and the location/size of the module’s metadata, resources, strong name, etc

Every managed module contains two types of metadata tables: tables that describe the types and members defined in your source code and tables that describe the types and members referenced by your source code.

During compilation, .NET source code is converted into the intermediate format to be known by CLR. This type of intermediate format code is termed as IL in .NET environment. At runtime, the CLR converts IL into native CPU instructions.

Friday, September 10, 2010

Compiler switch /Platform


On drilling one of C# compiler (CSC) switch /platform, learned quite interesting info. Letz share it here.

Platform has 4 key switches, anycpu(default), x86, x64 and Itanium. anycpu switch creates PE32/agnostic signature in managed module, which runs as 32 bit app in x86 Windows, as 64 bit in x64 Windows and 64 bit in IA64 Windows. Second switch x86 creates PE32/x86 sign in module, which runs as 32 bit in x86, WoW64 (Windows on Windows64) in x64 & IA64 Windows.
x64 switch creates PE32+/x64 in managed module, which runs as 64 bit app only in x64 Windows. Last switch Itanium makes PE32+/Itanium signature, which runs as 64 bit app only in IA64 Windows.

Windows OS loads x86, x64, or IA64 version of MSCorEE.dll into the process’s address space from C:\Windows\System32 directory. For WoW64, it loads from C:\Windows\SysWow64 directory. Primary thread calls a method defined inside MSCore.dll. This method initializes the CLR, loads the EXE assembly, and then calls its entry point method (Main). At this point, the managed application is up and running.

.NET FW 4.0 has Environment’s Is64BitOperatingSystem property to determine if it is running on a 64-bit version of Windows


Saturday, September 4, 2010

Enum usage in WCF

On working in a defect tracking tool using WCF, I faced a weird problem and thought it might be interesting to you.

Application throws service connection error when I used enums in data contract. The real problem was: DefectStatus
enums was assigned with int values. Itz started by 1 instead of 0. Obviously WCF requires that there is an enum value equal to 0 for serialization. If not, server layer won't get that to your client through WCF - strange but true!

On analysing this problem, there is a work around and a solution. Work around is simiple to start with zero as follows.
public enum DefectStatus
{Unknown = 0,Open = 1,Assigned = 2}

Solution is to put [ServiceKnownType(typeof(Enum))] attribute on the service interface contract, and also add the [EnumMember] attribute to every enum value within the Enumeration data contract
[ServiceKnownType(typeof(DefectStatus))]
public interface IDefectMaintenace
{
}

public enum DefectStatus
{
[EnumMember()]
Open = 1,
[EnumMember()]
Assigned = 2
}

Root cause for the problem is defined in msdn as 'enumeration types can be marked with the DataContractAttribute attribute, in which case every member that participates in serialization must be marked with the EnumMemberAttribute attribute. Members that are not marked are not serialized'. Ref is:
http://msdn.microsoft.com/en-us/library/ms731923.aspx