This is Xamarin's bug tracking system. For product support, please use the support links listed in your Xamarin Account.
Bug 8448 - `sizeof` IL opcode doesn't behave properly with respect to reference types
: `sizeof` IL opcode doesn't behave properly with respect to reference types
Status: RESOLVED FIXED
Product: Runtime
Classification: Mono
Component: JIT
: unspecified
: PC Linux
: --- normal
: ---
Assigned To: Bugzilla
:
:
:
:
  Show dependency treegraph
 
Reported: 2012-11-15 21:31 EST by Jordan Earls
Modified: 2012-11-17 04:15 EST (History)
3 users (show)

See Also:
Tags:
Test Case URL:
External Submit: ---


Attachments
compiled test case (4.00 KB, application/x-msdos-program)
2012-11-15 21:31 EST, Jordan Earls
Details
sizeof IL library (required to run example program) (2.00 KB, application/x-msdos-program)
2012-11-15 21:31 EST, Jordan Earls
Details

Description Jordan Earls 2012-11-15 21:31:11 EST
Created attachment 2953 [details]
compiled test case

I believe I've found a bug concerning the `sizeof` opcode in Mono's IL
implementation. Note: I'm NOT talking about the C# `sizeof()` operator. 

I made a tiny library in IL that has this method:

    .method public static hidebysig
           default int32 SizeOf<T> ()  cil managed
    {
        .maxstack 1
    sizeof !!T
          ret
    }

And then I tested it with:

    class MainClass
    {
        public static void Main (string[] args)
        {
            Console.WriteLine(BareMetal.SizeOf<int>());
            Console.WriteLine(BareMetal.SizeOf<string>());
            Console.WriteLine(BareMetal.SizeOf<Foo>());
            Console.WriteLine(BareMetal.SizeOf<Bar>()); //THIS
            Console.ReadKey();
        }
    }
    struct Foo
    {
        int a, b;
        byte c;
        object foo;
    }
    class Bar
    {
        string foo;
        string bar;
        AssemblyLoadEventArgs meh;
        DateTime d;
        byte[] Buffer;
        int mejhf;
        long fjke;
        byte jkfd;
        int fjkd;
        int jfke;
    }

The output from this program is rather surprising for the sizeof Bar. Here is
the full output (on my 64-bit machine):

4
8
24
72

I posted about this issue in the mailing list, but was told to look here:
http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.sizeof%28v=vs.95%29.aspx

That link appears to indicate my IL is invalid, but it does verify. I believe
that page is flat-out wrong also. In the ECMA spec, on page 423 for partition
III, it says "For a reference type, the size returned is the size of a
reference value to the corresponding type, not the size of the data stored in
objects referred to by a reference value"

Unless Mono is doing some really weird "inlining" of classes into value-types,
then Mono is doing it wrong. This can cause a lot of problems because the
sizeof opcode was created so that pointer arithmetic with arrays is possible
with structures as the elements of the array. 

For reference, on .Net I get the expected value of either 4 or 8 for the size
of "Bar" when running the program there (depends on platform of course)
Comment 1 Jordan Earls 2012-11-15 21:31:53 EST
Created attachment 2954 [details]
sizeof IL library (required to run example program)
Comment 2 Jordan Earls 2012-11-15 21:39:38 EST
The pages are identical, but here is the link to the actual .Net framework
doc(not silverlight):
http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.sizeof%28v=vs.110%29.aspx
Comment 3 Zoltan Varga 2012-11-17 04:15:11 EST
Fixed in master.

Note You need to log in before you can comment on or make changes to this bug.