Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Would the .NET JIT compiler optimize out a method call?

The stack trace I get back from an ASP.NET application, generated from an ArgumentNullException, gives the impression that an error occurs on the last line of the code below. As far as I can see, that is impossible, but if the JIT optimized out the call to Bar, which would result in a different stack trace, it would explain all. I know for sure its not the c# compiler, as the CIL looks like I would expect. Is it possible the JIT compiler removed the call to Bar?

c# 4, .NET 4.0.30319.1, ASP.NET 4.0.30319.1

EDIT: I should have mentioned this is a release configuration, with Optimize code = on, Debug Info = pdb-only.

Stack Trace:

[ArgumentNullException: Value cannot be null. Parameter name: value]
CreateHiddenField(HtmlTextWriter tr, String name, String value) in Foo.cs:129
Foo(IHttpContext context, HtmlTextWriter writer) in Foo.cs:106

private static void Foo(IHttpContext context, HtmlTextWriter writer)
{ // line 103
  Bar(writer, AuthorizationServerResponseDetailsHttpRequestParser.RequestSAMLFieldName, context);
  Bar(writer, AuthorizationServerResponseDetailsHttpRequestParser.RequestTargetFieldName, context);
  // line 106 - blank line in source code.
  CreateHiddenField(tr, name, string.Empty); // looks like its here
}

private static void Bar(HtmlTextWriter tr,string name, IHttpContext context)
{ // line 116
   #region Sanitation
   if (tr == null) { throw new System.ArgumentNullException("tr"); }
   if (name == null) { throw new System.ArgumentNullException("name"); }
   if (context == null) { throw new System.ArgumentNullException("context"); }
   #endregion

   CreateHiddenField(tr, name, context.RequestQueryString(name));
}

private static void CreateHiddenField(HtmlTextWriter tr, string name, string value)
{ // line 127
   #region Sanitation
   if (tr == null) { throw new System.ArgumentNullException("tr"); }
   if (name == null) { throw new System.ArgumentNullException("name"); }
   if (value == null) { throw new System.ArgumentNullException("value"); }
   #endregion

   // payload...
}
like image 809
jasper Avatar asked Apr 11 '13 17:04

jasper


People also ask

What is the role of JIT compiler in .NET framework?

Working of JIT Compiler: The JIT compiler is required to speed up the code execution and provide support for multiple platforms. Its working is given as follows: The JIT compiler converts the Microsoft Intermediate Language(MSIL) or Common Intermediate Language(CIL) into the machine code.

How does JIT optimization work?

JIT compiler monitors the java program and compiles the bytecode of hot methods (i.e. methods that get called frequently) into machine specific code (i.e. platform binary or native code). This compilation of bytecode into native code occurs as the program executes.

How does JIT compiler work in C#?

The JIT compiler translates the MSIL code of an assembly to native code and uses the CPU architecture of the target machine to execute a . NET application. It also stores the resulting native code so that it is accessible for subsequent calls.

Why does .NET use a JIT compiler instead of just compiling the code once on the target machine?

If it was compiled once for the first machine's specific processor, it would not be able to take advantage of a (possibly) more advanced or efficient instruction set available on the new processor.


1 Answers

According to http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx, if the JITter inlines a method call, it will indeed be collapsed in the stack trace. If you don't want it to inline (which is probably not a good idea), you can use

[MethodImpl(MethodImplOptions.NoInlining)] 

on the method. For an exe, you can also use an INI file to tell the JITter to generate tracking information (at the bottom of the linked page), but I'm not sure how that would work for an ASP.NET app.

like image 133
Ryan M Avatar answered Sep 19 '22 14:09

Ryan M