Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Yet another MSIL question (ldsfld, ldarg_0 problem)

Yet another MSIL question (ldsfld, ldarg_0 problem)

Scheduled Pinned Locked Moved C#
data-structureshelpquestiondotnetalgorithms
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rcollina
    wrote on last edited by
    #1

    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  |          *
    
    L 1 Reply Last reply
    0
    • R rcollina

      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  |          *
      
      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi, isnt the method you call popping all its args ?? If so, you could contemplate a "duplicate" before the call. if not, are you sure it is not modifying the stacked values ? At a more macroscopic level: are you sure a few loads will be noticed amongst those calls ? I expect call to be more expensive than load, and unless your called method is extremely short, the loads wouldnt matter much... Hope this helps. :)

      Luc Pattyn

      R 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi, isnt the method you call popping all its args ?? If so, you could contemplate a "duplicate" before the call. if not, are you sure it is not modifying the stacked values ? At a more macroscopic level: are you sure a few loads will be noticed amongst those calls ? I expect call to be more expensive than load, and unless your called method is extremely short, the loads wouldnt matter much... Hope this helps. :)

        Luc Pattyn

        R Offline
        R Offline
        rcollina
        wrote on last edited by
        #3

        Hello Luc, thanks for your reply. I will consider what you wrote about the loads. Can you please extend what you mean with a "duplicate"? I don't know if other variables will remain into the stack after the calls, I'll check further into this. Thanks again!

        L 1 Reply Last reply
        0
        • R rcollina

          Hello Luc, thanks for your reply. I will consider what you wrote about the loads. Can you please extend what you mean with a "duplicate"? I don't know if other variables will remain into the stack after the calls, I'll check further into this. Thanks again!

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          Hi Roberto, I dont know MSIL in detail, but some stack oriented machines have a "duplicate" or "dup" instruction that just duplicates "top of stack" (I know PostScript has it). If there is, it may be cheaper than a second load. BTW I forgot the most obvious tip of all: if the method you call is short, you should inline it (and if its long, then thats where you should optimize). Regards,

          Luc Pattyn

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups