Bug 19070

Summary: AOT compiler skips "System.Threading.Interlocked:Exchange (System.Threading.Tasks.IContinuation&,System.Threading.Tasks.IContinuation)" in some cases
Product: iOS Reporter: Brendan Zagaeski (Xamarin Support) <brendan.zagaeski>
Component: XI runtimeAssignee: Zoltan Varga <vargaz>
Severity: normal CC: brandon.lyn, mono-bugs+monotouch, sebastien, udhams
Priority: Normal    
Version: 7.2.0   
Target Milestone: Untriaged   
Hardware: PC   
OS: Mac OS   
Tags: Is this bug a regression?: ---
Last known good build:
Attachments: Test case

Description Brendan Zagaeski (Xamarin Support) 2014-04-16 00:37:38 UTC
Created attachment 6589 [details]
Test case

This bug is reminiscent of the old bug #234, but in this new test case, the AOT compiler still skips `System.Threading.Interlocked.Exchange()` when it shouldn't. The reference to the `Exchange()` method is less direct in this case than in the old bug.

## Steps to reproduce

1. Open the attached test case in Xamarin Studio or Visual Studio.

2. Set the debugger to break on `System.Exception` (in "Run -> Exceptions" in Xamarin Studio, or "Debug -> Exceptions" in Visual Studio).

3. Build and run the attached test case in the Debug configuration on device.

4. Tap the "Click me" button.

## Result

The debugger breaks on this exception:

> System.ExecutionEngineException: Attempting to JIT compile method '(wrapper managed-to-native) System.Threading.Interlocked:Exchange (System.Threading.Tasks.IContinuation&,System.Threading.Tasks.IContinuation)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.
>   at System.Threading.Tasks.TaskCompletionQueue`1[System.Threading.Tasks.IContinuation].TryGetNextCompletion (IContinuation& continuation) [0x00000] in <filename unknown>:0 
>   at System.Threading.Tasks.Task.ProcessCompleteDelegates () [0x0001b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:585 
>   at System.Threading.Tasks.Task.Finish () [0x000ce] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:569 
>   at System.Threading.Tasks.Task.<Delay>m__1 (System.Object state) [0x0001a] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading.Tasks/Task.cs:1001 
>   at System.Threading.Timer+Scheduler.TimerCB (System.Object o) [0x00007] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Threading/Timer.cs:317 

## Workaround

Un-comment these two lines in the `MyViewController` constructor:
> var dummyTask = new Task (() => {});
> var dummy = System.Threading.Interlocked.Exchange (ref dummyTask, System.Threading.Tasks.Task.Factory.StartNew (() =>{}));

(Thanks to http://stackoverflow.com/a/13710933/2561894)

## Additional information

The test case depends on the "protobuf-net" NuGet package. Somehow the call to ProtoBuf's `RuntimeTypeModel.Default.Serialize()` method causes a problem for the simple `await Task.Delay(100)` that follows it.

## Version information
Xamarin Studio 4.2.3 (build 60)
Mono 3.2.6 ((no/9b58377)
Xcode 5.1 (5084), build 5B130a
Mac OS X 10.8.5
Comment 2 Udham Singh 2014-04-16 06:27:34 UTC
I have checked this issue and observed the same behavior mentioned into bug description. To reproduce this issue I have followed the steps mentioned in bug description and used the Test case attached into bug description.

Screencast : http://screencast.com/t/gkScmlQZ

Exception Log : https://gist.github.com/anonymous/44cad00484afca7093cb

Environment Info:

=== Xamarin Studio ===

Version 4.2.3 (build 60)
Installation UUID: 011d70a5-dede-428b-ab04-ef451c2e539d
	Mono 3.2.6 ((no/9b58377)
	GTK+ 2.24.23 theme: Raleigh
	GTK# (
	Package version: 302060000

=== Apple Developer Tools ===

Xcode 5.1 (5084)
Build 5B130a

=== Xamarin.iOS ===

Version: (Trial Edition)
Hash: 58c3efa
Build date: 2014-10-03 18:02:26-0400

=== Build Information ===

Release ID: 402030060
Git revision: 30c4afc300c2a39ec5300851357ce02e49dd217e
Build date: 2014-03-05 22:09:33+0000
Xamarin addins: f8a9589b57c2bfab2ccd73c880e7ad81e3ecf044

=== Operating System ===

Mac OS X 10.9.2
Darwin MacMini.local 13.1.0 Darwin Kernel Version 13.1.0
    Thu Jan 16 19:40:37 PST 2014
    root:xnu-2422.90.20~2/RELEASE_X86_64 x86_64
Comment 3 Sebastien Pouliot 2014-04-16 09:32:52 UTC
The same happens on 7.2.1 (and goes away when the workaround code is uncommented) -> Zoltan
Comment 4 Zoltan Varga 2014-04-16 12:07:17 UTC
Fixed in mono master 10f6606d5bcbb6a7b663c5b38a4ab46d51491bc6/mono-3.4.0-branch 3f61b88aa730163aeb24a1f9db9fed6e919d39d9.
Comment 5 Zoltan Varga 2014-04-16 12:08:45 UTC
Mt master bumped in c11d0ed690dca2508d73d42e501ce8d07b9a860f.
Comment 6 Brandon Lyn 2014-04-16 13:27:13 UTC
Thank you for posting and fixing this bug, I've run into the same issue as well.

Would you be able to give an indication of when we can expect to see this change pulled into Xamarin?
Comment 7 Brendan Zagaeski (Xamarin Support) 2014-04-16 14:07:29 UTC
Many thanks for the quick fix!

Just a small additional note for any users who might hit similar errors in the future:

`System.Threading.Interlocked.Exchange(ref Task, Task)` is a shorthand for the generic method `System.Threading.Interlocked.Exchange<Task>(ref Task, Task)`.