|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
MSIL Inquiry involving boxingI'm following a tutorial and they translate this C#: object[] a = {1, "Hello", 123}; to this IL: ..entrypoint ..locals (class System.Object[] V_0,class System.Object V_1,class System.Object[] V_2,int32 V_3) ldc.i4.3 newarr [mscorlib]System.Object stloc.2 ldloc.2 ldc.i4.0 ldc.i4.1 stloc.3 ldloca.s V_3 box [mscorlib]System.Int32 stelem.ref ldloc.2 ldc.i4.1 ldstr "Hello" stelem.ref ldloc.2 ldc.i4.2 ldc.i4.s 123 stloc.3 ldloca.s V_3 box [mscorlib]System.Int32 stelem.ref But when I compile similar code, I get a big difference. Instead of putting the integers in a local variable, they are stored directly and boxed via: IL_0006: stloc.2 IL_0007: ldloc.2 IL_0008: ldc.i4.0 IL_0009: ldc.i4.1 IL_000a: box [mscorlib]System.Int32 IL_000f: stelem.ref IL_0010: ldloc.2 IL_0011: ldc.i4.1 IL_0012: ldstr "Hello" IL_0017: stelem.ref IL_0018: ldloc.2 IL_0019: ldc.i4.2 IL_001a: ldc.i4.s 123 IL_001c: box [mscorlib]System.Int32 IL_0021: stelem.ref The big difference is that the number is pushed directly on the stack and boxed, rather than the number going into a local variable and the address being pushed and then boxed. So 2 questions: 1) Why would there be a difference? I tried both 1.1 and 2.0 compilers, but can't seem to get the ldloca.s version? 2) The more interesting question is how does the box instruction work on a "transient pointer?" Here's the interesting segment: ldloc.2 <- push address of array ldc.i4.0 <- push index 0 ldc.i4.1 stloc.3 <- store number one in local integer variable V_3 ldloca.s V_3 <- Put address of local variable on stack box [mscorlib]System.Int32 <- I guess Box will be able to work with the address??? and make a box based on the dereferenced address? stelem.ref For those curious, the tutorial I'm following is: http://www.vijaymukhi.com/documents/books/ilbook/chap12.htm And do a search for the text "It is in stelem.ref and we are not privy to this code". (It's the following example, after this text) Thanks all... -Ben Hi Ben,
Based on my test, I will get the similar result as you, below is what I got from Reflector: .method private hidebysig static void Main() cil managed { .entrypoint .maxstack 3 .locals init ( [0] object[] objArray1, [1] object obj1, [2] object[] objArray2) L_0000: ldc.i4.3 L_0001: newarr object L_0006: stloc.2 L_0007: ldloc.2 L_0008: ldc.i4.0 L_0009: ldc.i4.1 L_000a: box int32 L_000f: stelem.ref L_0010: ldloc.2 L_0011: ldc.i4.1 L_0012: ldstr "Hello" L_0017: stelem.ref L_0018: ldloc.2 L_0019: ldc.i4.2 L_001a: ldc.i4.s 123 L_001c: box int32 L_0021: stelem.ref ... } I can not find the usage of retrieving the address of local variable with *ldloca.s* instruction. The decision of IL output is controlled by the C# compiler. This means the offical Microsoft provided C# compiler will try to generate a redundant local variable for holding the about-to-be-box value. I am not sure of what C# compiler the author used. I will try to test this on Rotor. I think the output provided by the tutorial author may not be a pratical C# compiler generation, since it event does not generate *init* keyword for .locals. The keyword *init* means that the local variables must be initialized before the method executes. I think this is an important keyword for a commercial C# compiler, since it can leverage CLR's verification process to detect the security hole/programming error for the developer. Anyway, I think you'd better contact the author of the tutorial for which compiler he used to generate his sample output. Thanks. Regarding the boxing for local variable address issue, this is handled by JIT compiler in CLR. I think JIT compiler will take care of getting the value data from the address and do boxing with this value data. If you are curious with the boxing process, the most clear way of understanding it is looking the Rotor source code for boxing. This souce code is defined in Jitinterface.cpp JIT_Box() function(Rotor1.0). <Shared Source CLI Essentials> gives box/unbox an explanation with source code in chapter3. You may comiple the IL code provided by the IL tutorial and set a breakpoint in JIT_Box function, then you will see the call stack of the CLR, which you may find out how box instruction is doing under the cover. Hope this helps. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Jeffrey,
Thanks for the response. The info you gave me on the boxing command was helpful. Thanks... -Ben ""Jeffrey Tan[MSFT]"" wrote: Show quote > Hi Ben, > > Based on my test, I will get the similar result as you, below is what I got > from Reflector: > > .method private hidebysig static void Main() cil managed > { > .entrypoint > .maxstack 3 > .locals init ( > [0] object[] objArray1, > [1] object obj1, > [2] object[] objArray2) > L_0000: ldc.i4.3 > L_0001: newarr object > L_0006: stloc.2 > L_0007: ldloc.2 > L_0008: ldc.i4.0 > L_0009: ldc.i4.1 > L_000a: box int32 > L_000f: stelem.ref > L_0010: ldloc.2 > L_0011: ldc.i4.1 > L_0012: ldstr "Hello" > L_0017: stelem.ref > L_0018: ldloc.2 > L_0019: ldc.i4.2 > L_001a: ldc.i4.s 123 > L_001c: box int32 > L_0021: stelem.ref > ... > } > > I can not find the usage of retrieving the address of local variable with > *ldloca.s* instruction. The decision of IL output is controlled by the C# > compiler. This means the offical Microsoft provided C# compiler will try to > generate a redundant local variable for holding the about-to-be-box value. > > I am not sure of what C# compiler the author used. I will try to test this > on Rotor. > > I think the output provided by the tutorial author may not be a pratical C# > compiler generation, since it event does not generate *init* keyword for > .locals. The keyword *init* means that the local variables must be > initialized before the method executes. I think this is an important > keyword for a commercial C# compiler, since it can leverage CLR's > verification process to detect the security hole/programming error for the > developer. > > Anyway, I think you'd better contact the author of the tutorial for which > compiler he used to generate his sample output. Thanks. > > Regarding the boxing for local variable address issue, this is handled by > JIT compiler in CLR. I think JIT compiler will take care of getting the > value data from the address and do boxing with this value data. If you are > curious with the boxing process, the most clear way of understanding it is > looking the Rotor source code for boxing. This souce code is defined in > Jitinterface.cpp JIT_Box() function(Rotor1.0). <Shared Source CLI > Essentials> gives box/unbox an explanation with source code in chapter3. > You may comiple the IL code provided by the IL tutorial and set a > breakpoint in JIT_Box function, then you will see the call stack of the > CLR, which you may find out how box instruction is doing under the cover. > > Hope this helps. > > Best regards, > Jeffrey Tan > Microsoft Online Community Support > ================================================== > Get notification to my posts through email? Please refer to > http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif > ications. > > Note: The MSDN Managed Newsgroup support offering is for non-urgent issues > where an initial response from the community or a Microsoft Support > Engineer within 1 business day is acceptable. Please note that each follow > up response may take approximately 2 business days as the support > professional working with you may need further investigation to reach the > most efficient resolution. The offering is not appropriate for situations > that require urgent, real-time or phone-based interactions or complex > project analysis and dump analysis issues. Issues of this nature are best > handled working with a dedicated Microsoft Support Engineer by contacting > Microsoft Customer Support Services (CSS) at > http://msdn.microsoft.com/subscriptions/support/default.aspx. > ================================================== > This posting is provided "AS IS" with no warranties, and confers no rights. > > Hi Ben,
Glad to see that my reply can help you. Note: Microsoft has released SSCLI2.0 which makes many changes in the source code. Since <Shared Source CLI Essentials> is targeting Rotor1.0, based on my experience, you'd better download SSCLI1.0 for better source code level learning with this book. The 1.0 version of SSCLI can be downloaded from the link below: http://www.microsoft.com/downloads/details.aspx?familyid=3A1C93FA-7462-47D0- 8E56-8DD34C6292F0&displaylang=en If you need further help, please feel free to post, thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. |
|||||||||||||||||||||||