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
Summary: `sizeof` IL opcode doesn't behave properly with respect to reference types
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: JIT (show other bugs)
Version: unspecified
Hardware: PC Linux
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-11-15 21:31 UTC by Jordan Earls
Modified: 2012-11-17 04:15 UTC (History)
3 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


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

Description Jordan Earls 2012-11-15 21:31:11 UTC
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 UTC
Created attachment 2954 [details]
sizeof IL library (required to run example program)
Comment 2 Jordan Earls 2012-11-15 21:39:38 UTC
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 UTC
Fixed in master.

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