DotNet: Yet another MSIL question (ldsfld, ldarg_0 problem)

  • robertocollina / 100 / Fri, 27 Mar 2009 22:04:00 GMT / Comments (2)
  • Hello everyone,

    I really hope someone can help me out as this is a major break point in my development process. I've been googling for info to no avail, and sadly my knowledge reaches a certain extent, being self-taught.

    I've been working with IL lately, and I came to the point where optimization was needed (since I'm working in a real-time 3d environment).

    The code - which was working (thanks to S. Senthil Kumar) - contained ldarg_0 instructions. Too many in my opinion, since the argument was already loaded onto the stack, as far as I know.

    I was passing to the dynamic method an object array (defined as params object[] in the delegate).

    Argument: object[] objectParams

    ldarg_0
    ldc.I4 0
    ldelem_ref
    call (calling some method included in the objectParams[0] object)
    ldarg_0

    ldc.I4 1

    ldelem_ref

    call (calling some method included in the objectParams[1] object)
    ...


    This code worked. As I stated above, I needed to optimize this, since I found pretty useless to reload the argument every time I switched to the subsequent array item.
    I decided to have a static field in my static class which contained that object array, instead of passing it to the dynamic method.
    m_MyField is a FieldInfo reference to this object array. I can safely obtain it, it's not null.

    Code:
    ldsfld m_MyField

    ldc.I4 0

    ldelem_ref

    So, I should have three values in my stack, in this sequence: m_MyField (object[]), 0, m_MyField[0]

    If I were to pop twice, the current value in the stack should be m_MyField, right?

    So that this could would be right:

    Code:

    ldsfld m_MyField

    ldc.I4 0

    ldelem_ref
    call (some method contained in the referenced object)

    pop

    pop

    //back to m_MyField, I can load the next array item

    //the stack is containing the m_MyField array

    ldc.I4 1

    ldelem_ref

    call (some method contained in the referenced object)

    pop

    pop


    As you can see, there's only one ldsfld instruction, and then two pops, in order to get back to the object array. Sadly, this is not working. I am assuming that ldarg_0 works just like ldsfld in order to get that specific object array.

    Here's a ILStream excerpt:
    IL_0000: /* 7e | 04000002 */ ldsfld System.Object[] m_MSILMethodTemporaryParamField/Dreams.PlugInManager
    IL_0005: /* 20 | 00000000 */ ldc.i4 0
    IL_000a: /* 9a | */ ldelem.ref
    IL_000b: /* 28 | 06000003 */ call Void PreRender()/Dreams.UserInterface.UserInterface
    IL_0010: /* 26 | */ pop
    IL_0011: /* 26 | */ pop
    IL_0012: /* 20 | 00000001 */ ldc.i4 1
    IL_0017: /* 9a | */ ldelem.ref
    IL_0018: /* 28 | 06000004 */ call Void PreRender()/Dreams.UserInterface.UserInterfaceEditor
    IL_001d: /* 26 | */ pop
    IL_001e: /* 26 | */ pop
    IL_001f: /* 2a | */ ret

    Any help is much, much appreciated.
    Thanks for your time.

  • Keywords:

    msil, ldsfld, ldarg_0, dotnet, .net

  • http://dotnet.itags.org/dotnet-tech/302/«« Last Thread - Next Thread »»
    1. Moving to the Common Language Runtime forum.

      -Tom Meschter
      Software Dev, Visual C# IDE

      tommeschtermsft | Wed, 05 Sep 2007 18:09:00 GMT |

    2. >>> ldsfld m_MyField
      >>> ldc.I4 0
      >>> ldelem_ref
      >>> So, I should have three values in my stack, in this sequence: m_MyField (object[]), 0, m_MyField[0]

      ldelem_ref will replace two values on the stack with the array element. You will have just one value on the stack: m_MyField[0].

      ECMA 335 Partition III (http://msdn2.microsoft.com/en-us/netframework/aa569283.aspx) describes how IL works. You may find it useful.

      Also, when optimizing IL, you should keep in mind that it will be translated to native code by the JIT. Smaller IL does not necessarily lead to faster native code. In this particular case, the original code that you have started with is likely the most officient one.

      -Jan Kotas
      CLR JIT/NGEN

      jkotas | Wed, 05 Sep 2007 18:10:00 GMT |