MSIL Inquiry involving boxing

G

Guest

Hi,

I'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
 
J

Jeffrey Tan[MSFT]

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.
 
G

Guest

Hi Jeffrey,

Thanks for the response. The info you gave me on the boxing command was
helpful.

Thanks...

-Ben

"Jeffrey Tan[MSFT]" said:
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.
 
J

Jeffrey Tan[MSFT]

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top