Bug 3444 - JIT compile exception when using ConcurrentDictionary in SplitOrderedList ctor()
Summary: JIT compile exception when using ConcurrentDictionary in SplitOrderedList ctor()
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 5.2
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-02-14 10:36 UTC by Brad Pillow
Modified: 2013-05-29 20:11 UTC (History)
8 users (show)

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

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Brad Pillow 2012-02-14 10:36:52 UTC
I'm trying to use ConcurrentDictionary<string, object> and getting the dreaded JIT exception on device in MonoTouch. Apparently the trick of implementing IEqualityComparer as per the issue with Dictionary generics does not work in this case (it did not for me and in this case, both generic items are ref's and not structs, so it should not have been an issue anyway). It turns out, that the JIT exception is thrown when the ctor for ConcurrentDictionary calls the ctor for SplitOrderedList. I would have tried to force instantiation of SplitOrderedList, but it is internal. 

Attached below is a MonoTouch unit test (you need to run it on a device) to demonstrate the issue.

Thanks,
Brad



------------

using System;
using NUnit.Framework;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace GeneralUnitTests.MonoTouch
{
[TestFixture]
public class DatStructuresTest
{
private readonly ConcurrentDictionary<string, object> _subjects = new ConcurrentDictionary<string, object>(new StringEqualityComparer());

class StringEqualityComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return x == y;
}

public int GetHashCode(string obj)
{
return obj.GetHashCode();
}
}

[Test]
public void ConcurrentDictionryJITError()
{
_subjects["problem"] = new List<int>();
}
}
}
Comment 1 Sebastien Pouliot 2012-03-10 13:56:03 UTC
Recent fixes (likely from Rodrigo) in MonoTouch have made our regression test case (for this bug) turn green. As such the next alpha (or beta) from 5.3.x should work.
Comment 2 Brad Pillow 2012-03-10 16:32:31 UTC
Awesome!  I'll look forward to testing it. Any notes on what the fix is?  I.e. is it a larger change that handles jit issues with generics in general or just this specific case?  Thanks!
Comment 3 Sebastien Pouliot 2012-03-11 11:57:22 UTC
Sorry for the false alarm, it still/again fails. My build likely included other code that triggered this (more code being compiled) into working.
Comment 4 Brad Pillow 2012-03-11 21:23:21 UTC
Bummers :( Any news on a more "generic" solution for the issue of generics and JITing exceptions?
Comment 5 JohanO 2012-04-16 17:52:01 UTC
I also had the same issue the other day... I fixed it by manually locking which defeats the concurrent part I suppose.
Comment 6 Brad Pillow 2012-04-16 23:11:59 UTC
Yes, I had already done that to "work around" the issue. The larger issue is more that this is a basic standard .net library class that should work out-of-the-box.  In various code I write, I do I run into the JIT-exception-on-generics issue, but I can usually get around it by forcing an instantiation of the needed generic type. This issue with ConcurrentDictionary and probably others in the .NET framework is that I can't force a reference to a internal private class, which is what would need to be done to "force" ConcurrentDictionary to work. I know it's a touch problem to solve, but still hoping the great MT wizards can come up with a god solution.
Comment 7 Steve Williams 2012-06-01 09:18:05 UTC
The SignalR libraries for ASP.NET use ConcurrentDictionary, so a fix for this issue would help MonoTouch projects access ASP servers that are using SignalR.
Comment 8 Sebastien Pouliot 2012-06-18 15:58:48 UTC
Please try 5.3.4 as the original test case now works on devices. Let us know if there's anything else.
Comment 9 Brad Pillow 2012-06-18 21:42:49 UTC
Alas, no luck :(  I upgraded to 5.3.4 (see "About" attached below), rebuilt and ran on my iPhone 4S in debug. I still get the same JIT error (also copied below).  Do you know what you changed that you believe has fixed it? Was it a change in ConcurrentDictionary or generic handling in general? Let me know if there are other things you would like me to try. I'm just running the Unit test as initially reported in the bug above.

Thanks,
Brad

-----------

MonoDevelop 3.0.3.2
Installation UUID: e4d798a5-fb79-40f3-9bc2-1cf5543116c4
Runtime:
	Mono 2.10.9 (tarball)
	GTK 2.24.10
	GTK# (2.12.0.0)
	Package version: 210090011
Apple Developer Tools:
	 Xcode 4.3.2 (1177)
	 Build 4E2002
Monotouch: 5.3.4
Mono for Android not installed
Build information:
	Release ID: 30003002
	Git revision: 7bf6ac0ca43c1b12703176ad9933c3484c05c84c-dirty
	Build date: 2012-06-16 04:36:10+0000
	Xamarin addins: 62ad7268d38c2ece7e00dc32960bd3bdab8fec38
Operating System:
	Mac OS X 10.7.4
	Darwin devserver.local 11.4.0 Darwin Kernel Version 11.4.0
	    Mon Apr  9 19:32:15 PDT 2012
	    root:xnu-1699.26.8~1/RELEASE_X86_64 x86_64

--------------


System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Exception: Attempting to JIT compile method 'System.Collections.Concurrent.SplitOrderedList`2<string, System.Collections.Generic.KeyValuePair`2<string, object>>:.ctor (System.Collections.Generic.IEqualityComparer`1<string>)' while running with --aot-only.

  at System.Collections.Concurrent.ConcurrentDictionary`2[System.String,System.Object]..ctor (IEqualityComparer`1 comparer) [0x00000] in <filename unknown>:0
  at GeneralUnitTests.MonoTouch.DatStructuresTest..ctor () [0x00000] in <filename unknown>:0
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00109] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:536
  --- End of inner exception stack trace ---
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0011f] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:542
  at System.MonoType.InvokeMember (System.String name, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object target, System.Object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, System.String[] namedParameters) [0x001a2] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/MonoType.cs:403
  at System.Type.InvokeMember (System.String name, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object target, System.Object[] args) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Type.cs:1334
  at MonoTouch.NUnit.UI.TestCaseElement.Run () [0x00000] in /Developer/MonoTouch/Source/Touch.Unit/NUnitLite/TouchRunner/TestCaseElement.cs:50
  at MonoTouch.NUnit.UI.TestCaseElement+<TestCaseElement>c__AnonStorey4.<>m__6 () [0x00026] in /Developer/MonoTouch/Source/Touch.Unit/NUnitLite/TouchRunner/TestCaseElement.cs:29
  at MonoTouch.Dialog.StringElement.Selected (MonoTouch.Dialog.DialogViewController dvc, MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) [0x0000b] in /Developer/MonoTouch/Source/MonoTouch.Dialog/MonoTouch.Dialog/Elements.cs:692
  at MonoTouch.Dialog.DialogViewController.Selected (MonoTouch.Foundation.NSIndexPath indexPath) [0x00029] in /Developer/MonoTouch/Source/MonoTouch.Dialog/MonoTouch.Dialog/DialogViewController.cs:518
  at MonoTouch.Dialog.DialogViewController+Source.RowSelected (MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) [0x00019] in /Developer/MonoTouch/Source/MonoTouch.Dialog/MonoTouch.Dialog/DialogViewController.cs:364
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
  at TestConcurrentDictionary.Application.Main (System.String[] args) [0x00000] in /Users/bpillow/Projects/TestConcurrentDictionary/TestConcurrentDictionary/Main.cs:17
Comment 10 Sebastien Pouliot 2012-06-18 21:53:40 UTC
The test "failed" in our internal test suite. That test is expected to catch the ExecutionEngineException and it did not get any exception. This could be due to changes more recent than 5.3.4 (which was branched a while ago) or something else was added in the test suite that "hinted" the AOT compiler to add the missing pieces. I'll investigate this further (by isolated this test case). Thanks for testing this.
Comment 11 Sebastien Pouliot 2012-06-20 11:30:06 UTC
I rebuilt 5.3.4 and the crash occurs in that version. IOW the fix is more recent than this. Keeping this open until 5.3.5 is released.
Comment 12 Brad Pillow 2012-06-21 17:42:51 UTC
I will await the next rev and try again. I had to downgrade from 5.3.4 as it was giving this weird error about not being able to load mscorlib.dll. No time to research it right now.

Can you elaborate what you believe the fix is for this bug that is in 5.3.5? 

I have revisited using Reactive Extensions a number of times on MonoTouch, but as it makes extensive use of generics, I get get frustrated at all the JIT exceptions that come up (would be the same for F#, which I also wish I could run on MT).  Any chance a more generic, solution for "generics" will happen (i.e. a mechanism to give annotations for generic instantiations so they would know what extra forms to instantiate, or possibly a CLR interpreter that would at least allow the code to run)?

Thanks!
Comment 13 Aaron Oneal 2012-09-08 15:00:40 UTC
I tried to work around this by just including a local copy of ConcurrentDictionary and SplitOrderedList in my library, which gets me past the first JIT exception, but then I eventually hit another because SplitOrderedList.SetBucket calls:

Interlocked.CompareExchange (ref buckets[index], node, null)

I can't think of a good way to work around that one.
Comment 14 Sebastien Pouliot 2013-05-29 20:11:58 UTC
The test case work (since 5.3.5) -> closing

Also worth nothing that 6.3.x beta releases have much improved to avoid this situation (the EngineExecutionException). You might want to try this, or similar code, again and report any remaining issues (with a test case).