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. From ILGenerator and emit to fixed? [modified + solution]

From ILGenerator and emit to fixed? [modified + solution]

Scheduled Pinned Locked Moved C#
questiondotnetalgorithmsperformancehelp
7 Posts 3 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
    Ravadre
    wrote on last edited by
    #1

    Hi, Recently I'm working on small compiler for fun (or actually still thinking about it's main features and implementing basic syntax) and I've ran into strange problem. Something that I thought would be easy seem not to be that easy :). What is troubling my mind, is that construction:

    int[] b = new int [100];
    fixed (int* p = b)
    {
    int* z = p;
    for (int i = 0; i < 100; ++i)
    {
    *z = i;
    z++;
    }
    }

    Such code when compiled and disassembled produces such code:

    .locals init ([0] int32[] b,
    [1] int32 i,
    [2] int32& pinned p,
    [3] int32* z,
    [4] bool CS$4$0000,
    [5] int32[] CS$0$0001)
    [...]
    IL_0031: ldloc.s CS$0$0001
    IL_0033: ldc.i4.0
    IL_0034: ldelema [mscorlib]System.Int32
    IL_0039: stloc.2

    This code, from what I understand after searching information in MSDN and few other articles, pins table b (table [5] is the same as b) by pointing to it's first element with p pointer. I've tried to produce such code using ILGenerator, but I have no idea how to declare local variable of type int& (managed pointer), I guess I can declare only int* pointers, now the main question is, will above code work if I change [2] int32& pinned p to [2] int* pinned p. If yes, why compiler uses this type, not just int* pointers, if no - how I can generate such code using code emit? I've made small test, disassembled code compiled with csc, changed pointer from int& to int* and yes, it works, but I can't prove anything with that, because GC had no reason to move the table in memory and I can't force him to try that, so that answered nothing except that I know such construction would be legal. [Solution] For future use hehe, I'll post solution I've come by accident, and it does seem to work: ilGen.DeclareLocal(Type.GetType("System.Int32&"), true); Although it's impossible to "do" anything with this type in code, it seems that it is possible to emit it to assembly (after all :) ).

    modified on Wednesday, December 10, 2008 12:23 PM

    L S 2 Replies Last reply
    0
    • R Ravadre

      Hi, Recently I'm working on small compiler for fun (or actually still thinking about it's main features and implementing basic syntax) and I've ran into strange problem. Something that I thought would be easy seem not to be that easy :). What is troubling my mind, is that construction:

      int[] b = new int [100];
      fixed (int* p = b)
      {
      int* z = p;
      for (int i = 0; i < 100; ++i)
      {
      *z = i;
      z++;
      }
      }

      Such code when compiled and disassembled produces such code:

      .locals init ([0] int32[] b,
      [1] int32 i,
      [2] int32& pinned p,
      [3] int32* z,
      [4] bool CS$4$0000,
      [5] int32[] CS$0$0001)
      [...]
      IL_0031: ldloc.s CS$0$0001
      IL_0033: ldc.i4.0
      IL_0034: ldelema [mscorlib]System.Int32
      IL_0039: stloc.2

      This code, from what I understand after searching information in MSDN and few other articles, pins table b (table [5] is the same as b) by pointing to it's first element with p pointer. I've tried to produce such code using ILGenerator, but I have no idea how to declare local variable of type int& (managed pointer), I guess I can declare only int* pointers, now the main question is, will above code work if I change [2] int32& pinned p to [2] int* pinned p. If yes, why compiler uses this type, not just int* pointers, if no - how I can generate such code using code emit? I've made small test, disassembled code compiled with csc, changed pointer from int& to int* and yes, it works, but I can't prove anything with that, because GC had no reason to move the table in memory and I can't force him to try that, so that answered nothing except that I know such construction would be legal. [Solution] For future use hehe, I'll post solution I've come by accident, and it does seem to work: ilGen.DeclareLocal(Type.GetType("System.Int32&"), true); Although it's impossible to "do" anything with this type in code, it seems that it is possible to emit it to assembly (after all :) ).

      modified on Wednesday, December 10, 2008 12:23 PM

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

      Hi, could it be the "int32& pinned p" line is actually a mistake in the disassembly process, and "int32* pinned p" is what is meant from the start? What does the disassembly show for your own code? IMO you can force the GC to move things using a scenario like this one: - create a class A that takes a lot of memory, say 50KB, but well below the "huge object" threshold (which is around 75KB IIRC). - create a second class B that takes slightly more memory. - instantiate a lot of objects A, keeping their references somewhere, say in a List, until allocating a few more would make you run out of memory. - remove half (i.e.every second) of those objects - now start instantiating the same number of objects from class B. Such scenario is bound to call the GC, which will have to compact (i.e. move most of the A objects) to fill the order. You can fix your class A objects, or alternatively you can replace class A by an array of appropriate size. :)

      Luc Pattyn [Forum Guidelines] [My Articles]


      Fixturized forever. :confused:


      R 1 Reply Last reply
      0
      • R Ravadre

        Hi, Recently I'm working on small compiler for fun (or actually still thinking about it's main features and implementing basic syntax) and I've ran into strange problem. Something that I thought would be easy seem not to be that easy :). What is troubling my mind, is that construction:

        int[] b = new int [100];
        fixed (int* p = b)
        {
        int* z = p;
        for (int i = 0; i < 100; ++i)
        {
        *z = i;
        z++;
        }
        }

        Such code when compiled and disassembled produces such code:

        .locals init ([0] int32[] b,
        [1] int32 i,
        [2] int32& pinned p,
        [3] int32* z,
        [4] bool CS$4$0000,
        [5] int32[] CS$0$0001)
        [...]
        IL_0031: ldloc.s CS$0$0001
        IL_0033: ldc.i4.0
        IL_0034: ldelema [mscorlib]System.Int32
        IL_0039: stloc.2

        This code, from what I understand after searching information in MSDN and few other articles, pins table b (table [5] is the same as b) by pointing to it's first element with p pointer. I've tried to produce such code using ILGenerator, but I have no idea how to declare local variable of type int& (managed pointer), I guess I can declare only int* pointers, now the main question is, will above code work if I change [2] int32& pinned p to [2] int* pinned p. If yes, why compiler uses this type, not just int* pointers, if no - how I can generate such code using code emit? I've made small test, disassembled code compiled with csc, changed pointer from int& to int* and yes, it works, but I can't prove anything with that, because GC had no reason to move the table in memory and I can't force him to try that, so that answered nothing except that I know such construction would be legal. [Solution] For future use hehe, I'll post solution I've come by accident, and it does seem to work: ilGen.DeclareLocal(Type.GetType("System.Int32&"), true); Although it's impossible to "do" anything with this type in code, it seems that it is possible to emit it to assembly (after all :) ).

        modified on Wednesday, December 10, 2008 12:23 PM

        S Offline
        S Offline
        Simon P Stevens
        wrote on last edited by
        #3

        Sorry, I can't answer your question. That's the kind of question that you are only likely to get a proper answer from someone who worked at MS, and wrote portions of the CLR/C# compiler. (Do you have an MSDN license, try the MS managed forums) All I can do is point out a reflector plugin I came across the other day: http://www.codeplex.com/reflectoraddins/Wiki/View.aspx?title=ReflectionEmitLanguage&referringTitle=Home[^] Basically, it displays the C# code that you would need to write to output the same IL for the method. Maybe it will help you figure out how to do what you are trying. Good luck. :)

        Simon

        R 1 Reply Last reply
        0
        • S Simon P Stevens

          Sorry, I can't answer your question. That's the kind of question that you are only likely to get a proper answer from someone who worked at MS, and wrote portions of the CLR/C# compiler. (Do you have an MSDN license, try the MS managed forums) All I can do is point out a reflector plugin I came across the other day: http://www.codeplex.com/reflectoraddins/Wiki/View.aspx?title=ReflectionEmitLanguage&referringTitle=Home[^] Basically, it displays the C# code that you would need to write to output the same IL for the method. Maybe it will help you figure out how to do what you are trying. Good luck. :)

          Simon

          R Offline
          R Offline
          Ravadre
          wrote on last edited by
          #4

          Well, I was hoping someone had similiar problem, that's why I asked here in first place :). I've tried this plugin that you've recommened, but unfortunately without any success. This plugin just copy&paste type from exe, which produces line like that: LocalBuilder p = gen.DeclareLocal(typeof(Int32&)); This isn't even proper c# statement hehe :). So I guess, this path leads to the dead end.

          S 1 Reply Last reply
          0
          • L Luc Pattyn

            Hi, could it be the "int32& pinned p" line is actually a mistake in the disassembly process, and "int32* pinned p" is what is meant from the start? What does the disassembly show for your own code? IMO you can force the GC to move things using a scenario like this one: - create a class A that takes a lot of memory, say 50KB, but well below the "huge object" threshold (which is around 75KB IIRC). - create a second class B that takes slightly more memory. - instantiate a lot of objects A, keeping their references somewhere, say in a List, until allocating a few more would make you run out of memory. - remove half (i.e.every second) of those objects - now start instantiating the same number of objects from class B. Such scenario is bound to call the GC, which will have to compact (i.e. move most of the A objects) to fill the order. You can fix your class A objects, or alternatively you can replace class A by an array of appropriate size. :)

            Luc Pattyn [Forum Guidelines] [My Articles]


            Fixturized forever. :confused:


            R Offline
            R Offline
            Ravadre
            wrote on last edited by
            #5

            Hi, I'm afraid it's not a mistake of a compiler. Based on this article for example: http://www.codeproject.com/KB/msil/ilassembly.aspx It looks like it's just a type, now the question is, does it has some special meaning, especially when pinning objects in memory. Your method looks like it should work, I'll try it and do some tests as soon as I have few free minutes, which means now :).

            1 Reply Last reply
            0
            • R Ravadre

              Well, I was hoping someone had similiar problem, that's why I asked here in first place :). I've tried this plugin that you've recommened, but unfortunately without any success. This plugin just copy&paste type from exe, which produces line like that: LocalBuilder p = gen.DeclareLocal(typeof(Int32&)); This isn't even proper c# statement hehe :). So I guess, this path leads to the dead end.

              S Offline
              S Offline
              Simon P Stevens
              wrote on last edited by
              #6

              Ravadre wrote:

              This isn't even proper c# statement hehe Smile. So I guess, this path leads to the dead end.

              Oh well. I've not used it myself, I just remember seeing it and thinking it looked interesting while looking for a different plug-in. Sorry. Good luck. ;)

              Simon

              R 1 Reply Last reply
              0
              • S Simon P Stevens

                Ravadre wrote:

                This isn't even proper c# statement hehe Smile. So I guess, this path leads to the dead end.

                Oh well. I've not used it myself, I just remember seeing it and thinking it looked interesting while looking for a different plug-in. Sorry. Good luck. ;)

                Simon

                R Offline
                R Offline
                Ravadre
                wrote on last edited by
                #7

                The bright side is that I didn't know that such plugin exists, and it is cool, it will be handy, that's for sure. So thanks for showing me it :)

                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