Bug 3706 - generics aot jit problem
Summary: generics aot jit problem
Alias: None
Product: iOS
Classification: Xamarin
Component: General (show other bugs)
Version: 5.2
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2012-03-01 13:55 UTC by Chris Toshok
Modified: 2016-02-11 15:03 UTC (History)
5 users (show)

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

AppDelegate.cs file (1.42 KB, text/plain)
2012-03-01 13:55 UTC, Chris Toshok
solution I've been using (7.21 KB, application/x-gzip)
2012-03-03 01:38 UTC, Chris Toshok

Description Chris Toshok 2012-03-01 13:55:45 UTC
Created attachment 1447 [details]
AppDelegate.cs file

The attached AppDelegate.cs (just create a normal single view iphone app and replace that file with the attached) crashes with the usual "Could not JIT method ... full-aot..." with or without INTERNAL_SLOT_STRUCT defined.

Neither case seems like it should crash.  The type info should propagate in such a way that the aot compiler knows that (in the !INTERNAL_SLOT_STRUCT case) it needs an instantiation of Slot<ListObject>, shouldn't it?
Comment 1 Chris Toshok 2012-03-01 14:03:07 UTC
changing CrashMono to the following keeps things from crashing:

		public void CrashMono ()
			List<ListSlot<ListObject>> foo = new List<ListSlot<ListObject>>();
			MyList<ListObject> list = new MyList<ListObject>();

but I'm at a loss for how the mono compiler can't propagate T=ListObject into the instantiation of MyList, and know that List<ListSlot<ListObject>> is required itself.
Comment 2 Zoltan Varga 2012-03-01 19:12:29 UTC
I can't reproduce this with a console test program, neither with master or 2.10.
using System;
using System.Collections.Generic;
using System.Linq;

namespace genericsbug
	public class Tests {
		public static void Main (String[] args) {
			MyList<ListObject> list = new MyList<ListObject>();
	class ListObject
	class MyList<T> where T : ListObject
		protected struct Slot
			T item;
		List<Slot> slots = new List<Slot>();
Comment 3 Zoltan Varga 2012-03-02 17:36:20 UTC
I can't repro this with mt 5.2.5 either.
Comment 4 Chris Toshok 2012-03-02 18:24:00 UTC
On device?

it definitely happens here.. 100% of the time...

hrm..  mono version shouldn't matter as monotouch uses all its own stuff.

anything I can do on my end to gather more data?
Comment 5 Zoltan Varga 2012-03-02 19:02:25 UTC
Are you using some special linker flags etc ?
Comment 6 Chris Toshok 2012-03-03 01:35:13 UTC
nope, just a totally vanilla solution.

Let me attach it.
Comment 7 Chris Toshok 2012-03-03 01:38:14 UTC
Created attachment 1456 [details]
solution I've been using
Comment 8 Zoltan Varga 2012-03-03 06:32:54 UTC
I can somewhat reproduce this. I get a runtime assertion in Release|iPhone configuration instead of an exception printed to the application output window.
Comment 9 Zoltan Varga 2012-03-03 06:39:36 UTC
Correction: it only happens in Debug|iHpone configuration, and only if 'Enable debugging' is enabled. Probably the JIT optimizations disabled in debug mode cause this.
Comment 10 Zoltan Varga 2012-03-03 15:12:53 UTC
So the problem happens because of generic sharing. ListObject is a reference type,
so the 	MyList<ListObject> list = new MyList<ListObject>(); call doesn't cause any additional methods to be compiled because MyList<ListObject>.ctor () is generic shared, so it is implemented by MyList<T>.ctor ().
When MyList<T>.ctor () is compiled, it doesn't know about the non-gshared
List<MyList`1/Slot<ListObject>> type which is needed at runtime.
Comment 11 Chris Toshok 2012-03-04 00:31:14 UTC
gsharing isn't turned off in release mode, is it?  is there some other pass that's propagating type info?
Comment 12 Zoltan Varga 2012-03-04 08:51:47 UTC
I can only repro this in Debug mode.
Comment 13 Chris Toshok 2012-03-05 22:09:42 UTC
right.  Just wondering if there's an optimization pass that should be turned on for debug mode so that the code can execute?
Comment 14 Zoltan Varga 2012-03-06 14:15:53 UTC
You can turn on inlining by disabling the code which disables it in mini.c:

                cfg->opt &= ~MONO_OPT_DEADCE;
                //cfg->opt &= ~MONO_OPT_INLINE;
                cfg->opt &= ~MONO_OPT_COPYPROP;
                cfg->opt &= ~MONO_OPT_CONSPROP;
                /* This is no longer needed with sdb */
                //cfg->opt &= ~MONO_OPT_GSHARED;

This will make sdb less usable or not usable at all.
Comment 15 Rodrigo Kumpera 2012-03-06 14:35:25 UTC
Hey Zoltan,

The type List<MyList`1/Slot<T>> can be gshare'able. We should proably should look into how much work it would entail.
Comment 16 Rolf Bjarne Kvinge [MSFT] 2016-02-11 15:03:25 UTC
This works fine now.

Notice (2018-05-21): bugzilla.xamarin.com will be switching to read-only mode on Thursday, 2018-05-25 22:00 UTC.

Please join us on Visual Studio Developer Community and GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs and copy them to the new locations as needed for follow-up. The See Also field on each Bugzilla bug will be updated with a link to its new location when applicable.

After Bugzilla is read-only, if you have new information to add for a bug that does not yet have a matching issue on Developer Community or GitHub, you can create a follow-up issue in the new location. Copy and paste the title and description from this bug, and then add your new details. You can get a pre-formatted version of the title and description here:

In special cases you might also want the comments:

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.

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