Bug 44440

Summary: Attempting to JIT error in function with pointer arithmetic
Product: [Mono] Compilers Reporter: Frank A. Krueger <fak>
Component: C#Assignee: Marek Safar <masafa>
Status: RESOLVED FIXED    
Severity: blocker CC: bryanc, kumpera, miguel, mono-bugs+monotouch, mono-bugs+mono, vargaz
Priority: Highest    
Version: 4.6.0 (C8)   
Target Milestone: ---   
Hardware: PC   
OS: Mac OS   
Tags: Is this bug a regression?: ---
Last known good build:
Attachments: Project that reproduces the bug

Description Frank A. Krueger 2016-09-16 20:22:47 UTC
Created attachment 17556 [details]
Project that reproduces the bug

When the following code is added to "CopyImage":

			for (var y = 0; y < height; y++)
			{
				var bp = ba + y * bytesPerRow / 4;
				var dp = da + y * bytesPerRow / 4;

				for (var x = 0; x < width; x++)
				{
					var color = *bp;
					*dp = color;
					bp++;
					dp++;
				}
			}

I get these errors:

System.ExecutionEngineException: Attempting to JIT compile method 'NightVision.Camera:CopyImage (intptr,System.nint,System.nint,System.nint)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.

  at NightVision.Camera.ImageFromSampleBuffer (CoreMedia.CMSampleBuffer sampleBuffer, System.nint& width, System.nint& height) [0x0004b] in /Users/fak/Dropbox/Projects/NightVision/NightVision/Camera.cs:219 
  at NightVision.Camera+CameraDelegate.DidOutputSampleBuffer (AVFoundation.AVCaptureOutput captureOutput, CoreMedia.CMSampleBuffer sampleBuffer, AVFoundation.AVCaptureConnection connection) [0x0000d] in /Users/fak/Dropbox/Projects/NightVision/NightVision/Camera.cs:149 

If I replace the pointer math with Buffer.MemoryCopy, everything works.

This code used to work without a problem. I presented it at Xamarin Evolve years ago. I'm not sure when Xamarin regressed.

I attached a repro project. Just run it on device. The code in question is on line 185 of Camera.cs.

=== Xamarin Studio Enterprise ===

Version 6.1 (build 5441)
Installation UUID: 033a3a98-f63f-44a3-8bd3-bb3b731f3639
Runtime:
	Mono 4.6.0 (mono-4.6.0-branch/746756c) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 406000245

=== NuGet ===

Version: 3.4.3.0

=== Xamarin.Profiler ===

Version: 0.32.0
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 8.0 (11246)
Build 8A218a

=== Xamarin.Mac ===

Version: 2.10.0.99 (Xamarin Enterprise)

=== Xamarin.Android ===

Version: 7.0.0.18 (Xamarin Enterprise)
Android SDK: /Users/fak/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		2.3   (API level 10)
		4.0.3 (API level 15)
		4.3   (API level 18)
		4.4   (API level 19)
		5.0   (API level 21)
		5.1   (API level 22)
		6.0   (API level 23)

SDK Tools Version: 25.2.2
SDK Platform Tools Version: 24.0.3
SDK Build Tools Version: 24.0.2

Java SDK: /usr
java version "1.8.0_20-ea"
Java(TM) SE Runtime Environment (build 1.8.0_20-ea-b23)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b22, mixed mode)

Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL

=== Xamarin Android Player ===

Version: 0.6.5
Location: /Applications/Xamarin Android Player.app

=== Xamarin.iOS ===

Version: 10.0.0.6 (Xamarin Enterprise)
Hash: 6c3fee4
Branch: xcode8
Build date: 2016-09-09 13:01:32-0400

=== Xamarin Inspector ===

Version: 0.8.0.0
Hash: dc081aa
Branch: master
Build date: Tue Apr 26 23:07:44 UTC 2016

=== Build Information ===

Release ID: 601005441
Git revision: 68292d1ab289911c815ddc715dd7cc29a9752f9f
Build date: 2016-09-09 04:43:23-04
Xamarin addins: ed25d008672663eeb9db55f1ccecb3c24d2fd3b2
Build lane: monodevelop-lion-cycle8

=== Operating System ===

Mac OS X 10.12.0
Darwin muon.local 16.0.0 Darwin Kernel Version 16.0.0
    Mon Aug 29 17:56:20 PDT 2016
    root:xnu-3789.1.32~3/RELEASE_X86_64 x86_64

=== Enabled user installed addins ===

Xamarin Inspector 0.8.0.0
Comment 1 Zoltan Varga 2016-09-16 23:20:45 UTC
This looks like a c# compiler bug. For this method:

		unsafe void CopyImage2(nint width, nint bytesPerRow)
		{
			var buf = IntPtr.Zero;

			var da = (uint*)reuseBuffer;

			var dp = da + width * bytesPerRow;			
		}

It creates the following IL:

    IL_0000:  nop
    IL_0001:  ldsfld     native int [mscorlib]System.IntPtr::Zero
    IL_0006:  stloc.0
    IL_0007:  ldarg.0
    IL_0008:  ldfld      native int NightVision.Camera::reuseBuffer
    IL_000d:  call       void* [mscorlib]System.IntPtr::op_Explicit(native int)
    IL_0012:  stloc.1
    IL_0013:  ldloc.1
    IL_0014:  ldarg.1
    IL_0015:  ldarg.2
    IL_0016:  call       valuetype [Xamarin.iOS]System.nint [Xamarin.iOS]System.nint::op_Multiply(valuetype [Xamarin.iOS]System.nint,
                                                                                                  valuetype [Xamarin.iOS]System.nint)
    IL_001b:  ldc.i4.4
    IL_001c:  conv.i8
    IL_001d:  mul
    IL_001e:  conv.i
    IL_001f:  add
    IL_0020:  stloc.2
    IL_0021:  ret

At 0x1d, a 'mul' is called with a System.nint and an i8 on the stack, so probably a conversion op is missing.
Comment 2 Zoltan Varga 2016-09-16 23:21:46 UTC
This is with the mcs from c8:

Mono C# compiler version 4.6.0.0
Comment 3 Marek Safar 2016-09-19 15:00:09 UTC
Fixed in master and Mono 4.8