Hi all,

when working on debugger integration, i took a look to the generated
assembly. I found that there is a lot of jmp instruction ("jmp $+5") that do
nothing else but jumping to the very next instruction. Considering a jmp
instruction takes about 7 clocks ticks, it can be a noticeable waste of
time...
After a little digging, I've found two main sources for this.

The first one is directly in the IL code generated by the C# compiler. I
don't know why but the compiler sometime produce a pattern like this:
IL_0005: br.s IL_0007
IL_0007: ...
This code is obviously translated to "jmp $+5". The proposed correction is
to check if the offset equals 2, and in this case to remove the IL
instruction.
Modified files: AOT\Core\IR\Block.cs,

The second source is in the AOT itself. When translating a return
instruction, the AOT inserts a jump to the method epilogue, which is just
after the last block of the method.
If return is the last instruction of the last block, it logically generates
a "jmp $+5" code.
The proposed correction is to check if it's the last instruction of the last
block. If it's not the case, the AOT can insert a jmp instruction.
Modified files: AOT\Core\IR\Method.cs, AOT\Core\X86\AssemblyMethod.cs and
AOT\Core\X86\IR.cs

Before any correction there are about 3500 "jmp $+5" instruction.
The first patch reduces this amount to about 2500.
After the second, there are about 750 "jmp $+5" left (i need much time to
find the cause of these last ones)

Cédric Rousseau
Index: AOT/Core/IR/Block.cs
===================================================================
--- AOT/Core/IR/Block.cs	(revision 989)
+++ AOT/Core/IR/Block.cs	(working copy)
@@ -1367,6 +1367,10 @@
 
 		private SharpOS.AOT.IR.Instructions.Instruction Br_S (Mono.Cecil.Cil.Instruction cilInstruction)
 		{
+			Mono.Cecil.Cil.Instruction op = cilInstruction.Operand as Mono.Cecil.Cil.Instruction;
+			if (op != null && op.Offset - cilInstruction.Offset == 2)
+				return null;
+
 			return new Jump ();
 		}
 
Index: AOT/Core/IR/Method.cs
===================================================================
--- AOT/Core/IR/Method.cs	(revision 989)
+++ AOT/Core/IR/Method.cs	(working copy)
@@ -2046,6 +2046,8 @@
 
 		private List<Block> blocks;
 
+		internal List<Block> Blocks { get { return blocks; } }
+
 		/// <summary>
 		/// Returns an enumerator that iterates through the collection.
 		/// </summary>
Index: AOT/Core/X86/AssemblyMethod.cs
===================================================================
--- AOT/Core/X86/AssemblyMethod.cs	(revision 989)
+++ AOT/Core/X86/AssemblyMethod.cs	(working copy)
@@ -125,7 +125,10 @@
 			if (stackSize > 0)
 				assembly.SUB (R32.ESP, (UInt32) (stackSize * this.assembly.IntSize));
 
-			foreach (Block block in method) {
+			//foreach (Block block in method) {
+			for ( int b=0; b<method.Blocks.Count; b++ ) {
+				Block block = method.Blocks [b];
+
 				assembly.LABEL (string.Format (Assembly.METHOD_BLOCK_LABEL, fullname, block.Index.ToString ()));
 
 				if (block.IsFinallyBegin
@@ -151,7 +154,10 @@
 					}
 				}
 
-				foreach (SharpOS.AOT.IR.Instructions.Instruction instruction in block) {
+				//foreach (SharpOS.AOT.IR.Instructions.Instruction instruction in block) {
+				for (int i = 0; i<block.InstructionsCount; i++) {
+					SharpOS.AOT.IR.Instructions.Instruction instruction = block[i];
+
 					assembly.COMMENT (instruction.ToString ());
 
 					if (instruction.Ignore)
@@ -161,8 +167,15 @@
 						this.Call (instruction as SharpOS.AOT.IR.Instructions.Call);
 
 					else if (instruction is IR.Instructions.Return)
+					{
 						this.Return (instruction as IR.Instructions.Return);
 
+						if ((b < method.Blocks.Count - 1) || (i < block.InstructionsCount - 1))
+						{
+							assembly.JMP (method.MethodFullName + " exit");
+						}
+					}
+
 					else if (instruction is IR.Instructions.Initialize)
 						this.Initialize (instruction as IR.Instructions.Initialize);
 
Index: AOT/Core/X86/IR.cs
===================================================================
--- AOT/Core/X86/IR.cs	(revision 989)
+++ AOT/Core/X86/IR.cs	(working copy)
@@ -662,8 +662,6 @@
 					throw new NotImplementedEngineException ("'" + instruction + "' is not supported.");
 				}
 			}
-
-			assembly.JMP (method.MethodFullName + " exit");
 		}
 
 		private void Initialize (IR.Instructions.Initialize initialize)
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
SharpOS-Developers mailing list
SharpOS-Developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sharpos-developers

Reply via email to